ActivityManagerService.java revision e091f22e226f7177e45e23850670c1ad9b63fd75
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20
21import com.android.internal.R;
22import com.android.internal.os.BatteryStatsImpl;
23import com.android.internal.os.ProcessStats;
24import com.android.server.AttributeCache;
25import com.android.server.IntentResolver;
26import com.android.server.ProcessMap;
27import com.android.server.SystemServer;
28import com.android.server.Watchdog;
29import com.android.server.am.ActivityStack.ActivityState;
30import com.android.server.pm.UserManagerService;
31import com.android.server.wm.WindowManagerService;
32
33import dalvik.system.Zygote;
34
35import android.app.Activity;
36import android.app.ActivityManager;
37import android.app.ActivityManagerNative;
38import android.app.ActivityOptions;
39import android.app.ActivityThread;
40import android.app.AlertDialog;
41import android.app.AppGlobals;
42import android.app.ApplicationErrorReport;
43import android.app.Dialog;
44import android.app.IActivityController;
45import android.app.IApplicationThread;
46import android.app.IInstrumentationWatcher;
47import android.app.INotificationManager;
48import android.app.IProcessObserver;
49import android.app.IServiceConnection;
50import android.app.IStopUserCallback;
51import android.app.IThumbnailReceiver;
52import android.app.Instrumentation;
53import android.app.Notification;
54import android.app.NotificationManager;
55import android.app.PendingIntent;
56import android.app.backup.IBackupManager;
57import android.content.ActivityNotFoundException;
58import android.content.BroadcastReceiver;
59import android.content.ClipData;
60import android.content.ComponentCallbacks2;
61import android.content.ComponentName;
62import android.content.ContentProvider;
63import android.content.ContentResolver;
64import android.content.Context;
65import android.content.DialogInterface;
66import android.content.IContentProvider;
67import android.content.IIntentReceiver;
68import android.content.IIntentSender;
69import android.content.Intent;
70import android.content.IntentFilter;
71import android.content.IntentSender;
72import android.content.pm.ActivityInfo;
73import android.content.pm.ApplicationInfo;
74import android.content.pm.ConfigurationInfo;
75import android.content.pm.IPackageDataObserver;
76import android.content.pm.IPackageManager;
77import android.content.pm.InstrumentationInfo;
78import android.content.pm.PackageInfo;
79import android.content.pm.PackageManager;
80import android.content.pm.UserInfo;
81import android.content.pm.PackageManager.NameNotFoundException;
82import android.content.pm.PathPermission;
83import android.content.pm.ProviderInfo;
84import android.content.pm.ResolveInfo;
85import android.content.pm.ServiceInfo;
86import android.content.res.CompatibilityInfo;
87import android.content.res.Configuration;
88import android.graphics.Bitmap;
89import android.net.Proxy;
90import android.net.ProxyProperties;
91import android.net.Uri;
92import android.os.Binder;
93import android.os.Build;
94import android.os.Bundle;
95import android.os.Debug;
96import android.os.DropBoxManager;
97import android.os.Environment;
98import android.os.FileObserver;
99import android.os.FileUtils;
100import android.os.Handler;
101import android.os.IBinder;
102import android.os.IPermissionController;
103import android.os.IUserManager;
104import android.os.Looper;
105import android.os.Message;
106import android.os.Parcel;
107import android.os.ParcelFileDescriptor;
108import android.os.Process;
109import android.os.RemoteCallbackList;
110import android.os.RemoteException;
111import android.os.SELinux;
112import android.os.ServiceManager;
113import android.os.StrictMode;
114import android.os.SystemClock;
115import android.os.SystemProperties;
116import android.os.UserHandle;
117import android.provider.Settings;
118import android.text.format.Time;
119import android.util.EventLog;
120import android.util.Log;
121import android.util.Pair;
122import android.util.PrintWriterPrinter;
123import android.util.Slog;
124import android.util.SparseArray;
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.Set;
157import java.util.concurrent.atomic.AtomicBoolean;
158import java.util.concurrent.atomic.AtomicLong;
159
160public final class ActivityManagerService extends ActivityManagerNative
161        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
162    private static final String USER_DATA_DIR = "/data/user/";
163    static final String TAG = "ActivityManager";
164    static final String TAG_MU = "ActivityManagerServiceMU";
165    static final boolean DEBUG = false;
166    static final boolean localLOGV = DEBUG;
167    static final boolean DEBUG_SWITCH = localLOGV || false;
168    static final boolean DEBUG_TASKS = localLOGV || false;
169    static final boolean DEBUG_PAUSE = localLOGV || false;
170    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
171    static final boolean DEBUG_TRANSITION = localLOGV || false;
172    static final boolean DEBUG_BROADCAST = localLOGV || false;
173    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
174    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
175    static final boolean DEBUG_SERVICE = localLOGV || false;
176    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
177    static final boolean DEBUG_VISBILITY = localLOGV || false;
178    static final boolean DEBUG_PROCESSES = localLOGV || false;
179    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
180    static final boolean DEBUG_PROVIDER = localLOGV || false;
181    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
182    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
183    static final boolean DEBUG_RESULTS = localLOGV || false;
184    static final boolean DEBUG_BACKUP = localLOGV || false;
185    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
186    static final boolean DEBUG_POWER = localLOGV || false;
187    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
188    static final boolean DEBUG_MU = localLOGV || false;
189    static final boolean VALIDATE_TOKENS = false;
190    static final boolean SHOW_ACTIVITY_START_TIME = true;
191
192    // Control over CPU and battery monitoring.
193    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
194    static final boolean MONITOR_CPU_USAGE = true;
195    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
196    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
197    static final boolean MONITOR_THREAD_CPU_USAGE = false;
198
199    // The flags that are set for all calls we make to the package manager.
200    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
201
202    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
203
204    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
205
206    // Maximum number of recent tasks that we can remember.
207    static final int MAX_RECENT_TASKS = 20;
208
209    // Amount of time after a call to stopAppSwitches() during which we will
210    // prevent further untrusted switches from happening.
211    static final long APP_SWITCH_DELAY_TIME = 5*1000;
212
213    // How long we wait for a launched process to attach to the activity manager
214    // before we decide it's never going to come up for real.
215    static final int PROC_START_TIMEOUT = 10*1000;
216
217    // How long we wait for a launched process to attach to the activity manager
218    // before we decide it's never going to come up for real, when the process was
219    // started with a wrapper for instrumentation (such as Valgrind) because it
220    // could take much longer than usual.
221    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
222
223    // How long to wait after going idle before forcing apps to GC.
224    static final int GC_TIMEOUT = 5*1000;
225
226    // The minimum amount of time between successive GC requests for a process.
227    static final int GC_MIN_INTERVAL = 60*1000;
228
229    // The rate at which we check for apps using excessive power -- 15 mins.
230    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
231
232    // The minimum sample duration we will allow before deciding we have
233    // enough data on wake locks to start killing things.
234    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
235
236    // The minimum sample duration we will allow before deciding we have
237    // enough data on CPU usage to start killing things.
238    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
239
240    // How long we allow a receiver to run before giving up on it.
241    static final int BROADCAST_FG_TIMEOUT = 10*1000;
242    static final int BROADCAST_BG_TIMEOUT = 60*1000;
243
244    // How long we wait until we timeout on key dispatching.
245    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
246
247    // How long we wait until we timeout on key dispatching during instrumentation.
248    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
249
250    static final int MY_PID = Process.myPid();
251
252    static final String[] EMPTY_STRING_ARRAY = new String[0];
253
254    public ActivityStack mMainStack;
255
256    private final boolean mHeadless;
257
258    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
259    // default actuion automatically.  Important for devices without direct input
260    // devices.
261    private boolean mShowDialogs = true;
262
263    /**
264     * Description of a request to start a new activity, which has been held
265     * due to app switches being disabled.
266     */
267    static class PendingActivityLaunch {
268        ActivityRecord r;
269        ActivityRecord sourceRecord;
270        int startFlags;
271    }
272
273    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
274            = new ArrayList<PendingActivityLaunch>();
275
276
277    BroadcastQueue mFgBroadcastQueue;
278    BroadcastQueue mBgBroadcastQueue;
279    // Convenient for easy iteration over the queues. Foreground is first
280    // so that dispatch of foreground broadcasts gets precedence.
281    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
282
283    BroadcastQueue broadcastQueueForIntent(Intent intent) {
284        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
285        if (DEBUG_BACKGROUND_BROADCAST) {
286            Slog.i(TAG, "Broadcast intent " + intent + " on "
287                    + (isFg ? "foreground" : "background")
288                    + " queue");
289        }
290        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
291    }
292
293    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
294        for (BroadcastQueue queue : mBroadcastQueues) {
295            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
296            if (r != null) {
297                return r;
298            }
299        }
300        return null;
301    }
302
303    /**
304     * Activity we have told the window manager to have key focus.
305     */
306    ActivityRecord mFocusedActivity = null;
307    /**
308     * List of intents that were used to start the most recent tasks.
309     */
310    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
311
312    /**
313     * Process management.
314     */
315    final ProcessList mProcessList = new ProcessList();
316
317    /**
318     * All of the applications we currently have running organized by name.
319     * The keys are strings of the application package name (as
320     * returned by the package manager), and the keys are ApplicationRecord
321     * objects.
322     */
323    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
324
325    /**
326     * The currently running isolated processes.
327     */
328    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
329
330    /**
331     * Counter for assigning isolated process uids, to avoid frequently reusing the
332     * same ones.
333     */
334    int mNextIsolatedProcessUid = 0;
335
336    /**
337     * The currently running heavy-weight process, if any.
338     */
339    ProcessRecord mHeavyWeightProcess = null;
340
341    /**
342     * The last time that various processes have crashed.
343     */
344    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
345
346    /**
347     * Set of applications that we consider to be bad, and will reject
348     * incoming broadcasts from (which the user has no control over).
349     * Processes are added to this set when they have crashed twice within
350     * a minimum amount of time; they are removed from it when they are
351     * later restarted (hopefully due to some user action).  The value is the
352     * time it was added to the list.
353     */
354    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
355
356    /**
357     * All of the processes we currently have running organized by pid.
358     * The keys are the pid running the application.
359     *
360     * <p>NOTE: This object is protected by its own lock, NOT the global
361     * activity manager lock!
362     */
363    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
364
365    /**
366     * All of the processes that have been forced to be foreground.  The key
367     * is the pid of the caller who requested it (we hold a death
368     * link on it).
369     */
370    abstract class ForegroundToken implements IBinder.DeathRecipient {
371        int pid;
372        IBinder token;
373    }
374    final SparseArray<ForegroundToken> mForegroundProcesses
375            = new SparseArray<ForegroundToken>();
376
377    /**
378     * List of records for processes that someone had tried to start before the
379     * system was ready.  We don't start them at that point, but ensure they
380     * are started by the time booting is complete.
381     */
382    final ArrayList<ProcessRecord> mProcessesOnHold
383            = new ArrayList<ProcessRecord>();
384
385    /**
386     * List of persistent applications that are in the process
387     * of being started.
388     */
389    final ArrayList<ProcessRecord> mPersistentStartingProcesses
390            = new ArrayList<ProcessRecord>();
391
392    /**
393     * Processes that are being forcibly torn down.
394     */
395    final ArrayList<ProcessRecord> mRemovedProcesses
396            = new ArrayList<ProcessRecord>();
397
398    /**
399     * List of running applications, sorted by recent usage.
400     * The first entry in the list is the least recently used.
401     * It contains ApplicationRecord objects.  This list does NOT include
402     * any persistent application records (since we never want to exit them).
403     */
404    final ArrayList<ProcessRecord> mLruProcesses
405            = new ArrayList<ProcessRecord>();
406
407    /**
408     * List of processes that should gc as soon as things are idle.
409     */
410    final ArrayList<ProcessRecord> mProcessesToGc
411            = new ArrayList<ProcessRecord>();
412
413    /**
414     * This is the process holding what we currently consider to be
415     * the "home" activity.
416     */
417    ProcessRecord mHomeProcess;
418
419    /**
420     * This is the process holding the activity the user last visited that
421     * is in a different process from the one they are currently in.
422     */
423    ProcessRecord mPreviousProcess;
424
425    /**
426     * The time at which the previous process was last visible.
427     */
428    long mPreviousProcessVisibleTime;
429
430    /**
431     * Which uses have been started, so are allowed to run code.
432     */
433    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
434
435    /**
436     * LRU list of history of current users.  Most recently current is at the end.
437     */
438    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
439
440    /**
441     * Packages that the user has asked to have run in screen size
442     * compatibility mode instead of filling the screen.
443     */
444    final CompatModePackages mCompatModePackages;
445
446    /**
447     * Set of PendingResultRecord objects that are currently active.
448     */
449    final HashSet mPendingResultRecords = new HashSet();
450
451    /**
452     * Set of IntentSenderRecord objects that are currently active.
453     */
454    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
455            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
456
457    /**
458     * Fingerprints (hashCode()) of stack traces that we've
459     * already logged DropBox entries for.  Guarded by itself.  If
460     * something (rogue user app) forces this over
461     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
462     */
463    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
464    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
465
466    /**
467     * Strict Mode background batched logging state.
468     *
469     * The string buffer is guarded by itself, and its lock is also
470     * used to determine if another batched write is already
471     * in-flight.
472     */
473    private final StringBuilder mStrictModeBuffer = new StringBuilder();
474
475    /**
476     * Keeps track of all IIntentReceivers that have been registered for
477     * broadcasts.  Hash keys are the receiver IBinder, hash value is
478     * a ReceiverList.
479     */
480    final HashMap mRegisteredReceivers = new HashMap();
481
482    /**
483     * Resolver for broadcast intents to registered receivers.
484     * Holds BroadcastFilter (subclass of IntentFilter).
485     */
486    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
487            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
488        @Override
489        protected boolean allowFilterResult(
490                BroadcastFilter filter, List<BroadcastFilter> dest) {
491            IBinder target = filter.receiverList.receiver.asBinder();
492            for (int i=dest.size()-1; i>=0; i--) {
493                if (dest.get(i).receiverList.receiver.asBinder() == target) {
494                    return false;
495                }
496            }
497            return true;
498        }
499
500        @Override
501        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
502            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
503                    || userId == filter.owningUserId) {
504                return super.newResult(filter, match, userId);
505            }
506            return null;
507        }
508
509        @Override
510        protected BroadcastFilter[] newArray(int size) {
511            return new BroadcastFilter[size];
512        }
513
514        @Override
515        protected String packageForFilter(BroadcastFilter filter) {
516            return filter.packageName;
517        }
518    };
519
520    /**
521     * State of all active sticky broadcasts per user.  Keys are the action of the
522     * sticky Intent, values are an ArrayList of all broadcasted intents with
523     * that action (which should usually be one).  The SparseArray is keyed
524     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
525     * for stickies that are sent to all users.
526     */
527    final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts =
528            new SparseArray<HashMap<String, ArrayList<Intent>>>();
529
530    final ActiveServices mServices;
531
532    /**
533     * Backup/restore process management
534     */
535    String mBackupAppName = null;
536    BackupRecord mBackupTarget = null;
537
538    /**
539     * List of PendingThumbnailsRecord objects of clients who are still
540     * waiting to receive all of the thumbnails for a task.
541     */
542    final ArrayList mPendingThumbnails = new ArrayList();
543
544    /**
545     * List of HistoryRecord objects that have been finished and must
546     * still report back to a pending thumbnail receiver.
547     */
548    final ArrayList mCancelledThumbnails = new ArrayList();
549
550    final ProviderMap mProviderMap;
551
552    /**
553     * List of content providers who have clients waiting for them.  The
554     * application is currently being launched and the provider will be
555     * removed from this list once it is published.
556     */
557    final ArrayList<ContentProviderRecord> mLaunchingProviders
558            = new ArrayList<ContentProviderRecord>();
559
560    /**
561     * Global set of specific Uri permissions that have been granted.
562     */
563    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
564            = new SparseArray<HashMap<Uri, UriPermission>>();
565
566    CoreSettingsObserver mCoreSettingsObserver;
567
568    /**
569     * Thread-local storage used to carry caller permissions over through
570     * indirect content-provider access.
571     * @see #ActivityManagerService.openContentUri()
572     */
573    private class Identity {
574        public int pid;
575        public int uid;
576
577        Identity(int _pid, int _uid) {
578            pid = _pid;
579            uid = _uid;
580        }
581    }
582
583    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
584
585    /**
586     * All information we have collected about the runtime performance of
587     * any user id that can impact battery performance.
588     */
589    final BatteryStatsService mBatteryStatsService;
590
591    /**
592     * information about component usage
593     */
594    final UsageStatsService mUsageStatsService;
595
596    /**
597     * Current configuration information.  HistoryRecord objects are given
598     * a reference to this object to indicate which configuration they are
599     * currently running in, so this object must be kept immutable.
600     */
601    Configuration mConfiguration = new Configuration();
602
603    /**
604     * Current sequencing integer of the configuration, for skipping old
605     * configurations.
606     */
607    int mConfigurationSeq = 0;
608
609    /**
610     * Hardware-reported OpenGLES version.
611     */
612    final int GL_ES_VERSION;
613
614    /**
615     * List of initialization arguments to pass to all processes when binding applications to them.
616     * For example, references to the commonly used services.
617     */
618    HashMap<String, IBinder> mAppBindArgs;
619
620    /**
621     * Temporary to avoid allocations.  Protected by main lock.
622     */
623    final StringBuilder mStringBuilder = new StringBuilder(256);
624
625    /**
626     * Used to control how we initialize the service.
627     */
628    boolean mStartRunning = false;
629    ComponentName mTopComponent;
630    String mTopAction;
631    String mTopData;
632    boolean mProcessesReady = false;
633    boolean mSystemReady = false;
634    boolean mBooting = false;
635    boolean mWaitingUpdate = false;
636    boolean mDidUpdate = false;
637    boolean mOnBattery = false;
638    boolean mLaunchWarningShown = false;
639
640    Context mContext;
641
642    int mFactoryTest;
643
644    boolean mCheckedForSetup;
645
646    /**
647     * The time at which we will allow normal application switches again,
648     * after a call to {@link #stopAppSwitches()}.
649     */
650    long mAppSwitchesAllowedTime;
651
652    /**
653     * This is set to true after the first switch after mAppSwitchesAllowedTime
654     * is set; any switches after that will clear the time.
655     */
656    boolean mDidAppSwitch;
657
658    /**
659     * Last time (in realtime) at which we checked for power usage.
660     */
661    long mLastPowerCheckRealtime;
662
663    /**
664     * Last time (in uptime) at which we checked for power usage.
665     */
666    long mLastPowerCheckUptime;
667
668    /**
669     * Set while we are wanting to sleep, to prevent any
670     * activities from being started/resumed.
671     */
672    boolean mSleeping = false;
673
674    /**
675     * State of external calls telling us if the device is asleep.
676     */
677    boolean mWentToSleep = false;
678
679    /**
680     * State of external call telling us if the lock screen is shown.
681     */
682    boolean mLockScreenShown = false;
683
684    /**
685     * Set if we are shutting down the system, similar to sleeping.
686     */
687    boolean mShuttingDown = false;
688
689    /**
690     * Task identifier that activities are currently being started
691     * in.  Incremented each time a new task is created.
692     * todo: Replace this with a TokenSpace class that generates non-repeating
693     * integers that won't wrap.
694     */
695    int mCurTask = 1;
696
697    /**
698     * Current sequence id for oom_adj computation traversal.
699     */
700    int mAdjSeq = 0;
701
702    /**
703     * Current sequence id for process LRU updating.
704     */
705    int mLruSeq = 0;
706
707    /**
708     * Keep track of the non-hidden/empty process we last found, to help
709     * determine how to distribute hidden/empty processes next time.
710     */
711    int mNumNonHiddenProcs = 0;
712
713    /**
714     * Keep track of the number of hidden procs, to balance oom adj
715     * distribution between those and empty procs.
716     */
717    int mNumHiddenProcs = 0;
718
719    /**
720     * Keep track of the number of service processes we last found, to
721     * determine on the next iteration which should be B services.
722     */
723    int mNumServiceProcs = 0;
724    int mNewNumServiceProcs = 0;
725
726    /**
727     * System monitoring: number of processes that died since the last
728     * N procs were started.
729     */
730    int[] mProcDeaths = new int[20];
731
732    /**
733     * This is set if we had to do a delayed dexopt of an app before launching
734     * it, to increasing the ANR timeouts in that case.
735     */
736    boolean mDidDexOpt;
737
738    String mDebugApp = null;
739    boolean mWaitForDebugger = false;
740    boolean mDebugTransient = false;
741    String mOrigDebugApp = null;
742    boolean mOrigWaitForDebugger = false;
743    boolean mAlwaysFinishActivities = false;
744    IActivityController mController = null;
745    String mProfileApp = null;
746    ProcessRecord mProfileProc = null;
747    String mProfileFile;
748    ParcelFileDescriptor mProfileFd;
749    int mProfileType = 0;
750    boolean mAutoStopProfiler = false;
751    String mOpenGlTraceApp = null;
752
753    static class ProcessChangeItem {
754        static final int CHANGE_ACTIVITIES = 1<<0;
755        static final int CHANGE_IMPORTANCE= 1<<1;
756        int changes;
757        int uid;
758        int pid;
759        int importance;
760        boolean foregroundActivities;
761    }
762
763    final RemoteCallbackList<IProcessObserver> mProcessObservers
764            = new RemoteCallbackList<IProcessObserver>();
765    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
766
767    final ArrayList<ProcessChangeItem> mPendingProcessChanges
768            = new ArrayList<ProcessChangeItem>();
769    final ArrayList<ProcessChangeItem> mAvailProcessChanges
770            = new ArrayList<ProcessChangeItem>();
771
772    /**
773     * Callback of last caller to {@link #requestPss}.
774     */
775    Runnable mRequestPssCallback;
776
777    /**
778     * Remaining processes for which we are waiting results from the last
779     * call to {@link #requestPss}.
780     */
781    final ArrayList<ProcessRecord> mRequestPssList
782            = new ArrayList<ProcessRecord>();
783
784    /**
785     * Runtime statistics collection thread.  This object's lock is used to
786     * protect all related state.
787     */
788    final Thread mProcessStatsThread;
789
790    /**
791     * Used to collect process stats when showing not responding dialog.
792     * Protected by mProcessStatsThread.
793     */
794    final ProcessStats mProcessStats = new ProcessStats(
795            MONITOR_THREAD_CPU_USAGE);
796    final AtomicLong mLastCpuTime = new AtomicLong(0);
797    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
798
799    long mLastWriteTime = 0;
800
801    /**
802     * Set to true after the system has finished booting.
803     */
804    boolean mBooted = false;
805
806    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
807    int mProcessLimitOverride = -1;
808
809    WindowManagerService mWindowManager;
810
811    static ActivityManagerService mSelf;
812    static ActivityThread mSystemThread;
813
814    private int mCurrentUserId;
815    private UserManagerService mUserManager;
816
817    private final class AppDeathRecipient implements IBinder.DeathRecipient {
818        final ProcessRecord mApp;
819        final int mPid;
820        final IApplicationThread mAppThread;
821
822        AppDeathRecipient(ProcessRecord app, int pid,
823                IApplicationThread thread) {
824            if (localLOGV) Slog.v(
825                TAG, "New death recipient " + this
826                + " for thread " + thread.asBinder());
827            mApp = app;
828            mPid = pid;
829            mAppThread = thread;
830        }
831
832        public void binderDied() {
833            if (localLOGV) Slog.v(
834                TAG, "Death received in " + this
835                + " for thread " + mAppThread.asBinder());
836            synchronized(ActivityManagerService.this) {
837                appDiedLocked(mApp, mPid, mAppThread);
838            }
839        }
840    }
841
842    static final int SHOW_ERROR_MSG = 1;
843    static final int SHOW_NOT_RESPONDING_MSG = 2;
844    static final int SHOW_FACTORY_ERROR_MSG = 3;
845    static final int UPDATE_CONFIGURATION_MSG = 4;
846    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
847    static final int WAIT_FOR_DEBUGGER_MSG = 6;
848    static final int SERVICE_TIMEOUT_MSG = 12;
849    static final int UPDATE_TIME_ZONE = 13;
850    static final int SHOW_UID_ERROR_MSG = 14;
851    static final int IM_FEELING_LUCKY_MSG = 15;
852    static final int PROC_START_TIMEOUT_MSG = 20;
853    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
854    static final int KILL_APPLICATION_MSG = 22;
855    static final int FINALIZE_PENDING_INTENT_MSG = 23;
856    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
857    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
858    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
859    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
860    static final int CLEAR_DNS_CACHE = 28;
861    static final int UPDATE_HTTP_PROXY = 29;
862    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
863    static final int DISPATCH_PROCESSES_CHANGED = 31;
864    static final int DISPATCH_PROCESS_DIED = 32;
865    static final int REPORT_MEM_USAGE = 33;
866
867    static final int FIRST_ACTIVITY_STACK_MSG = 100;
868    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
869    static final int FIRST_COMPAT_MODE_MSG = 300;
870
871    AlertDialog mUidAlert;
872    CompatModeDialog mCompatModeDialog;
873    long mLastMemUsageReportTime = 0;
874
875    final Handler mHandler = new Handler() {
876        //public Handler() {
877        //    if (localLOGV) Slog.v(TAG, "Handler started!");
878        //}
879
880        public void handleMessage(Message msg) {
881            switch (msg.what) {
882            case SHOW_ERROR_MSG: {
883                HashMap data = (HashMap) msg.obj;
884                synchronized (ActivityManagerService.this) {
885                    ProcessRecord proc = (ProcessRecord)data.get("app");
886                    if (proc != null && proc.crashDialog != null) {
887                        Slog.e(TAG, "App already has crash dialog: " + proc);
888                        return;
889                    }
890                    AppErrorResult res = (AppErrorResult) data.get("result");
891                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
892                        Dialog d = new AppErrorDialog(mContext, res, proc);
893                        d.show();
894                        proc.crashDialog = d;
895                    } else {
896                        // The device is asleep, so just pretend that the user
897                        // saw a crash dialog and hit "force quit".
898                        res.set(0);
899                    }
900                }
901
902                ensureBootCompleted();
903            } break;
904            case SHOW_NOT_RESPONDING_MSG: {
905                synchronized (ActivityManagerService.this) {
906                    HashMap data = (HashMap) msg.obj;
907                    ProcessRecord proc = (ProcessRecord)data.get("app");
908                    if (proc != null && proc.anrDialog != null) {
909                        Slog.e(TAG, "App already has anr dialog: " + proc);
910                        return;
911                    }
912
913                    Intent intent = new Intent("android.intent.action.ANR");
914                    if (!mProcessesReady) {
915                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
916                                | Intent.FLAG_RECEIVER_FOREGROUND);
917                    }
918                    broadcastIntentLocked(null, null, intent,
919                            null, null, 0, null, null, null,
920                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
921
922                    if (mShowDialogs) {
923                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
924                                mContext, proc, (ActivityRecord)data.get("activity"));
925                        d.show();
926                        proc.anrDialog = d;
927                    } else {
928                        // Just kill the app if there is no dialog to be shown.
929                        killAppAtUsersRequest(proc, null);
930                    }
931                }
932
933                ensureBootCompleted();
934            } break;
935            case SHOW_STRICT_MODE_VIOLATION_MSG: {
936                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
937                synchronized (ActivityManagerService.this) {
938                    ProcessRecord proc = (ProcessRecord) data.get("app");
939                    if (proc == null) {
940                        Slog.e(TAG, "App not found when showing strict mode dialog.");
941                        break;
942                    }
943                    if (proc.crashDialog != null) {
944                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
945                        return;
946                    }
947                    AppErrorResult res = (AppErrorResult) data.get("result");
948                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
949                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
950                        d.show();
951                        proc.crashDialog = d;
952                    } else {
953                        // The device is asleep, so just pretend that the user
954                        // saw a crash dialog and hit "force quit".
955                        res.set(0);
956                    }
957                }
958                ensureBootCompleted();
959            } break;
960            case SHOW_FACTORY_ERROR_MSG: {
961                Dialog d = new FactoryErrorDialog(
962                    mContext, msg.getData().getCharSequence("msg"));
963                d.show();
964                ensureBootCompleted();
965            } break;
966            case UPDATE_CONFIGURATION_MSG: {
967                final ContentResolver resolver = mContext.getContentResolver();
968                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
969            } break;
970            case GC_BACKGROUND_PROCESSES_MSG: {
971                synchronized (ActivityManagerService.this) {
972                    performAppGcsIfAppropriateLocked();
973                }
974            } break;
975            case WAIT_FOR_DEBUGGER_MSG: {
976                synchronized (ActivityManagerService.this) {
977                    ProcessRecord app = (ProcessRecord)msg.obj;
978                    if (msg.arg1 != 0) {
979                        if (!app.waitedForDebugger) {
980                            Dialog d = new AppWaitingForDebuggerDialog(
981                                    ActivityManagerService.this,
982                                    mContext, app);
983                            app.waitDialog = d;
984                            app.waitedForDebugger = true;
985                            d.show();
986                        }
987                    } else {
988                        if (app.waitDialog != null) {
989                            app.waitDialog.dismiss();
990                            app.waitDialog = null;
991                        }
992                    }
993                }
994            } break;
995            case SERVICE_TIMEOUT_MSG: {
996                if (mDidDexOpt) {
997                    mDidDexOpt = false;
998                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
999                    nmsg.obj = msg.obj;
1000                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1001                    return;
1002                }
1003                mServices.serviceTimeout((ProcessRecord)msg.obj);
1004            } break;
1005            case UPDATE_TIME_ZONE: {
1006                synchronized (ActivityManagerService.this) {
1007                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1008                        ProcessRecord r = mLruProcesses.get(i);
1009                        if (r.thread != null) {
1010                            try {
1011                                r.thread.updateTimeZone();
1012                            } catch (RemoteException ex) {
1013                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1014                            }
1015                        }
1016                    }
1017                }
1018            } break;
1019            case CLEAR_DNS_CACHE: {
1020                synchronized (ActivityManagerService.this) {
1021                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1022                        ProcessRecord r = mLruProcesses.get(i);
1023                        if (r.thread != null) {
1024                            try {
1025                                r.thread.clearDnsCache();
1026                            } catch (RemoteException ex) {
1027                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1028                            }
1029                        }
1030                    }
1031                }
1032            } break;
1033            case UPDATE_HTTP_PROXY: {
1034                ProxyProperties proxy = (ProxyProperties)msg.obj;
1035                String host = "";
1036                String port = "";
1037                String exclList = "";
1038                if (proxy != null) {
1039                    host = proxy.getHost();
1040                    port = Integer.toString(proxy.getPort());
1041                    exclList = proxy.getExclusionList();
1042                }
1043                synchronized (ActivityManagerService.this) {
1044                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1045                        ProcessRecord r = mLruProcesses.get(i);
1046                        if (r.thread != null) {
1047                            try {
1048                                r.thread.setHttpProxy(host, port, exclList);
1049                            } catch (RemoteException ex) {
1050                                Slog.w(TAG, "Failed to update http proxy for: " +
1051                                        r.info.processName);
1052                            }
1053                        }
1054                    }
1055                }
1056            } break;
1057            case SHOW_UID_ERROR_MSG: {
1058                String title = "System UIDs Inconsistent";
1059                String text = "UIDs on the system are inconsistent, you need to wipe your"
1060                        + " data partition or your device will be unstable.";
1061                Log.e(TAG, title + ": " + text);
1062                if (mShowDialogs) {
1063                    // XXX This is a temporary dialog, no need to localize.
1064                    AlertDialog d = new BaseErrorDialog(mContext);
1065                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1066                    d.setCancelable(false);
1067                    d.setTitle(title);
1068                    d.setMessage(text);
1069                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1070                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1071                    mUidAlert = d;
1072                    d.show();
1073                }
1074            } break;
1075            case IM_FEELING_LUCKY_MSG: {
1076                if (mUidAlert != null) {
1077                    mUidAlert.dismiss();
1078                    mUidAlert = null;
1079                }
1080            } break;
1081            case PROC_START_TIMEOUT_MSG: {
1082                if (mDidDexOpt) {
1083                    mDidDexOpt = false;
1084                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1085                    nmsg.obj = msg.obj;
1086                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1087                    return;
1088                }
1089                ProcessRecord app = (ProcessRecord)msg.obj;
1090                synchronized (ActivityManagerService.this) {
1091                    processStartTimedOutLocked(app);
1092                }
1093            } break;
1094            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1095                synchronized (ActivityManagerService.this) {
1096                    doPendingActivityLaunchesLocked(true);
1097                }
1098            } break;
1099            case KILL_APPLICATION_MSG: {
1100                synchronized (ActivityManagerService.this) {
1101                    int appid = msg.arg1;
1102                    boolean restart = (msg.arg2 == 1);
1103                    String pkg = (String) msg.obj;
1104                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1105                            UserHandle.USER_ALL);
1106                }
1107            } break;
1108            case FINALIZE_PENDING_INTENT_MSG: {
1109                ((PendingIntentRecord)msg.obj).completeFinalize();
1110            } break;
1111            case POST_HEAVY_NOTIFICATION_MSG: {
1112                INotificationManager inm = NotificationManager.getService();
1113                if (inm == null) {
1114                    return;
1115                }
1116
1117                ActivityRecord root = (ActivityRecord)msg.obj;
1118                ProcessRecord process = root.app;
1119                if (process == null) {
1120                    return;
1121                }
1122
1123                try {
1124                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1125                    String text = mContext.getString(R.string.heavy_weight_notification,
1126                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1127                    Notification notification = new Notification();
1128                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1129                    notification.when = 0;
1130                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1131                    notification.tickerText = text;
1132                    notification.defaults = 0; // please be quiet
1133                    notification.sound = null;
1134                    notification.vibrate = null;
1135                    notification.setLatestEventInfo(context, text,
1136                            mContext.getText(R.string.heavy_weight_notification_detail),
1137                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1138                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1139                                    new UserHandle(root.userId)));
1140
1141                    try {
1142                        int[] outId = new int[1];
1143                        inm.enqueueNotificationWithTag("android", null,
1144                                R.string.heavy_weight_notification,
1145                                notification, outId, root.userId);
1146                    } catch (RuntimeException e) {
1147                        Slog.w(ActivityManagerService.TAG,
1148                                "Error showing notification for heavy-weight app", e);
1149                    } catch (RemoteException e) {
1150                    }
1151                } catch (NameNotFoundException e) {
1152                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1153                }
1154            } break;
1155            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1156                INotificationManager inm = NotificationManager.getService();
1157                if (inm == null) {
1158                    return;
1159                }
1160                try {
1161                    inm.cancelNotificationWithTag("android", null,
1162                            R.string.heavy_weight_notification,  msg.arg1);
1163                } catch (RuntimeException e) {
1164                    Slog.w(ActivityManagerService.TAG,
1165                            "Error canceling notification for service", e);
1166                } catch (RemoteException e) {
1167                }
1168            } break;
1169            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1170                synchronized (ActivityManagerService.this) {
1171                    checkExcessivePowerUsageLocked(true);
1172                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1173                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1174                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1175                }
1176            } break;
1177            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1178                synchronized (ActivityManagerService.this) {
1179                    ActivityRecord ar = (ActivityRecord)msg.obj;
1180                    if (mCompatModeDialog != null) {
1181                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1182                                ar.info.applicationInfo.packageName)) {
1183                            return;
1184                        }
1185                        mCompatModeDialog.dismiss();
1186                        mCompatModeDialog = null;
1187                    }
1188                    if (ar != null && false) {
1189                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1190                                ar.packageName)) {
1191                            int mode = mCompatModePackages.computeCompatModeLocked(
1192                                    ar.info.applicationInfo);
1193                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1194                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1195                                mCompatModeDialog = new CompatModeDialog(
1196                                        ActivityManagerService.this, mContext,
1197                                        ar.info.applicationInfo);
1198                                mCompatModeDialog.show();
1199                            }
1200                        }
1201                    }
1202                }
1203                break;
1204            }
1205            case DISPATCH_PROCESSES_CHANGED: {
1206                dispatchProcessesChanged();
1207                break;
1208            }
1209            case DISPATCH_PROCESS_DIED: {
1210                final int pid = msg.arg1;
1211                final int uid = msg.arg2;
1212                dispatchProcessDied(pid, uid);
1213                break;
1214            }
1215            case REPORT_MEM_USAGE: {
1216                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1217                if (!isDebuggable) {
1218                    return;
1219                }
1220                synchronized (ActivityManagerService.this) {
1221                    long now = SystemClock.uptimeMillis();
1222                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1223                        // Don't report more than every 5 minutes to somewhat
1224                        // avoid spamming.
1225                        return;
1226                    }
1227                    mLastMemUsageReportTime = now;
1228                }
1229                Thread thread = new Thread() {
1230                    @Override public void run() {
1231                        StringBuilder dropBuilder = new StringBuilder(1024);
1232                        StringBuilder logBuilder = new StringBuilder(1024);
1233                        StringWriter oomSw = new StringWriter();
1234                        PrintWriter oomPw = new PrintWriter(oomSw);
1235                        StringWriter catSw = new StringWriter();
1236                        PrintWriter catPw = new PrintWriter(catSw);
1237                        String[] emptyArgs = new String[] { };
1238                        StringBuilder tag = new StringBuilder(128);
1239                        StringBuilder stack = new StringBuilder(128);
1240                        tag.append("Low on memory -- ");
1241                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1242                                tag, stack);
1243                        dropBuilder.append(stack);
1244                        dropBuilder.append('\n');
1245                        dropBuilder.append('\n');
1246                        String oomString = oomSw.toString();
1247                        dropBuilder.append(oomString);
1248                        dropBuilder.append('\n');
1249                        logBuilder.append(oomString);
1250                        try {
1251                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1252                                    "procrank", });
1253                            final InputStreamReader converter = new InputStreamReader(
1254                                    proc.getInputStream());
1255                            BufferedReader in = new BufferedReader(converter);
1256                            String line;
1257                            while (true) {
1258                                line = in.readLine();
1259                                if (line == null) {
1260                                    break;
1261                                }
1262                                if (line.length() > 0) {
1263                                    logBuilder.append(line);
1264                                    logBuilder.append('\n');
1265                                }
1266                                dropBuilder.append(line);
1267                                dropBuilder.append('\n');
1268                            }
1269                            converter.close();
1270                        } catch (IOException e) {
1271                        }
1272                        synchronized (ActivityManagerService.this) {
1273                            catPw.println();
1274                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1275                            catPw.println();
1276                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1277                                    false, false, null);
1278                            catPw.println();
1279                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1280                        }
1281                        dropBuilder.append(catSw.toString());
1282                        addErrorToDropBox("lowmem", null, "system_server", null,
1283                                null, tag.toString(), dropBuilder.toString(), null, null);
1284                        Slog.i(TAG, logBuilder.toString());
1285                        synchronized (ActivityManagerService.this) {
1286                            long now = SystemClock.uptimeMillis();
1287                            if (mLastMemUsageReportTime < now) {
1288                                mLastMemUsageReportTime = now;
1289                            }
1290                        }
1291                    }
1292                };
1293                thread.start();
1294                break;
1295            }
1296            }
1297        }
1298    };
1299
1300    public static void setSystemProcess() {
1301        try {
1302            ActivityManagerService m = mSelf;
1303
1304            ServiceManager.addService("activity", m, true);
1305            ServiceManager.addService("meminfo", new MemBinder(m));
1306            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1307            ServiceManager.addService("dbinfo", new DbBinder(m));
1308            if (MONITOR_CPU_USAGE) {
1309                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1310            }
1311            ServiceManager.addService("permission", new PermissionController(m));
1312
1313            ApplicationInfo info =
1314                mSelf.mContext.getPackageManager().getApplicationInfo(
1315                            "android", STOCK_PM_FLAGS);
1316            mSystemThread.installSystemApplicationInfo(info);
1317
1318            synchronized (mSelf) {
1319                ProcessRecord app = mSelf.newProcessRecordLocked(
1320                        mSystemThread.getApplicationThread(), info,
1321                        info.processName, false);
1322                app.persistent = true;
1323                app.pid = MY_PID;
1324                app.maxAdj = ProcessList.SYSTEM_ADJ;
1325                mSelf.mProcessNames.put(app.processName, app.uid, app);
1326                synchronized (mSelf.mPidsSelfLocked) {
1327                    mSelf.mPidsSelfLocked.put(app.pid, app);
1328                }
1329                mSelf.updateLruProcessLocked(app, true, true);
1330            }
1331        } catch (PackageManager.NameNotFoundException e) {
1332            throw new RuntimeException(
1333                    "Unable to find android system package", e);
1334        }
1335    }
1336
1337    public void setWindowManager(WindowManagerService wm) {
1338        mWindowManager = wm;
1339    }
1340
1341    public static final Context main(int factoryTest) {
1342        AThread thr = new AThread();
1343        thr.start();
1344
1345        synchronized (thr) {
1346            while (thr.mService == null) {
1347                try {
1348                    thr.wait();
1349                } catch (InterruptedException e) {
1350                }
1351            }
1352        }
1353
1354        ActivityManagerService m = thr.mService;
1355        mSelf = m;
1356        ActivityThread at = ActivityThread.systemMain();
1357        mSystemThread = at;
1358        Context context = at.getSystemContext();
1359        context.setTheme(android.R.style.Theme_Holo);
1360        m.mContext = context;
1361        m.mFactoryTest = factoryTest;
1362        m.mMainStack = new ActivityStack(m, context, true);
1363
1364        m.mBatteryStatsService.publish(context);
1365        m.mUsageStatsService.publish(context);
1366
1367        synchronized (thr) {
1368            thr.mReady = true;
1369            thr.notifyAll();
1370        }
1371
1372        m.startRunning(null, null, null, null);
1373
1374        return context;
1375    }
1376
1377    public static ActivityManagerService self() {
1378        return mSelf;
1379    }
1380
1381    static class AThread extends Thread {
1382        ActivityManagerService mService;
1383        boolean mReady = false;
1384
1385        public AThread() {
1386            super("ActivityManager");
1387        }
1388
1389        public void run() {
1390            Looper.prepare();
1391
1392            android.os.Process.setThreadPriority(
1393                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1394            android.os.Process.setCanSelfBackground(false);
1395
1396            ActivityManagerService m = new ActivityManagerService();
1397
1398            synchronized (this) {
1399                mService = m;
1400                notifyAll();
1401            }
1402
1403            synchronized (this) {
1404                while (!mReady) {
1405                    try {
1406                        wait();
1407                    } catch (InterruptedException e) {
1408                    }
1409                }
1410            }
1411
1412            // For debug builds, log event loop stalls to dropbox for analysis.
1413            if (StrictMode.conditionallyEnableDebugLogging()) {
1414                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1415            }
1416
1417            Looper.loop();
1418        }
1419    }
1420
1421    static class MemBinder extends Binder {
1422        ActivityManagerService mActivityManagerService;
1423        MemBinder(ActivityManagerService activityManagerService) {
1424            mActivityManagerService = activityManagerService;
1425        }
1426
1427        @Override
1428        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1429            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1430                    != PackageManager.PERMISSION_GRANTED) {
1431                pw.println("Permission Denial: can't dump meminfo from from pid="
1432                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1433                        + " without permission " + android.Manifest.permission.DUMP);
1434                return;
1435            }
1436
1437            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1438                    false, null, null, null);
1439        }
1440    }
1441
1442    static class GraphicsBinder extends Binder {
1443        ActivityManagerService mActivityManagerService;
1444        GraphicsBinder(ActivityManagerService activityManagerService) {
1445            mActivityManagerService = activityManagerService;
1446        }
1447
1448        @Override
1449        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1450            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1451                    != PackageManager.PERMISSION_GRANTED) {
1452                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1453                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1454                        + " without permission " + android.Manifest.permission.DUMP);
1455                return;
1456            }
1457
1458            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1459        }
1460    }
1461
1462    static class DbBinder extends Binder {
1463        ActivityManagerService mActivityManagerService;
1464        DbBinder(ActivityManagerService activityManagerService) {
1465            mActivityManagerService = activityManagerService;
1466        }
1467
1468        @Override
1469        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1470            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1471                    != PackageManager.PERMISSION_GRANTED) {
1472                pw.println("Permission Denial: can't dump dbinfo from from pid="
1473                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1474                        + " without permission " + android.Manifest.permission.DUMP);
1475                return;
1476            }
1477
1478            mActivityManagerService.dumpDbInfo(fd, pw, args);
1479        }
1480    }
1481
1482    static class CpuBinder extends Binder {
1483        ActivityManagerService mActivityManagerService;
1484        CpuBinder(ActivityManagerService activityManagerService) {
1485            mActivityManagerService = activityManagerService;
1486        }
1487
1488        @Override
1489        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1490            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1491                    != PackageManager.PERMISSION_GRANTED) {
1492                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1493                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1494                        + " without permission " + android.Manifest.permission.DUMP);
1495                return;
1496            }
1497
1498            synchronized (mActivityManagerService.mProcessStatsThread) {
1499                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1500                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1501                        SystemClock.uptimeMillis()));
1502            }
1503        }
1504    }
1505
1506    private ActivityManagerService() {
1507        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1508
1509        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1510        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1511        mBroadcastQueues[0] = mFgBroadcastQueue;
1512        mBroadcastQueues[1] = mBgBroadcastQueue;
1513
1514        mServices = new ActiveServices(this);
1515        mProviderMap = new ProviderMap(this);
1516
1517        File dataDir = Environment.getDataDirectory();
1518        File systemDir = new File(dataDir, "system");
1519        systemDir.mkdirs();
1520        mBatteryStatsService = new BatteryStatsService(new File(
1521                systemDir, "batterystats.bin").toString());
1522        mBatteryStatsService.getActiveStatistics().readLocked();
1523        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1524        mOnBattery = DEBUG_POWER ? true
1525                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1526        mBatteryStatsService.getActiveStatistics().setCallback(this);
1527
1528        mUsageStatsService = new UsageStatsService(new File(
1529                systemDir, "usagestats").toString());
1530        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1531
1532        // User 0 is the first and only user that runs at boot.
1533        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1534        mUserLru.add(Integer.valueOf(0));
1535
1536        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1537            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1538
1539        mConfiguration.setToDefaults();
1540        mConfiguration.setLocale(Locale.getDefault());
1541
1542        mConfigurationSeq = mConfiguration.seq = 1;
1543        mProcessStats.init();
1544
1545        mCompatModePackages = new CompatModePackages(this, systemDir);
1546
1547        // Add ourself to the Watchdog monitors.
1548        Watchdog.getInstance().addMonitor(this);
1549
1550        mProcessStatsThread = new Thread("ProcessStats") {
1551            public void run() {
1552                while (true) {
1553                    try {
1554                        try {
1555                            synchronized(this) {
1556                                final long now = SystemClock.uptimeMillis();
1557                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1558                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1559                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1560                                //        + ", write delay=" + nextWriteDelay);
1561                                if (nextWriteDelay < nextCpuDelay) {
1562                                    nextCpuDelay = nextWriteDelay;
1563                                }
1564                                if (nextCpuDelay > 0) {
1565                                    mProcessStatsMutexFree.set(true);
1566                                    this.wait(nextCpuDelay);
1567                                }
1568                            }
1569                        } catch (InterruptedException e) {
1570                        }
1571                        updateCpuStatsNow();
1572                    } catch (Exception e) {
1573                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1574                    }
1575                }
1576            }
1577        };
1578        mProcessStatsThread.start();
1579    }
1580
1581    @Override
1582    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1583            throws RemoteException {
1584        if (code == SYSPROPS_TRANSACTION) {
1585            // We need to tell all apps about the system property change.
1586            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1587            synchronized(this) {
1588                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1589                    final int NA = apps.size();
1590                    for (int ia=0; ia<NA; ia++) {
1591                        ProcessRecord app = apps.valueAt(ia);
1592                        if (app.thread != null) {
1593                            procs.add(app.thread.asBinder());
1594                        }
1595                    }
1596                }
1597            }
1598
1599            int N = procs.size();
1600            for (int i=0; i<N; i++) {
1601                Parcel data2 = Parcel.obtain();
1602                try {
1603                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1604                } catch (RemoteException e) {
1605                }
1606                data2.recycle();
1607            }
1608        }
1609        try {
1610            return super.onTransact(code, data, reply, flags);
1611        } catch (RuntimeException e) {
1612            // The activity manager only throws security exceptions, so let's
1613            // log all others.
1614            if (!(e instanceof SecurityException)) {
1615                Slog.e(TAG, "Activity Manager Crash", e);
1616            }
1617            throw e;
1618        }
1619    }
1620
1621    void updateCpuStats() {
1622        final long now = SystemClock.uptimeMillis();
1623        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1624            return;
1625        }
1626        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1627            synchronized (mProcessStatsThread) {
1628                mProcessStatsThread.notify();
1629            }
1630        }
1631    }
1632
1633    void updateCpuStatsNow() {
1634        synchronized (mProcessStatsThread) {
1635            mProcessStatsMutexFree.set(false);
1636            final long now = SystemClock.uptimeMillis();
1637            boolean haveNewCpuStats = false;
1638
1639            if (MONITOR_CPU_USAGE &&
1640                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1641                mLastCpuTime.set(now);
1642                haveNewCpuStats = true;
1643                mProcessStats.update();
1644                //Slog.i(TAG, mProcessStats.printCurrentState());
1645                //Slog.i(TAG, "Total CPU usage: "
1646                //        + mProcessStats.getTotalCpuPercent() + "%");
1647
1648                // Slog the cpu usage if the property is set.
1649                if ("true".equals(SystemProperties.get("events.cpu"))) {
1650                    int user = mProcessStats.getLastUserTime();
1651                    int system = mProcessStats.getLastSystemTime();
1652                    int iowait = mProcessStats.getLastIoWaitTime();
1653                    int irq = mProcessStats.getLastIrqTime();
1654                    int softIrq = mProcessStats.getLastSoftIrqTime();
1655                    int idle = mProcessStats.getLastIdleTime();
1656
1657                    int total = user + system + iowait + irq + softIrq + idle;
1658                    if (total == 0) total = 1;
1659
1660                    EventLog.writeEvent(EventLogTags.CPU,
1661                            ((user+system+iowait+irq+softIrq) * 100) / total,
1662                            (user * 100) / total,
1663                            (system * 100) / total,
1664                            (iowait * 100) / total,
1665                            (irq * 100) / total,
1666                            (softIrq * 100) / total);
1667                }
1668            }
1669
1670            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1671            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1672            synchronized(bstats) {
1673                synchronized(mPidsSelfLocked) {
1674                    if (haveNewCpuStats) {
1675                        if (mOnBattery) {
1676                            int perc = bstats.startAddingCpuLocked();
1677                            int totalUTime = 0;
1678                            int totalSTime = 0;
1679                            final int N = mProcessStats.countStats();
1680                            for (int i=0; i<N; i++) {
1681                                ProcessStats.Stats st = mProcessStats.getStats(i);
1682                                if (!st.working) {
1683                                    continue;
1684                                }
1685                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1686                                int otherUTime = (st.rel_utime*perc)/100;
1687                                int otherSTime = (st.rel_stime*perc)/100;
1688                                totalUTime += otherUTime;
1689                                totalSTime += otherSTime;
1690                                if (pr != null) {
1691                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1692                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1693                                            st.rel_stime-otherSTime);
1694                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1695                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1696                                } else {
1697                                    BatteryStatsImpl.Uid.Proc ps =
1698                                            bstats.getProcessStatsLocked(st.name, st.pid);
1699                                    if (ps != null) {
1700                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1701                                                st.rel_stime-otherSTime);
1702                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1703                                    }
1704                                }
1705                            }
1706                            bstats.finishAddingCpuLocked(perc, totalUTime,
1707                                    totalSTime, cpuSpeedTimes);
1708                        }
1709                    }
1710                }
1711
1712                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1713                    mLastWriteTime = now;
1714                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1715                }
1716            }
1717        }
1718    }
1719
1720    @Override
1721    public void batteryNeedsCpuUpdate() {
1722        updateCpuStatsNow();
1723    }
1724
1725    @Override
1726    public void batteryPowerChanged(boolean onBattery) {
1727        // When plugging in, update the CPU stats first before changing
1728        // the plug state.
1729        updateCpuStatsNow();
1730        synchronized (this) {
1731            synchronized(mPidsSelfLocked) {
1732                mOnBattery = DEBUG_POWER ? true : onBattery;
1733            }
1734        }
1735    }
1736
1737    /**
1738     * Initialize the application bind args. These are passed to each
1739     * process when the bindApplication() IPC is sent to the process. They're
1740     * lazily setup to make sure the services are running when they're asked for.
1741     */
1742    private HashMap<String, IBinder> getCommonServicesLocked() {
1743        if (mAppBindArgs == null) {
1744            mAppBindArgs = new HashMap<String, IBinder>();
1745
1746            // Setup the application init args
1747            mAppBindArgs.put("package", ServiceManager.getService("package"));
1748            mAppBindArgs.put("window", ServiceManager.getService("window"));
1749            mAppBindArgs.put(Context.ALARM_SERVICE,
1750                    ServiceManager.getService(Context.ALARM_SERVICE));
1751        }
1752        return mAppBindArgs;
1753    }
1754
1755    final void setFocusedActivityLocked(ActivityRecord r) {
1756        if (mFocusedActivity != r) {
1757            mFocusedActivity = r;
1758            if (r != null) {
1759                mWindowManager.setFocusedApp(r.appToken, true);
1760            }
1761        }
1762    }
1763
1764    private final void updateLruProcessInternalLocked(ProcessRecord app,
1765            boolean oomAdj, boolean updateActivityTime, int bestPos) {
1766        // put it on the LRU to keep track of when it should be exited.
1767        int lrui = mLruProcesses.indexOf(app);
1768        if (lrui >= 0) mLruProcesses.remove(lrui);
1769
1770        int i = mLruProcesses.size()-1;
1771        int skipTop = 0;
1772
1773        app.lruSeq = mLruSeq;
1774
1775        // compute the new weight for this process.
1776        if (updateActivityTime) {
1777            app.lastActivityTime = SystemClock.uptimeMillis();
1778        }
1779        if (app.activities.size() > 0) {
1780            // If this process has activities, we more strongly want to keep
1781            // it around.
1782            app.lruWeight = app.lastActivityTime;
1783        } else if (app.pubProviders.size() > 0) {
1784            // If this process contains content providers, we want to keep
1785            // it a little more strongly.
1786            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1787            // Also don't let it kick out the first few "real" hidden processes.
1788            skipTop = ProcessList.MIN_HIDDEN_APPS;
1789        } else {
1790            // If this process doesn't have activities, we less strongly
1791            // want to keep it around, and generally want to avoid getting
1792            // in front of any very recently used activities.
1793            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1794            // Also don't let it kick out the first few "real" hidden processes.
1795            skipTop = ProcessList.MIN_HIDDEN_APPS;
1796        }
1797
1798        while (i >= 0) {
1799            ProcessRecord p = mLruProcesses.get(i);
1800            // If this app shouldn't be in front of the first N background
1801            // apps, then skip over that many that are currently hidden.
1802            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1803                skipTop--;
1804            }
1805            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1806                mLruProcesses.add(i+1, app);
1807                break;
1808            }
1809            i--;
1810        }
1811        if (i < 0) {
1812            mLruProcesses.add(0, app);
1813        }
1814
1815        // If the app is currently using a content provider or service,
1816        // bump those processes as well.
1817        if (app.connections.size() > 0) {
1818            for (ConnectionRecord cr : app.connections) {
1819                if (cr.binding != null && cr.binding.service != null
1820                        && cr.binding.service.app != null
1821                        && cr.binding.service.app.lruSeq != mLruSeq) {
1822                    updateLruProcessInternalLocked(cr.binding.service.app, false,
1823                            updateActivityTime, i+1);
1824                }
1825            }
1826        }
1827        for (int j=app.conProviders.size()-1; j>=0; j--) {
1828            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1829            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1830                updateLruProcessInternalLocked(cpr.proc, false,
1831                        updateActivityTime, i+1);
1832            }
1833        }
1834
1835        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1836        if (oomAdj) {
1837            updateOomAdjLocked();
1838        }
1839    }
1840
1841    final void updateLruProcessLocked(ProcessRecord app,
1842            boolean oomAdj, boolean updateActivityTime) {
1843        mLruSeq++;
1844        updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1845    }
1846
1847    final ProcessRecord getProcessRecordLocked(
1848            String processName, int uid) {
1849        if (uid == Process.SYSTEM_UID) {
1850            // The system gets to run in any process.  If there are multiple
1851            // processes with the same uid, just pick the first (this
1852            // should never happen).
1853            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1854                    processName);
1855            if (procs == null) return null;
1856            final int N = procs.size();
1857            for (int i = 0; i < N; i++) {
1858                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1859            }
1860        }
1861        ProcessRecord proc = mProcessNames.get(processName, uid);
1862        return proc;
1863    }
1864
1865    void ensurePackageDexOpt(String packageName) {
1866        IPackageManager pm = AppGlobals.getPackageManager();
1867        try {
1868            if (pm.performDexOpt(packageName)) {
1869                mDidDexOpt = true;
1870            }
1871        } catch (RemoteException e) {
1872        }
1873    }
1874
1875    boolean isNextTransitionForward() {
1876        int transit = mWindowManager.getPendingAppTransition();
1877        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1878                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1879                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1880    }
1881
1882    final ProcessRecord startProcessLocked(String processName,
1883            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1884            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1885            boolean isolated) {
1886        ProcessRecord app;
1887        if (!isolated) {
1888            app = getProcessRecordLocked(processName, info.uid);
1889        } else {
1890            // If this is an isolated process, it can't re-use an existing process.
1891            app = null;
1892        }
1893        // We don't have to do anything more if:
1894        // (1) There is an existing application record; and
1895        // (2) The caller doesn't think it is dead, OR there is no thread
1896        //     object attached to it so we know it couldn't have crashed; and
1897        // (3) There is a pid assigned to it, so it is either starting or
1898        //     already running.
1899        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1900                + " app=" + app + " knownToBeDead=" + knownToBeDead
1901                + " thread=" + (app != null ? app.thread : null)
1902                + " pid=" + (app != null ? app.pid : -1));
1903        if (app != null && app.pid > 0) {
1904            if (!knownToBeDead || app.thread == null) {
1905                // We already have the app running, or are waiting for it to
1906                // come up (we have a pid but not yet its thread), so keep it.
1907                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1908                // If this is a new package in the process, add the package to the list
1909                app.addPackage(info.packageName);
1910                return app;
1911            } else {
1912                // An application record is attached to a previous process,
1913                // clean it up now.
1914                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1915                handleAppDiedLocked(app, true, true);
1916            }
1917        }
1918
1919        String hostingNameStr = hostingName != null
1920                ? hostingName.flattenToShortString() : null;
1921
1922        if (!isolated) {
1923            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1924                // If we are in the background, then check to see if this process
1925                // is bad.  If so, we will just silently fail.
1926                if (mBadProcesses.get(info.processName, info.uid) != null) {
1927                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1928                            + "/" + info.processName);
1929                    return null;
1930                }
1931            } else {
1932                // When the user is explicitly starting a process, then clear its
1933                // crash count so that we won't make it bad until they see at
1934                // least one crash dialog again, and make the process good again
1935                // if it had been bad.
1936                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1937                        + "/" + info.processName);
1938                mProcessCrashTimes.remove(info.processName, info.uid);
1939                if (mBadProcesses.get(info.processName, info.uid) != null) {
1940                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1941                            info.processName);
1942                    mBadProcesses.remove(info.processName, info.uid);
1943                    if (app != null) {
1944                        app.bad = false;
1945                    }
1946                }
1947            }
1948        }
1949
1950        if (app == null) {
1951            app = newProcessRecordLocked(null, info, processName, isolated);
1952            if (app == null) {
1953                Slog.w(TAG, "Failed making new process record for "
1954                        + processName + "/" + info.uid + " isolated=" + isolated);
1955                return null;
1956            }
1957            mProcessNames.put(processName, app.uid, app);
1958            if (isolated) {
1959                mIsolatedProcesses.put(app.uid, app);
1960            }
1961        } else {
1962            // If this is a new package in the process, add the package to the list
1963            app.addPackage(info.packageName);
1964        }
1965
1966        // If the system is not ready yet, then hold off on starting this
1967        // process until it is.
1968        if (!mProcessesReady
1969                && !isAllowedWhileBooting(info)
1970                && !allowWhileBooting) {
1971            if (!mProcessesOnHold.contains(app)) {
1972                mProcessesOnHold.add(app);
1973            }
1974            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
1975            return app;
1976        }
1977
1978        startProcessLocked(app, hostingType, hostingNameStr);
1979        return (app.pid != 0) ? app : null;
1980    }
1981
1982    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1983        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1984    }
1985
1986    private final void startProcessLocked(ProcessRecord app,
1987            String hostingType, String hostingNameStr) {
1988        if (app.pid > 0 && app.pid != MY_PID) {
1989            synchronized (mPidsSelfLocked) {
1990                mPidsSelfLocked.remove(app.pid);
1991                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1992            }
1993            app.setPid(0);
1994        }
1995
1996        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1997                "startProcessLocked removing on hold: " + app);
1998        mProcessesOnHold.remove(app);
1999
2000        updateCpuStats();
2001
2002        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
2003        mProcDeaths[0] = 0;
2004
2005        try {
2006            int uid = app.uid;
2007
2008            int[] gids = null;
2009            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2010            if (!app.isolated) {
2011                int[] permGids = null;
2012                try {
2013                    final PackageManager pm = mContext.getPackageManager();
2014                    permGids = pm.getPackageGids(app.info.packageName);
2015
2016                    if (Environment.isExternalStorageEmulated()) {
2017                        if (pm.checkPermission(
2018                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2019                                app.info.packageName) == PERMISSION_GRANTED) {
2020                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2021                        } else {
2022                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2023                        }
2024                    }
2025                } catch (PackageManager.NameNotFoundException e) {
2026                    Slog.w(TAG, "Unable to retrieve gids", e);
2027                }
2028
2029                /*
2030                 * Add shared application GID so applications can share some
2031                 * resources like shared libraries
2032                 */
2033                if (permGids == null) {
2034                    gids = new int[1];
2035                } else {
2036                    gids = new int[permGids.length + 1];
2037                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2038                }
2039                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2040            }
2041            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2042                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2043                        && mTopComponent != null
2044                        && app.processName.equals(mTopComponent.getPackageName())) {
2045                    uid = 0;
2046                }
2047                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2048                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2049                    uid = 0;
2050                }
2051            }
2052            int debugFlags = 0;
2053            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2054                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2055                // Also turn on CheckJNI for debuggable apps. It's quite
2056                // awkward to turn on otherwise.
2057                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2058            }
2059            // Run the app in safe mode if its manifest requests so or the
2060            // system is booted in safe mode.
2061            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2062                Zygote.systemInSafeMode == true) {
2063                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2064            }
2065            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2066                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2067            }
2068            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2069                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2070            }
2071            if ("1".equals(SystemProperties.get("debug.assert"))) {
2072                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2073            }
2074
2075            // Start the process.  It will either succeed and return a result containing
2076            // the PID of the new process, or else throw a RuntimeException.
2077            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2078                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2079                    app.info.targetSdkVersion, null, null);
2080
2081            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2082            synchronized (bs) {
2083                if (bs.isOnBattery()) {
2084                    app.batteryStats.incStartsLocked();
2085                }
2086            }
2087
2088            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
2089                    app.processName, hostingType,
2090                    hostingNameStr != null ? hostingNameStr : "");
2091
2092            if (app.persistent) {
2093                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2094            }
2095
2096            StringBuilder buf = mStringBuilder;
2097            buf.setLength(0);
2098            buf.append("Start proc ");
2099            buf.append(app.processName);
2100            buf.append(" for ");
2101            buf.append(hostingType);
2102            if (hostingNameStr != null) {
2103                buf.append(" ");
2104                buf.append(hostingNameStr);
2105            }
2106            buf.append(": pid=");
2107            buf.append(startResult.pid);
2108            buf.append(" uid=");
2109            buf.append(uid);
2110            buf.append(" gids={");
2111            if (gids != null) {
2112                for (int gi=0; gi<gids.length; gi++) {
2113                    if (gi != 0) buf.append(", ");
2114                    buf.append(gids[gi]);
2115
2116                }
2117            }
2118            buf.append("}");
2119            Slog.i(TAG, buf.toString());
2120            app.setPid(startResult.pid);
2121            app.usingWrapper = startResult.usingWrapper;
2122            app.removed = false;
2123            synchronized (mPidsSelfLocked) {
2124                this.mPidsSelfLocked.put(startResult.pid, app);
2125                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2126                msg.obj = app;
2127                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2128                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2129            }
2130        } catch (RuntimeException e) {
2131            // XXX do better error recovery.
2132            app.setPid(0);
2133            Slog.e(TAG, "Failure starting process " + app.processName, e);
2134        }
2135    }
2136
2137    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2138        if (resumed) {
2139            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2140        } else {
2141            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2142        }
2143    }
2144
2145    boolean startHomeActivityLocked(int userId, UserStartedState startingUser) {
2146        if (mHeadless) {
2147            // Added because none of the other calls to ensureBootCompleted seem to fire
2148            // when running headless.
2149            ensureBootCompleted();
2150            return false;
2151        }
2152
2153        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2154                && mTopAction == null) {
2155            // We are running in factory test mode, but unable to find
2156            // the factory test app, so just sit around displaying the
2157            // error message and don't try to start anything.
2158            return false;
2159        }
2160        Intent intent = new Intent(
2161            mTopAction,
2162            mTopData != null ? Uri.parse(mTopData) : null);
2163        intent.setComponent(mTopComponent);
2164        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2165            intent.addCategory(Intent.CATEGORY_HOME);
2166        }
2167        ActivityInfo aInfo =
2168            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2169        if (aInfo != null) {
2170            intent.setComponent(new ComponentName(
2171                    aInfo.applicationInfo.packageName, aInfo.name));
2172            // Don't do this if the home app is currently being
2173            // instrumented.
2174            aInfo = new ActivityInfo(aInfo);
2175            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2176            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2177                    aInfo.applicationInfo.uid);
2178            if (app == null || app.instrumentationClass == null) {
2179                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2180                mMainStack.startActivityLocked(null, intent, null, aInfo,
2181                        null, null, 0, 0, 0, 0, null, false, null);
2182            }
2183        }
2184        if (startingUser != null) {
2185            mMainStack.addStartingUserLocked(startingUser);
2186        }
2187
2188        return true;
2189    }
2190
2191    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2192        ActivityInfo ai = null;
2193        ComponentName comp = intent.getComponent();
2194        try {
2195            if (comp != null) {
2196                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2197            } else {
2198                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2199                        intent,
2200                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2201                            flags, userId);
2202
2203                if (info != null) {
2204                    ai = info.activityInfo;
2205                }
2206            }
2207        } catch (RemoteException e) {
2208            // ignore
2209        }
2210
2211        return ai;
2212    }
2213
2214    /**
2215     * Starts the "new version setup screen" if appropriate.
2216     */
2217    void startSetupActivityLocked() {
2218        // Only do this once per boot.
2219        if (mCheckedForSetup) {
2220            return;
2221        }
2222
2223        // We will show this screen if the current one is a different
2224        // version than the last one shown, and we are not running in
2225        // low-level factory test mode.
2226        final ContentResolver resolver = mContext.getContentResolver();
2227        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2228                Settings.Secure.getInt(resolver,
2229                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2230            mCheckedForSetup = true;
2231
2232            // See if we should be showing the platform update setup UI.
2233            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2234            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2235                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2236
2237            // We don't allow third party apps to replace this.
2238            ResolveInfo ri = null;
2239            for (int i=0; ris != null && i<ris.size(); i++) {
2240                if ((ris.get(i).activityInfo.applicationInfo.flags
2241                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2242                    ri = ris.get(i);
2243                    break;
2244                }
2245            }
2246
2247            if (ri != null) {
2248                String vers = ri.activityInfo.metaData != null
2249                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2250                        : null;
2251                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2252                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2253                            Intent.METADATA_SETUP_VERSION);
2254                }
2255                String lastVers = Settings.Secure.getString(
2256                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2257                if (vers != null && !vers.equals(lastVers)) {
2258                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2259                    intent.setComponent(new ComponentName(
2260                            ri.activityInfo.packageName, ri.activityInfo.name));
2261                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2262                            null, null, 0, 0, 0, 0, null, false, null);
2263                }
2264            }
2265        }
2266    }
2267
2268    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2269        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2270    }
2271
2272    void enforceNotIsolatedCaller(String caller) {
2273        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2274            throw new SecurityException("Isolated process not allowed to call " + caller);
2275        }
2276    }
2277
2278    public int getFrontActivityScreenCompatMode() {
2279        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2280        synchronized (this) {
2281            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2282        }
2283    }
2284
2285    public void setFrontActivityScreenCompatMode(int mode) {
2286        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2287                "setFrontActivityScreenCompatMode");
2288        synchronized (this) {
2289            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2290        }
2291    }
2292
2293    public int getPackageScreenCompatMode(String packageName) {
2294        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2295        synchronized (this) {
2296            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2297        }
2298    }
2299
2300    public void setPackageScreenCompatMode(String packageName, int mode) {
2301        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2302                "setPackageScreenCompatMode");
2303        synchronized (this) {
2304            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2305        }
2306    }
2307
2308    public boolean getPackageAskScreenCompat(String packageName) {
2309        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2310        synchronized (this) {
2311            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2312        }
2313    }
2314
2315    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2316        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2317                "setPackageAskScreenCompat");
2318        synchronized (this) {
2319            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2320        }
2321    }
2322
2323    void reportResumedActivityLocked(ActivityRecord r) {
2324        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2325        updateUsageStats(r, true);
2326    }
2327
2328    private void dispatchProcessesChanged() {
2329        int N;
2330        synchronized (this) {
2331            N = mPendingProcessChanges.size();
2332            if (mActiveProcessChanges.length < N) {
2333                mActiveProcessChanges = new ProcessChangeItem[N];
2334            }
2335            mPendingProcessChanges.toArray(mActiveProcessChanges);
2336            mAvailProcessChanges.addAll(mPendingProcessChanges);
2337            mPendingProcessChanges.clear();
2338            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2339        }
2340        int i = mProcessObservers.beginBroadcast();
2341        while (i > 0) {
2342            i--;
2343            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2344            if (observer != null) {
2345                try {
2346                    for (int j=0; j<N; j++) {
2347                        ProcessChangeItem item = mActiveProcessChanges[j];
2348                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2349                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2350                                    + item.pid + " uid=" + item.uid + ": "
2351                                    + item.foregroundActivities);
2352                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2353                                    item.foregroundActivities);
2354                        }
2355                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2356                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2357                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2358                            observer.onImportanceChanged(item.pid, item.uid,
2359                                    item.importance);
2360                        }
2361                    }
2362                } catch (RemoteException e) {
2363                }
2364            }
2365        }
2366        mProcessObservers.finishBroadcast();
2367    }
2368
2369    private void dispatchProcessDied(int pid, int uid) {
2370        int i = mProcessObservers.beginBroadcast();
2371        while (i > 0) {
2372            i--;
2373            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2374            if (observer != null) {
2375                try {
2376                    observer.onProcessDied(pid, uid);
2377                } catch (RemoteException e) {
2378                }
2379            }
2380        }
2381        mProcessObservers.finishBroadcast();
2382    }
2383
2384    final void doPendingActivityLaunchesLocked(boolean doResume) {
2385        final int N = mPendingActivityLaunches.size();
2386        if (N <= 0) {
2387            return;
2388        }
2389        for (int i=0; i<N; i++) {
2390            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2391            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2392                    pal.startFlags, doResume && i == (N-1), null);
2393        }
2394        mPendingActivityLaunches.clear();
2395    }
2396
2397    public final int startActivity(IApplicationThread caller,
2398            Intent intent, String resolvedType, IBinder resultTo,
2399            String resultWho, int requestCode, int startFlags,
2400            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2401        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2402                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2403    }
2404
2405    public final int startActivityAsUser(IApplicationThread caller,
2406            Intent intent, String resolvedType, IBinder resultTo,
2407            String resultWho, int requestCode, int startFlags,
2408            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2409        enforceNotIsolatedCaller("startActivity");
2410        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2411                false, true, "startActivity", null);
2412        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2413                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2414                null, null, options, userId);
2415    }
2416
2417    public final WaitResult startActivityAndWait(IApplicationThread caller,
2418            Intent intent, String resolvedType, IBinder resultTo,
2419            String resultWho, int requestCode, int startFlags, String profileFile,
2420            ParcelFileDescriptor profileFd, Bundle options, int userId) {
2421        enforceNotIsolatedCaller("startActivityAndWait");
2422        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2423                false, true, "startActivityAndWait", null);
2424        WaitResult res = new WaitResult();
2425        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2426                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2427                res, null, options, UserHandle.getCallingUserId());
2428        return res;
2429    }
2430
2431    public final int startActivityWithConfig(IApplicationThread caller,
2432            Intent intent, String resolvedType, IBinder resultTo,
2433            String resultWho, int requestCode, int startFlags, Configuration config,
2434            Bundle options, int userId) {
2435        enforceNotIsolatedCaller("startActivityWithConfig");
2436        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2437                false, true, "startActivityWithConfig", null);
2438        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2439                resultTo, resultWho, requestCode, startFlags,
2440                null, null, null, config, options, userId);
2441        return ret;
2442    }
2443
2444    public int startActivityIntentSender(IApplicationThread caller,
2445            IntentSender intent, Intent fillInIntent, String resolvedType,
2446            IBinder resultTo, String resultWho, int requestCode,
2447            int flagsMask, int flagsValues, Bundle options) {
2448        enforceNotIsolatedCaller("startActivityIntentSender");
2449        // Refuse possible leaked file descriptors
2450        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2451            throw new IllegalArgumentException("File descriptors passed in Intent");
2452        }
2453
2454        IIntentSender sender = intent.getTarget();
2455        if (!(sender instanceof PendingIntentRecord)) {
2456            throw new IllegalArgumentException("Bad PendingIntent object");
2457        }
2458
2459        PendingIntentRecord pir = (PendingIntentRecord)sender;
2460
2461        synchronized (this) {
2462            // If this is coming from the currently resumed activity, it is
2463            // effectively saying that app switches are allowed at this point.
2464            if (mMainStack.mResumedActivity != null
2465                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2466                            Binder.getCallingUid()) {
2467                mAppSwitchesAllowedTime = 0;
2468            }
2469        }
2470        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2471                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2472        return ret;
2473    }
2474
2475    public boolean startNextMatchingActivity(IBinder callingActivity,
2476            Intent intent, Bundle options) {
2477        // Refuse possible leaked file descriptors
2478        if (intent != null && intent.hasFileDescriptors() == true) {
2479            throw new IllegalArgumentException("File descriptors passed in Intent");
2480        }
2481
2482        synchronized (this) {
2483            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2484            if (r == null) {
2485                ActivityOptions.abort(options);
2486                return false;
2487            }
2488            if (r.app == null || r.app.thread == null) {
2489                // The caller is not running...  d'oh!
2490                ActivityOptions.abort(options);
2491                return false;
2492            }
2493            intent = new Intent(intent);
2494            // The caller is not allowed to change the data.
2495            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2496            // And we are resetting to find the next component...
2497            intent.setComponent(null);
2498
2499            ActivityInfo aInfo = null;
2500            try {
2501                List<ResolveInfo> resolves =
2502                    AppGlobals.getPackageManager().queryIntentActivities(
2503                            intent, r.resolvedType,
2504                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2505                            UserHandle.getCallingUserId());
2506
2507                // Look for the original activity in the list...
2508                final int N = resolves != null ? resolves.size() : 0;
2509                for (int i=0; i<N; i++) {
2510                    ResolveInfo rInfo = resolves.get(i);
2511                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2512                            && rInfo.activityInfo.name.equals(r.info.name)) {
2513                        // We found the current one...  the next matching is
2514                        // after it.
2515                        i++;
2516                        if (i<N) {
2517                            aInfo = resolves.get(i).activityInfo;
2518                        }
2519                        break;
2520                    }
2521                }
2522            } catch (RemoteException e) {
2523            }
2524
2525            if (aInfo == null) {
2526                // Nobody who is next!
2527                ActivityOptions.abort(options);
2528                return false;
2529            }
2530
2531            intent.setComponent(new ComponentName(
2532                    aInfo.applicationInfo.packageName, aInfo.name));
2533            intent.setFlags(intent.getFlags()&~(
2534                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2535                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2536                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2537                    Intent.FLAG_ACTIVITY_NEW_TASK));
2538
2539            // Okay now we need to start the new activity, replacing the
2540            // currently running activity.  This is a little tricky because
2541            // we want to start the new one as if the current one is finished,
2542            // but not finish the current one first so that there is no flicker.
2543            // And thus...
2544            final boolean wasFinishing = r.finishing;
2545            r.finishing = true;
2546
2547            // Propagate reply information over to the new activity.
2548            final ActivityRecord resultTo = r.resultTo;
2549            final String resultWho = r.resultWho;
2550            final int requestCode = r.requestCode;
2551            r.resultTo = null;
2552            if (resultTo != null) {
2553                resultTo.removeResultsLocked(r, resultWho, requestCode);
2554            }
2555
2556            final long origId = Binder.clearCallingIdentity();
2557            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2558                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2559                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2560                    options, false, null);
2561            Binder.restoreCallingIdentity(origId);
2562
2563            r.finishing = wasFinishing;
2564            if (res != ActivityManager.START_SUCCESS) {
2565                return false;
2566            }
2567            return true;
2568        }
2569    }
2570
2571    final int startActivityInPackage(int uid,
2572            Intent intent, String resolvedType, IBinder resultTo,
2573            String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
2574
2575        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2576                false, true, "startActivityInPackage", null);
2577
2578        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2579                resultTo, resultWho, requestCode, startFlags,
2580                null, null, null, null, options, userId);
2581        return ret;
2582    }
2583
2584    public final int startActivities(IApplicationThread caller,
2585            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
2586        enforceNotIsolatedCaller("startActivities");
2587        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2588                options, UserHandle.getCallingUserId());
2589        return ret;
2590    }
2591
2592    final int startActivitiesInPackage(int uid,
2593            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2594            Bundle options, int userId) {
2595
2596        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2597                false, true, "startActivityInPackage", null);
2598        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2599                options, userId);
2600        return ret;
2601    }
2602
2603    final void addRecentTaskLocked(TaskRecord task) {
2604        int N = mRecentTasks.size();
2605        // Quick case: check if the top-most recent task is the same.
2606        if (N > 0 && mRecentTasks.get(0) == task) {
2607            return;
2608        }
2609        // Remove any existing entries that are the same kind of task.
2610        for (int i=0; i<N; i++) {
2611            TaskRecord tr = mRecentTasks.get(i);
2612            if (task.userId == tr.userId
2613                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2614                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2615                mRecentTasks.remove(i);
2616                i--;
2617                N--;
2618                if (task.intent == null) {
2619                    // If the new recent task we are adding is not fully
2620                    // specified, then replace it with the existing recent task.
2621                    task = tr;
2622                }
2623            }
2624        }
2625        if (N >= MAX_RECENT_TASKS) {
2626            mRecentTasks.remove(N-1);
2627        }
2628        mRecentTasks.add(0, task);
2629    }
2630
2631    public void setRequestedOrientation(IBinder token,
2632            int requestedOrientation) {
2633        synchronized (this) {
2634            ActivityRecord r = mMainStack.isInStackLocked(token);
2635            if (r == null) {
2636                return;
2637            }
2638            final long origId = Binder.clearCallingIdentity();
2639            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2640            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2641                    mConfiguration,
2642                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2643            if (config != null) {
2644                r.frozenBeforeDestroy = true;
2645                if (!updateConfigurationLocked(config, r, false, false)) {
2646                    mMainStack.resumeTopActivityLocked(null);
2647                }
2648            }
2649            Binder.restoreCallingIdentity(origId);
2650        }
2651    }
2652
2653    public int getRequestedOrientation(IBinder token) {
2654        synchronized (this) {
2655            ActivityRecord r = mMainStack.isInStackLocked(token);
2656            if (r == null) {
2657                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2658            }
2659            return mWindowManager.getAppOrientation(r.appToken);
2660        }
2661    }
2662
2663    /**
2664     * This is the internal entry point for handling Activity.finish().
2665     *
2666     * @param token The Binder token referencing the Activity we want to finish.
2667     * @param resultCode Result code, if any, from this Activity.
2668     * @param resultData Result data (Intent), if any, from this Activity.
2669     *
2670     * @return Returns true if the activity successfully finished, or false if it is still running.
2671     */
2672    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2673        // Refuse possible leaked file descriptors
2674        if (resultData != null && resultData.hasFileDescriptors() == true) {
2675            throw new IllegalArgumentException("File descriptors passed in Intent");
2676        }
2677
2678        synchronized(this) {
2679            if (mController != null) {
2680                // Find the first activity that is not finishing.
2681                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2682                if (next != null) {
2683                    // ask watcher if this is allowed
2684                    boolean resumeOK = true;
2685                    try {
2686                        resumeOK = mController.activityResuming(next.packageName);
2687                    } catch (RemoteException e) {
2688                        mController = null;
2689                    }
2690
2691                    if (!resumeOK) {
2692                        return false;
2693                    }
2694                }
2695            }
2696            final long origId = Binder.clearCallingIdentity();
2697            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2698                    resultData, "app-request", true);
2699            Binder.restoreCallingIdentity(origId);
2700            return res;
2701        }
2702    }
2703
2704    public final void finishHeavyWeightApp() {
2705        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2706                != PackageManager.PERMISSION_GRANTED) {
2707            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2708                    + Binder.getCallingPid()
2709                    + ", uid=" + Binder.getCallingUid()
2710                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2711            Slog.w(TAG, msg);
2712            throw new SecurityException(msg);
2713        }
2714
2715        synchronized(this) {
2716            if (mHeavyWeightProcess == null) {
2717                return;
2718            }
2719
2720            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2721                    mHeavyWeightProcess.activities);
2722            for (int i=0; i<activities.size(); i++) {
2723                ActivityRecord r = activities.get(i);
2724                if (!r.finishing) {
2725                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2726                    if (index >= 0) {
2727                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2728                                null, "finish-heavy", true);
2729                    }
2730                }
2731            }
2732
2733            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
2734                    mHeavyWeightProcess.userId, 0));
2735            mHeavyWeightProcess = null;
2736        }
2737    }
2738
2739    public void crashApplication(int uid, int initialPid, String packageName,
2740            String message) {
2741        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2742                != PackageManager.PERMISSION_GRANTED) {
2743            String msg = "Permission Denial: crashApplication() from pid="
2744                    + Binder.getCallingPid()
2745                    + ", uid=" + Binder.getCallingUid()
2746                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2747            Slog.w(TAG, msg);
2748            throw new SecurityException(msg);
2749        }
2750
2751        synchronized(this) {
2752            ProcessRecord proc = null;
2753
2754            // Figure out which process to kill.  We don't trust that initialPid
2755            // still has any relation to current pids, so must scan through the
2756            // list.
2757            synchronized (mPidsSelfLocked) {
2758                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2759                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2760                    if (p.uid != uid) {
2761                        continue;
2762                    }
2763                    if (p.pid == initialPid) {
2764                        proc = p;
2765                        break;
2766                    }
2767                    for (String str : p.pkgList) {
2768                        if (str.equals(packageName)) {
2769                            proc = p;
2770                        }
2771                    }
2772                }
2773            }
2774
2775            if (proc == null) {
2776                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2777                        + " initialPid=" + initialPid
2778                        + " packageName=" + packageName);
2779                return;
2780            }
2781
2782            if (proc.thread != null) {
2783                if (proc.pid == Process.myPid()) {
2784                    Log.w(TAG, "crashApplication: trying to crash self!");
2785                    return;
2786                }
2787                long ident = Binder.clearCallingIdentity();
2788                try {
2789                    proc.thread.scheduleCrash(message);
2790                } catch (RemoteException e) {
2791                }
2792                Binder.restoreCallingIdentity(ident);
2793            }
2794        }
2795    }
2796
2797    public final void finishSubActivity(IBinder token, String resultWho,
2798            int requestCode) {
2799        synchronized(this) {
2800            final long origId = Binder.clearCallingIdentity();
2801            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2802            Binder.restoreCallingIdentity(origId);
2803        }
2804    }
2805
2806    public boolean finishActivityAffinity(IBinder token) {
2807        synchronized(this) {
2808            final long origId = Binder.clearCallingIdentity();
2809            boolean res = mMainStack.finishActivityAffinityLocked(token);
2810            Binder.restoreCallingIdentity(origId);
2811            return res;
2812        }
2813    }
2814
2815    public boolean willActivityBeVisible(IBinder token) {
2816        synchronized(this) {
2817            int i;
2818            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2819                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2820                if (r.appToken == token) {
2821                    return true;
2822                }
2823                if (r.fullscreen && !r.finishing) {
2824                    return false;
2825                }
2826            }
2827            return true;
2828        }
2829    }
2830
2831    public void overridePendingTransition(IBinder token, String packageName,
2832            int enterAnim, int exitAnim) {
2833        synchronized(this) {
2834            ActivityRecord self = mMainStack.isInStackLocked(token);
2835            if (self == null) {
2836                return;
2837            }
2838
2839            final long origId = Binder.clearCallingIdentity();
2840
2841            if (self.state == ActivityState.RESUMED
2842                    || self.state == ActivityState.PAUSING) {
2843                mWindowManager.overridePendingAppTransition(packageName,
2844                        enterAnim, exitAnim, null);
2845            }
2846
2847            Binder.restoreCallingIdentity(origId);
2848        }
2849    }
2850
2851    /**
2852     * Main function for removing an existing process from the activity manager
2853     * as a result of that process going away.  Clears out all connections
2854     * to the process.
2855     */
2856    private final void handleAppDiedLocked(ProcessRecord app,
2857            boolean restarting, boolean allowRestart) {
2858        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2859        if (!restarting) {
2860            mLruProcesses.remove(app);
2861        }
2862
2863        if (mProfileProc == app) {
2864            clearProfilerLocked();
2865        }
2866
2867        // Just in case...
2868        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2869            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2870            mMainStack.mPausingActivity = null;
2871        }
2872        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2873            mMainStack.mLastPausedActivity = null;
2874        }
2875
2876        // Remove this application's activities from active lists.
2877        mMainStack.removeHistoryRecordsForAppLocked(app);
2878
2879        boolean atTop = true;
2880        boolean hasVisibleActivities = false;
2881
2882        // Clean out the history list.
2883        int i = mMainStack.mHistory.size();
2884        if (localLOGV) Slog.v(
2885            TAG, "Removing app " + app + " from history with " + i + " entries");
2886        while (i > 0) {
2887            i--;
2888            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2889            if (localLOGV) Slog.v(
2890                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2891            if (r.app == app) {
2892                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2893                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2894                        RuntimeException here = new RuntimeException("here");
2895                        here.fillInStackTrace();
2896                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2897                                + ": haveState=" + r.haveState
2898                                + " stateNotNeeded=" + r.stateNotNeeded
2899                                + " finishing=" + r.finishing
2900                                + " state=" + r.state, here);
2901                    }
2902                    if (!r.finishing) {
2903                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2904                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2905                                System.identityHashCode(r),
2906                                r.task.taskId, r.shortComponentName,
2907                                "proc died without state saved");
2908                    }
2909                    mMainStack.removeActivityFromHistoryLocked(r);
2910
2911                } else {
2912                    // We have the current state for this activity, so
2913                    // it can be restarted later when needed.
2914                    if (localLOGV) Slog.v(
2915                        TAG, "Keeping entry, setting app to null");
2916                    if (r.visible) {
2917                        hasVisibleActivities = true;
2918                    }
2919                    r.app = null;
2920                    r.nowVisible = false;
2921                    if (!r.haveState) {
2922                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2923                                "App died, clearing saved state of " + r);
2924                        r.icicle = null;
2925                    }
2926                }
2927
2928                r.stack.cleanUpActivityLocked(r, true, true);
2929            }
2930            atTop = false;
2931        }
2932
2933        app.activities.clear();
2934
2935        if (app.instrumentationClass != null) {
2936            Slog.w(TAG, "Crash of app " + app.processName
2937                  + " running instrumentation " + app.instrumentationClass);
2938            Bundle info = new Bundle();
2939            info.putString("shortMsg", "Process crashed.");
2940            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2941        }
2942
2943        if (!restarting) {
2944            if (!mMainStack.resumeTopActivityLocked(null)) {
2945                // If there was nothing to resume, and we are not already
2946                // restarting this process, but there is a visible activity that
2947                // is hosted by the process...  then make sure all visible
2948                // activities are running, taking care of restarting this
2949                // process.
2950                if (hasVisibleActivities) {
2951                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2952                }
2953            }
2954        }
2955    }
2956
2957    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2958        IBinder threadBinder = thread.asBinder();
2959        // Find the application record.
2960        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2961            ProcessRecord rec = mLruProcesses.get(i);
2962            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2963                return i;
2964            }
2965        }
2966        return -1;
2967    }
2968
2969    final ProcessRecord getRecordForAppLocked(
2970            IApplicationThread thread) {
2971        if (thread == null) {
2972            return null;
2973        }
2974
2975        int appIndex = getLRURecordIndexForAppLocked(thread);
2976        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2977    }
2978
2979    final void appDiedLocked(ProcessRecord app, int pid,
2980            IApplicationThread thread) {
2981
2982        mProcDeaths[0]++;
2983
2984        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2985        synchronized (stats) {
2986            stats.noteProcessDiedLocked(app.info.uid, pid);
2987        }
2988
2989        // Clean up already done if the process has been re-started.
2990        if (app.pid == pid && app.thread != null &&
2991                app.thread.asBinder() == thread.asBinder()) {
2992            if (!app.killedBackground) {
2993                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2994                        + ") has died.");
2995            }
2996            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2997            if (localLOGV) Slog.v(
2998                TAG, "Dying app: " + app + ", pid: " + pid
2999                + ", thread: " + thread.asBinder());
3000            boolean doLowMem = app.instrumentationClass == null;
3001            handleAppDiedLocked(app, false, true);
3002
3003            if (doLowMem) {
3004                // If there are no longer any background processes running,
3005                // and the app that died was not running instrumentation,
3006                // then tell everyone we are now low on memory.
3007                boolean haveBg = false;
3008                for (int i=mLruProcesses.size()-1; i>=0; i--) {
3009                    ProcessRecord rec = mLruProcesses.get(i);
3010                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3011                        haveBg = true;
3012                        break;
3013                    }
3014                }
3015
3016                if (!haveBg) {
3017                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3018                    long now = SystemClock.uptimeMillis();
3019                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
3020                        ProcessRecord rec = mLruProcesses.get(i);
3021                        if (rec != app && rec.thread != null &&
3022                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3023                            // The low memory report is overriding any current
3024                            // state for a GC request.  Make sure to do
3025                            // heavy/important/visible/foreground processes first.
3026                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3027                                rec.lastRequestedGc = 0;
3028                            } else {
3029                                rec.lastRequestedGc = rec.lastLowMemory;
3030                            }
3031                            rec.reportLowMemory = true;
3032                            rec.lastLowMemory = now;
3033                            mProcessesToGc.remove(rec);
3034                            addProcessToGcListLocked(rec);
3035                        }
3036                    }
3037                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3038                    scheduleAppGcsLocked();
3039                }
3040            }
3041        } else if (app.pid != pid) {
3042            // A new process has already been started.
3043            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3044                    + ") has died and restarted (pid " + app.pid + ").");
3045            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
3046        } else if (DEBUG_PROCESSES) {
3047            Slog.d(TAG, "Received spurious death notification for thread "
3048                    + thread.asBinder());
3049        }
3050    }
3051
3052    /**
3053     * If a stack trace dump file is configured, dump process stack traces.
3054     * @param clearTraces causes the dump file to be erased prior to the new
3055     *    traces being written, if true; when false, the new traces will be
3056     *    appended to any existing file content.
3057     * @param firstPids of dalvik VM processes to dump stack traces for first
3058     * @param lastPids of dalvik VM processes to dump stack traces for last
3059     * @param nativeProcs optional list of native process names to dump stack crawls
3060     * @return file containing stack traces, or null if no dump file is configured
3061     */
3062    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3063            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3064        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3065        if (tracesPath == null || tracesPath.length() == 0) {
3066            return null;
3067        }
3068
3069        File tracesFile = new File(tracesPath);
3070        try {
3071            File tracesDir = tracesFile.getParentFile();
3072            if (!tracesDir.exists()) {
3073                tracesFile.mkdirs();
3074                if (!SELinux.restorecon(tracesDir)) {
3075                    return null;
3076                }
3077            }
3078            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3079
3080            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3081            tracesFile.createNewFile();
3082            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3083        } catch (IOException e) {
3084            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3085            return null;
3086        }
3087
3088        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3089        return tracesFile;
3090    }
3091
3092    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3093            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3094        // Use a FileObserver to detect when traces finish writing.
3095        // The order of traces is considered important to maintain for legibility.
3096        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3097            public synchronized void onEvent(int event, String path) { notify(); }
3098        };
3099
3100        try {
3101            observer.startWatching();
3102
3103            // First collect all of the stacks of the most important pids.
3104            if (firstPids != null) {
3105                try {
3106                    int num = firstPids.size();
3107                    for (int i = 0; i < num; i++) {
3108                        synchronized (observer) {
3109                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3110                            observer.wait(200);  // Wait for write-close, give up after 200msec
3111                        }
3112                    }
3113                } catch (InterruptedException e) {
3114                    Log.wtf(TAG, e);
3115                }
3116            }
3117
3118            // Next measure CPU usage.
3119            if (processStats != null) {
3120                processStats.init();
3121                System.gc();
3122                processStats.update();
3123                try {
3124                    synchronized (processStats) {
3125                        processStats.wait(500); // measure over 1/2 second.
3126                    }
3127                } catch (InterruptedException e) {
3128                }
3129                processStats.update();
3130
3131                // We'll take the stack crawls of just the top apps using CPU.
3132                final int N = processStats.countWorkingStats();
3133                int numProcs = 0;
3134                for (int i=0; i<N && numProcs<5; i++) {
3135                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3136                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3137                        numProcs++;
3138                        try {
3139                            synchronized (observer) {
3140                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3141                                observer.wait(200);  // Wait for write-close, give up after 200msec
3142                            }
3143                        } catch (InterruptedException e) {
3144                            Log.wtf(TAG, e);
3145                        }
3146
3147                    }
3148                }
3149            }
3150
3151        } finally {
3152            observer.stopWatching();
3153        }
3154
3155        if (nativeProcs != null) {
3156            int[] pids = Process.getPidsForCommands(nativeProcs);
3157            if (pids != null) {
3158                for (int pid : pids) {
3159                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3160                }
3161            }
3162        }
3163    }
3164
3165    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3166        if (true || IS_USER_BUILD) {
3167            return;
3168        }
3169        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3170        if (tracesPath == null || tracesPath.length() == 0) {
3171            return;
3172        }
3173
3174        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3175        StrictMode.allowThreadDiskWrites();
3176        try {
3177            final File tracesFile = new File(tracesPath);
3178            final File tracesDir = tracesFile.getParentFile();
3179            final File tracesTmp = new File(tracesDir, "__tmp__");
3180            try {
3181                if (!tracesDir.exists()) {
3182                    tracesFile.mkdirs();
3183                    if (!SELinux.restorecon(tracesDir.getPath())) {
3184                        return;
3185                    }
3186                }
3187                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3188
3189                if (tracesFile.exists()) {
3190                    tracesTmp.delete();
3191                    tracesFile.renameTo(tracesTmp);
3192                }
3193                StringBuilder sb = new StringBuilder();
3194                Time tobj = new Time();
3195                tobj.set(System.currentTimeMillis());
3196                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3197                sb.append(": ");
3198                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3199                sb.append(" since ");
3200                sb.append(msg);
3201                FileOutputStream fos = new FileOutputStream(tracesFile);
3202                fos.write(sb.toString().getBytes());
3203                if (app == null) {
3204                    fos.write("\n*** No application process!".getBytes());
3205                }
3206                fos.close();
3207                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3208            } catch (IOException e) {
3209                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3210                return;
3211            }
3212
3213            if (app != null) {
3214                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3215                firstPids.add(app.pid);
3216                dumpStackTraces(tracesPath, firstPids, null, null, null);
3217            }
3218
3219            File lastTracesFile = null;
3220            File curTracesFile = null;
3221            for (int i=9; i>=0; i--) {
3222                String name = String.format("slow%02d.txt", i);
3223                curTracesFile = new File(tracesDir, name);
3224                if (curTracesFile.exists()) {
3225                    if (lastTracesFile != null) {
3226                        curTracesFile.renameTo(lastTracesFile);
3227                    } else {
3228                        curTracesFile.delete();
3229                    }
3230                }
3231                lastTracesFile = curTracesFile;
3232            }
3233            tracesFile.renameTo(curTracesFile);
3234            if (tracesTmp.exists()) {
3235                tracesTmp.renameTo(tracesFile);
3236            }
3237        } finally {
3238            StrictMode.setThreadPolicy(oldPolicy);
3239        }
3240    }
3241
3242    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3243            ActivityRecord parent, final String annotation) {
3244        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3245        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3246
3247        if (mController != null) {
3248            try {
3249                // 0 == continue, -1 = kill process immediately
3250                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3251                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3252            } catch (RemoteException e) {
3253                mController = null;
3254            }
3255        }
3256
3257        long anrTime = SystemClock.uptimeMillis();
3258        if (MONITOR_CPU_USAGE) {
3259            updateCpuStatsNow();
3260        }
3261
3262        synchronized (this) {
3263            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3264            if (mShuttingDown) {
3265                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3266                return;
3267            } else if (app.notResponding) {
3268                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3269                return;
3270            } else if (app.crashing) {
3271                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3272                return;
3273            }
3274
3275            // In case we come through here for the same app before completing
3276            // this one, mark as anring now so we will bail out.
3277            app.notResponding = true;
3278
3279            // Log the ANR to the event log.
3280            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3281                    annotation);
3282
3283            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3284            firstPids.add(app.pid);
3285
3286            int parentPid = app.pid;
3287            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3288            if (parentPid != app.pid) firstPids.add(parentPid);
3289
3290            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3291
3292            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3293                ProcessRecord r = mLruProcesses.get(i);
3294                if (r != null && r.thread != null) {
3295                    int pid = r.pid;
3296                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3297                        if (r.persistent) {
3298                            firstPids.add(pid);
3299                        } else {
3300                            lastPids.put(pid, Boolean.TRUE);
3301                        }
3302                    }
3303                }
3304            }
3305        }
3306
3307        // Log the ANR to the main log.
3308        StringBuilder info = new StringBuilder();
3309        info.setLength(0);
3310        info.append("ANR in ").append(app.processName);
3311        if (activity != null && activity.shortComponentName != null) {
3312            info.append(" (").append(activity.shortComponentName).append(")");
3313        }
3314        info.append("\n");
3315        if (annotation != null) {
3316            info.append("Reason: ").append(annotation).append("\n");
3317        }
3318        if (parent != null && parent != activity) {
3319            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3320        }
3321
3322        final ProcessStats processStats = new ProcessStats(true);
3323
3324        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3325
3326        String cpuInfo = null;
3327        if (MONITOR_CPU_USAGE) {
3328            updateCpuStatsNow();
3329            synchronized (mProcessStatsThread) {
3330                cpuInfo = mProcessStats.printCurrentState(anrTime);
3331            }
3332            info.append(processStats.printCurrentLoad());
3333            info.append(cpuInfo);
3334        }
3335
3336        info.append(processStats.printCurrentState(anrTime));
3337
3338        Slog.e(TAG, info.toString());
3339        if (tracesFile == null) {
3340            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3341            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3342        }
3343
3344        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3345                cpuInfo, tracesFile, null);
3346
3347        if (mController != null) {
3348            try {
3349                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3350                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3351                if (res != 0) {
3352                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3353                    return;
3354                }
3355            } catch (RemoteException e) {
3356                mController = null;
3357            }
3358        }
3359
3360        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3361        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3362                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3363
3364        synchronized (this) {
3365            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3366                Slog.w(TAG, "Killing " + app + ": background ANR");
3367                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3368                        app.processName, app.setAdj, "background ANR");
3369                Process.killProcessQuiet(app.pid);
3370                return;
3371            }
3372
3373            // Set the app's notResponding state, and look up the errorReportReceiver
3374            makeAppNotRespondingLocked(app,
3375                    activity != null ? activity.shortComponentName : null,
3376                    annotation != null ? "ANR " + annotation : "ANR",
3377                    info.toString());
3378
3379            // Bring up the infamous App Not Responding dialog
3380            Message msg = Message.obtain();
3381            HashMap map = new HashMap();
3382            msg.what = SHOW_NOT_RESPONDING_MSG;
3383            msg.obj = map;
3384            map.put("app", app);
3385            if (activity != null) {
3386                map.put("activity", activity);
3387            }
3388
3389            mHandler.sendMessage(msg);
3390        }
3391    }
3392
3393    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3394        if (!mLaunchWarningShown) {
3395            mLaunchWarningShown = true;
3396            mHandler.post(new Runnable() {
3397                @Override
3398                public void run() {
3399                    synchronized (ActivityManagerService.this) {
3400                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3401                        d.show();
3402                        mHandler.postDelayed(new Runnable() {
3403                            @Override
3404                            public void run() {
3405                                synchronized (ActivityManagerService.this) {
3406                                    d.dismiss();
3407                                    mLaunchWarningShown = false;
3408                                }
3409                            }
3410                        }, 4000);
3411                    }
3412                }
3413            });
3414        }
3415    }
3416
3417    public boolean clearApplicationUserData(final String packageName,
3418            final IPackageDataObserver observer, int userId) {
3419        enforceNotIsolatedCaller("clearApplicationUserData");
3420        int uid = Binder.getCallingUid();
3421        int pid = Binder.getCallingPid();
3422        userId = handleIncomingUserLocked(pid, uid,
3423                userId, false, true, "clearApplicationUserData", null);
3424        long callingId = Binder.clearCallingIdentity();
3425        try {
3426            IPackageManager pm = AppGlobals.getPackageManager();
3427            int pkgUid = -1;
3428            synchronized(this) {
3429                try {
3430                    pkgUid = pm.getPackageUid(packageName, userId);
3431                } catch (RemoteException e) {
3432                }
3433                if (pkgUid == -1) {
3434                    Slog.w(TAG, "Invalid packageName:" + packageName);
3435                    return false;
3436                }
3437                if (uid == pkgUid || checkComponentPermission(
3438                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3439                        pid, uid, -1, true)
3440                        == PackageManager.PERMISSION_GRANTED) {
3441                    forceStopPackageLocked(packageName, pkgUid);
3442                } else {
3443                    throw new SecurityException(pid+" does not have permission:"+
3444                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3445                                    "for process:"+packageName);
3446                }
3447            }
3448
3449            try {
3450                //clear application user data
3451                pm.clearApplicationUserData(packageName, observer, userId);
3452                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3453                        Uri.fromParts("package", packageName, null));
3454                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3455                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3456                        null, null, 0, null, null, null, false, false, userId);
3457            } catch (RemoteException e) {
3458            }
3459        } finally {
3460            Binder.restoreCallingIdentity(callingId);
3461        }
3462        return true;
3463    }
3464
3465    public void killBackgroundProcesses(final String packageName, int userId) {
3466        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3467                != PackageManager.PERMISSION_GRANTED &&
3468                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3469                        != PackageManager.PERMISSION_GRANTED) {
3470            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3471                    + Binder.getCallingPid()
3472                    + ", uid=" + Binder.getCallingUid()
3473                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3474            Slog.w(TAG, msg);
3475            throw new SecurityException(msg);
3476        }
3477
3478        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
3479                userId, true, true, "killBackgroundProcesses", null);
3480        long callingId = Binder.clearCallingIdentity();
3481        try {
3482            IPackageManager pm = AppGlobals.getPackageManager();
3483            synchronized(this) {
3484                int appId = -1;
3485                try {
3486                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
3487                } catch (RemoteException e) {
3488                }
3489                if (appId == -1) {
3490                    Slog.w(TAG, "Invalid packageName: " + packageName);
3491                    return;
3492                }
3493                killPackageProcessesLocked(packageName, appId, userId,
3494                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3495            }
3496        } finally {
3497            Binder.restoreCallingIdentity(callingId);
3498        }
3499    }
3500
3501    public void killAllBackgroundProcesses() {
3502        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3503                != PackageManager.PERMISSION_GRANTED) {
3504            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3505                    + Binder.getCallingPid()
3506                    + ", uid=" + Binder.getCallingUid()
3507                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3508            Slog.w(TAG, msg);
3509            throw new SecurityException(msg);
3510        }
3511
3512        long callingId = Binder.clearCallingIdentity();
3513        try {
3514            synchronized(this) {
3515                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3516                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3517                    final int NA = apps.size();
3518                    for (int ia=0; ia<NA; ia++) {
3519                        ProcessRecord app = apps.valueAt(ia);
3520                        if (app.persistent) {
3521                            // we don't kill persistent processes
3522                            continue;
3523                        }
3524                        if (app.removed) {
3525                            procs.add(app);
3526                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3527                            app.removed = true;
3528                            procs.add(app);
3529                        }
3530                    }
3531                }
3532
3533                int N = procs.size();
3534                for (int i=0; i<N; i++) {
3535                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3536                }
3537            }
3538        } finally {
3539            Binder.restoreCallingIdentity(callingId);
3540        }
3541    }
3542
3543    public void forceStopPackage(final String packageName, int userId) {
3544        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3545                != PackageManager.PERMISSION_GRANTED) {
3546            String msg = "Permission Denial: forceStopPackage() from pid="
3547                    + Binder.getCallingPid()
3548                    + ", uid=" + Binder.getCallingUid()
3549                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3550            Slog.w(TAG, msg);
3551            throw new SecurityException(msg);
3552        }
3553        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
3554                userId, true, true, "forceStopPackage", null);
3555        long callingId = Binder.clearCallingIdentity();
3556        try {
3557            IPackageManager pm = AppGlobals.getPackageManager();
3558            synchronized(this) {
3559                int[] users = userId == UserHandle.USER_ALL
3560                        ? getUsersLocked() : new int[] { userId };
3561                for (int user : users) {
3562                    int pkgUid = -1;
3563                    try {
3564                        pkgUid = pm.getPackageUid(packageName, user);
3565                    } catch (RemoteException e) {
3566                    }
3567                    if (pkgUid == -1) {
3568                        Slog.w(TAG, "Invalid packageName: " + packageName);
3569                        continue;
3570                    }
3571                    try {
3572                        pm.setPackageStoppedState(packageName, true, user);
3573                    } catch (RemoteException e) {
3574                    } catch (IllegalArgumentException e) {
3575                        Slog.w(TAG, "Failed trying to unstop package "
3576                                + packageName + ": " + e);
3577                    }
3578                    if (isUserRunningLocked(user)) {
3579                        forceStopPackageLocked(packageName, pkgUid);
3580                    }
3581                }
3582            }
3583        } finally {
3584            Binder.restoreCallingIdentity(callingId);
3585        }
3586    }
3587
3588    /*
3589     * The pkg name and app id have to be specified.
3590     */
3591    public void killApplicationWithAppId(String pkg, int appid) {
3592        if (pkg == null) {
3593            return;
3594        }
3595        // Make sure the uid is valid.
3596        if (appid < 0) {
3597            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
3598            return;
3599        }
3600        int callerUid = Binder.getCallingUid();
3601        // Only the system server can kill an application
3602        if (callerUid == Process.SYSTEM_UID) {
3603            // Post an aysnc message to kill the application
3604            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3605            msg.arg1 = appid;
3606            msg.arg2 = 0;
3607            msg.obj = pkg;
3608            mHandler.sendMessage(msg);
3609        } else {
3610            throw new SecurityException(callerUid + " cannot kill pkg: " +
3611                    pkg);
3612        }
3613    }
3614
3615    public void closeSystemDialogs(String reason) {
3616        enforceNotIsolatedCaller("closeSystemDialogs");
3617
3618        final int pid = Binder.getCallingPid();
3619        final int uid = Binder.getCallingUid();
3620        final long origId = Binder.clearCallingIdentity();
3621        try {
3622            synchronized (this) {
3623                // Only allow this from foreground processes, so that background
3624                // applications can't abuse it to prevent system UI from being shown.
3625                if (uid >= Process.FIRST_APPLICATION_UID) {
3626                    ProcessRecord proc;
3627                    synchronized (mPidsSelfLocked) {
3628                        proc = mPidsSelfLocked.get(pid);
3629                    }
3630                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
3631                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
3632                                + " from background process " + proc);
3633                        return;
3634                    }
3635                }
3636                closeSystemDialogsLocked(reason);
3637            }
3638        } finally {
3639            Binder.restoreCallingIdentity(origId);
3640        }
3641    }
3642
3643    void closeSystemDialogsLocked(String reason) {
3644        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3645        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3646        if (reason != null) {
3647            intent.putExtra("reason", reason);
3648        }
3649        mWindowManager.closeSystemDialogs(reason);
3650
3651        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3652            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3653            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3654                r.stack.finishActivityLocked(r, i,
3655                        Activity.RESULT_CANCELED, null, "close-sys", true);
3656            }
3657        }
3658
3659        broadcastIntentLocked(null, null, intent, null,
3660                null, 0, null, null, null, false, false, -1,
3661                Process.SYSTEM_UID, UserHandle.USER_ALL);
3662    }
3663
3664    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3665            throws RemoteException {
3666        enforceNotIsolatedCaller("getProcessMemoryInfo");
3667        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3668        for (int i=pids.length-1; i>=0; i--) {
3669            infos[i] = new Debug.MemoryInfo();
3670            Debug.getMemoryInfo(pids[i], infos[i]);
3671        }
3672        return infos;
3673    }
3674
3675    public long[] getProcessPss(int[] pids) throws RemoteException {
3676        enforceNotIsolatedCaller("getProcessPss");
3677        long[] pss = new long[pids.length];
3678        for (int i=pids.length-1; i>=0; i--) {
3679            pss[i] = Debug.getPss(pids[i]);
3680        }
3681        return pss;
3682    }
3683
3684    public void killApplicationProcess(String processName, int uid) {
3685        if (processName == null) {
3686            return;
3687        }
3688
3689        int callerUid = Binder.getCallingUid();
3690        // Only the system server can kill an application
3691        if (callerUid == Process.SYSTEM_UID) {
3692            synchronized (this) {
3693                ProcessRecord app = getProcessRecordLocked(processName, uid);
3694                if (app != null && app.thread != null) {
3695                    try {
3696                        app.thread.scheduleSuicide();
3697                    } catch (RemoteException e) {
3698                        // If the other end already died, then our work here is done.
3699                    }
3700                } else {
3701                    Slog.w(TAG, "Process/uid not found attempting kill of "
3702                            + processName + " / " + uid);
3703                }
3704            }
3705        } else {
3706            throw new SecurityException(callerUid + " cannot kill app process: " +
3707                    processName);
3708        }
3709    }
3710
3711    private void forceStopPackageLocked(final String packageName, int uid) {
3712        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
3713                false, true, false, UserHandle.getUserId(uid));
3714        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3715                Uri.fromParts("package", packageName, null));
3716        if (!mProcessesReady) {
3717            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3718        }
3719        intent.putExtra(Intent.EXTRA_UID, uid);
3720        broadcastIntentLocked(null, null, intent,
3721                null, null, 0, null, null, null,
3722                false, false,
3723                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3724    }
3725
3726    private void forceStopUserLocked(int userId) {
3727        forceStopPackageLocked(null, -1, false, false, true, false, userId);
3728        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
3729        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3730        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3731        broadcastIntentLocked(null, null, intent,
3732                null, null, 0, null, null, null,
3733                false, false,
3734                MY_PID, Process.SYSTEM_UID, userId);
3735    }
3736
3737    private final boolean killPackageProcessesLocked(String packageName, int appId,
3738            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
3739            boolean doit, boolean evenPersistent, String reason) {
3740        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3741
3742        // Remove all processes this package may have touched: all with the
3743        // same UID (except for the system or root user), and all whose name
3744        // matches the package name.
3745        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
3746        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3747            final int NA = apps.size();
3748            for (int ia=0; ia<NA; ia++) {
3749                ProcessRecord app = apps.valueAt(ia);
3750                if (app.persistent && !evenPersistent) {
3751                    // we don't kill persistent processes
3752                    continue;
3753                }
3754                if (app.removed) {
3755                    if (doit) {
3756                        procs.add(app);
3757                    }
3758                    continue;
3759                }
3760
3761                // Skip process if it doesn't meet our oom adj requirement.
3762                if (app.setAdj < minOomAdj) {
3763                    continue;
3764                }
3765
3766                // If no package is specified, we call all processes under the
3767                // give user id.
3768                if (packageName == null) {
3769                    if (app.userId != userId) {
3770                        continue;
3771                    }
3772                // Package has been specified, we want to hit all processes
3773                // that match it.  We need to qualify this by the processes
3774                // that are running under the specified app and user ID.
3775                } else {
3776                    if (UserHandle.getAppId(app.uid) != appId) {
3777                        continue;
3778                    }
3779                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
3780                        continue;
3781                    }
3782                    if (!app.pkgList.contains(packageName)) {
3783                        continue;
3784                    }
3785                }
3786
3787                // Process has passed all conditions, kill it!
3788                if (!doit) {
3789                    return true;
3790                }
3791                app.removed = true;
3792                procs.add(app);
3793            }
3794        }
3795
3796        int N = procs.size();
3797        for (int i=0; i<N; i++) {
3798            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3799        }
3800        return N > 0;
3801    }
3802
3803    private final boolean forceStopPackageLocked(String name, int appId,
3804            boolean callerWillRestart, boolean purgeCache, boolean doit,
3805            boolean evenPersistent, int userId) {
3806        int i;
3807        int N;
3808
3809        if (userId == UserHandle.USER_ALL && name == null) {
3810            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
3811        }
3812
3813        if (appId < 0 && name != null) {
3814            try {
3815                appId = UserHandle.getAppId(
3816                        AppGlobals.getPackageManager().getPackageUid(name, 0));
3817            } catch (RemoteException e) {
3818            }
3819        }
3820
3821        if (doit) {
3822            if (name != null) {
3823                Slog.i(TAG, "Force stopping package " + name + " appid=" + appId
3824                        + " user=" + userId);
3825            } else {
3826                Slog.i(TAG, "Force stopping user " + userId);
3827            }
3828
3829            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3830            while (badApps.hasNext()) {
3831                SparseArray<Long> ba = badApps.next();
3832                for (i=ba.size()-1; i>=0; i--) {
3833                    boolean remove = false;
3834                    final int entUid = ba.keyAt(i);
3835                    if (name != null) {
3836                        if (userId == UserHandle.USER_ALL) {
3837                            if (UserHandle.getAppId(entUid) == appId) {
3838                                remove = true;
3839                            }
3840                        } else {
3841                            if (entUid == UserHandle.getUid(userId, appId)) {
3842                                remove = true;
3843                            }
3844                        }
3845                    } else if (UserHandle.getUserId(entUid) == userId) {
3846                        remove = true;
3847                    }
3848                    if (remove) {
3849                        ba.removeAt(i);
3850                    }
3851                }
3852                if (ba.size() == 0) {
3853                    badApps.remove();
3854                }
3855            }
3856        }
3857
3858        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
3859                -100, callerWillRestart, false, doit, evenPersistent,
3860                name == null ? ("force stop user " + userId) : ("force stop " + name));
3861
3862        TaskRecord lastTask = null;
3863        for (i=0; i<mMainStack.mHistory.size(); i++) {
3864            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3865            final boolean samePackage = r.packageName.equals(name)
3866                    || (name == null && r.userId == userId);
3867            if ((userId == UserHandle.USER_ALL || r.userId == userId)
3868                    && (samePackage || r.task == lastTask)
3869                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3870                if (!doit) {
3871                    if (r.finishing) {
3872                        // If this activity is just finishing, then it is not
3873                        // interesting as far as something to stop.
3874                        continue;
3875                    }
3876                    return true;
3877                }
3878                didSomething = true;
3879                Slog.i(TAG, "  Force finishing activity " + r);
3880                if (samePackage) {
3881                    if (r.app != null) {
3882                        r.app.removed = true;
3883                    }
3884                    r.app = null;
3885                }
3886                lastTask = r.task;
3887                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3888                        null, "force-stop", true)) {
3889                    i--;
3890                }
3891            }
3892        }
3893
3894        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3895            if (!doit) {
3896                return true;
3897            }
3898            didSomething = true;
3899        }
3900
3901        if (name == null) {
3902            // Remove all sticky broadcasts from this user.
3903            mStickyBroadcasts.remove(userId);
3904        }
3905
3906        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3907        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
3908                userId, providers)) {
3909            if (!doit) {
3910                return true;
3911            }
3912            didSomething = true;
3913        }
3914        N = providers.size();
3915        for (i=0; i<N; i++) {
3916            removeDyingProviderLocked(null, providers.get(i), true);
3917        }
3918
3919        if (mIntentSenderRecords.size() > 0) {
3920            Iterator<WeakReference<PendingIntentRecord>> it
3921                    = mIntentSenderRecords.values().iterator();
3922            while (it.hasNext()) {
3923                WeakReference<PendingIntentRecord> wpir = it.next();
3924                if (wpir == null) {
3925                    it.remove();
3926                    continue;
3927                }
3928                PendingIntentRecord pir = wpir.get();
3929                if (pir == null) {
3930                    it.remove();
3931                    continue;
3932                }
3933                if (name == null) {
3934                    // Stopping user, remove all objects for the user.
3935                    if (pir.key.userId != userId) {
3936                        // Not the same user, skip it.
3937                        continue;
3938                    }
3939                } else {
3940                    if (UserHandle.getAppId(pir.uid) != appId) {
3941                        // Different app id, skip it.
3942                        continue;
3943                    }
3944                    if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
3945                        // Different user, skip it.
3946                        continue;
3947                    }
3948                    if (!pir.key.packageName.equals(name)) {
3949                        // Different package, skip it.
3950                        continue;
3951                    }
3952                }
3953                if (!doit) {
3954                    return true;
3955                }
3956                didSomething = true;
3957                it.remove();
3958                pir.canceled = true;
3959                if (pir.key.activity != null) {
3960                    pir.key.activity.pendingResults.remove(pir.ref);
3961                }
3962            }
3963        }
3964
3965        if (doit) {
3966            if (purgeCache && name != null) {
3967                AttributeCache ac = AttributeCache.instance();
3968                if (ac != null) {
3969                    ac.removePackage(name);
3970                }
3971            }
3972            if (mBooted) {
3973                mMainStack.resumeTopActivityLocked(null);
3974                mMainStack.scheduleIdleLocked();
3975            }
3976        }
3977
3978        return didSomething;
3979    }
3980
3981    private final boolean removeProcessLocked(ProcessRecord app,
3982            boolean callerWillRestart, boolean allowRestart, String reason) {
3983        final String name = app.processName;
3984        final int uid = app.uid;
3985        if (DEBUG_PROCESSES) Slog.d(
3986            TAG, "Force removing proc " + app.toShortString() + " (" + name
3987            + "/" + uid + ")");
3988
3989        mProcessNames.remove(name, uid);
3990        mIsolatedProcesses.remove(app.uid);
3991        if (mHeavyWeightProcess == app) {
3992            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3993                    mHeavyWeightProcess.userId, 0));
3994            mHeavyWeightProcess = null;
3995        }
3996        boolean needRestart = false;
3997        if (app.pid > 0 && app.pid != MY_PID) {
3998            int pid = app.pid;
3999            synchronized (mPidsSelfLocked) {
4000                mPidsSelfLocked.remove(pid);
4001                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4002            }
4003            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
4004            handleAppDiedLocked(app, true, allowRestart);
4005            mLruProcesses.remove(app);
4006            Process.killProcessQuiet(pid);
4007
4008            if (app.persistent && !app.isolated) {
4009                if (!callerWillRestart) {
4010                    addAppLocked(app.info, false);
4011                } else {
4012                    needRestart = true;
4013                }
4014            }
4015        } else {
4016            mRemovedProcesses.add(app);
4017        }
4018
4019        return needRestart;
4020    }
4021
4022    private final void processStartTimedOutLocked(ProcessRecord app) {
4023        final int pid = app.pid;
4024        boolean gone = false;
4025        synchronized (mPidsSelfLocked) {
4026            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4027            if (knownApp != null && knownApp.thread == null) {
4028                mPidsSelfLocked.remove(pid);
4029                gone = true;
4030            }
4031        }
4032
4033        if (gone) {
4034            Slog.w(TAG, "Process " + app + " failed to attach");
4035            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
4036                    app.processName);
4037            mProcessNames.remove(app.processName, app.uid);
4038            mIsolatedProcesses.remove(app.uid);
4039            if (mHeavyWeightProcess == app) {
4040                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4041                        mHeavyWeightProcess.userId, 0));
4042                mHeavyWeightProcess = null;
4043            }
4044            // Take care of any launching providers waiting for this process.
4045            checkAppInLaunchingProvidersLocked(app, true);
4046            // Take care of any services that are waiting for the process.
4047            mServices.processStartTimedOutLocked(app);
4048            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
4049                    app.processName, app.setAdj, "start timeout");
4050            Process.killProcessQuiet(pid);
4051            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4052                Slog.w(TAG, "Unattached app died before backup, skipping");
4053                try {
4054                    IBackupManager bm = IBackupManager.Stub.asInterface(
4055                            ServiceManager.getService(Context.BACKUP_SERVICE));
4056                    bm.agentDisconnected(app.info.packageName);
4057                } catch (RemoteException e) {
4058                    // Can't happen; the backup manager is local
4059                }
4060            }
4061            if (isPendingBroadcastProcessLocked(pid)) {
4062                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4063                skipPendingBroadcastLocked(pid);
4064            }
4065        } else {
4066            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4067        }
4068    }
4069
4070    private final boolean attachApplicationLocked(IApplicationThread thread,
4071            int pid) {
4072
4073        // Find the application record that is being attached...  either via
4074        // the pid if we are running in multiple processes, or just pull the
4075        // next app record if we are emulating process with anonymous threads.
4076        ProcessRecord app;
4077        if (pid != MY_PID && pid >= 0) {
4078            synchronized (mPidsSelfLocked) {
4079                app = mPidsSelfLocked.get(pid);
4080            }
4081        } else {
4082            app = null;
4083        }
4084
4085        if (app == null) {
4086            Slog.w(TAG, "No pending application record for pid " + pid
4087                    + " (IApplicationThread " + thread + "); dropping process");
4088            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4089            if (pid > 0 && pid != MY_PID) {
4090                Process.killProcessQuiet(pid);
4091            } else {
4092                try {
4093                    thread.scheduleExit();
4094                } catch (Exception e) {
4095                    // Ignore exceptions.
4096                }
4097            }
4098            return false;
4099        }
4100
4101        // If this application record is still attached to a previous
4102        // process, clean it up now.
4103        if (app.thread != null) {
4104            handleAppDiedLocked(app, true, true);
4105        }
4106
4107        // Tell the process all about itself.
4108
4109        if (localLOGV) Slog.v(
4110                TAG, "Binding process pid " + pid + " to record " + app);
4111
4112        String processName = app.processName;
4113        try {
4114            AppDeathRecipient adr = new AppDeathRecipient(
4115                    app, pid, thread);
4116            thread.asBinder().linkToDeath(adr, 0);
4117            app.deathRecipient = adr;
4118        } catch (RemoteException e) {
4119            app.resetPackageList();
4120            startProcessLocked(app, "link fail", processName);
4121            return false;
4122        }
4123
4124        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
4125
4126        app.thread = thread;
4127        app.curAdj = app.setAdj = -100;
4128        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4129        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
4130        app.forcingToForeground = null;
4131        app.foregroundServices = false;
4132        app.hasShownUi = false;
4133        app.debugging = false;
4134
4135        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4136
4137        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4138        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4139
4140        if (!normalMode) {
4141            Slog.i(TAG, "Launching preboot mode app: " + app);
4142        }
4143
4144        if (localLOGV) Slog.v(
4145            TAG, "New app record " + app
4146            + " thread=" + thread.asBinder() + " pid=" + pid);
4147        try {
4148            int testMode = IApplicationThread.DEBUG_OFF;
4149            if (mDebugApp != null && mDebugApp.equals(processName)) {
4150                testMode = mWaitForDebugger
4151                    ? IApplicationThread.DEBUG_WAIT
4152                    : IApplicationThread.DEBUG_ON;
4153                app.debugging = true;
4154                if (mDebugTransient) {
4155                    mDebugApp = mOrigDebugApp;
4156                    mWaitForDebugger = mOrigWaitForDebugger;
4157                }
4158            }
4159            String profileFile = app.instrumentationProfileFile;
4160            ParcelFileDescriptor profileFd = null;
4161            boolean profileAutoStop = false;
4162            if (mProfileApp != null && mProfileApp.equals(processName)) {
4163                mProfileProc = app;
4164                profileFile = mProfileFile;
4165                profileFd = mProfileFd;
4166                profileAutoStop = mAutoStopProfiler;
4167            }
4168            boolean enableOpenGlTrace = false;
4169            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4170                enableOpenGlTrace = true;
4171                mOpenGlTraceApp = null;
4172            }
4173
4174            // If the app is being launched for restore or full backup, set it up specially
4175            boolean isRestrictedBackupMode = false;
4176            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4177                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4178                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4179                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4180            }
4181
4182            ensurePackageDexOpt(app.instrumentationInfo != null
4183                    ? app.instrumentationInfo.packageName
4184                    : app.info.packageName);
4185            if (app.instrumentationClass != null) {
4186                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4187            }
4188            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4189                    + processName + " with config " + mConfiguration);
4190            ApplicationInfo appInfo = app.instrumentationInfo != null
4191                    ? app.instrumentationInfo : app.info;
4192            app.compat = compatibilityInfoForPackageLocked(appInfo);
4193            if (profileFd != null) {
4194                profileFd = profileFd.dup();
4195            }
4196            thread.bindApplication(processName, appInfo, providers,
4197                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4198                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4199                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4200                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4201                    mCoreSettingsObserver.getCoreSettingsLocked());
4202            updateLruProcessLocked(app, false, true);
4203            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4204        } catch (Exception e) {
4205            // todo: Yikes!  What should we do?  For now we will try to
4206            // start another process, but that could easily get us in
4207            // an infinite loop of restarting processes...
4208            Slog.w(TAG, "Exception thrown during bind!", e);
4209
4210            app.resetPackageList();
4211            app.unlinkDeathRecipient();
4212            startProcessLocked(app, "bind fail", processName);
4213            return false;
4214        }
4215
4216        // Remove this record from the list of starting applications.
4217        mPersistentStartingProcesses.remove(app);
4218        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4219                "Attach application locked removing on hold: " + app);
4220        mProcessesOnHold.remove(app);
4221
4222        boolean badApp = false;
4223        boolean didSomething = false;
4224
4225        // See if the top visible activity is waiting to run in this process...
4226        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4227        if (hr != null && normalMode) {
4228            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4229                    && processName.equals(hr.processName)) {
4230                try {
4231                    if (mHeadless) {
4232                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4233                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4234                        didSomething = true;
4235                    }
4236                } catch (Exception e) {
4237                    Slog.w(TAG, "Exception in new application when starting activity "
4238                          + hr.intent.getComponent().flattenToShortString(), e);
4239                    badApp = true;
4240                }
4241            } else {
4242                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4243            }
4244        }
4245
4246        // Find any services that should be running in this process...
4247        if (!badApp) {
4248            try {
4249                didSomething |= mServices.attachApplicationLocked(app, processName);
4250            } catch (Exception e) {
4251                badApp = true;
4252            }
4253        }
4254
4255        // Check if a next-broadcast receiver is in this process...
4256        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4257            try {
4258                didSomething = sendPendingBroadcastsLocked(app);
4259            } catch (Exception e) {
4260                // If the app died trying to launch the receiver we declare it 'bad'
4261                badApp = true;
4262            }
4263        }
4264
4265        // Check whether the next backup agent is in this process...
4266        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4267            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4268            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4269            try {
4270                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4271                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4272                        mBackupTarget.backupMode);
4273            } catch (Exception e) {
4274                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4275                e.printStackTrace();
4276            }
4277        }
4278
4279        if (badApp) {
4280            // todo: Also need to kill application to deal with all
4281            // kinds of exceptions.
4282            handleAppDiedLocked(app, false, true);
4283            return false;
4284        }
4285
4286        if (!didSomething) {
4287            updateOomAdjLocked();
4288        }
4289
4290        return true;
4291    }
4292
4293    public final void attachApplication(IApplicationThread thread) {
4294        synchronized (this) {
4295            int callingPid = Binder.getCallingPid();
4296            final long origId = Binder.clearCallingIdentity();
4297            attachApplicationLocked(thread, callingPid);
4298            Binder.restoreCallingIdentity(origId);
4299        }
4300    }
4301
4302    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4303        final long origId = Binder.clearCallingIdentity();
4304        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4305        if (stopProfiling) {
4306            synchronized (this) {
4307                if (mProfileProc == r.app) {
4308                    if (mProfileFd != null) {
4309                        try {
4310                            mProfileFd.close();
4311                        } catch (IOException e) {
4312                        }
4313                        clearProfilerLocked();
4314                    }
4315                }
4316            }
4317        }
4318        Binder.restoreCallingIdentity(origId);
4319    }
4320
4321    void enableScreenAfterBoot() {
4322        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4323                SystemClock.uptimeMillis());
4324        mWindowManager.enableScreenAfterBoot();
4325
4326        synchronized (this) {
4327            updateEventDispatchingLocked();
4328        }
4329    }
4330
4331    public void showBootMessage(final CharSequence msg, final boolean always) {
4332        enforceNotIsolatedCaller("showBootMessage");
4333        mWindowManager.showBootMessage(msg, always);
4334    }
4335
4336    public void dismissKeyguardOnNextActivity() {
4337        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4338        final long token = Binder.clearCallingIdentity();
4339        try {
4340            synchronized (this) {
4341                if (mLockScreenShown) {
4342                    mLockScreenShown = false;
4343                    comeOutOfSleepIfNeededLocked();
4344                }
4345                mMainStack.dismissKeyguardOnNextActivityLocked();
4346            }
4347        } finally {
4348            Binder.restoreCallingIdentity(token);
4349        }
4350    }
4351
4352    final void finishBooting() {
4353        IntentFilter pkgFilter = new IntentFilter();
4354        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4355        pkgFilter.addDataScheme("package");
4356        mContext.registerReceiver(new BroadcastReceiver() {
4357            @Override
4358            public void onReceive(Context context, Intent intent) {
4359                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4360                if (pkgs != null) {
4361                    for (String pkg : pkgs) {
4362                        synchronized (ActivityManagerService.this) {
4363                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4364                                setResultCode(Activity.RESULT_OK);
4365                                return;
4366                            }
4367                        }
4368                    }
4369                }
4370            }
4371        }, pkgFilter);
4372
4373        synchronized (this) {
4374            // Ensure that any processes we had put on hold are now started
4375            // up.
4376            final int NP = mProcessesOnHold.size();
4377            if (NP > 0) {
4378                ArrayList<ProcessRecord> procs =
4379                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4380                for (int ip=0; ip<NP; ip++) {
4381                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4382                            + procs.get(ip));
4383                    startProcessLocked(procs.get(ip), "on-hold", null);
4384                }
4385            }
4386
4387            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4388                // Start looking for apps that are abusing wake locks.
4389                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4390                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4391                // Tell anyone interested that we are done booting!
4392                SystemProperties.set("sys.boot_completed", "1");
4393                SystemProperties.set("dev.bootcomplete", "1");
4394                for (int i=0; i<mStartedUsers.size(); i++) {
4395                    UserStartedState uss = mStartedUsers.valueAt(i);
4396                    if (uss.mState == UserStartedState.STATE_BOOTING) {
4397                        uss.mState = UserStartedState.STATE_RUNNING;
4398                        final int userId = mStartedUsers.keyAt(i);
4399                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
4400                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4401                        broadcastIntentLocked(null, null, intent,
4402                                null, null, 0, null, null,
4403                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4404                                false, false, MY_PID, Process.SYSTEM_UID, userId);
4405                    }
4406                }
4407            }
4408        }
4409    }
4410
4411    final void ensureBootCompleted() {
4412        boolean booting;
4413        boolean enableScreen;
4414        synchronized (this) {
4415            booting = mBooting;
4416            mBooting = false;
4417            enableScreen = !mBooted;
4418            mBooted = true;
4419        }
4420
4421        if (booting) {
4422            finishBooting();
4423        }
4424
4425        if (enableScreen) {
4426            enableScreenAfterBoot();
4427        }
4428    }
4429
4430    public final void activityPaused(IBinder token) {
4431        final long origId = Binder.clearCallingIdentity();
4432        mMainStack.activityPaused(token, false);
4433        Binder.restoreCallingIdentity(origId);
4434    }
4435
4436    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4437            CharSequence description) {
4438        if (localLOGV) Slog.v(
4439            TAG, "Activity stopped: token=" + token);
4440
4441        // Refuse possible leaked file descriptors
4442        if (icicle != null && icicle.hasFileDescriptors()) {
4443            throw new IllegalArgumentException("File descriptors passed in Bundle");
4444        }
4445
4446        ActivityRecord r = null;
4447
4448        final long origId = Binder.clearCallingIdentity();
4449
4450        synchronized (this) {
4451            r = mMainStack.isInStackLocked(token);
4452            if (r != null) {
4453                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4454            }
4455        }
4456
4457        if (r != null) {
4458            sendPendingThumbnail(r, null, null, null, false);
4459        }
4460
4461        trimApplications();
4462
4463        Binder.restoreCallingIdentity(origId);
4464    }
4465
4466    public final void activityDestroyed(IBinder token) {
4467        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4468        mMainStack.activityDestroyed(token);
4469    }
4470
4471    public String getCallingPackage(IBinder token) {
4472        synchronized (this) {
4473            ActivityRecord r = getCallingRecordLocked(token);
4474            return r != null && r.app != null ? r.info.packageName : null;
4475        }
4476    }
4477
4478    public ComponentName getCallingActivity(IBinder token) {
4479        synchronized (this) {
4480            ActivityRecord r = getCallingRecordLocked(token);
4481            return r != null ? r.intent.getComponent() : null;
4482        }
4483    }
4484
4485    private ActivityRecord getCallingRecordLocked(IBinder token) {
4486        ActivityRecord r = mMainStack.isInStackLocked(token);
4487        if (r == null) {
4488            return null;
4489        }
4490        return r.resultTo;
4491    }
4492
4493    public ComponentName getActivityClassForToken(IBinder token) {
4494        synchronized(this) {
4495            ActivityRecord r = mMainStack.isInStackLocked(token);
4496            if (r == null) {
4497                return null;
4498            }
4499            return r.intent.getComponent();
4500        }
4501    }
4502
4503    public String getPackageForToken(IBinder token) {
4504        synchronized(this) {
4505            ActivityRecord r = mMainStack.isInStackLocked(token);
4506            if (r == null) {
4507                return null;
4508            }
4509            return r.packageName;
4510        }
4511    }
4512
4513    public IIntentSender getIntentSender(int type,
4514            String packageName, IBinder token, String resultWho,
4515            int requestCode, Intent[] intents, String[] resolvedTypes,
4516            int flags, Bundle options, int userId) {
4517        enforceNotIsolatedCaller("getIntentSender");
4518        // Refuse possible leaked file descriptors
4519        if (intents != null) {
4520            if (intents.length < 1) {
4521                throw new IllegalArgumentException("Intents array length must be >= 1");
4522            }
4523            for (int i=0; i<intents.length; i++) {
4524                Intent intent = intents[i];
4525                if (intent != null) {
4526                    if (intent.hasFileDescriptors()) {
4527                        throw new IllegalArgumentException("File descriptors passed in Intent");
4528                    }
4529                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4530                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4531                        throw new IllegalArgumentException(
4532                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4533                    }
4534                    intents[i] = new Intent(intent);
4535                }
4536            }
4537            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4538                throw new IllegalArgumentException(
4539                        "Intent array length does not match resolvedTypes length");
4540            }
4541        }
4542        if (options != null) {
4543            if (options.hasFileDescriptors()) {
4544                throw new IllegalArgumentException("File descriptors passed in options");
4545            }
4546        }
4547
4548        synchronized(this) {
4549            int callingUid = Binder.getCallingUid();
4550            userId = handleIncomingUserLocked(Binder.getCallingPid(), callingUid, userId,
4551                    false, true, "getIntentSender", null);
4552            try {
4553                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4554                    int uid = AppGlobals.getPackageManager()
4555                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4556                    if (!UserHandle.isSameApp(callingUid, uid)) {
4557                        String msg = "Permission Denial: getIntentSender() from pid="
4558                            + Binder.getCallingPid()
4559                            + ", uid=" + Binder.getCallingUid()
4560                            + ", (need uid=" + uid + ")"
4561                            + " is not allowed to send as package " + packageName;
4562                        Slog.w(TAG, msg);
4563                        throw new SecurityException(msg);
4564                    }
4565                }
4566
4567                return getIntentSenderLocked(type, packageName, callingUid, userId,
4568                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4569
4570            } catch (RemoteException e) {
4571                throw new SecurityException(e);
4572            }
4573        }
4574    }
4575
4576    IIntentSender getIntentSenderLocked(int type, String packageName,
4577            int callingUid, int userId, IBinder token, String resultWho,
4578            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4579            Bundle options) {
4580        if (DEBUG_MU)
4581            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4582        ActivityRecord activity = null;
4583        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4584            activity = mMainStack.isInStackLocked(token);
4585            if (activity == null) {
4586                return null;
4587            }
4588            if (activity.finishing) {
4589                return null;
4590            }
4591        }
4592
4593        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4594        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4595        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4596        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4597                |PendingIntent.FLAG_UPDATE_CURRENT);
4598
4599        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4600                type, packageName, activity, resultWho,
4601                requestCode, intents, resolvedTypes, flags, options, userId);
4602        WeakReference<PendingIntentRecord> ref;
4603        ref = mIntentSenderRecords.get(key);
4604        PendingIntentRecord rec = ref != null ? ref.get() : null;
4605        if (rec != null) {
4606            if (!cancelCurrent) {
4607                if (updateCurrent) {
4608                    if (rec.key.requestIntent != null) {
4609                        rec.key.requestIntent.replaceExtras(intents != null ?
4610                                intents[intents.length - 1] : null);
4611                    }
4612                    if (intents != null) {
4613                        intents[intents.length-1] = rec.key.requestIntent;
4614                        rec.key.allIntents = intents;
4615                        rec.key.allResolvedTypes = resolvedTypes;
4616                    } else {
4617                        rec.key.allIntents = null;
4618                        rec.key.allResolvedTypes = null;
4619                    }
4620                }
4621                return rec;
4622            }
4623            rec.canceled = true;
4624            mIntentSenderRecords.remove(key);
4625        }
4626        if (noCreate) {
4627            return rec;
4628        }
4629        rec = new PendingIntentRecord(this, key, callingUid);
4630        mIntentSenderRecords.put(key, rec.ref);
4631        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4632            if (activity.pendingResults == null) {
4633                activity.pendingResults
4634                        = new HashSet<WeakReference<PendingIntentRecord>>();
4635            }
4636            activity.pendingResults.add(rec.ref);
4637        }
4638        return rec;
4639    }
4640
4641    public void cancelIntentSender(IIntentSender sender) {
4642        if (!(sender instanceof PendingIntentRecord)) {
4643            return;
4644        }
4645        synchronized(this) {
4646            PendingIntentRecord rec = (PendingIntentRecord)sender;
4647            try {
4648                int uid = AppGlobals.getPackageManager()
4649                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4650                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4651                    String msg = "Permission Denial: cancelIntentSender() from pid="
4652                        + Binder.getCallingPid()
4653                        + ", uid=" + Binder.getCallingUid()
4654                        + " is not allowed to cancel packges "
4655                        + rec.key.packageName;
4656                    Slog.w(TAG, msg);
4657                    throw new SecurityException(msg);
4658                }
4659            } catch (RemoteException e) {
4660                throw new SecurityException(e);
4661            }
4662            cancelIntentSenderLocked(rec, true);
4663        }
4664    }
4665
4666    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4667        rec.canceled = true;
4668        mIntentSenderRecords.remove(rec.key);
4669        if (cleanActivity && rec.key.activity != null) {
4670            rec.key.activity.pendingResults.remove(rec.ref);
4671        }
4672    }
4673
4674    public String getPackageForIntentSender(IIntentSender pendingResult) {
4675        if (!(pendingResult instanceof PendingIntentRecord)) {
4676            return null;
4677        }
4678        try {
4679            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4680            return res.key.packageName;
4681        } catch (ClassCastException e) {
4682        }
4683        return null;
4684    }
4685
4686    public int getUidForIntentSender(IIntentSender sender) {
4687        if (sender instanceof PendingIntentRecord) {
4688            try {
4689                PendingIntentRecord res = (PendingIntentRecord)sender;
4690                return res.uid;
4691            } catch (ClassCastException e) {
4692            }
4693        }
4694        return -1;
4695    }
4696
4697    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4698        if (!(pendingResult instanceof PendingIntentRecord)) {
4699            return false;
4700        }
4701        try {
4702            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4703            if (res.key.allIntents == null) {
4704                return false;
4705            }
4706            for (int i=0; i<res.key.allIntents.length; i++) {
4707                Intent intent = res.key.allIntents[i];
4708                if (intent.getPackage() != null && intent.getComponent() != null) {
4709                    return false;
4710                }
4711            }
4712            return true;
4713        } catch (ClassCastException e) {
4714        }
4715        return false;
4716    }
4717
4718    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4719        if (!(pendingResult instanceof PendingIntentRecord)) {
4720            return false;
4721        }
4722        try {
4723            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4724            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4725                return true;
4726            }
4727            return false;
4728        } catch (ClassCastException e) {
4729        }
4730        return false;
4731    }
4732
4733    public void setProcessLimit(int max) {
4734        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4735                "setProcessLimit()");
4736        synchronized (this) {
4737            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4738            mProcessLimitOverride = max;
4739        }
4740        trimApplications();
4741    }
4742
4743    public int getProcessLimit() {
4744        synchronized (this) {
4745            return mProcessLimitOverride;
4746        }
4747    }
4748
4749    void foregroundTokenDied(ForegroundToken token) {
4750        synchronized (ActivityManagerService.this) {
4751            synchronized (mPidsSelfLocked) {
4752                ForegroundToken cur
4753                    = mForegroundProcesses.get(token.pid);
4754                if (cur != token) {
4755                    return;
4756                }
4757                mForegroundProcesses.remove(token.pid);
4758                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4759                if (pr == null) {
4760                    return;
4761                }
4762                pr.forcingToForeground = null;
4763                pr.foregroundServices = false;
4764            }
4765            updateOomAdjLocked();
4766        }
4767    }
4768
4769    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4770        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4771                "setProcessForeground()");
4772        synchronized(this) {
4773            boolean changed = false;
4774
4775            synchronized (mPidsSelfLocked) {
4776                ProcessRecord pr = mPidsSelfLocked.get(pid);
4777                if (pr == null && isForeground) {
4778                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4779                    return;
4780                }
4781                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4782                if (oldToken != null) {
4783                    oldToken.token.unlinkToDeath(oldToken, 0);
4784                    mForegroundProcesses.remove(pid);
4785                    if (pr != null) {
4786                        pr.forcingToForeground = null;
4787                    }
4788                    changed = true;
4789                }
4790                if (isForeground && token != null) {
4791                    ForegroundToken newToken = new ForegroundToken() {
4792                        public void binderDied() {
4793                            foregroundTokenDied(this);
4794                        }
4795                    };
4796                    newToken.pid = pid;
4797                    newToken.token = token;
4798                    try {
4799                        token.linkToDeath(newToken, 0);
4800                        mForegroundProcesses.put(pid, newToken);
4801                        pr.forcingToForeground = token;
4802                        changed = true;
4803                    } catch (RemoteException e) {
4804                        // If the process died while doing this, we will later
4805                        // do the cleanup with the process death link.
4806                    }
4807                }
4808            }
4809
4810            if (changed) {
4811                updateOomAdjLocked();
4812            }
4813        }
4814    }
4815
4816    // =========================================================
4817    // PERMISSIONS
4818    // =========================================================
4819
4820    static class PermissionController extends IPermissionController.Stub {
4821        ActivityManagerService mActivityManagerService;
4822        PermissionController(ActivityManagerService activityManagerService) {
4823            mActivityManagerService = activityManagerService;
4824        }
4825
4826        public boolean checkPermission(String permission, int pid, int uid) {
4827            return mActivityManagerService.checkPermission(permission, pid,
4828                    uid) == PackageManager.PERMISSION_GRANTED;
4829        }
4830    }
4831
4832    /**
4833     * This can be called with or without the global lock held.
4834     */
4835    int checkComponentPermission(String permission, int pid, int uid,
4836            int owningUid, boolean exported) {
4837        // We might be performing an operation on behalf of an indirect binder
4838        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4839        // client identity accordingly before proceeding.
4840        Identity tlsIdentity = sCallerIdentity.get();
4841        if (tlsIdentity != null) {
4842            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4843                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4844            uid = tlsIdentity.uid;
4845            pid = tlsIdentity.pid;
4846        }
4847
4848        if (pid == MY_PID) {
4849            return PackageManager.PERMISSION_GRANTED;
4850        }
4851
4852        return ActivityManager.checkComponentPermission(permission, uid,
4853                owningUid, exported);
4854    }
4855
4856    /**
4857     * As the only public entry point for permissions checking, this method
4858     * can enforce the semantic that requesting a check on a null global
4859     * permission is automatically denied.  (Internally a null permission
4860     * string is used when calling {@link #checkComponentPermission} in cases
4861     * when only uid-based security is needed.)
4862     *
4863     * This can be called with or without the global lock held.
4864     */
4865    public int checkPermission(String permission, int pid, int uid) {
4866        if (permission == null) {
4867            return PackageManager.PERMISSION_DENIED;
4868        }
4869        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4870    }
4871
4872    /**
4873     * Binder IPC calls go through the public entry point.
4874     * This can be called with or without the global lock held.
4875     */
4876    int checkCallingPermission(String permission) {
4877        return checkPermission(permission,
4878                Binder.getCallingPid(),
4879                UserHandle.getAppId(Binder.getCallingUid()));
4880    }
4881
4882    /**
4883     * This can be called with or without the global lock held.
4884     */
4885    void enforceCallingPermission(String permission, String func) {
4886        if (checkCallingPermission(permission)
4887                == PackageManager.PERMISSION_GRANTED) {
4888            return;
4889        }
4890
4891        String msg = "Permission Denial: " + func + " from pid="
4892                + Binder.getCallingPid()
4893                + ", uid=" + Binder.getCallingUid()
4894                + " requires " + permission;
4895        Slog.w(TAG, msg);
4896        throw new SecurityException(msg);
4897    }
4898
4899    /**
4900     * Determine if UID is holding permissions required to access {@link Uri} in
4901     * the given {@link ProviderInfo}. Final permission checking is always done
4902     * in {@link ContentProvider}.
4903     */
4904    private final boolean checkHoldingPermissionsLocked(
4905            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4906        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4907                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4908
4909        if (pi.applicationInfo.uid == uid) {
4910            return true;
4911        } else if (!pi.exported) {
4912            return false;
4913        }
4914
4915        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4916        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4917        try {
4918            // check if target holds top-level <provider> permissions
4919            if (!readMet && pi.readPermission != null
4920                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4921                readMet = true;
4922            }
4923            if (!writeMet && pi.writePermission != null
4924                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4925                writeMet = true;
4926            }
4927
4928            // track if unprotected read/write is allowed; any denied
4929            // <path-permission> below removes this ability
4930            boolean allowDefaultRead = pi.readPermission == null;
4931            boolean allowDefaultWrite = pi.writePermission == null;
4932
4933            // check if target holds any <path-permission> that match uri
4934            final PathPermission[] pps = pi.pathPermissions;
4935            if (pps != null) {
4936                final String path = uri.getPath();
4937                int i = pps.length;
4938                while (i > 0 && (!readMet || !writeMet)) {
4939                    i--;
4940                    PathPermission pp = pps[i];
4941                    if (pp.match(path)) {
4942                        if (!readMet) {
4943                            final String pprperm = pp.getReadPermission();
4944                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4945                                    + pprperm + " for " + pp.getPath()
4946                                    + ": match=" + pp.match(path)
4947                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4948                            if (pprperm != null) {
4949                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4950                                    readMet = true;
4951                                } else {
4952                                    allowDefaultRead = false;
4953                                }
4954                            }
4955                        }
4956                        if (!writeMet) {
4957                            final String ppwperm = pp.getWritePermission();
4958                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4959                                    + ppwperm + " for " + pp.getPath()
4960                                    + ": match=" + pp.match(path)
4961                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4962                            if (ppwperm != null) {
4963                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4964                                    writeMet = true;
4965                                } else {
4966                                    allowDefaultWrite = false;
4967                                }
4968                            }
4969                        }
4970                    }
4971                }
4972            }
4973
4974            // grant unprotected <provider> read/write, if not blocked by
4975            // <path-permission> above
4976            if (allowDefaultRead) readMet = true;
4977            if (allowDefaultWrite) writeMet = true;
4978
4979        } catch (RemoteException e) {
4980            return false;
4981        }
4982
4983        return readMet && writeMet;
4984    }
4985
4986    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4987            int modeFlags) {
4988        // Root gets to do everything.
4989        if (uid == 0) {
4990            return true;
4991        }
4992        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4993        if (perms == null) return false;
4994        UriPermission perm = perms.get(uri);
4995        if (perm == null) return false;
4996        return (modeFlags&perm.modeFlags) == modeFlags;
4997    }
4998
4999    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5000        enforceNotIsolatedCaller("checkUriPermission");
5001
5002        // Another redirected-binder-call permissions check as in
5003        // {@link checkComponentPermission}.
5004        Identity tlsIdentity = sCallerIdentity.get();
5005        if (tlsIdentity != null) {
5006            uid = tlsIdentity.uid;
5007            pid = tlsIdentity.pid;
5008        }
5009
5010        uid = UserHandle.getAppId(uid);
5011        // Our own process gets to do everything.
5012        if (pid == MY_PID) {
5013            return PackageManager.PERMISSION_GRANTED;
5014        }
5015        synchronized(this) {
5016            return checkUriPermissionLocked(uri, uid, modeFlags)
5017                    ? PackageManager.PERMISSION_GRANTED
5018                    : PackageManager.PERMISSION_DENIED;
5019        }
5020    }
5021
5022    /**
5023     * Check if the targetPkg can be granted permission to access uri by
5024     * the callingUid using the given modeFlags.  Throws a security exception
5025     * if callingUid is not allowed to do this.  Returns the uid of the target
5026     * if the URI permission grant should be performed; returns -1 if it is not
5027     * needed (for example targetPkg already has permission to access the URI).
5028     * If you already know the uid of the target, you can supply it in
5029     * lastTargetUid else set that to -1.
5030     */
5031    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5032            Uri uri, int modeFlags, int lastTargetUid) {
5033        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5034                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5035        if (modeFlags == 0) {
5036            return -1;
5037        }
5038
5039        if (targetPkg != null) {
5040            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5041                    "Checking grant " + targetPkg + " permission to " + uri);
5042        }
5043
5044        final IPackageManager pm = AppGlobals.getPackageManager();
5045
5046        // If this is not a content: uri, we can't do anything with it.
5047        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5048            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5049                    "Can't grant URI permission for non-content URI: " + uri);
5050            return -1;
5051        }
5052
5053        String name = uri.getAuthority();
5054        ProviderInfo pi = null;
5055        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
5056                UserHandle.getUserId(callingUid));
5057        if (cpr != null) {
5058            pi = cpr.info;
5059        } else {
5060            try {
5061                pi = pm.resolveContentProvider(name,
5062                        PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid));
5063            } catch (RemoteException ex) {
5064            }
5065        }
5066        if (pi == null) {
5067            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5068            return -1;
5069        }
5070
5071        int targetUid = lastTargetUid;
5072        if (targetUid < 0 && targetPkg != null) {
5073            try {
5074                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5075                if (targetUid < 0) {
5076                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5077                            "Can't grant URI permission no uid for: " + targetPkg);
5078                    return -1;
5079                }
5080            } catch (RemoteException ex) {
5081                return -1;
5082            }
5083        }
5084
5085        if (targetUid >= 0) {
5086            // First...  does the target actually need this permission?
5087            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5088                // No need to grant the target this permission.
5089                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5090                        "Target " + targetPkg + " already has full permission to " + uri);
5091                return -1;
5092            }
5093        } else {
5094            // First...  there is no target package, so can anyone access it?
5095            boolean allowed = pi.exported;
5096            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5097                if (pi.readPermission != null) {
5098                    allowed = false;
5099                }
5100            }
5101            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5102                if (pi.writePermission != null) {
5103                    allowed = false;
5104                }
5105            }
5106            if (allowed) {
5107                return -1;
5108            }
5109        }
5110
5111        // Second...  is the provider allowing granting of URI permissions?
5112        if (!pi.grantUriPermissions) {
5113            throw new SecurityException("Provider " + pi.packageName
5114                    + "/" + pi.name
5115                    + " does not allow granting of Uri permissions (uri "
5116                    + uri + ")");
5117        }
5118        if (pi.uriPermissionPatterns != null) {
5119            final int N = pi.uriPermissionPatterns.length;
5120            boolean allowed = false;
5121            for (int i=0; i<N; i++) {
5122                if (pi.uriPermissionPatterns[i] != null
5123                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5124                    allowed = true;
5125                    break;
5126                }
5127            }
5128            if (!allowed) {
5129                throw new SecurityException("Provider " + pi.packageName
5130                        + "/" + pi.name
5131                        + " does not allow granting of permission to path of Uri "
5132                        + uri);
5133            }
5134        }
5135
5136        // Third...  does the caller itself have permission to access
5137        // this uri?
5138        if (callingUid != Process.myUid()) {
5139            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5140                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5141                    throw new SecurityException("Uid " + callingUid
5142                            + " does not have permission to uri " + uri);
5143                }
5144            }
5145        }
5146
5147        return targetUid;
5148    }
5149
5150    public int checkGrantUriPermission(int callingUid, String targetPkg,
5151            Uri uri, int modeFlags) {
5152        enforceNotIsolatedCaller("checkGrantUriPermission");
5153        synchronized(this) {
5154            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5155        }
5156    }
5157
5158    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5159            Uri uri, int modeFlags, UriPermissionOwner owner) {
5160        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5161                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5162        if (modeFlags == 0) {
5163            return;
5164        }
5165
5166        // So here we are: the caller has the assumed permission
5167        // to the uri, and the target doesn't.  Let's now give this to
5168        // the target.
5169
5170        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5171                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5172
5173        HashMap<Uri, UriPermission> targetUris
5174                = mGrantedUriPermissions.get(targetUid);
5175        if (targetUris == null) {
5176            targetUris = new HashMap<Uri, UriPermission>();
5177            mGrantedUriPermissions.put(targetUid, targetUris);
5178        }
5179
5180        UriPermission perm = targetUris.get(uri);
5181        if (perm == null) {
5182            perm = new UriPermission(targetUid, uri);
5183            targetUris.put(uri, perm);
5184        }
5185
5186        perm.modeFlags |= modeFlags;
5187        if (owner == null) {
5188            perm.globalModeFlags |= modeFlags;
5189        } else {
5190            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5191                 perm.readOwners.add(owner);
5192                 owner.addReadPermission(perm);
5193            }
5194            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5195                 perm.writeOwners.add(owner);
5196                 owner.addWritePermission(perm);
5197            }
5198        }
5199    }
5200
5201    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5202            int modeFlags, UriPermissionOwner owner) {
5203        if (targetPkg == null) {
5204            throw new NullPointerException("targetPkg");
5205        }
5206
5207        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5208        if (targetUid < 0) {
5209            return;
5210        }
5211
5212        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5213    }
5214
5215    static class NeededUriGrants extends ArrayList<Uri> {
5216        final String targetPkg;
5217        final int targetUid;
5218        final int flags;
5219
5220        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5221            targetPkg = _targetPkg;
5222            targetUid = _targetUid;
5223            flags = _flags;
5224        }
5225    }
5226
5227    /**
5228     * Like checkGrantUriPermissionLocked, but takes an Intent.
5229     */
5230    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5231            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5232        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5233                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5234                + " clip=" + (intent != null ? intent.getClipData() : null)
5235                + " from " + intent + "; flags=0x"
5236                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5237
5238        if (targetPkg == null) {
5239            throw new NullPointerException("targetPkg");
5240        }
5241
5242        if (intent == null) {
5243            return null;
5244        }
5245        Uri data = intent.getData();
5246        ClipData clip = intent.getClipData();
5247        if (data == null && clip == null) {
5248            return null;
5249        }
5250        if (data != null) {
5251            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5252                mode, needed != null ? needed.targetUid : -1);
5253            if (target > 0) {
5254                if (needed == null) {
5255                    needed = new NeededUriGrants(targetPkg, target, mode);
5256                }
5257                needed.add(data);
5258            }
5259        }
5260        if (clip != null) {
5261            for (int i=0; i<clip.getItemCount(); i++) {
5262                Uri uri = clip.getItemAt(i).getUri();
5263                if (uri != null) {
5264                    int target = -1;
5265                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5266                            mode, needed != null ? needed.targetUid : -1);
5267                    if (target > 0) {
5268                        if (needed == null) {
5269                            needed = new NeededUriGrants(targetPkg, target, mode);
5270                        }
5271                        needed.add(uri);
5272                    }
5273                } else {
5274                    Intent clipIntent = clip.getItemAt(i).getIntent();
5275                    if (clipIntent != null) {
5276                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5277                                callingUid, targetPkg, clipIntent, mode, needed);
5278                        if (newNeeded != null) {
5279                            needed = newNeeded;
5280                        }
5281                    }
5282                }
5283            }
5284        }
5285
5286        return needed;
5287    }
5288
5289    /**
5290     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5291     */
5292    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5293            UriPermissionOwner owner) {
5294        if (needed != null) {
5295            for (int i=0; i<needed.size(); i++) {
5296                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5297                        needed.get(i), needed.flags, owner);
5298            }
5299        }
5300    }
5301
5302    void grantUriPermissionFromIntentLocked(int callingUid,
5303            String targetPkg, Intent intent, UriPermissionOwner owner) {
5304        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5305                intent, intent != null ? intent.getFlags() : 0, null);
5306        if (needed == null) {
5307            return;
5308        }
5309
5310        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5311    }
5312
5313    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5314            Uri uri, int modeFlags) {
5315        enforceNotIsolatedCaller("grantUriPermission");
5316        synchronized(this) {
5317            final ProcessRecord r = getRecordForAppLocked(caller);
5318            if (r == null) {
5319                throw new SecurityException("Unable to find app for caller "
5320                        + caller
5321                        + " when granting permission to uri " + uri);
5322            }
5323            if (targetPkg == null) {
5324                throw new IllegalArgumentException("null target");
5325            }
5326            if (uri == null) {
5327                throw new IllegalArgumentException("null uri");
5328            }
5329
5330            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5331                    null);
5332        }
5333    }
5334
5335    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5336        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5337                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5338            HashMap<Uri, UriPermission> perms
5339                    = mGrantedUriPermissions.get(perm.uid);
5340            if (perms != null) {
5341                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5342                        "Removing " + perm.uid + " permission to " + perm.uri);
5343                perms.remove(perm.uri);
5344                if (perms.size() == 0) {
5345                    mGrantedUriPermissions.remove(perm.uid);
5346                }
5347            }
5348        }
5349    }
5350
5351    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5352            int modeFlags) {
5353        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5354                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5355        if (modeFlags == 0) {
5356            return;
5357        }
5358
5359        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5360                "Revoking all granted permissions to " + uri);
5361
5362        final IPackageManager pm = AppGlobals.getPackageManager();
5363
5364        final String authority = uri.getAuthority();
5365        ProviderInfo pi = null;
5366        int userId = UserHandle.getUserId(callingUid);
5367        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5368        if (cpr != null) {
5369            pi = cpr.info;
5370        } else {
5371            try {
5372                pi = pm.resolveContentProvider(authority,
5373                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5374            } catch (RemoteException ex) {
5375            }
5376        }
5377        if (pi == null) {
5378            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5379            return;
5380        }
5381
5382        // Does the caller have this permission on the URI?
5383        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5384            // Right now, if you are not the original owner of the permission,
5385            // you are not allowed to revoke it.
5386            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5387                throw new SecurityException("Uid " + callingUid
5388                        + " does not have permission to uri " + uri);
5389            //}
5390        }
5391
5392        // Go through all of the permissions and remove any that match.
5393        final List<String> SEGMENTS = uri.getPathSegments();
5394        if (SEGMENTS != null) {
5395            final int NS = SEGMENTS.size();
5396            int N = mGrantedUriPermissions.size();
5397            for (int i=0; i<N; i++) {
5398                HashMap<Uri, UriPermission> perms
5399                        = mGrantedUriPermissions.valueAt(i);
5400                Iterator<UriPermission> it = perms.values().iterator();
5401            toploop:
5402                while (it.hasNext()) {
5403                    UriPermission perm = it.next();
5404                    Uri targetUri = perm.uri;
5405                    if (!authority.equals(targetUri.getAuthority())) {
5406                        continue;
5407                    }
5408                    List<String> targetSegments = targetUri.getPathSegments();
5409                    if (targetSegments == null) {
5410                        continue;
5411                    }
5412                    if (targetSegments.size() < NS) {
5413                        continue;
5414                    }
5415                    for (int j=0; j<NS; j++) {
5416                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5417                            continue toploop;
5418                        }
5419                    }
5420                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5421                            "Revoking " + perm.uid + " permission to " + perm.uri);
5422                    perm.clearModes(modeFlags);
5423                    if (perm.modeFlags == 0) {
5424                        it.remove();
5425                    }
5426                }
5427                if (perms.size() == 0) {
5428                    mGrantedUriPermissions.remove(
5429                            mGrantedUriPermissions.keyAt(i));
5430                    N--;
5431                    i--;
5432                }
5433            }
5434        }
5435    }
5436
5437    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5438            int modeFlags) {
5439        enforceNotIsolatedCaller("revokeUriPermission");
5440        synchronized(this) {
5441            final ProcessRecord r = getRecordForAppLocked(caller);
5442            if (r == null) {
5443                throw new SecurityException("Unable to find app for caller "
5444                        + caller
5445                        + " when revoking permission to uri " + uri);
5446            }
5447            if (uri == null) {
5448                Slog.w(TAG, "revokeUriPermission: null uri");
5449                return;
5450            }
5451
5452            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5453                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5454            if (modeFlags == 0) {
5455                return;
5456            }
5457
5458            final IPackageManager pm = AppGlobals.getPackageManager();
5459
5460            final String authority = uri.getAuthority();
5461            ProviderInfo pi = null;
5462            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5463            if (cpr != null) {
5464                pi = cpr.info;
5465            } else {
5466                try {
5467                    pi = pm.resolveContentProvider(authority,
5468                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5469                } catch (RemoteException ex) {
5470                }
5471            }
5472            if (pi == null) {
5473                Slog.w(TAG, "No content provider found for permission revoke: "
5474                        + uri.toSafeString());
5475                return;
5476            }
5477
5478            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5479        }
5480    }
5481
5482    @Override
5483    public IBinder newUriPermissionOwner(String name) {
5484        enforceNotIsolatedCaller("newUriPermissionOwner");
5485        synchronized(this) {
5486            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5487            return owner.getExternalTokenLocked();
5488        }
5489    }
5490
5491    @Override
5492    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5493            Uri uri, int modeFlags) {
5494        synchronized(this) {
5495            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5496            if (owner == null) {
5497                throw new IllegalArgumentException("Unknown owner: " + token);
5498            }
5499            if (fromUid != Binder.getCallingUid()) {
5500                if (Binder.getCallingUid() != Process.myUid()) {
5501                    // Only system code can grant URI permissions on behalf
5502                    // of other users.
5503                    throw new SecurityException("nice try");
5504                }
5505            }
5506            if (targetPkg == null) {
5507                throw new IllegalArgumentException("null target");
5508            }
5509            if (uri == null) {
5510                throw new IllegalArgumentException("null uri");
5511            }
5512
5513            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5514        }
5515    }
5516
5517    @Override
5518    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5519        synchronized(this) {
5520            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5521            if (owner == null) {
5522                throw new IllegalArgumentException("Unknown owner: " + token);
5523            }
5524
5525            if (uri == null) {
5526                owner.removeUriPermissionsLocked(mode);
5527            } else {
5528                owner.removeUriPermissionLocked(uri, mode);
5529            }
5530        }
5531    }
5532
5533    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5534        synchronized (this) {
5535            ProcessRecord app =
5536                who != null ? getRecordForAppLocked(who) : null;
5537            if (app == null) return;
5538
5539            Message msg = Message.obtain();
5540            msg.what = WAIT_FOR_DEBUGGER_MSG;
5541            msg.obj = app;
5542            msg.arg1 = waiting ? 1 : 0;
5543            mHandler.sendMessage(msg);
5544        }
5545    }
5546
5547    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5548        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5549        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5550        outInfo.availMem = Process.getFreeMemory();
5551        outInfo.totalMem = Process.getTotalMemory();
5552        outInfo.threshold = homeAppMem;
5553        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5554        outInfo.hiddenAppThreshold = hiddenAppMem;
5555        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5556                ProcessList.SERVICE_ADJ);
5557        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5558                ProcessList.VISIBLE_APP_ADJ);
5559        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5560                ProcessList.FOREGROUND_APP_ADJ);
5561    }
5562
5563    // =========================================================
5564    // TASK MANAGEMENT
5565    // =========================================================
5566
5567    public List getTasks(int maxNum, int flags,
5568                         IThumbnailReceiver receiver) {
5569        ArrayList list = new ArrayList();
5570
5571        PendingThumbnailsRecord pending = null;
5572        IApplicationThread topThumbnail = null;
5573        ActivityRecord topRecord = null;
5574
5575        synchronized(this) {
5576            if (localLOGV) Slog.v(
5577                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5578                + ", receiver=" + receiver);
5579
5580            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5581                    != PackageManager.PERMISSION_GRANTED) {
5582                if (receiver != null) {
5583                    // If the caller wants to wait for pending thumbnails,
5584                    // it ain't gonna get them.
5585                    try {
5586                        receiver.finished();
5587                    } catch (RemoteException ex) {
5588                    }
5589                }
5590                String msg = "Permission Denial: getTasks() from pid="
5591                        + Binder.getCallingPid()
5592                        + ", uid=" + Binder.getCallingUid()
5593                        + " requires " + android.Manifest.permission.GET_TASKS;
5594                Slog.w(TAG, msg);
5595                throw new SecurityException(msg);
5596            }
5597
5598            int pos = mMainStack.mHistory.size()-1;
5599            ActivityRecord next =
5600                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5601            ActivityRecord top = null;
5602            TaskRecord curTask = null;
5603            int numActivities = 0;
5604            int numRunning = 0;
5605            while (pos >= 0 && maxNum > 0) {
5606                final ActivityRecord r = next;
5607                pos--;
5608                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5609
5610                // Initialize state for next task if needed.
5611                if (top == null ||
5612                        (top.state == ActivityState.INITIALIZING
5613                            && top.task == r.task)) {
5614                    top = r;
5615                    curTask = r.task;
5616                    numActivities = numRunning = 0;
5617                }
5618
5619                // Add 'r' into the current task.
5620                numActivities++;
5621                if (r.app != null && r.app.thread != null) {
5622                    numRunning++;
5623                }
5624
5625                if (localLOGV) Slog.v(
5626                    TAG, r.intent.getComponent().flattenToShortString()
5627                    + ": task=" + r.task);
5628
5629                // If the next one is a different task, generate a new
5630                // TaskInfo entry for what we have.
5631                if (next == null || next.task != curTask) {
5632                    ActivityManager.RunningTaskInfo ci
5633                            = new ActivityManager.RunningTaskInfo();
5634                    ci.id = curTask.taskId;
5635                    ci.baseActivity = r.intent.getComponent();
5636                    ci.topActivity = top.intent.getComponent();
5637                    if (top.thumbHolder != null) {
5638                        ci.description = top.thumbHolder.lastDescription;
5639                    }
5640                    ci.numActivities = numActivities;
5641                    ci.numRunning = numRunning;
5642                    //System.out.println(
5643                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5644                    if (ci.thumbnail == null && receiver != null) {
5645                        if (localLOGV) Slog.v(
5646                            TAG, "State=" + top.state + "Idle=" + top.idle
5647                            + " app=" + top.app
5648                            + " thr=" + (top.app != null ? top.app.thread : null));
5649                        if (top.state == ActivityState.RESUMED
5650                                || top.state == ActivityState.PAUSING) {
5651                            if (top.idle && top.app != null
5652                                && top.app.thread != null) {
5653                                topRecord = top;
5654                                topThumbnail = top.app.thread;
5655                            } else {
5656                                top.thumbnailNeeded = true;
5657                            }
5658                        }
5659                        if (pending == null) {
5660                            pending = new PendingThumbnailsRecord(receiver);
5661                        }
5662                        pending.pendingRecords.add(top);
5663                    }
5664                    list.add(ci);
5665                    maxNum--;
5666                    top = null;
5667                }
5668            }
5669
5670            if (pending != null) {
5671                mPendingThumbnails.add(pending);
5672            }
5673        }
5674
5675        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5676
5677        if (topThumbnail != null) {
5678            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5679            try {
5680                topThumbnail.requestThumbnail(topRecord.appToken);
5681            } catch (Exception e) {
5682                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5683                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5684            }
5685        }
5686
5687        if (pending == null && receiver != null) {
5688            // In this case all thumbnails were available and the client
5689            // is being asked to be told when the remaining ones come in...
5690            // which is unusually, since the top-most currently running
5691            // activity should never have a canned thumbnail!  Oh well.
5692            try {
5693                receiver.finished();
5694            } catch (RemoteException ex) {
5695            }
5696        }
5697
5698        return list;
5699    }
5700
5701    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5702            int flags, int userId) {
5703        final int callingUid = Binder.getCallingUid();
5704        if (userId != UserHandle.getCallingUserId()) {
5705            // Check if the caller is holding permissions for cross-user requests.
5706            if (checkComponentPermission(
5707                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5708                    Binder.getCallingPid(), callingUid, -1, true)
5709                    != PackageManager.PERMISSION_GRANTED) {
5710                String msg = "Permission Denial: "
5711                        + "Request to get recent tasks for user " + userId
5712                        + " but is calling from user " + UserHandle.getUserId(callingUid)
5713                        + "; this requires "
5714                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
5715                Slog.w(TAG, msg);
5716                throw new SecurityException(msg);
5717            } else {
5718                if (userId == UserHandle.USER_CURRENT) {
5719                    userId = mCurrentUserId;
5720                }
5721            }
5722        }
5723
5724        synchronized (this) {
5725            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5726                    "getRecentTasks()");
5727            final boolean detailed = checkCallingPermission(
5728                    android.Manifest.permission.GET_DETAILED_TASKS)
5729                    == PackageManager.PERMISSION_GRANTED;
5730
5731            IPackageManager pm = AppGlobals.getPackageManager();
5732
5733            final int N = mRecentTasks.size();
5734            ArrayList<ActivityManager.RecentTaskInfo> res
5735                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5736                            maxNum < N ? maxNum : N);
5737            for (int i=0; i<N && maxNum > 0; i++) {
5738                TaskRecord tr = mRecentTasks.get(i);
5739                // Only add calling user's recent tasks
5740                if (tr.userId != userId) continue;
5741                // Return the entry if desired by the caller.  We always return
5742                // the first entry, because callers always expect this to be the
5743                // foreground app.  We may filter others if the caller has
5744                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5745                // we should exclude the entry.
5746
5747                if (i == 0
5748                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5749                        || (tr.intent == null)
5750                        || ((tr.intent.getFlags()
5751                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5752                    ActivityManager.RecentTaskInfo rti
5753                            = new ActivityManager.RecentTaskInfo();
5754                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5755                    rti.persistentId = tr.taskId;
5756                    rti.baseIntent = new Intent(
5757                            tr.intent != null ? tr.intent : tr.affinityIntent);
5758                    if (!detailed) {
5759                        rti.baseIntent.replaceExtras((Bundle)null);
5760                    }
5761                    rti.origActivity = tr.origActivity;
5762                    rti.description = tr.lastDescription;
5763
5764                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5765                        // Check whether this activity is currently available.
5766                        try {
5767                            if (rti.origActivity != null) {
5768                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5769                                        == null) {
5770                                    continue;
5771                                }
5772                            } else if (rti.baseIntent != null) {
5773                                if (pm.queryIntentActivities(rti.baseIntent,
5774                                        null, 0, userId) == null) {
5775                                    continue;
5776                                }
5777                            }
5778                        } catch (RemoteException e) {
5779                            // Will never happen.
5780                        }
5781                    }
5782
5783                    res.add(rti);
5784                    maxNum--;
5785                }
5786            }
5787            return res;
5788        }
5789    }
5790
5791    private TaskRecord taskForIdLocked(int id) {
5792        final int N = mRecentTasks.size();
5793        for (int i=0; i<N; i++) {
5794            TaskRecord tr = mRecentTasks.get(i);
5795            if (tr.taskId == id) {
5796                return tr;
5797            }
5798        }
5799        return null;
5800    }
5801
5802    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5803        synchronized (this) {
5804            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5805                    "getTaskThumbnails()");
5806            TaskRecord tr = taskForIdLocked(id);
5807            if (tr != null) {
5808                return mMainStack.getTaskThumbnailsLocked(tr);
5809            }
5810        }
5811        return null;
5812    }
5813
5814    public boolean removeSubTask(int taskId, int subTaskIndex) {
5815        synchronized (this) {
5816            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5817                    "removeSubTask()");
5818            long ident = Binder.clearCallingIdentity();
5819            try {
5820                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5821                        true) != null;
5822            } finally {
5823                Binder.restoreCallingIdentity(ident);
5824            }
5825        }
5826    }
5827
5828    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5829        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5830        Intent baseIntent = new Intent(
5831                tr.intent != null ? tr.intent : tr.affinityIntent);
5832        ComponentName component = baseIntent.getComponent();
5833        if (component == null) {
5834            Slog.w(TAG, "Now component for base intent of task: " + tr);
5835            return;
5836        }
5837
5838        // Find any running services associated with this app.
5839        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5840
5841        if (killProcesses) {
5842            // Find any running processes associated with this app.
5843            final String pkg = component.getPackageName();
5844            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5845            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5846            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5847                for (int i=0; i<uids.size(); i++) {
5848                    ProcessRecord proc = uids.valueAt(i);
5849                    if (proc.userId != tr.userId) {
5850                        continue;
5851                    }
5852                    if (!proc.pkgList.contains(pkg)) {
5853                        continue;
5854                    }
5855                    procs.add(proc);
5856                }
5857            }
5858
5859            // Kill the running processes.
5860            for (int i=0; i<procs.size(); i++) {
5861                ProcessRecord pr = procs.get(i);
5862                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5863                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5864                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5865                            pr.processName, pr.setAdj, "remove task");
5866                    pr.killedBackground = true;
5867                    Process.killProcessQuiet(pr.pid);
5868                } else {
5869                    pr.waitingToKill = "remove task";
5870                }
5871            }
5872        }
5873    }
5874
5875    public boolean removeTask(int taskId, int flags) {
5876        synchronized (this) {
5877            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5878                    "removeTask()");
5879            long ident = Binder.clearCallingIdentity();
5880            try {
5881                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5882                        false);
5883                if (r != null) {
5884                    mRecentTasks.remove(r.task);
5885                    cleanUpRemovedTaskLocked(r.task, flags);
5886                    return true;
5887                } else {
5888                    TaskRecord tr = null;
5889                    int i=0;
5890                    while (i < mRecentTasks.size()) {
5891                        TaskRecord t = mRecentTasks.get(i);
5892                        if (t.taskId == taskId) {
5893                            tr = t;
5894                            break;
5895                        }
5896                        i++;
5897                    }
5898                    if (tr != null) {
5899                        if (tr.numActivities <= 0) {
5900                            // Caller is just removing a recent task that is
5901                            // not actively running.  That is easy!
5902                            mRecentTasks.remove(i);
5903                            cleanUpRemovedTaskLocked(tr, flags);
5904                            return true;
5905                        } else {
5906                            Slog.w(TAG, "removeTask: task " + taskId
5907                                    + " does not have activities to remove, "
5908                                    + " but numActivities=" + tr.numActivities
5909                                    + ": " + tr);
5910                        }
5911                    }
5912                }
5913            } finally {
5914                Binder.restoreCallingIdentity(ident);
5915            }
5916        }
5917        return false;
5918    }
5919
5920    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5921        int j;
5922        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5923        TaskRecord jt = startTask;
5924
5925        // First look backwards
5926        for (j=startIndex-1; j>=0; j--) {
5927            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5928            if (r.task != jt) {
5929                jt = r.task;
5930                if (affinity.equals(jt.affinity)) {
5931                    return j;
5932                }
5933            }
5934        }
5935
5936        // Now look forwards
5937        final int N = mMainStack.mHistory.size();
5938        jt = startTask;
5939        for (j=startIndex+1; j<N; j++) {
5940            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5941            if (r.task != jt) {
5942                if (affinity.equals(jt.affinity)) {
5943                    return j;
5944                }
5945                jt = r.task;
5946            }
5947        }
5948
5949        // Might it be at the top?
5950        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5951            return N-1;
5952        }
5953
5954        return -1;
5955    }
5956
5957    /**
5958     * TODO: Add mController hook
5959     */
5960    public void moveTaskToFront(int task, int flags, Bundle options) {
5961        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5962                "moveTaskToFront()");
5963
5964        synchronized(this) {
5965            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5966                    Binder.getCallingUid(), "Task to front")) {
5967                ActivityOptions.abort(options);
5968                return;
5969            }
5970            final long origId = Binder.clearCallingIdentity();
5971            try {
5972                TaskRecord tr = taskForIdLocked(task);
5973                if (tr != null) {
5974                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5975                        mMainStack.mUserLeaving = true;
5976                    }
5977                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5978                        // Caller wants the home activity moved with it.  To accomplish this,
5979                        // we'll just move the home task to the top first.
5980                        mMainStack.moveHomeToFrontLocked();
5981                    }
5982                    mMainStack.moveTaskToFrontLocked(tr, null, options);
5983                    return;
5984                }
5985                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5986                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
5987                    if (hr.task.taskId == task) {
5988                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5989                            mMainStack.mUserLeaving = true;
5990                        }
5991                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5992                            // Caller wants the home activity moved with it.  To accomplish this,
5993                            // we'll just move the home task to the top first.
5994                            mMainStack.moveHomeToFrontLocked();
5995                        }
5996                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
5997                        return;
5998                    }
5999                }
6000            } finally {
6001                Binder.restoreCallingIdentity(origId);
6002            }
6003            ActivityOptions.abort(options);
6004        }
6005    }
6006
6007    public void moveTaskToBack(int task) {
6008        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6009                "moveTaskToBack()");
6010
6011        synchronized(this) {
6012            if (mMainStack.mResumedActivity != null
6013                    && mMainStack.mResumedActivity.task.taskId == task) {
6014                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6015                        Binder.getCallingUid(), "Task to back")) {
6016                    return;
6017                }
6018            }
6019            final long origId = Binder.clearCallingIdentity();
6020            mMainStack.moveTaskToBackLocked(task, null);
6021            Binder.restoreCallingIdentity(origId);
6022        }
6023    }
6024
6025    /**
6026     * Moves an activity, and all of the other activities within the same task, to the bottom
6027     * of the history stack.  The activity's order within the task is unchanged.
6028     *
6029     * @param token A reference to the activity we wish to move
6030     * @param nonRoot If false then this only works if the activity is the root
6031     *                of a task; if true it will work for any activity in a task.
6032     * @return Returns true if the move completed, false if not.
6033     */
6034    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
6035        enforceNotIsolatedCaller("moveActivityTaskToBack");
6036        synchronized(this) {
6037            final long origId = Binder.clearCallingIdentity();
6038            int taskId = getTaskForActivityLocked(token, !nonRoot);
6039            if (taskId >= 0) {
6040                return mMainStack.moveTaskToBackLocked(taskId, null);
6041            }
6042            Binder.restoreCallingIdentity(origId);
6043        }
6044        return false;
6045    }
6046
6047    public void moveTaskBackwards(int task) {
6048        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6049                "moveTaskBackwards()");
6050
6051        synchronized(this) {
6052            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6053                    Binder.getCallingUid(), "Task backwards")) {
6054                return;
6055            }
6056            final long origId = Binder.clearCallingIdentity();
6057            moveTaskBackwardsLocked(task);
6058            Binder.restoreCallingIdentity(origId);
6059        }
6060    }
6061
6062    private final void moveTaskBackwardsLocked(int task) {
6063        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
6064    }
6065
6066    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6067        synchronized(this) {
6068            return getTaskForActivityLocked(token, onlyRoot);
6069        }
6070    }
6071
6072    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
6073        final int N = mMainStack.mHistory.size();
6074        TaskRecord lastTask = null;
6075        for (int i=0; i<N; i++) {
6076            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
6077            if (r.appToken == token) {
6078                if (!onlyRoot || lastTask != r.task) {
6079                    return r.task.taskId;
6080                }
6081                return -1;
6082            }
6083            lastTask = r.task;
6084        }
6085
6086        return -1;
6087    }
6088
6089    // =========================================================
6090    // THUMBNAILS
6091    // =========================================================
6092
6093    public void reportThumbnail(IBinder token,
6094            Bitmap thumbnail, CharSequence description) {
6095        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6096        final long origId = Binder.clearCallingIdentity();
6097        sendPendingThumbnail(null, token, thumbnail, description, true);
6098        Binder.restoreCallingIdentity(origId);
6099    }
6100
6101    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
6102            Bitmap thumbnail, CharSequence description, boolean always) {
6103        TaskRecord task = null;
6104        ArrayList receivers = null;
6105
6106        //System.out.println("Send pending thumbnail: " + r);
6107
6108        synchronized(this) {
6109            if (r == null) {
6110                r = mMainStack.isInStackLocked(token);
6111                if (r == null) {
6112                    return;
6113                }
6114            }
6115            if (thumbnail == null && r.thumbHolder != null) {
6116                thumbnail = r.thumbHolder.lastThumbnail;
6117                description = r.thumbHolder.lastDescription;
6118            }
6119            if (thumbnail == null && !always) {
6120                // If there is no thumbnail, and this entry is not actually
6121                // going away, then abort for now and pick up the next
6122                // thumbnail we get.
6123                return;
6124            }
6125            task = r.task;
6126
6127            int N = mPendingThumbnails.size();
6128            int i=0;
6129            while (i<N) {
6130                PendingThumbnailsRecord pr =
6131                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6132                //System.out.println("Looking in " + pr.pendingRecords);
6133                if (pr.pendingRecords.remove(r)) {
6134                    if (receivers == null) {
6135                        receivers = new ArrayList();
6136                    }
6137                    receivers.add(pr);
6138                    if (pr.pendingRecords.size() == 0) {
6139                        pr.finished = true;
6140                        mPendingThumbnails.remove(i);
6141                        N--;
6142                        continue;
6143                    }
6144                }
6145                i++;
6146            }
6147        }
6148
6149        if (receivers != null) {
6150            final int N = receivers.size();
6151            for (int i=0; i<N; i++) {
6152                try {
6153                    PendingThumbnailsRecord pr =
6154                        (PendingThumbnailsRecord)receivers.get(i);
6155                    pr.receiver.newThumbnail(
6156                        task != null ? task.taskId : -1, thumbnail, description);
6157                    if (pr.finished) {
6158                        pr.receiver.finished();
6159                    }
6160                } catch (Exception e) {
6161                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6162                }
6163            }
6164        }
6165    }
6166
6167    // =========================================================
6168    // CONTENT PROVIDERS
6169    // =========================================================
6170
6171    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6172        List<ProviderInfo> providers = null;
6173        try {
6174            providers = AppGlobals.getPackageManager().
6175                queryContentProviders(app.processName, app.uid,
6176                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6177        } catch (RemoteException ex) {
6178        }
6179        if (DEBUG_MU)
6180            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6181        int userId = app.userId;
6182        if (providers != null) {
6183            int N = providers.size();
6184            for (int i=0; i<N; i++) {
6185                ProviderInfo cpi =
6186                    (ProviderInfo)providers.get(i);
6187                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6188                        cpi.name, cpi.flags);
6189                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6190                    // This is a singleton provider, but a user besides the
6191                    // default user is asking to initialize a process it runs
6192                    // in...  well, no, it doesn't actually run in this process,
6193                    // it runs in the process of the default user.  Get rid of it.
6194                    providers.remove(i);
6195                    N--;
6196                    continue;
6197                }
6198
6199                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6200                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6201                if (cpr == null) {
6202                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6203                    mProviderMap.putProviderByClass(comp, cpr);
6204                }
6205                if (DEBUG_MU)
6206                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6207                app.pubProviders.put(cpi.name, cpr);
6208                app.addPackage(cpi.applicationInfo.packageName);
6209                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6210            }
6211        }
6212        return providers;
6213    }
6214
6215    /**
6216     * Check if {@link ProcessRecord} has a possible chance at accessing the
6217     * given {@link ProviderInfo}. Final permission checking is always done
6218     * in {@link ContentProvider}.
6219     */
6220    private final String checkContentProviderPermissionLocked(
6221            ProviderInfo cpi, ProcessRecord r) {
6222        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6223        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6224        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6225                cpi.applicationInfo.uid, cpi.exported)
6226                == PackageManager.PERMISSION_GRANTED) {
6227            return null;
6228        }
6229        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6230                cpi.applicationInfo.uid, cpi.exported)
6231                == PackageManager.PERMISSION_GRANTED) {
6232            return null;
6233        }
6234
6235        PathPermission[] pps = cpi.pathPermissions;
6236        if (pps != null) {
6237            int i = pps.length;
6238            while (i > 0) {
6239                i--;
6240                PathPermission pp = pps[i];
6241                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6242                        cpi.applicationInfo.uid, cpi.exported)
6243                        == PackageManager.PERMISSION_GRANTED) {
6244                    return null;
6245                }
6246                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6247                        cpi.applicationInfo.uid, cpi.exported)
6248                        == PackageManager.PERMISSION_GRANTED) {
6249                    return null;
6250                }
6251            }
6252        }
6253
6254        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6255        if (perms != null) {
6256            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6257                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6258                    return null;
6259                }
6260            }
6261        }
6262
6263        String msg;
6264        if (!cpi.exported) {
6265            msg = "Permission Denial: opening provider " + cpi.name
6266                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6267                    + ", uid=" + callingUid + ") that is not exported from uid "
6268                    + cpi.applicationInfo.uid;
6269        } else {
6270            msg = "Permission Denial: opening provider " + cpi.name
6271                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6272                    + ", uid=" + callingUid + ") requires "
6273                    + cpi.readPermission + " or " + cpi.writePermission;
6274        }
6275        Slog.w(TAG, msg);
6276        return msg;
6277    }
6278
6279    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6280            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6281        if (r != null) {
6282            for (int i=0; i<r.conProviders.size(); i++) {
6283                ContentProviderConnection conn = r.conProviders.get(i);
6284                if (conn.provider == cpr) {
6285                    if (DEBUG_PROVIDER) Slog.v(TAG,
6286                            "Adding provider requested by "
6287                            + r.processName + " from process "
6288                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6289                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6290                    if (stable) {
6291                        conn.stableCount++;
6292                        conn.numStableIncs++;
6293                    } else {
6294                        conn.unstableCount++;
6295                        conn.numUnstableIncs++;
6296                    }
6297                    return conn;
6298                }
6299            }
6300            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6301            if (stable) {
6302                conn.stableCount = 1;
6303                conn.numStableIncs = 1;
6304            } else {
6305                conn.unstableCount = 1;
6306                conn.numUnstableIncs = 1;
6307            }
6308            cpr.connections.add(conn);
6309            r.conProviders.add(conn);
6310            return conn;
6311        }
6312        cpr.addExternalProcessHandleLocked(externalProcessToken);
6313        return null;
6314    }
6315
6316    boolean decProviderCountLocked(ContentProviderConnection conn,
6317            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6318        if (conn != null) {
6319            cpr = conn.provider;
6320            if (DEBUG_PROVIDER) Slog.v(TAG,
6321                    "Removing provider requested by "
6322                    + conn.client.processName + " from process "
6323                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6324                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6325            if (stable) {
6326                conn.stableCount--;
6327            } else {
6328                conn.unstableCount--;
6329            }
6330            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6331                cpr.connections.remove(conn);
6332                conn.client.conProviders.remove(conn);
6333                return true;
6334            }
6335            return false;
6336        }
6337        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6338        return false;
6339    }
6340
6341    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6342            String name, IBinder token, boolean stable, int userId) {
6343        ContentProviderRecord cpr;
6344        ContentProviderConnection conn = null;
6345        ProviderInfo cpi = null;
6346
6347        synchronized(this) {
6348            ProcessRecord r = null;
6349            if (caller != null) {
6350                r = getRecordForAppLocked(caller);
6351                if (r == null) {
6352                    throw new SecurityException(
6353                            "Unable to find app for caller " + caller
6354                          + " (pid=" + Binder.getCallingPid()
6355                          + ") when getting content provider " + name);
6356                }
6357                if (r.userId != userId) {
6358                    throw new SecurityException("Calling requested user " + userId
6359                            + " but app is user " + r.userId);
6360                }
6361            }
6362
6363            // First check if this content provider has been published...
6364            cpr = mProviderMap.getProviderByName(name, userId);
6365            boolean providerRunning = cpr != null;
6366            if (providerRunning) {
6367                cpi = cpr.info;
6368                String msg;
6369                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6370                    throw new SecurityException(msg);
6371                }
6372
6373                if (r != null && cpr.canRunHere(r)) {
6374                    // This provider has been published or is in the process
6375                    // of being published...  but it is also allowed to run
6376                    // in the caller's process, so don't make a connection
6377                    // and just let the caller instantiate its own instance.
6378                    ContentProviderHolder holder = cpr.newHolder(null);
6379                    // don't give caller the provider object, it needs
6380                    // to make its own.
6381                    holder.provider = null;
6382                    return holder;
6383                }
6384
6385                final long origId = Binder.clearCallingIdentity();
6386
6387                // In this case the provider instance already exists, so we can
6388                // return it right away.
6389                conn = incProviderCountLocked(r, cpr, token, stable);
6390                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6391                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6392                        // If this is a perceptible app accessing the provider,
6393                        // make sure to count it as being accessed and thus
6394                        // back up on the LRU list.  This is good because
6395                        // content providers are often expensive to start.
6396                        updateLruProcessLocked(cpr.proc, false, true);
6397                    }
6398                }
6399
6400                if (cpr.proc != null) {
6401                    if (false) {
6402                        if (cpr.name.flattenToShortString().equals(
6403                                "com.android.providers.calendar/.CalendarProvider2")) {
6404                            Slog.v(TAG, "****************** KILLING "
6405                                + cpr.name.flattenToShortString());
6406                            Process.killProcess(cpr.proc.pid);
6407                        }
6408                    }
6409                    boolean success = updateOomAdjLocked(cpr.proc);
6410                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6411                    // NOTE: there is still a race here where a signal could be
6412                    // pending on the process even though we managed to update its
6413                    // adj level.  Not sure what to do about this, but at least
6414                    // the race is now smaller.
6415                    if (!success) {
6416                        // Uh oh...  it looks like the provider's process
6417                        // has been killed on us.  We need to wait for a new
6418                        // process to be started, and make sure its death
6419                        // doesn't kill our process.
6420                        Slog.i(TAG,
6421                                "Existing provider " + cpr.name.flattenToShortString()
6422                                + " is crashing; detaching " + r);
6423                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6424                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6425                        if (!lastRef) {
6426                            // This wasn't the last ref our process had on
6427                            // the provider...  we have now been killed, bail.
6428                            return null;
6429                        }
6430                        providerRunning = false;
6431                        conn = null;
6432                    }
6433                }
6434
6435                Binder.restoreCallingIdentity(origId);
6436            }
6437
6438            boolean singleton;
6439            if (!providerRunning) {
6440                try {
6441                    cpi = AppGlobals.getPackageManager().
6442                        resolveContentProvider(name,
6443                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6444                } catch (RemoteException ex) {
6445                }
6446                if (cpi == null) {
6447                    return null;
6448                }
6449                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6450                        cpi.name, cpi.flags);
6451                if (singleton) {
6452                    userId = 0;
6453                }
6454                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6455
6456                String msg;
6457                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6458                    throw new SecurityException(msg);
6459                }
6460
6461                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6462                        && !cpi.processName.equals("system")) {
6463                    // If this content provider does not run in the system
6464                    // process, and the system is not yet ready to run other
6465                    // processes, then fail fast instead of hanging.
6466                    throw new IllegalArgumentException(
6467                            "Attempt to launch content provider before system ready");
6468                }
6469
6470                // Make sure that the user who owns this provider is started.  If not,
6471                // we don't want to allow it to run.
6472                if (mStartedUsers.get(userId) == null) {
6473                    Slog.w(TAG, "Unable to launch app "
6474                            + cpi.applicationInfo.packageName + "/"
6475                            + cpi.applicationInfo.uid + " for provider "
6476                            + name + ": user " + userId + " is stopped");
6477                    return null;
6478                }
6479
6480                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6481                cpr = mProviderMap.getProviderByClass(comp, userId);
6482                final boolean firstClass = cpr == null;
6483                if (firstClass) {
6484                    try {
6485                        ApplicationInfo ai =
6486                            AppGlobals.getPackageManager().
6487                                getApplicationInfo(
6488                                        cpi.applicationInfo.packageName,
6489                                        STOCK_PM_FLAGS, userId);
6490                        if (ai == null) {
6491                            Slog.w(TAG, "No package info for content provider "
6492                                    + cpi.name);
6493                            return null;
6494                        }
6495                        ai = getAppInfoForUser(ai, userId);
6496                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6497                    } catch (RemoteException ex) {
6498                        // pm is in same process, this will never happen.
6499                    }
6500                }
6501
6502                if (r != null && cpr.canRunHere(r)) {
6503                    // If this is a multiprocess provider, then just return its
6504                    // info and allow the caller to instantiate it.  Only do
6505                    // this if the provider is the same user as the caller's
6506                    // process, or can run as root (so can be in any process).
6507                    return cpr.newHolder(null);
6508                }
6509
6510                if (DEBUG_PROVIDER) {
6511                    RuntimeException e = new RuntimeException("here");
6512                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6513                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6514                }
6515
6516                // This is single process, and our app is now connecting to it.
6517                // See if we are already in the process of launching this
6518                // provider.
6519                final int N = mLaunchingProviders.size();
6520                int i;
6521                for (i=0; i<N; i++) {
6522                    if (mLaunchingProviders.get(i) == cpr) {
6523                        break;
6524                    }
6525                }
6526
6527                // If the provider is not already being launched, then get it
6528                // started.
6529                if (i >= N) {
6530                    final long origId = Binder.clearCallingIdentity();
6531
6532                    try {
6533                        // Content provider is now in use, its package can't be stopped.
6534                        try {
6535                            AppGlobals.getPackageManager().setPackageStoppedState(
6536                                    cpr.appInfo.packageName, false, userId);
6537                        } catch (RemoteException e) {
6538                        } catch (IllegalArgumentException e) {
6539                            Slog.w(TAG, "Failed trying to unstop package "
6540                                    + cpr.appInfo.packageName + ": " + e);
6541                        }
6542
6543                        ProcessRecord proc = startProcessLocked(cpi.processName,
6544                                cpr.appInfo, false, 0, "content provider",
6545                                new ComponentName(cpi.applicationInfo.packageName,
6546                                        cpi.name), false, false);
6547                        if (proc == null) {
6548                            Slog.w(TAG, "Unable to launch app "
6549                                    + cpi.applicationInfo.packageName + "/"
6550                                    + cpi.applicationInfo.uid + " for provider "
6551                                    + name + ": process is bad");
6552                            return null;
6553                        }
6554                        cpr.launchingApp = proc;
6555                        mLaunchingProviders.add(cpr);
6556                    } finally {
6557                        Binder.restoreCallingIdentity(origId);
6558                    }
6559                }
6560
6561                // Make sure the provider is published (the same provider class
6562                // may be published under multiple names).
6563                if (firstClass) {
6564                    mProviderMap.putProviderByClass(comp, cpr);
6565                }
6566
6567                mProviderMap.putProviderByName(name, cpr);
6568                conn = incProviderCountLocked(r, cpr, token, stable);
6569                if (conn != null) {
6570                    conn.waiting = true;
6571                }
6572            }
6573        }
6574
6575        // Wait for the provider to be published...
6576        synchronized (cpr) {
6577            while (cpr.provider == null) {
6578                if (cpr.launchingApp == null) {
6579                    Slog.w(TAG, "Unable to launch app "
6580                            + cpi.applicationInfo.packageName + "/"
6581                            + cpi.applicationInfo.uid + " for provider "
6582                            + name + ": launching app became null");
6583                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6584                            cpi.applicationInfo.packageName,
6585                            cpi.applicationInfo.uid, name);
6586                    return null;
6587                }
6588                try {
6589                    if (DEBUG_MU) {
6590                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6591                                + cpr.launchingApp);
6592                    }
6593                    if (conn != null) {
6594                        conn.waiting = true;
6595                    }
6596                    cpr.wait();
6597                } catch (InterruptedException ex) {
6598                } finally {
6599                    if (conn != null) {
6600                        conn.waiting = false;
6601                    }
6602                }
6603            }
6604        }
6605        return cpr != null ? cpr.newHolder(conn) : null;
6606    }
6607
6608    public final ContentProviderHolder getContentProvider(
6609            IApplicationThread caller, String name, boolean stable) {
6610        enforceNotIsolatedCaller("getContentProvider");
6611        if (caller == null) {
6612            String msg = "null IApplicationThread when getting content provider "
6613                    + name;
6614            Slog.w(TAG, msg);
6615            throw new SecurityException(msg);
6616        }
6617
6618        return getContentProviderImpl(caller, name, null, stable,
6619                UserHandle.getCallingUserId());
6620    }
6621
6622    public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6623        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6624            "Do not have permission in call getContentProviderExternal()");
6625        return getContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6626    }
6627
6628    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
6629            IBinder token, int userId) {
6630        return getContentProviderImpl(null, name, token, true, userId);
6631    }
6632
6633    /**
6634     * Drop a content provider from a ProcessRecord's bookkeeping
6635     * @param cpr
6636     */
6637    public void removeContentProvider(IBinder connection, boolean stable) {
6638        enforceNotIsolatedCaller("removeContentProvider");
6639        synchronized (this) {
6640            ContentProviderConnection conn;
6641            try {
6642                conn = (ContentProviderConnection)connection;
6643            } catch (ClassCastException e) {
6644                String msg ="removeContentProvider: " + connection
6645                        + " not a ContentProviderConnection";
6646                Slog.w(TAG, msg);
6647                throw new IllegalArgumentException(msg);
6648            }
6649            if (conn == null) {
6650                throw new NullPointerException("connection is null");
6651            }
6652            if (decProviderCountLocked(conn, null, null, stable)) {
6653                updateOomAdjLocked();
6654            }
6655        }
6656    }
6657
6658    public void removeContentProviderExternal(String name, IBinder token) {
6659        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6660            "Do not have permission in call removeContentProviderExternal()");
6661        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6662    }
6663
6664    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
6665        synchronized (this) {
6666            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
6667            if(cpr == null) {
6668                //remove from mProvidersByClass
6669                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6670                return;
6671            }
6672
6673            //update content provider record entry info
6674            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6675            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
6676            if (localCpr.hasExternalProcessHandles()) {
6677                if (localCpr.removeExternalProcessHandleLocked(token)) {
6678                    updateOomAdjLocked();
6679                } else {
6680                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6681                            + " with no external reference for token: "
6682                            + token + ".");
6683                }
6684            } else {
6685                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6686                        + " with no external references.");
6687            }
6688        }
6689    }
6690
6691    public final void publishContentProviders(IApplicationThread caller,
6692            List<ContentProviderHolder> providers) {
6693        if (providers == null) {
6694            return;
6695        }
6696
6697        enforceNotIsolatedCaller("publishContentProviders");
6698        synchronized (this) {
6699            final ProcessRecord r = getRecordForAppLocked(caller);
6700            if (DEBUG_MU)
6701                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6702            if (r == null) {
6703                throw new SecurityException(
6704                        "Unable to find app for caller " + caller
6705                      + " (pid=" + Binder.getCallingPid()
6706                      + ") when publishing content providers");
6707            }
6708
6709            final long origId = Binder.clearCallingIdentity();
6710
6711            final int N = providers.size();
6712            for (int i=0; i<N; i++) {
6713                ContentProviderHolder src = providers.get(i);
6714                if (src == null || src.info == null || src.provider == null) {
6715                    continue;
6716                }
6717                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6718                if (DEBUG_MU)
6719                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6720                if (dst != null) {
6721                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6722                    mProviderMap.putProviderByClass(comp, dst);
6723                    String names[] = dst.info.authority.split(";");
6724                    for (int j = 0; j < names.length; j++) {
6725                        mProviderMap.putProviderByName(names[j], dst);
6726                    }
6727
6728                    int NL = mLaunchingProviders.size();
6729                    int j;
6730                    for (j=0; j<NL; j++) {
6731                        if (mLaunchingProviders.get(j) == dst) {
6732                            mLaunchingProviders.remove(j);
6733                            j--;
6734                            NL--;
6735                        }
6736                    }
6737                    synchronized (dst) {
6738                        dst.provider = src.provider;
6739                        dst.proc = r;
6740                        dst.notifyAll();
6741                    }
6742                    updateOomAdjLocked(r);
6743                }
6744            }
6745
6746            Binder.restoreCallingIdentity(origId);
6747        }
6748    }
6749
6750    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6751        ContentProviderConnection conn;
6752        try {
6753            conn = (ContentProviderConnection)connection;
6754        } catch (ClassCastException e) {
6755            String msg ="refContentProvider: " + connection
6756                    + " not a ContentProviderConnection";
6757            Slog.w(TAG, msg);
6758            throw new IllegalArgumentException(msg);
6759        }
6760        if (conn == null) {
6761            throw new NullPointerException("connection is null");
6762        }
6763
6764        synchronized (this) {
6765            if (stable > 0) {
6766                conn.numStableIncs += stable;
6767            }
6768            stable = conn.stableCount + stable;
6769            if (stable < 0) {
6770                throw new IllegalStateException("stableCount < 0: " + stable);
6771            }
6772
6773            if (unstable > 0) {
6774                conn.numUnstableIncs += unstable;
6775            }
6776            unstable = conn.unstableCount + unstable;
6777            if (unstable < 0) {
6778                throw new IllegalStateException("unstableCount < 0: " + unstable);
6779            }
6780
6781            if ((stable+unstable) <= 0) {
6782                throw new IllegalStateException("ref counts can't go to zero here: stable="
6783                        + stable + " unstable=" + unstable);
6784            }
6785            conn.stableCount = stable;
6786            conn.unstableCount = unstable;
6787            return !conn.dead;
6788        }
6789    }
6790
6791    public void unstableProviderDied(IBinder connection) {
6792        ContentProviderConnection conn;
6793        try {
6794            conn = (ContentProviderConnection)connection;
6795        } catch (ClassCastException e) {
6796            String msg ="refContentProvider: " + connection
6797                    + " not a ContentProviderConnection";
6798            Slog.w(TAG, msg);
6799            throw new IllegalArgumentException(msg);
6800        }
6801        if (conn == null) {
6802            throw new NullPointerException("connection is null");
6803        }
6804
6805        // Safely retrieve the content provider associated with the connection.
6806        IContentProvider provider;
6807        synchronized (this) {
6808            provider = conn.provider.provider;
6809        }
6810
6811        if (provider == null) {
6812            // Um, yeah, we're way ahead of you.
6813            return;
6814        }
6815
6816        // Make sure the caller is being honest with us.
6817        if (provider.asBinder().pingBinder()) {
6818            // Er, no, still looks good to us.
6819            synchronized (this) {
6820                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6821                        + " says " + conn + " died, but we don't agree");
6822                return;
6823            }
6824        }
6825
6826        // Well look at that!  It's dead!
6827        synchronized (this) {
6828            if (conn.provider.provider != provider) {
6829                // But something changed...  good enough.
6830                return;
6831            }
6832
6833            ProcessRecord proc = conn.provider.proc;
6834            if (proc == null || proc.thread == null) {
6835                // Seems like the process is already cleaned up.
6836                return;
6837            }
6838
6839            // As far as we're concerned, this is just like receiving a
6840            // death notification...  just a bit prematurely.
6841            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6842                    + ") early provider death");
6843            final long ident = Binder.clearCallingIdentity();
6844            try {
6845                appDiedLocked(proc, proc.pid, proc.thread);
6846            } finally {
6847                Binder.restoreCallingIdentity(ident);
6848            }
6849        }
6850    }
6851
6852    public static final void installSystemProviders() {
6853        List<ProviderInfo> providers;
6854        synchronized (mSelf) {
6855            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6856            providers = mSelf.generateApplicationProvidersLocked(app);
6857            if (providers != null) {
6858                for (int i=providers.size()-1; i>=0; i--) {
6859                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6860                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6861                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6862                                + ": not system .apk");
6863                        providers.remove(i);
6864                    }
6865                }
6866            }
6867        }
6868        if (providers != null) {
6869            mSystemThread.installSystemProviders(providers);
6870        }
6871
6872        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6873
6874        mSelf.mUsageStatsService.monitorPackages();
6875    }
6876
6877    /**
6878     * Allows app to retrieve the MIME type of a URI without having permission
6879     * to access its content provider.
6880     *
6881     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6882     *
6883     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6884     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6885     */
6886    public String getProviderMimeType(Uri uri, int userId) {
6887        enforceNotIsolatedCaller("getProviderMimeType");
6888        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
6889                userId, false, true, "getProviderMimeType", null);
6890        final String name = uri.getAuthority();
6891        final long ident = Binder.clearCallingIdentity();
6892        ContentProviderHolder holder = null;
6893
6894        try {
6895            holder = getContentProviderExternalUnchecked(name, null, userId);
6896            if (holder != null) {
6897                return holder.provider.getType(uri);
6898            }
6899        } catch (RemoteException e) {
6900            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6901            return null;
6902        } finally {
6903            if (holder != null) {
6904                removeContentProviderExternalUnchecked(name, null, userId);
6905            }
6906            Binder.restoreCallingIdentity(ident);
6907        }
6908
6909        return null;
6910    }
6911
6912    // =========================================================
6913    // GLOBAL MANAGEMENT
6914    // =========================================================
6915
6916    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6917            ApplicationInfo info, String customProcess, boolean isolated) {
6918        String proc = customProcess != null ? customProcess : info.processName;
6919        BatteryStatsImpl.Uid.Proc ps = null;
6920        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6921        int uid = info.uid;
6922        if (isolated) {
6923            int userId = UserHandle.getUserId(uid);
6924            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6925            uid = 0;
6926            while (true) {
6927                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6928                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6929                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6930                }
6931                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
6932                mNextIsolatedProcessUid++;
6933                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6934                    // No process for this uid, use it.
6935                    break;
6936                }
6937                stepsLeft--;
6938                if (stepsLeft <= 0) {
6939                    return null;
6940                }
6941            }
6942        }
6943        synchronized (stats) {
6944            ps = stats.getProcessStatsLocked(info.uid, proc);
6945        }
6946        return new ProcessRecord(ps, thread, info, proc, uid);
6947    }
6948
6949    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6950        ProcessRecord app;
6951        if (!isolated) {
6952            app = getProcessRecordLocked(info.processName, info.uid);
6953        } else {
6954            app = null;
6955        }
6956
6957        if (app == null) {
6958            app = newProcessRecordLocked(null, info, null, isolated);
6959            mProcessNames.put(info.processName, app.uid, app);
6960            if (isolated) {
6961                mIsolatedProcesses.put(app.uid, app);
6962            }
6963            updateLruProcessLocked(app, true, true);
6964        }
6965
6966        // This package really, really can not be stopped.
6967        try {
6968            AppGlobals.getPackageManager().setPackageStoppedState(
6969                    info.packageName, false, UserHandle.getUserId(app.uid));
6970        } catch (RemoteException e) {
6971        } catch (IllegalArgumentException e) {
6972            Slog.w(TAG, "Failed trying to unstop package "
6973                    + info.packageName + ": " + e);
6974        }
6975
6976        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6977                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6978            app.persistent = true;
6979            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
6980        }
6981        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6982            mPersistentStartingProcesses.add(app);
6983            startProcessLocked(app, "added application", app.processName);
6984        }
6985
6986        return app;
6987    }
6988
6989    public void unhandledBack() {
6990        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6991                "unhandledBack()");
6992
6993        synchronized(this) {
6994            int count = mMainStack.mHistory.size();
6995            if (DEBUG_SWITCH) Slog.d(
6996                TAG, "Performing unhandledBack(): stack size = " + count);
6997            if (count > 1) {
6998                final long origId = Binder.clearCallingIdentity();
6999                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
7000                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true);
7001                Binder.restoreCallingIdentity(origId);
7002            }
7003        }
7004    }
7005
7006    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
7007        enforceNotIsolatedCaller("openContentUri");
7008        final int userId = UserHandle.getCallingUserId();
7009        String name = uri.getAuthority();
7010        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
7011        ParcelFileDescriptor pfd = null;
7012        if (cph != null) {
7013            // We record the binder invoker's uid in thread-local storage before
7014            // going to the content provider to open the file.  Later, in the code
7015            // that handles all permissions checks, we look for this uid and use
7016            // that rather than the Activity Manager's own uid.  The effect is that
7017            // we do the check against the caller's permissions even though it looks
7018            // to the content provider like the Activity Manager itself is making
7019            // the request.
7020            sCallerIdentity.set(new Identity(
7021                    Binder.getCallingPid(), Binder.getCallingUid()));
7022            try {
7023                pfd = cph.provider.openFile(uri, "r");
7024            } catch (FileNotFoundException e) {
7025                // do nothing; pfd will be returned null
7026            } finally {
7027                // Ensure that whatever happens, we clean up the identity state
7028                sCallerIdentity.remove();
7029            }
7030
7031            // We've got the fd now, so we're done with the provider.
7032            removeContentProviderExternalUnchecked(name, null, userId);
7033        } else {
7034            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
7035        }
7036        return pfd;
7037    }
7038
7039    // Actually is sleeping or shutting down or whatever else in the future
7040    // is an inactive state.
7041    public boolean isSleeping() {
7042        return mSleeping || mShuttingDown;
7043    }
7044
7045    public void goingToSleep() {
7046        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7047                != PackageManager.PERMISSION_GRANTED) {
7048            throw new SecurityException("Requires permission "
7049                    + android.Manifest.permission.DEVICE_POWER);
7050        }
7051
7052        synchronized(this) {
7053            mWentToSleep = true;
7054            updateEventDispatchingLocked();
7055
7056            if (!mSleeping) {
7057                mSleeping = true;
7058                mMainStack.stopIfSleepingLocked();
7059
7060                // Initialize the wake times of all processes.
7061                checkExcessivePowerUsageLocked(false);
7062                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7063                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7064                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
7065            }
7066        }
7067    }
7068
7069    public boolean shutdown(int timeout) {
7070        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7071                != PackageManager.PERMISSION_GRANTED) {
7072            throw new SecurityException("Requires permission "
7073                    + android.Manifest.permission.SHUTDOWN);
7074        }
7075
7076        boolean timedout = false;
7077
7078        synchronized(this) {
7079            mShuttingDown = true;
7080            updateEventDispatchingLocked();
7081
7082            if (mMainStack.mResumedActivity != null) {
7083                mMainStack.stopIfSleepingLocked();
7084                final long endTime = System.currentTimeMillis() + timeout;
7085                while (mMainStack.mResumedActivity != null
7086                        || mMainStack.mPausingActivity != null) {
7087                    long delay = endTime - System.currentTimeMillis();
7088                    if (delay <= 0) {
7089                        Slog.w(TAG, "Activity manager shutdown timed out");
7090                        timedout = true;
7091                        break;
7092                    }
7093                    try {
7094                        this.wait();
7095                    } catch (InterruptedException e) {
7096                    }
7097                }
7098            }
7099        }
7100
7101        mUsageStatsService.shutdown();
7102        mBatteryStatsService.shutdown();
7103
7104        return timedout;
7105    }
7106
7107    public final void activitySlept(IBinder token) {
7108        if (localLOGV) Slog.v(
7109            TAG, "Activity slept: token=" + token);
7110
7111        ActivityRecord r = null;
7112
7113        final long origId = Binder.clearCallingIdentity();
7114
7115        synchronized (this) {
7116            r = mMainStack.isInStackLocked(token);
7117            if (r != null) {
7118                mMainStack.activitySleptLocked(r);
7119            }
7120        }
7121
7122        Binder.restoreCallingIdentity(origId);
7123    }
7124
7125    private void comeOutOfSleepIfNeededLocked() {
7126        if (!mWentToSleep && !mLockScreenShown) {
7127            if (mSleeping) {
7128                mSleeping = false;
7129                mMainStack.awakeFromSleepingLocked();
7130                mMainStack.resumeTopActivityLocked(null);
7131            }
7132        }
7133    }
7134
7135    public void wakingUp() {
7136        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7137                != PackageManager.PERMISSION_GRANTED) {
7138            throw new SecurityException("Requires permission "
7139                    + android.Manifest.permission.DEVICE_POWER);
7140        }
7141
7142        synchronized(this) {
7143            mWentToSleep = false;
7144            updateEventDispatchingLocked();
7145            comeOutOfSleepIfNeededLocked();
7146        }
7147    }
7148
7149    private void updateEventDispatchingLocked() {
7150        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
7151    }
7152
7153    public void setLockScreenShown(boolean shown) {
7154        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7155                != PackageManager.PERMISSION_GRANTED) {
7156            throw new SecurityException("Requires permission "
7157                    + android.Manifest.permission.DEVICE_POWER);
7158        }
7159
7160        synchronized(this) {
7161            mLockScreenShown = shown;
7162            comeOutOfSleepIfNeededLocked();
7163        }
7164    }
7165
7166    public void stopAppSwitches() {
7167        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7168                != PackageManager.PERMISSION_GRANTED) {
7169            throw new SecurityException("Requires permission "
7170                    + android.Manifest.permission.STOP_APP_SWITCHES);
7171        }
7172
7173        synchronized(this) {
7174            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7175                    + APP_SWITCH_DELAY_TIME;
7176            mDidAppSwitch = false;
7177            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7178            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7179            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7180        }
7181    }
7182
7183    public void resumeAppSwitches() {
7184        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7185                != PackageManager.PERMISSION_GRANTED) {
7186            throw new SecurityException("Requires permission "
7187                    + android.Manifest.permission.STOP_APP_SWITCHES);
7188        }
7189
7190        synchronized(this) {
7191            // Note that we don't execute any pending app switches... we will
7192            // let those wait until either the timeout, or the next start
7193            // activity request.
7194            mAppSwitchesAllowedTime = 0;
7195        }
7196    }
7197
7198    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7199            String name) {
7200        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7201            return true;
7202        }
7203
7204        final int perm = checkComponentPermission(
7205                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7206                callingUid, -1, true);
7207        if (perm == PackageManager.PERMISSION_GRANTED) {
7208            return true;
7209        }
7210
7211        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7212        return false;
7213    }
7214
7215    public void setDebugApp(String packageName, boolean waitForDebugger,
7216            boolean persistent) {
7217        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7218                "setDebugApp()");
7219
7220        // Note that this is not really thread safe if there are multiple
7221        // callers into it at the same time, but that's not a situation we
7222        // care about.
7223        if (persistent) {
7224            final ContentResolver resolver = mContext.getContentResolver();
7225            Settings.System.putString(
7226                resolver, Settings.System.DEBUG_APP,
7227                packageName);
7228            Settings.System.putInt(
7229                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7230                waitForDebugger ? 1 : 0);
7231        }
7232
7233        synchronized (this) {
7234            if (!persistent) {
7235                mOrigDebugApp = mDebugApp;
7236                mOrigWaitForDebugger = mWaitForDebugger;
7237            }
7238            mDebugApp = packageName;
7239            mWaitForDebugger = waitForDebugger;
7240            mDebugTransient = !persistent;
7241            if (packageName != null) {
7242                final long origId = Binder.clearCallingIdentity();
7243                forceStopPackageLocked(packageName, -1, false, false, true, true,
7244                        UserHandle.USER_ALL);
7245                Binder.restoreCallingIdentity(origId);
7246            }
7247        }
7248    }
7249
7250    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7251        synchronized (this) {
7252            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7253            if (!isDebuggable) {
7254                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7255                    throw new SecurityException("Process not debuggable: " + app.packageName);
7256                }
7257            }
7258
7259            mOpenGlTraceApp = processName;
7260        }
7261    }
7262
7263    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7264            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7265        synchronized (this) {
7266            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7267            if (!isDebuggable) {
7268                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7269                    throw new SecurityException("Process not debuggable: " + app.packageName);
7270                }
7271            }
7272            mProfileApp = processName;
7273            mProfileFile = profileFile;
7274            if (mProfileFd != null) {
7275                try {
7276                    mProfileFd.close();
7277                } catch (IOException e) {
7278                }
7279                mProfileFd = null;
7280            }
7281            mProfileFd = profileFd;
7282            mProfileType = 0;
7283            mAutoStopProfiler = autoStopProfiler;
7284        }
7285    }
7286
7287    public void setAlwaysFinish(boolean enabled) {
7288        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7289                "setAlwaysFinish()");
7290
7291        Settings.System.putInt(
7292                mContext.getContentResolver(),
7293                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7294
7295        synchronized (this) {
7296            mAlwaysFinishActivities = enabled;
7297        }
7298    }
7299
7300    public void setActivityController(IActivityController controller) {
7301        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7302                "setActivityController()");
7303        synchronized (this) {
7304            mController = controller;
7305        }
7306    }
7307
7308    public boolean isUserAMonkey() {
7309        // For now the fact that there is a controller implies
7310        // we have a monkey.
7311        synchronized (this) {
7312            return mController != null;
7313        }
7314    }
7315
7316    public void registerProcessObserver(IProcessObserver observer) {
7317        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7318                "registerProcessObserver()");
7319        synchronized (this) {
7320            mProcessObservers.register(observer);
7321        }
7322    }
7323
7324    public void unregisterProcessObserver(IProcessObserver observer) {
7325        synchronized (this) {
7326            mProcessObservers.unregister(observer);
7327        }
7328    }
7329
7330    public void setImmersive(IBinder token, boolean immersive) {
7331        synchronized(this) {
7332            ActivityRecord r = mMainStack.isInStackLocked(token);
7333            if (r == null) {
7334                throw new IllegalArgumentException();
7335            }
7336            r.immersive = immersive;
7337        }
7338    }
7339
7340    public boolean isImmersive(IBinder token) {
7341        synchronized (this) {
7342            ActivityRecord r = mMainStack.isInStackLocked(token);
7343            if (r == null) {
7344                throw new IllegalArgumentException();
7345            }
7346            return r.immersive;
7347        }
7348    }
7349
7350    public boolean isTopActivityImmersive() {
7351        enforceNotIsolatedCaller("startActivity");
7352        synchronized (this) {
7353            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7354            return (r != null) ? r.immersive : false;
7355        }
7356    }
7357
7358    public final void enterSafeMode() {
7359        synchronized(this) {
7360            // It only makes sense to do this before the system is ready
7361            // and started launching other packages.
7362            if (!mSystemReady) {
7363                try {
7364                    AppGlobals.getPackageManager().enterSafeMode();
7365                } catch (RemoteException e) {
7366                }
7367            }
7368        }
7369    }
7370
7371    public final void showSafeModeOverlay() {
7372        View v = LayoutInflater.from(mContext).inflate(
7373                com.android.internal.R.layout.safe_mode, null);
7374        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7375        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7376        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7377        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7378        lp.gravity = Gravity.BOTTOM | Gravity.START;
7379        lp.format = v.getBackground().getOpacity();
7380        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7381                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7382        ((WindowManager)mContext.getSystemService(
7383                Context.WINDOW_SERVICE)).addView(v, lp);
7384    }
7385
7386    public void noteWakeupAlarm(IIntentSender sender) {
7387        if (!(sender instanceof PendingIntentRecord)) {
7388            return;
7389        }
7390        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7391        synchronized (stats) {
7392            if (mBatteryStatsService.isOnBattery()) {
7393                mBatteryStatsService.enforceCallingPermission();
7394                PendingIntentRecord rec = (PendingIntentRecord)sender;
7395                int MY_UID = Binder.getCallingUid();
7396                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7397                BatteryStatsImpl.Uid.Pkg pkg =
7398                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7399                pkg.incWakeupsLocked();
7400            }
7401        }
7402    }
7403
7404    public boolean killPids(int[] pids, String pReason, boolean secure) {
7405        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7406            throw new SecurityException("killPids only available to the system");
7407        }
7408        String reason = (pReason == null) ? "Unknown" : pReason;
7409        // XXX Note: don't acquire main activity lock here, because the window
7410        // manager calls in with its locks held.
7411
7412        boolean killed = false;
7413        synchronized (mPidsSelfLocked) {
7414            int[] types = new int[pids.length];
7415            int worstType = 0;
7416            for (int i=0; i<pids.length; i++) {
7417                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7418                if (proc != null) {
7419                    int type = proc.setAdj;
7420                    types[i] = type;
7421                    if (type > worstType) {
7422                        worstType = type;
7423                    }
7424                }
7425            }
7426
7427            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7428            // then constrain it so we will kill all hidden procs.
7429            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7430                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7431                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7432            }
7433
7434            // If this is not a secure call, don't let it kill processes that
7435            // are important.
7436            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7437                worstType = ProcessList.SERVICE_ADJ;
7438            }
7439
7440            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7441            for (int i=0; i<pids.length; i++) {
7442                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7443                if (proc == null) {
7444                    continue;
7445                }
7446                int adj = proc.setAdj;
7447                if (adj >= worstType && !proc.killedBackground) {
7448                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7449                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7450                            proc.processName, adj, reason);
7451                    killed = true;
7452                    proc.killedBackground = true;
7453                    Process.killProcessQuiet(pids[i]);
7454                }
7455            }
7456        }
7457        return killed;
7458    }
7459
7460    @Override
7461    public boolean killProcessesBelowForeground(String reason) {
7462        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7463            throw new SecurityException("killProcessesBelowForeground() only available to system");
7464        }
7465
7466        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7467    }
7468
7469    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7470        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7471            throw new SecurityException("killProcessesBelowAdj() only available to system");
7472        }
7473
7474        boolean killed = false;
7475        synchronized (mPidsSelfLocked) {
7476            final int size = mPidsSelfLocked.size();
7477            for (int i = 0; i < size; i++) {
7478                final int pid = mPidsSelfLocked.keyAt(i);
7479                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7480                if (proc == null) continue;
7481
7482                final int adj = proc.setAdj;
7483                if (adj > belowAdj && !proc.killedBackground) {
7484                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7485                    EventLog.writeEvent(
7486                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7487                    killed = true;
7488                    proc.killedBackground = true;
7489                    Process.killProcessQuiet(pid);
7490                }
7491            }
7492        }
7493        return killed;
7494    }
7495
7496    public final void startRunning(String pkg, String cls, String action,
7497            String data) {
7498        synchronized(this) {
7499            if (mStartRunning) {
7500                return;
7501            }
7502            mStartRunning = true;
7503            mTopComponent = pkg != null && cls != null
7504                    ? new ComponentName(pkg, cls) : null;
7505            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7506            mTopData = data;
7507            if (!mSystemReady) {
7508                return;
7509            }
7510        }
7511
7512        systemReady(null);
7513    }
7514
7515    private void retrieveSettings() {
7516        final ContentResolver resolver = mContext.getContentResolver();
7517        String debugApp = Settings.System.getString(
7518            resolver, Settings.System.DEBUG_APP);
7519        boolean waitForDebugger = Settings.System.getInt(
7520            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7521        boolean alwaysFinishActivities = Settings.System.getInt(
7522            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7523
7524        Configuration configuration = new Configuration();
7525        Settings.System.getConfiguration(resolver, configuration);
7526
7527        synchronized (this) {
7528            mDebugApp = mOrigDebugApp = debugApp;
7529            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7530            mAlwaysFinishActivities = alwaysFinishActivities;
7531            // This happens before any activities are started, so we can
7532            // change mConfiguration in-place.
7533            updateConfigurationLocked(configuration, null, false, true);
7534            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7535        }
7536    }
7537
7538    public boolean testIsSystemReady() {
7539        // no need to synchronize(this) just to read & return the value
7540        return mSystemReady;
7541    }
7542
7543    private static File getCalledPreBootReceiversFile() {
7544        File dataDir = Environment.getDataDirectory();
7545        File systemDir = new File(dataDir, "system");
7546        File fname = new File(systemDir, "called_pre_boots.dat");
7547        return fname;
7548    }
7549
7550    static final int LAST_DONE_VERSION = 10000;
7551
7552    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7553        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7554        File file = getCalledPreBootReceiversFile();
7555        FileInputStream fis = null;
7556        try {
7557            fis = new FileInputStream(file);
7558            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7559            int fvers = dis.readInt();
7560            if (fvers == LAST_DONE_VERSION) {
7561                String vers = dis.readUTF();
7562                String codename = dis.readUTF();
7563                String build = dis.readUTF();
7564                if (android.os.Build.VERSION.RELEASE.equals(vers)
7565                        && android.os.Build.VERSION.CODENAME.equals(codename)
7566                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7567                    int num = dis.readInt();
7568                    while (num > 0) {
7569                        num--;
7570                        String pkg = dis.readUTF();
7571                        String cls = dis.readUTF();
7572                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7573                    }
7574                }
7575            }
7576        } catch (FileNotFoundException e) {
7577        } catch (IOException e) {
7578            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7579        } finally {
7580            if (fis != null) {
7581                try {
7582                    fis.close();
7583                } catch (IOException e) {
7584                }
7585            }
7586        }
7587        return lastDoneReceivers;
7588    }
7589
7590    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7591        File file = getCalledPreBootReceiversFile();
7592        FileOutputStream fos = null;
7593        DataOutputStream dos = null;
7594        try {
7595            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7596            fos = new FileOutputStream(file);
7597            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7598            dos.writeInt(LAST_DONE_VERSION);
7599            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7600            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7601            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7602            dos.writeInt(list.size());
7603            for (int i=0; i<list.size(); i++) {
7604                dos.writeUTF(list.get(i).getPackageName());
7605                dos.writeUTF(list.get(i).getClassName());
7606            }
7607        } catch (IOException e) {
7608            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7609            file.delete();
7610        } finally {
7611            FileUtils.sync(fos);
7612            if (dos != null) {
7613                try {
7614                    dos.close();
7615                } catch (IOException e) {
7616                    // TODO Auto-generated catch block
7617                    e.printStackTrace();
7618                }
7619            }
7620        }
7621    }
7622
7623    public void systemReady(final Runnable goingCallback) {
7624        synchronized(this) {
7625            if (mSystemReady) {
7626                if (goingCallback != null) goingCallback.run();
7627                return;
7628            }
7629
7630            // Check to see if there are any update receivers to run.
7631            if (!mDidUpdate) {
7632                if (mWaitingUpdate) {
7633                    return;
7634                }
7635                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7636                List<ResolveInfo> ris = null;
7637                try {
7638                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7639                            intent, null, 0, 0);
7640                } catch (RemoteException e) {
7641                }
7642                if (ris != null) {
7643                    for (int i=ris.size()-1; i>=0; i--) {
7644                        if ((ris.get(i).activityInfo.applicationInfo.flags
7645                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7646                            ris.remove(i);
7647                        }
7648                    }
7649                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7650
7651                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7652
7653                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7654                    for (int i=0; i<ris.size(); i++) {
7655                        ActivityInfo ai = ris.get(i).activityInfo;
7656                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7657                        if (lastDoneReceivers.contains(comp)) {
7658                            ris.remove(i);
7659                            i--;
7660                        }
7661                    }
7662
7663                    for (int i=0; i<ris.size(); i++) {
7664                        ActivityInfo ai = ris.get(i).activityInfo;
7665                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7666                        doneReceivers.add(comp);
7667                        intent.setComponent(comp);
7668                        IIntentReceiver finisher = null;
7669                        if (i == ris.size()-1) {
7670                            finisher = new IIntentReceiver.Stub() {
7671                                public void performReceive(Intent intent, int resultCode,
7672                                        String data, Bundle extras, boolean ordered,
7673                                        boolean sticky, int sendingUser) {
7674                                    // The raw IIntentReceiver interface is called
7675                                    // with the AM lock held, so redispatch to
7676                                    // execute our code without the lock.
7677                                    mHandler.post(new Runnable() {
7678                                        public void run() {
7679                                            synchronized (ActivityManagerService.this) {
7680                                                mDidUpdate = true;
7681                                            }
7682                                            writeLastDonePreBootReceivers(doneReceivers);
7683                                            showBootMessage(mContext.getText(
7684                                                    R.string.android_upgrading_complete),
7685                                                    false);
7686                                            systemReady(goingCallback);
7687                                        }
7688                                    });
7689                                }
7690                            };
7691                        }
7692                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
7693                        // XXX also need to send this to stopped users(!!!)
7694                        broadcastIntentLocked(null, null, intent, null, finisher,
7695                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7696                                UserHandle.USER_ALL);
7697                        if (finisher != null) {
7698                            mWaitingUpdate = true;
7699                        }
7700                    }
7701                }
7702                if (mWaitingUpdate) {
7703                    return;
7704                }
7705                mDidUpdate = true;
7706            }
7707
7708            mSystemReady = true;
7709            if (!mStartRunning) {
7710                return;
7711            }
7712        }
7713
7714        ArrayList<ProcessRecord> procsToKill = null;
7715        synchronized(mPidsSelfLocked) {
7716            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7717                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7718                if (!isAllowedWhileBooting(proc.info)){
7719                    if (procsToKill == null) {
7720                        procsToKill = new ArrayList<ProcessRecord>();
7721                    }
7722                    procsToKill.add(proc);
7723                }
7724            }
7725        }
7726
7727        synchronized(this) {
7728            if (procsToKill != null) {
7729                for (int i=procsToKill.size()-1; i>=0; i--) {
7730                    ProcessRecord proc = procsToKill.get(i);
7731                    Slog.i(TAG, "Removing system update proc: " + proc);
7732                    removeProcessLocked(proc, true, false, "system update done");
7733                }
7734            }
7735
7736            // Now that we have cleaned up any update processes, we
7737            // are ready to start launching real processes and know that
7738            // we won't trample on them any more.
7739            mProcessesReady = true;
7740        }
7741
7742        Slog.i(TAG, "System now ready");
7743        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7744            SystemClock.uptimeMillis());
7745
7746        synchronized(this) {
7747            // Make sure we have no pre-ready processes sitting around.
7748
7749            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7750                ResolveInfo ri = mContext.getPackageManager()
7751                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7752                                STOCK_PM_FLAGS);
7753                CharSequence errorMsg = null;
7754                if (ri != null) {
7755                    ActivityInfo ai = ri.activityInfo;
7756                    ApplicationInfo app = ai.applicationInfo;
7757                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7758                        mTopAction = Intent.ACTION_FACTORY_TEST;
7759                        mTopData = null;
7760                        mTopComponent = new ComponentName(app.packageName,
7761                                ai.name);
7762                    } else {
7763                        errorMsg = mContext.getResources().getText(
7764                                com.android.internal.R.string.factorytest_not_system);
7765                    }
7766                } else {
7767                    errorMsg = mContext.getResources().getText(
7768                            com.android.internal.R.string.factorytest_no_action);
7769                }
7770                if (errorMsg != null) {
7771                    mTopAction = null;
7772                    mTopData = null;
7773                    mTopComponent = null;
7774                    Message msg = Message.obtain();
7775                    msg.what = SHOW_FACTORY_ERROR_MSG;
7776                    msg.getData().putCharSequence("msg", errorMsg);
7777                    mHandler.sendMessage(msg);
7778                }
7779            }
7780        }
7781
7782        retrieveSettings();
7783
7784        if (goingCallback != null) goingCallback.run();
7785
7786        synchronized (this) {
7787            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7788                try {
7789                    List apps = AppGlobals.getPackageManager().
7790                        getPersistentApplications(STOCK_PM_FLAGS);
7791                    if (apps != null) {
7792                        int N = apps.size();
7793                        int i;
7794                        for (i=0; i<N; i++) {
7795                            ApplicationInfo info
7796                                = (ApplicationInfo)apps.get(i);
7797                            if (info != null &&
7798                                    !info.packageName.equals("android")) {
7799                                addAppLocked(info, false);
7800                            }
7801                        }
7802                    }
7803                } catch (RemoteException ex) {
7804                    // pm is in same process, this will never happen.
7805                }
7806            }
7807
7808            // Start up initial activity.
7809            mBooting = true;
7810
7811            try {
7812                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7813                    Message msg = Message.obtain();
7814                    msg.what = SHOW_UID_ERROR_MSG;
7815                    mHandler.sendMessage(msg);
7816                }
7817            } catch (RemoteException e) {
7818            }
7819
7820            mMainStack.resumeTopActivityLocked(null);
7821        }
7822    }
7823
7824    private boolean makeAppCrashingLocked(ProcessRecord app,
7825            String shortMsg, String longMsg, String stackTrace) {
7826        app.crashing = true;
7827        app.crashingReport = generateProcessError(app,
7828                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7829        startAppProblemLocked(app);
7830        app.stopFreezingAllLocked();
7831        return handleAppCrashLocked(app);
7832    }
7833
7834    private void makeAppNotRespondingLocked(ProcessRecord app,
7835            String activity, String shortMsg, String longMsg) {
7836        app.notResponding = true;
7837        app.notRespondingReport = generateProcessError(app,
7838                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7839                activity, shortMsg, longMsg, null);
7840        startAppProblemLocked(app);
7841        app.stopFreezingAllLocked();
7842    }
7843
7844    /**
7845     * Generate a process error record, suitable for attachment to a ProcessRecord.
7846     *
7847     * @param app The ProcessRecord in which the error occurred.
7848     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7849     *                      ActivityManager.AppErrorStateInfo
7850     * @param activity The activity associated with the crash, if known.
7851     * @param shortMsg Short message describing the crash.
7852     * @param longMsg Long message describing the crash.
7853     * @param stackTrace Full crash stack trace, may be null.
7854     *
7855     * @return Returns a fully-formed AppErrorStateInfo record.
7856     */
7857    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7858            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7859        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7860
7861        report.condition = condition;
7862        report.processName = app.processName;
7863        report.pid = app.pid;
7864        report.uid = app.info.uid;
7865        report.tag = activity;
7866        report.shortMsg = shortMsg;
7867        report.longMsg = longMsg;
7868        report.stackTrace = stackTrace;
7869
7870        return report;
7871    }
7872
7873    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7874        synchronized (this) {
7875            app.crashing = false;
7876            app.crashingReport = null;
7877            app.notResponding = false;
7878            app.notRespondingReport = null;
7879            if (app.anrDialog == fromDialog) {
7880                app.anrDialog = null;
7881            }
7882            if (app.waitDialog == fromDialog) {
7883                app.waitDialog = null;
7884            }
7885            if (app.pid > 0 && app.pid != MY_PID) {
7886                handleAppCrashLocked(app);
7887                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7888                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7889                        app.processName, app.setAdj, "user's request after error");
7890                Process.killProcessQuiet(app.pid);
7891            }
7892        }
7893    }
7894
7895    private boolean handleAppCrashLocked(ProcessRecord app) {
7896        if (mHeadless) {
7897            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7898            return false;
7899        }
7900        long now = SystemClock.uptimeMillis();
7901
7902        Long crashTime;
7903        if (!app.isolated) {
7904            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7905        } else {
7906            crashTime = null;
7907        }
7908        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7909            // This process loses!
7910            Slog.w(TAG, "Process " + app.info.processName
7911                    + " has crashed too many times: killing!");
7912            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7913                    app.info.processName, app.uid);
7914            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7915                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7916                if (r.app == app) {
7917                    Slog.w(TAG, "  Force finishing activity "
7918                        + r.intent.getComponent().flattenToShortString());
7919                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
7920                            null, "crashed", false);
7921                }
7922            }
7923            if (!app.persistent) {
7924                // We don't want to start this process again until the user
7925                // explicitly does so...  but for persistent process, we really
7926                // need to keep it running.  If a persistent process is actually
7927                // repeatedly crashing, then badness for everyone.
7928                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
7929                        app.info.processName);
7930                if (!app.isolated) {
7931                    // XXX We don't have a way to mark isolated processes
7932                    // as bad, since they don't have a peristent identity.
7933                    mBadProcesses.put(app.info.processName, app.uid, now);
7934                    mProcessCrashTimes.remove(app.info.processName, app.uid);
7935                }
7936                app.bad = true;
7937                app.removed = true;
7938                // Don't let services in this process be restarted and potentially
7939                // annoy the user repeatedly.  Unless it is persistent, since those
7940                // processes run critical code.
7941                removeProcessLocked(app, false, false, "crash");
7942                mMainStack.resumeTopActivityLocked(null);
7943                return false;
7944            }
7945            mMainStack.resumeTopActivityLocked(null);
7946        } else {
7947            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7948            if (r != null && r.app == app) {
7949                // If the top running activity is from this crashing
7950                // process, then terminate it to avoid getting in a loop.
7951                Slog.w(TAG, "  Force finishing activity "
7952                        + r.intent.getComponent().flattenToShortString());
7953                int index = mMainStack.indexOfActivityLocked(r);
7954                r.stack.finishActivityLocked(r, index,
7955                        Activity.RESULT_CANCELED, null, "crashed", false);
7956                // Also terminate any activities below it that aren't yet
7957                // stopped, to avoid a situation where one will get
7958                // re-start our crashing activity once it gets resumed again.
7959                index--;
7960                if (index >= 0) {
7961                    r = (ActivityRecord)mMainStack.mHistory.get(index);
7962                    if (r.state == ActivityState.RESUMED
7963                            || r.state == ActivityState.PAUSING
7964                            || r.state == ActivityState.PAUSED) {
7965                        if (!r.isHomeActivity || mHomeProcess != r.app) {
7966                            Slog.w(TAG, "  Force finishing activity "
7967                                    + r.intent.getComponent().flattenToShortString());
7968                            r.stack.finishActivityLocked(r, index,
7969                                    Activity.RESULT_CANCELED, null, "crashed", false);
7970                        }
7971                    }
7972                }
7973            }
7974        }
7975
7976        // Bump up the crash count of any services currently running in the proc.
7977        if (app.services.size() != 0) {
7978            // Any services running in the application need to be placed
7979            // back in the pending list.
7980            Iterator<ServiceRecord> it = app.services.iterator();
7981            while (it.hasNext()) {
7982                ServiceRecord sr = it.next();
7983                sr.crashCount++;
7984            }
7985        }
7986
7987        // If the crashing process is what we consider to be the "home process" and it has been
7988        // replaced by a third-party app, clear the package preferred activities from packages
7989        // with a home activity running in the process to prevent a repeatedly crashing app
7990        // from blocking the user to manually clear the list.
7991        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7992                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7993            Iterator it = mHomeProcess.activities.iterator();
7994            while (it.hasNext()) {
7995                ActivityRecord r = (ActivityRecord)it.next();
7996                if (r.isHomeActivity) {
7997                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7998                    try {
7999                        ActivityThread.getPackageManager()
8000                                .clearPackagePreferredActivities(r.packageName);
8001                    } catch (RemoteException c) {
8002                        // pm is in same process, this will never happen.
8003                    }
8004                }
8005            }
8006        }
8007
8008        if (!app.isolated) {
8009            // XXX Can't keep track of crash times for isolated processes,
8010            // because they don't have a perisistent identity.
8011            mProcessCrashTimes.put(app.info.processName, app.uid, now);
8012        }
8013
8014        return true;
8015    }
8016
8017    void startAppProblemLocked(ProcessRecord app) {
8018        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
8019                mContext, app.info.packageName, app.info.flags);
8020        skipCurrentReceiverLocked(app);
8021    }
8022
8023    void skipCurrentReceiverLocked(ProcessRecord app) {
8024        for (BroadcastQueue queue : mBroadcastQueues) {
8025            queue.skipCurrentReceiverLocked(app);
8026        }
8027    }
8028
8029    /**
8030     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8031     * The application process will exit immediately after this call returns.
8032     * @param app object of the crashing app, null for the system server
8033     * @param crashInfo describing the exception
8034     */
8035    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
8036        ProcessRecord r = findAppProcess(app, "Crash");
8037        final String processName = app == null ? "system_server"
8038                : (r == null ? "unknown" : r.processName);
8039
8040        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
8041                processName,
8042                r == null ? -1 : r.info.flags,
8043                crashInfo.exceptionClassName,
8044                crashInfo.exceptionMessage,
8045                crashInfo.throwFileName,
8046                crashInfo.throwLineNumber);
8047
8048        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
8049
8050        crashApplication(r, crashInfo);
8051    }
8052
8053    public void handleApplicationStrictModeViolation(
8054            IBinder app,
8055            int violationMask,
8056            StrictMode.ViolationInfo info) {
8057        ProcessRecord r = findAppProcess(app, "StrictMode");
8058        if (r == null) {
8059            return;
8060        }
8061
8062        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
8063            Integer stackFingerprint = info.hashCode();
8064            boolean logIt = true;
8065            synchronized (mAlreadyLoggedViolatedStacks) {
8066                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
8067                    logIt = false;
8068                    // TODO: sub-sample into EventLog for these, with
8069                    // the info.durationMillis?  Then we'd get
8070                    // the relative pain numbers, without logging all
8071                    // the stack traces repeatedly.  We'd want to do
8072                    // likewise in the client code, which also does
8073                    // dup suppression, before the Binder call.
8074                } else {
8075                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
8076                        mAlreadyLoggedViolatedStacks.clear();
8077                    }
8078                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
8079                }
8080            }
8081            if (logIt) {
8082                logStrictModeViolationToDropBox(r, info);
8083            }
8084        }
8085
8086        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
8087            AppErrorResult result = new AppErrorResult();
8088            synchronized (this) {
8089                final long origId = Binder.clearCallingIdentity();
8090
8091                Message msg = Message.obtain();
8092                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
8093                HashMap<String, Object> data = new HashMap<String, Object>();
8094                data.put("result", result);
8095                data.put("app", r);
8096                data.put("violationMask", violationMask);
8097                data.put("info", info);
8098                msg.obj = data;
8099                mHandler.sendMessage(msg);
8100
8101                Binder.restoreCallingIdentity(origId);
8102            }
8103            int res = result.get();
8104            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
8105        }
8106    }
8107
8108    // Depending on the policy in effect, there could be a bunch of
8109    // these in quick succession so we try to batch these together to
8110    // minimize disk writes, number of dropbox entries, and maximize
8111    // compression, by having more fewer, larger records.
8112    private void logStrictModeViolationToDropBox(
8113            ProcessRecord process,
8114            StrictMode.ViolationInfo info) {
8115        if (info == null) {
8116            return;
8117        }
8118        final boolean isSystemApp = process == null ||
8119                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8120                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
8121        final String processName = process == null ? "unknown" : process.processName;
8122        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8123        final DropBoxManager dbox = (DropBoxManager)
8124                mContext.getSystemService(Context.DROPBOX_SERVICE);
8125
8126        // Exit early if the dropbox isn't configured to accept this report type.
8127        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8128
8129        boolean bufferWasEmpty;
8130        boolean needsFlush;
8131        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8132        synchronized (sb) {
8133            bufferWasEmpty = sb.length() == 0;
8134            appendDropBoxProcessHeaders(process, processName, sb);
8135            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8136            sb.append("System-App: ").append(isSystemApp).append("\n");
8137            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8138            if (info.violationNumThisLoop != 0) {
8139                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8140            }
8141            if (info.numAnimationsRunning != 0) {
8142                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8143            }
8144            if (info.broadcastIntentAction != null) {
8145                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8146            }
8147            if (info.durationMillis != -1) {
8148                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
8149            }
8150            if (info.numInstances != -1) {
8151                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8152            }
8153            if (info.tags != null) {
8154                for (String tag : info.tags) {
8155                    sb.append("Span-Tag: ").append(tag).append("\n");
8156                }
8157            }
8158            sb.append("\n");
8159            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8160                sb.append(info.crashInfo.stackTrace);
8161            }
8162            sb.append("\n");
8163
8164            // Only buffer up to ~64k.  Various logging bits truncate
8165            // things at 128k.
8166            needsFlush = (sb.length() > 64 * 1024);
8167        }
8168
8169        // Flush immediately if the buffer's grown too large, or this
8170        // is a non-system app.  Non-system apps are isolated with a
8171        // different tag & policy and not batched.
8172        //
8173        // Batching is useful during internal testing with
8174        // StrictMode settings turned up high.  Without batching,
8175        // thousands of separate files could be created on boot.
8176        if (!isSystemApp || needsFlush) {
8177            new Thread("Error dump: " + dropboxTag) {
8178                @Override
8179                public void run() {
8180                    String report;
8181                    synchronized (sb) {
8182                        report = sb.toString();
8183                        sb.delete(0, sb.length());
8184                        sb.trimToSize();
8185                    }
8186                    if (report.length() != 0) {
8187                        dbox.addText(dropboxTag, report);
8188                    }
8189                }
8190            }.start();
8191            return;
8192        }
8193
8194        // System app batching:
8195        if (!bufferWasEmpty) {
8196            // An existing dropbox-writing thread is outstanding, so
8197            // we don't need to start it up.  The existing thread will
8198            // catch the buffer appends we just did.
8199            return;
8200        }
8201
8202        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8203        // (After this point, we shouldn't access AMS internal data structures.)
8204        new Thread("Error dump: " + dropboxTag) {
8205            @Override
8206            public void run() {
8207                // 5 second sleep to let stacks arrive and be batched together
8208                try {
8209                    Thread.sleep(5000);  // 5 seconds
8210                } catch (InterruptedException e) {}
8211
8212                String errorReport;
8213                synchronized (mStrictModeBuffer) {
8214                    errorReport = mStrictModeBuffer.toString();
8215                    if (errorReport.length() == 0) {
8216                        return;
8217                    }
8218                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8219                    mStrictModeBuffer.trimToSize();
8220                }
8221                dbox.addText(dropboxTag, errorReport);
8222            }
8223        }.start();
8224    }
8225
8226    /**
8227     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8228     * @param app object of the crashing app, null for the system server
8229     * @param tag reported by the caller
8230     * @param crashInfo describing the context of the error
8231     * @return true if the process should exit immediately (WTF is fatal)
8232     */
8233    public boolean handleApplicationWtf(IBinder app, String tag,
8234            ApplicationErrorReport.CrashInfo crashInfo) {
8235        ProcessRecord r = findAppProcess(app, "WTF");
8236        final String processName = app == null ? "system_server"
8237                : (r == null ? "unknown" : r.processName);
8238
8239        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8240                processName,
8241                r == null ? -1 : r.info.flags,
8242                tag, crashInfo.exceptionMessage);
8243
8244        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8245
8246        if (r != null && r.pid != Process.myPid() &&
8247                Settings.Secure.getInt(mContext.getContentResolver(),
8248                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
8249            crashApplication(r, crashInfo);
8250            return true;
8251        } else {
8252            return false;
8253        }
8254    }
8255
8256    /**
8257     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8258     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8259     */
8260    private ProcessRecord findAppProcess(IBinder app, String reason) {
8261        if (app == null) {
8262            return null;
8263        }
8264
8265        synchronized (this) {
8266            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8267                final int NA = apps.size();
8268                for (int ia=0; ia<NA; ia++) {
8269                    ProcessRecord p = apps.valueAt(ia);
8270                    if (p.thread != null && p.thread.asBinder() == app) {
8271                        return p;
8272                    }
8273                }
8274            }
8275
8276            Slog.w(TAG, "Can't find mystery application for " + reason
8277                    + " from pid=" + Binder.getCallingPid()
8278                    + " uid=" + Binder.getCallingUid() + ": " + app);
8279            return null;
8280        }
8281    }
8282
8283    /**
8284     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8285     * to append various headers to the dropbox log text.
8286     */
8287    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8288            StringBuilder sb) {
8289        // Watchdog thread ends up invoking this function (with
8290        // a null ProcessRecord) to add the stack file to dropbox.
8291        // Do not acquire a lock on this (am) in such cases, as it
8292        // could cause a potential deadlock, if and when watchdog
8293        // is invoked due to unavailability of lock on am and it
8294        // would prevent watchdog from killing system_server.
8295        if (process == null) {
8296            sb.append("Process: ").append(processName).append("\n");
8297            return;
8298        }
8299        // Note: ProcessRecord 'process' is guarded by the service
8300        // instance.  (notably process.pkgList, which could otherwise change
8301        // concurrently during execution of this method)
8302        synchronized (this) {
8303            sb.append("Process: ").append(processName).append("\n");
8304            int flags = process.info.flags;
8305            IPackageManager pm = AppGlobals.getPackageManager();
8306            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8307            for (String pkg : process.pkgList) {
8308                sb.append("Package: ").append(pkg);
8309                try {
8310                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
8311                    if (pi != null) {
8312                        sb.append(" v").append(pi.versionCode);
8313                        if (pi.versionName != null) {
8314                            sb.append(" (").append(pi.versionName).append(")");
8315                        }
8316                    }
8317                } catch (RemoteException e) {
8318                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8319                }
8320                sb.append("\n");
8321            }
8322        }
8323    }
8324
8325    private static String processClass(ProcessRecord process) {
8326        if (process == null || process.pid == MY_PID) {
8327            return "system_server";
8328        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8329            return "system_app";
8330        } else {
8331            return "data_app";
8332        }
8333    }
8334
8335    /**
8336     * Write a description of an error (crash, WTF, ANR) to the drop box.
8337     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8338     * @param process which caused the error, null means the system server
8339     * @param activity which triggered the error, null if unknown
8340     * @param parent activity related to the error, null if unknown
8341     * @param subject line related to the error, null if absent
8342     * @param report in long form describing the error, null if absent
8343     * @param logFile to include in the report, null if none
8344     * @param crashInfo giving an application stack trace, null if absent
8345     */
8346    public void addErrorToDropBox(String eventType,
8347            ProcessRecord process, String processName, ActivityRecord activity,
8348            ActivityRecord parent, String subject,
8349            final String report, final File logFile,
8350            final ApplicationErrorReport.CrashInfo crashInfo) {
8351        // NOTE -- this must never acquire the ActivityManagerService lock,
8352        // otherwise the watchdog may be prevented from resetting the system.
8353
8354        final String dropboxTag = processClass(process) + "_" + eventType;
8355        final DropBoxManager dbox = (DropBoxManager)
8356                mContext.getSystemService(Context.DROPBOX_SERVICE);
8357
8358        // Exit early if the dropbox isn't configured to accept this report type.
8359        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8360
8361        final StringBuilder sb = new StringBuilder(1024);
8362        appendDropBoxProcessHeaders(process, processName, sb);
8363        if (activity != null) {
8364            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8365        }
8366        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8367            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8368        }
8369        if (parent != null && parent != activity) {
8370            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8371        }
8372        if (subject != null) {
8373            sb.append("Subject: ").append(subject).append("\n");
8374        }
8375        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8376        if (Debug.isDebuggerConnected()) {
8377            sb.append("Debugger: Connected\n");
8378        }
8379        sb.append("\n");
8380
8381        // Do the rest in a worker thread to avoid blocking the caller on I/O
8382        // (After this point, we shouldn't access AMS internal data structures.)
8383        Thread worker = new Thread("Error dump: " + dropboxTag) {
8384            @Override
8385            public void run() {
8386                if (report != null) {
8387                    sb.append(report);
8388                }
8389                if (logFile != null) {
8390                    try {
8391                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8392                    } catch (IOException e) {
8393                        Slog.e(TAG, "Error reading " + logFile, e);
8394                    }
8395                }
8396                if (crashInfo != null && crashInfo.stackTrace != null) {
8397                    sb.append(crashInfo.stackTrace);
8398                }
8399
8400                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8401                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8402                if (lines > 0) {
8403                    sb.append("\n");
8404
8405                    // Merge several logcat streams, and take the last N lines
8406                    InputStreamReader input = null;
8407                    try {
8408                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8409                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8410                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8411
8412                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8413                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8414                        input = new InputStreamReader(logcat.getInputStream());
8415
8416                        int num;
8417                        char[] buf = new char[8192];
8418                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8419                    } catch (IOException e) {
8420                        Slog.e(TAG, "Error running logcat", e);
8421                    } finally {
8422                        if (input != null) try { input.close(); } catch (IOException e) {}
8423                    }
8424                }
8425
8426                dbox.addText(dropboxTag, sb.toString());
8427            }
8428        };
8429
8430        if (process == null) {
8431            // If process is null, we are being called from some internal code
8432            // and may be about to die -- run this synchronously.
8433            worker.run();
8434        } else {
8435            worker.start();
8436        }
8437    }
8438
8439    /**
8440     * Bring up the "unexpected error" dialog box for a crashing app.
8441     * Deal with edge cases (intercepts from instrumented applications,
8442     * ActivityController, error intent receivers, that sort of thing).
8443     * @param r the application crashing
8444     * @param crashInfo describing the failure
8445     */
8446    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8447        long timeMillis = System.currentTimeMillis();
8448        String shortMsg = crashInfo.exceptionClassName;
8449        String longMsg = crashInfo.exceptionMessage;
8450        String stackTrace = crashInfo.stackTrace;
8451        if (shortMsg != null && longMsg != null) {
8452            longMsg = shortMsg + ": " + longMsg;
8453        } else if (shortMsg != null) {
8454            longMsg = shortMsg;
8455        }
8456
8457        AppErrorResult result = new AppErrorResult();
8458        synchronized (this) {
8459            if (mController != null) {
8460                try {
8461                    String name = r != null ? r.processName : null;
8462                    int pid = r != null ? r.pid : Binder.getCallingPid();
8463                    if (!mController.appCrashed(name, pid,
8464                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8465                        Slog.w(TAG, "Force-killing crashed app " + name
8466                                + " at watcher's request");
8467                        Process.killProcess(pid);
8468                        return;
8469                    }
8470                } catch (RemoteException e) {
8471                    mController = null;
8472                }
8473            }
8474
8475            final long origId = Binder.clearCallingIdentity();
8476
8477            // If this process is running instrumentation, finish it.
8478            if (r != null && r.instrumentationClass != null) {
8479                Slog.w(TAG, "Error in app " + r.processName
8480                      + " running instrumentation " + r.instrumentationClass + ":");
8481                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8482                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8483                Bundle info = new Bundle();
8484                info.putString("shortMsg", shortMsg);
8485                info.putString("longMsg", longMsg);
8486                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8487                Binder.restoreCallingIdentity(origId);
8488                return;
8489            }
8490
8491            // If we can't identify the process or it's already exceeded its crash quota,
8492            // quit right away without showing a crash dialog.
8493            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8494                Binder.restoreCallingIdentity(origId);
8495                return;
8496            }
8497
8498            Message msg = Message.obtain();
8499            msg.what = SHOW_ERROR_MSG;
8500            HashMap data = new HashMap();
8501            data.put("result", result);
8502            data.put("app", r);
8503            msg.obj = data;
8504            mHandler.sendMessage(msg);
8505
8506            Binder.restoreCallingIdentity(origId);
8507        }
8508
8509        int res = result.get();
8510
8511        Intent appErrorIntent = null;
8512        synchronized (this) {
8513            if (r != null && !r.isolated) {
8514                // XXX Can't keep track of crash time for isolated processes,
8515                // since they don't have a persistent identity.
8516                mProcessCrashTimes.put(r.info.processName, r.uid,
8517                        SystemClock.uptimeMillis());
8518            }
8519            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8520                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8521            }
8522        }
8523
8524        if (appErrorIntent != null) {
8525            try {
8526                mContext.startActivity(appErrorIntent);
8527            } catch (ActivityNotFoundException e) {
8528                Slog.w(TAG, "bug report receiver dissappeared", e);
8529            }
8530        }
8531    }
8532
8533    Intent createAppErrorIntentLocked(ProcessRecord r,
8534            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8535        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8536        if (report == null) {
8537            return null;
8538        }
8539        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8540        result.setComponent(r.errorReportReceiver);
8541        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8542        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8543        return result;
8544    }
8545
8546    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8547            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8548        if (r.errorReportReceiver == null) {
8549            return null;
8550        }
8551
8552        if (!r.crashing && !r.notResponding) {
8553            return null;
8554        }
8555
8556        ApplicationErrorReport report = new ApplicationErrorReport();
8557        report.packageName = r.info.packageName;
8558        report.installerPackageName = r.errorReportReceiver.getPackageName();
8559        report.processName = r.processName;
8560        report.time = timeMillis;
8561        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8562
8563        if (r.crashing) {
8564            report.type = ApplicationErrorReport.TYPE_CRASH;
8565            report.crashInfo = crashInfo;
8566        } else if (r.notResponding) {
8567            report.type = ApplicationErrorReport.TYPE_ANR;
8568            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8569
8570            report.anrInfo.activity = r.notRespondingReport.tag;
8571            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8572            report.anrInfo.info = r.notRespondingReport.longMsg;
8573        }
8574
8575        return report;
8576    }
8577
8578    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8579        enforceNotIsolatedCaller("getProcessesInErrorState");
8580        // assume our apps are happy - lazy create the list
8581        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8582
8583        final boolean allUsers = ActivityManager.checkUidPermission(
8584                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8585                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8586        int userId = UserHandle.getUserId(Binder.getCallingUid());
8587
8588        synchronized (this) {
8589
8590            // iterate across all processes
8591            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8592                ProcessRecord app = mLruProcesses.get(i);
8593                if (!allUsers && app.userId != userId) {
8594                    continue;
8595                }
8596                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8597                    // This one's in trouble, so we'll generate a report for it
8598                    // crashes are higher priority (in case there's a crash *and* an anr)
8599                    ActivityManager.ProcessErrorStateInfo report = null;
8600                    if (app.crashing) {
8601                        report = app.crashingReport;
8602                    } else if (app.notResponding) {
8603                        report = app.notRespondingReport;
8604                    }
8605
8606                    if (report != null) {
8607                        if (errList == null) {
8608                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8609                        }
8610                        errList.add(report);
8611                    } else {
8612                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8613                                " crashing = " + app.crashing +
8614                                " notResponding = " + app.notResponding);
8615                    }
8616                }
8617            }
8618        }
8619
8620        return errList;
8621    }
8622
8623    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8624        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8625            if (currApp != null) {
8626                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8627            }
8628            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8629        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8630            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8631        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8632            if (currApp != null) {
8633                currApp.lru = 0;
8634            }
8635            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8636        } else if (adj >= ProcessList.SERVICE_ADJ) {
8637            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8638        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8639            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8640        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8641            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8642        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8643            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8644        } else {
8645            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8646        }
8647    }
8648
8649    private void fillInProcMemInfo(ProcessRecord app,
8650            ActivityManager.RunningAppProcessInfo outInfo) {
8651        outInfo.pid = app.pid;
8652        outInfo.uid = app.info.uid;
8653        if (mHeavyWeightProcess == app) {
8654            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8655        }
8656        if (app.persistent) {
8657            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8658        }
8659        if (app.hasActivities) {
8660            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8661        }
8662        outInfo.lastTrimLevel = app.trimMemoryLevel;
8663        int adj = app.curAdj;
8664        outInfo.importance = oomAdjToImportance(adj, outInfo);
8665        outInfo.importanceReasonCode = app.adjTypeCode;
8666    }
8667
8668    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8669        enforceNotIsolatedCaller("getRunningAppProcesses");
8670        // Lazy instantiation of list
8671        List<ActivityManager.RunningAppProcessInfo> runList = null;
8672        final boolean allUsers = ActivityManager.checkUidPermission(
8673                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8674                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8675        int userId = UserHandle.getUserId(Binder.getCallingUid());
8676        synchronized (this) {
8677            // Iterate across all processes
8678            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8679                ProcessRecord app = mLruProcesses.get(i);
8680                if (!allUsers && app.userId != userId) {
8681                    continue;
8682                }
8683                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8684                    // Generate process state info for running application
8685                    ActivityManager.RunningAppProcessInfo currApp =
8686                        new ActivityManager.RunningAppProcessInfo(app.processName,
8687                                app.pid, app.getPackageList());
8688                    fillInProcMemInfo(app, currApp);
8689                    if (app.adjSource instanceof ProcessRecord) {
8690                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8691                        currApp.importanceReasonImportance = oomAdjToImportance(
8692                                app.adjSourceOom, null);
8693                    } else if (app.adjSource instanceof ActivityRecord) {
8694                        ActivityRecord r = (ActivityRecord)app.adjSource;
8695                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8696                    }
8697                    if (app.adjTarget instanceof ComponentName) {
8698                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8699                    }
8700                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8701                    //        + " lru=" + currApp.lru);
8702                    if (runList == null) {
8703                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8704                    }
8705                    runList.add(currApp);
8706                }
8707            }
8708        }
8709        return runList;
8710    }
8711
8712    public List<ApplicationInfo> getRunningExternalApplications() {
8713        enforceNotIsolatedCaller("getRunningExternalApplications");
8714        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8715        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8716        if (runningApps != null && runningApps.size() > 0) {
8717            Set<String> extList = new HashSet<String>();
8718            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8719                if (app.pkgList != null) {
8720                    for (String pkg : app.pkgList) {
8721                        extList.add(pkg);
8722                    }
8723                }
8724            }
8725            IPackageManager pm = AppGlobals.getPackageManager();
8726            for (String pkg : extList) {
8727                try {
8728                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8729                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8730                        retList.add(info);
8731                    }
8732                } catch (RemoteException e) {
8733                }
8734            }
8735        }
8736        return retList;
8737    }
8738
8739    @Override
8740    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8741        enforceNotIsolatedCaller("getMyMemoryState");
8742        synchronized (this) {
8743            ProcessRecord proc;
8744            synchronized (mPidsSelfLocked) {
8745                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8746            }
8747            fillInProcMemInfo(proc, outInfo);
8748        }
8749    }
8750
8751    @Override
8752    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8753        if (checkCallingPermission(android.Manifest.permission.DUMP)
8754                != PackageManager.PERMISSION_GRANTED) {
8755            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8756                    + Binder.getCallingPid()
8757                    + ", uid=" + Binder.getCallingUid()
8758                    + " without permission "
8759                    + android.Manifest.permission.DUMP);
8760            return;
8761        }
8762
8763        boolean dumpAll = false;
8764        boolean dumpClient = false;
8765        String dumpPackage = null;
8766
8767        int opti = 0;
8768        while (opti < args.length) {
8769            String opt = args[opti];
8770            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8771                break;
8772            }
8773            opti++;
8774            if ("-a".equals(opt)) {
8775                dumpAll = true;
8776            } else if ("-c".equals(opt)) {
8777                dumpClient = true;
8778            } else if ("-h".equals(opt)) {
8779                pw.println("Activity manager dump options:");
8780                pw.println("  [-a] [-c] [-h] [cmd] ...");
8781                pw.println("  cmd may be one of:");
8782                pw.println("    a[ctivities]: activity stack state");
8783                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8784                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8785                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8786                pw.println("    o[om]: out of memory management");
8787                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8788                pw.println("    provider [COMP_SPEC]: provider client-side state");
8789                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8790                pw.println("    service [COMP_SPEC]: service client-side state");
8791                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8792                pw.println("    all: dump all activities");
8793                pw.println("    top: dump the top activity");
8794                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8795                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8796                pw.println("    a partial substring in a component name, a");
8797                pw.println("    hex object identifier.");
8798                pw.println("  -a: include all available server state.");
8799                pw.println("  -c: include client state.");
8800                return;
8801            } else {
8802                pw.println("Unknown argument: " + opt + "; use -h for help");
8803            }
8804        }
8805
8806        long origId = Binder.clearCallingIdentity();
8807        boolean more = false;
8808        // Is the caller requesting to dump a particular piece of data?
8809        if (opti < args.length) {
8810            String cmd = args[opti];
8811            opti++;
8812            if ("activities".equals(cmd) || "a".equals(cmd)) {
8813                synchronized (this) {
8814                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8815                }
8816            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8817                String[] newArgs;
8818                String name;
8819                if (opti >= args.length) {
8820                    name = null;
8821                    newArgs = EMPTY_STRING_ARRAY;
8822                } else {
8823                    name = args[opti];
8824                    opti++;
8825                    newArgs = new String[args.length - opti];
8826                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8827                            args.length - opti);
8828                }
8829                synchronized (this) {
8830                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8831                }
8832            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8833                String[] newArgs;
8834                String name;
8835                if (opti >= args.length) {
8836                    name = null;
8837                    newArgs = EMPTY_STRING_ARRAY;
8838                } else {
8839                    name = args[opti];
8840                    opti++;
8841                    newArgs = new String[args.length - opti];
8842                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8843                            args.length - opti);
8844                }
8845                synchronized (this) {
8846                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8847                }
8848            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8849                String[] newArgs;
8850                String name;
8851                if (opti >= args.length) {
8852                    name = null;
8853                    newArgs = EMPTY_STRING_ARRAY;
8854                } else {
8855                    name = args[opti];
8856                    opti++;
8857                    newArgs = new String[args.length - opti];
8858                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8859                            args.length - opti);
8860                }
8861                synchronized (this) {
8862                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8863                }
8864            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8865                synchronized (this) {
8866                    dumpOomLocked(fd, pw, args, opti, true);
8867                }
8868            } else if ("provider".equals(cmd)) {
8869                String[] newArgs;
8870                String name;
8871                if (opti >= args.length) {
8872                    name = null;
8873                    newArgs = EMPTY_STRING_ARRAY;
8874                } else {
8875                    name = args[opti];
8876                    opti++;
8877                    newArgs = new String[args.length - opti];
8878                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8879                }
8880                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8881                    pw.println("No providers match: " + name);
8882                    pw.println("Use -h for help.");
8883                }
8884            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8885                synchronized (this) {
8886                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8887                }
8888            } else if ("service".equals(cmd)) {
8889                String[] newArgs;
8890                String name;
8891                if (opti >= args.length) {
8892                    name = null;
8893                    newArgs = EMPTY_STRING_ARRAY;
8894                } else {
8895                    name = args[opti];
8896                    opti++;
8897                    newArgs = new String[args.length - opti];
8898                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8899                            args.length - opti);
8900                }
8901                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8902                    pw.println("No services match: " + name);
8903                    pw.println("Use -h for help.");
8904                }
8905            } else if ("package".equals(cmd)) {
8906                String[] newArgs;
8907                if (opti >= args.length) {
8908                    pw.println("package: no package name specified");
8909                    pw.println("Use -h for help.");
8910                } else {
8911                    dumpPackage = args[opti];
8912                    opti++;
8913                    newArgs = new String[args.length - opti];
8914                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8915                            args.length - opti);
8916                    args = newArgs;
8917                    opti = 0;
8918                    more = true;
8919                }
8920            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8921                synchronized (this) {
8922                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8923                }
8924            } else {
8925                // Dumping a single activity?
8926                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8927                    pw.println("Bad activity command, or no activities match: " + cmd);
8928                    pw.println("Use -h for help.");
8929                }
8930            }
8931            if (!more) {
8932                Binder.restoreCallingIdentity(origId);
8933                return;
8934            }
8935        }
8936
8937        // No piece of data specified, dump everything.
8938        synchronized (this) {
8939            boolean needSep;
8940            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8941            if (needSep) {
8942                pw.println(" ");
8943            }
8944            if (dumpAll) {
8945                pw.println("-------------------------------------------------------------------------------");
8946            }
8947            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8948            if (needSep) {
8949                pw.println(" ");
8950            }
8951            if (dumpAll) {
8952                pw.println("-------------------------------------------------------------------------------");
8953            }
8954            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8955            if (needSep) {
8956                pw.println(" ");
8957            }
8958            if (dumpAll) {
8959                pw.println("-------------------------------------------------------------------------------");
8960            }
8961            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8962            if (needSep) {
8963                pw.println(" ");
8964            }
8965            if (dumpAll) {
8966                pw.println("-------------------------------------------------------------------------------");
8967            }
8968            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8969            if (needSep) {
8970                pw.println(" ");
8971            }
8972            if (dumpAll) {
8973                pw.println("-------------------------------------------------------------------------------");
8974            }
8975            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8976        }
8977        Binder.restoreCallingIdentity(origId);
8978    }
8979
8980    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8981            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
8982        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8983        pw.println("  Main stack:");
8984        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
8985                dumpPackage);
8986        pw.println(" ");
8987        pw.println("  Running activities (most recent first):");
8988        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
8989                dumpPackage);
8990        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
8991            pw.println(" ");
8992            pw.println("  Activities waiting for another to become visible:");
8993            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
8994                    !dumpAll, false, dumpPackage);
8995        }
8996        if (mMainStack.mStoppingActivities.size() > 0) {
8997            pw.println(" ");
8998            pw.println("  Activities waiting to stop:");
8999            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
9000                    !dumpAll, false, dumpPackage);
9001        }
9002        if (mMainStack.mGoingToSleepActivities.size() > 0) {
9003            pw.println(" ");
9004            pw.println("  Activities waiting to sleep:");
9005            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
9006                    !dumpAll, false, dumpPackage);
9007        }
9008        if (mMainStack.mFinishingActivities.size() > 0) {
9009            pw.println(" ");
9010            pw.println("  Activities waiting to finish:");
9011            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
9012                    !dumpAll, false, dumpPackage);
9013        }
9014
9015        pw.println(" ");
9016        if (mMainStack.mPausingActivity != null) {
9017            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
9018        }
9019        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
9020        pw.println("  mFocusedActivity: " + mFocusedActivity);
9021        if (dumpAll) {
9022            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
9023            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
9024            pw.println("  mDismissKeyguardOnNextActivity: "
9025                    + mMainStack.mDismissKeyguardOnNextActivity);
9026        }
9027
9028        if (mRecentTasks.size() > 0) {
9029            pw.println();
9030            pw.println("  Recent tasks:");
9031
9032            final int N = mRecentTasks.size();
9033            for (int i=0; i<N; i++) {
9034                TaskRecord tr = mRecentTasks.get(i);
9035                if (dumpPackage != null) {
9036                    if (tr.realActivity == null ||
9037                            !dumpPackage.equals(tr.realActivity)) {
9038                        continue;
9039                    }
9040                }
9041                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
9042                        pw.println(tr);
9043                if (dumpAll) {
9044                    mRecentTasks.get(i).dump(pw, "    ");
9045                }
9046            }
9047        }
9048
9049        if (dumpAll) {
9050            pw.println(" ");
9051            pw.println("  mCurTask: " + mCurTask);
9052        }
9053
9054        return true;
9055    }
9056
9057    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9058            int opti, boolean dumpAll, String dumpPackage) {
9059        boolean needSep = false;
9060        int numPers = 0;
9061
9062        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
9063
9064        if (dumpAll) {
9065            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9066                final int NA = procs.size();
9067                for (int ia=0; ia<NA; ia++) {
9068                    ProcessRecord r = procs.valueAt(ia);
9069                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9070                        continue;
9071                    }
9072                    if (!needSep) {
9073                        pw.println("  All known processes:");
9074                        needSep = true;
9075                    }
9076                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
9077                        pw.print(" UID "); pw.print(procs.keyAt(ia));
9078                        pw.print(" "); pw.println(r);
9079                    r.dump(pw, "    ");
9080                    if (r.persistent) {
9081                        numPers++;
9082                    }
9083                }
9084            }
9085        }
9086
9087        if (mIsolatedProcesses.size() > 0) {
9088            if (needSep) pw.println(" ");
9089            needSep = true;
9090            pw.println("  Isolated process list (sorted by uid):");
9091            for (int i=0; i<mIsolatedProcesses.size(); i++) {
9092                ProcessRecord r = mIsolatedProcesses.valueAt(i);
9093                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9094                    continue;
9095                }
9096                pw.println(String.format("%sIsolated #%2d: %s",
9097                        "    ", i, r.toString()));
9098            }
9099        }
9100
9101        if (mLruProcesses.size() > 0) {
9102            if (needSep) pw.println(" ");
9103            needSep = true;
9104            pw.println("  Process LRU list (sorted by oom_adj):");
9105            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9106                    "Proc", "PERS", false, dumpPackage);
9107            needSep = true;
9108        }
9109
9110        if (dumpAll) {
9111            synchronized (mPidsSelfLocked) {
9112                boolean printed = false;
9113                for (int i=0; i<mPidsSelfLocked.size(); i++) {
9114                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
9115                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9116                        continue;
9117                    }
9118                    if (!printed) {
9119                        if (needSep) pw.println(" ");
9120                        needSep = true;
9121                        pw.println("  PID mappings:");
9122                        printed = true;
9123                    }
9124                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9125                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9126                }
9127            }
9128        }
9129
9130        if (mForegroundProcesses.size() > 0) {
9131            synchronized (mPidsSelfLocked) {
9132                boolean printed = false;
9133                for (int i=0; i<mForegroundProcesses.size(); i++) {
9134                    ProcessRecord r = mPidsSelfLocked.get(
9135                            mForegroundProcesses.valueAt(i).pid);
9136                    if (dumpPackage != null && (r == null
9137                            || !dumpPackage.equals(r.info.packageName))) {
9138                        continue;
9139                    }
9140                    if (!printed) {
9141                        if (needSep) pw.println(" ");
9142                        needSep = true;
9143                        pw.println("  Foreground Processes:");
9144                        printed = true;
9145                    }
9146                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9147                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9148                }
9149            }
9150        }
9151
9152        if (mPersistentStartingProcesses.size() > 0) {
9153            if (needSep) pw.println(" ");
9154            needSep = true;
9155            pw.println("  Persisent processes that are starting:");
9156            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
9157                    "Starting Norm", "Restarting PERS", dumpPackage);
9158        }
9159
9160        if (mRemovedProcesses.size() > 0) {
9161            if (needSep) pw.println(" ");
9162            needSep = true;
9163            pw.println("  Processes that are being removed:");
9164            dumpProcessList(pw, this, mRemovedProcesses, "    ",
9165                    "Removed Norm", "Removed PERS", dumpPackage);
9166        }
9167
9168        if (mProcessesOnHold.size() > 0) {
9169            if (needSep) pw.println(" ");
9170            needSep = true;
9171            pw.println("  Processes that are on old until the system is ready:");
9172            dumpProcessList(pw, this, mProcessesOnHold, "    ",
9173                    "OnHold Norm", "OnHold PERS", dumpPackage);
9174        }
9175
9176        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
9177
9178        if (mProcessCrashTimes.getMap().size() > 0) {
9179            boolean printed = false;
9180            long now = SystemClock.uptimeMillis();
9181            for (Map.Entry<String, SparseArray<Long>> procs
9182                    : mProcessCrashTimes.getMap().entrySet()) {
9183                String pname = procs.getKey();
9184                SparseArray<Long> uids = procs.getValue();
9185                final int N = uids.size();
9186                for (int i=0; i<N; i++) {
9187                    int puid = uids.keyAt(i);
9188                    ProcessRecord r = mProcessNames.get(pname, puid);
9189                    if (dumpPackage != null && (r == null
9190                            || !dumpPackage.equals(r.info.packageName))) {
9191                        continue;
9192                    }
9193                    if (!printed) {
9194                        if (needSep) pw.println(" ");
9195                        needSep = true;
9196                        pw.println("  Time since processes crashed:");
9197                        printed = true;
9198                    }
9199                    pw.print("    Process "); pw.print(pname);
9200                            pw.print(" uid "); pw.print(puid);
9201                            pw.print(": last crashed ");
9202                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9203                            pw.println(" ago");
9204                }
9205            }
9206        }
9207
9208        if (mBadProcesses.getMap().size() > 0) {
9209            boolean printed = false;
9210            for (Map.Entry<String, SparseArray<Long>> procs
9211                    : mBadProcesses.getMap().entrySet()) {
9212                String pname = procs.getKey();
9213                SparseArray<Long> uids = procs.getValue();
9214                final int N = uids.size();
9215                for (int i=0; i<N; i++) {
9216                    int puid = uids.keyAt(i);
9217                    ProcessRecord r = mProcessNames.get(pname, puid);
9218                    if (dumpPackage != null && (r == null
9219                            || !dumpPackage.equals(r.info.packageName))) {
9220                        continue;
9221                    }
9222                    if (!printed) {
9223                        if (needSep) pw.println(" ");
9224                        needSep = true;
9225                        pw.println("  Bad processes:");
9226                    }
9227                    pw.print("    Bad process "); pw.print(pname);
9228                            pw.print(" uid "); pw.print(puid);
9229                            pw.print(": crashed at time ");
9230                            pw.println(uids.valueAt(i));
9231                }
9232            }
9233        }
9234
9235        pw.println();
9236        pw.println("  mStartedUsers:");
9237        for (int i=0; i<mStartedUsers.size(); i++) {
9238            UserStartedState uss = mStartedUsers.valueAt(i);
9239            pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
9240                    pw.print(": "); uss.dump("", pw);
9241        }
9242        pw.print("  mUserLru: [");
9243        for (int i=0; i<mUserLru.size(); i++) {
9244            if (i > 0) pw.print(", ");
9245            pw.print(mUserLru.get(i));
9246        }
9247        pw.println("]");
9248        pw.println("  mHomeProcess: " + mHomeProcess);
9249        pw.println("  mPreviousProcess: " + mPreviousProcess);
9250        if (dumpAll) {
9251            StringBuilder sb = new StringBuilder(128);
9252            sb.append("  mPreviousProcessVisibleTime: ");
9253            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9254            pw.println(sb);
9255        }
9256        if (mHeavyWeightProcess != null) {
9257            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9258        }
9259        pw.println("  mConfiguration: " + mConfiguration);
9260        if (dumpAll) {
9261            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9262            if (mCompatModePackages.getPackages().size() > 0) {
9263                boolean printed = false;
9264                for (Map.Entry<String, Integer> entry
9265                        : mCompatModePackages.getPackages().entrySet()) {
9266                    String pkg = entry.getKey();
9267                    int mode = entry.getValue();
9268                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9269                        continue;
9270                    }
9271                    if (!printed) {
9272                        pw.println("  mScreenCompatPackages:");
9273                        printed = true;
9274                    }
9275                    pw.print("    "); pw.print(pkg); pw.print(": ");
9276                            pw.print(mode); pw.println();
9277                }
9278            }
9279        }
9280        if (mSleeping || mWentToSleep || mLockScreenShown) {
9281            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9282                    + " mLockScreenShown " + mLockScreenShown);
9283        }
9284        if (mShuttingDown) {
9285            pw.println("  mShuttingDown=" + mShuttingDown);
9286        }
9287        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9288                || mOrigWaitForDebugger) {
9289            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9290                    + " mDebugTransient=" + mDebugTransient
9291                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9292        }
9293        if (mOpenGlTraceApp != null) {
9294            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9295        }
9296        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9297                || mProfileFd != null) {
9298            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9299            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9300            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9301                    + mAutoStopProfiler);
9302        }
9303        if (mAlwaysFinishActivities || mController != null) {
9304            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9305                    + " mController=" + mController);
9306        }
9307        if (dumpAll) {
9308            pw.println("  Total persistent processes: " + numPers);
9309            pw.println("  mStartRunning=" + mStartRunning
9310                    + " mProcessesReady=" + mProcessesReady
9311                    + " mSystemReady=" + mSystemReady);
9312            pw.println("  mBooting=" + mBooting
9313                    + " mBooted=" + mBooted
9314                    + " mFactoryTest=" + mFactoryTest);
9315            pw.print("  mLastPowerCheckRealtime=");
9316                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9317                    pw.println("");
9318            pw.print("  mLastPowerCheckUptime=");
9319                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9320                    pw.println("");
9321            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9322            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9323            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9324            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9325                    + " mNumHiddenProcs=" + mNumHiddenProcs
9326                    + " mNumServiceProcs=" + mNumServiceProcs
9327                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9328        }
9329
9330        return true;
9331    }
9332
9333    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9334            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9335        if (mProcessesToGc.size() > 0) {
9336            boolean printed = false;
9337            long now = SystemClock.uptimeMillis();
9338            for (int i=0; i<mProcessesToGc.size(); i++) {
9339                ProcessRecord proc = mProcessesToGc.get(i);
9340                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9341                    continue;
9342                }
9343                if (!printed) {
9344                    if (needSep) pw.println(" ");
9345                    needSep = true;
9346                    pw.println("  Processes that are waiting to GC:");
9347                    printed = true;
9348                }
9349                pw.print("    Process "); pw.println(proc);
9350                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9351                        pw.print(", last gced=");
9352                        pw.print(now-proc.lastRequestedGc);
9353                        pw.print(" ms ago, last lowMem=");
9354                        pw.print(now-proc.lastLowMemory);
9355                        pw.println(" ms ago");
9356
9357            }
9358        }
9359        return needSep;
9360    }
9361
9362    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9363            int opti, boolean dumpAll) {
9364        boolean needSep = false;
9365
9366        if (mLruProcesses.size() > 0) {
9367            if (needSep) pw.println(" ");
9368            needSep = true;
9369            pw.println("  OOM levels:");
9370            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9371            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9372            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9373            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9374            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9375            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9376            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9377            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9378            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9379            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9380            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9381            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9382            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9383
9384            if (needSep) pw.println(" ");
9385            needSep = true;
9386            pw.println("  Process OOM control:");
9387            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9388                    "Proc", "PERS", true, null);
9389            needSep = true;
9390        }
9391
9392        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9393
9394        pw.println();
9395        pw.println("  mHomeProcess: " + mHomeProcess);
9396        pw.println("  mPreviousProcess: " + mPreviousProcess);
9397        if (mHeavyWeightProcess != null) {
9398            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9399        }
9400
9401        return true;
9402    }
9403
9404    /**
9405     * There are three ways to call this:
9406     *  - no provider specified: dump all the providers
9407     *  - a flattened component name that matched an existing provider was specified as the
9408     *    first arg: dump that one provider
9409     *  - the first arg isn't the flattened component name of an existing provider:
9410     *    dump all providers whose component contains the first arg as a substring
9411     */
9412    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9413            int opti, boolean dumpAll) {
9414        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9415    }
9416
9417    static class ItemMatcher {
9418        ArrayList<ComponentName> components;
9419        ArrayList<String> strings;
9420        ArrayList<Integer> objects;
9421        boolean all;
9422
9423        ItemMatcher() {
9424            all = true;
9425        }
9426
9427        void build(String name) {
9428            ComponentName componentName = ComponentName.unflattenFromString(name);
9429            if (componentName != null) {
9430                if (components == null) {
9431                    components = new ArrayList<ComponentName>();
9432                }
9433                components.add(componentName);
9434                all = false;
9435            } else {
9436                int objectId = 0;
9437                // Not a '/' separated full component name; maybe an object ID?
9438                try {
9439                    objectId = Integer.parseInt(name, 16);
9440                    if (objects == null) {
9441                        objects = new ArrayList<Integer>();
9442                    }
9443                    objects.add(objectId);
9444                    all = false;
9445                } catch (RuntimeException e) {
9446                    // Not an integer; just do string match.
9447                    if (strings == null) {
9448                        strings = new ArrayList<String>();
9449                    }
9450                    strings.add(name);
9451                    all = false;
9452                }
9453            }
9454        }
9455
9456        int build(String[] args, int opti) {
9457            for (; opti<args.length; opti++) {
9458                String name = args[opti];
9459                if ("--".equals(name)) {
9460                    return opti+1;
9461                }
9462                build(name);
9463            }
9464            return opti;
9465        }
9466
9467        boolean match(Object object, ComponentName comp) {
9468            if (all) {
9469                return true;
9470            }
9471            if (components != null) {
9472                for (int i=0; i<components.size(); i++) {
9473                    if (components.get(i).equals(comp)) {
9474                        return true;
9475                    }
9476                }
9477            }
9478            if (objects != null) {
9479                for (int i=0; i<objects.size(); i++) {
9480                    if (System.identityHashCode(object) == objects.get(i)) {
9481                        return true;
9482                    }
9483                }
9484            }
9485            if (strings != null) {
9486                String flat = comp.flattenToString();
9487                for (int i=0; i<strings.size(); i++) {
9488                    if (flat.contains(strings.get(i))) {
9489                        return true;
9490                    }
9491                }
9492            }
9493            return false;
9494        }
9495    }
9496
9497    /**
9498     * There are three things that cmd can be:
9499     *  - a flattened component name that matches an existing activity
9500     *  - the cmd arg isn't the flattened component name of an existing activity:
9501     *    dump all activity whose component contains the cmd as a substring
9502     *  - A hex number of the ActivityRecord object instance.
9503     */
9504    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9505            int opti, boolean dumpAll) {
9506        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9507
9508        if ("all".equals(name)) {
9509            synchronized (this) {
9510                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9511                    activities.add(r1);
9512                }
9513            }
9514        } else if ("top".equals(name)) {
9515            synchronized (this) {
9516                final int N = mMainStack.mHistory.size();
9517                if (N > 0) {
9518                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9519                }
9520            }
9521        } else {
9522            ItemMatcher matcher = new ItemMatcher();
9523            matcher.build(name);
9524
9525            synchronized (this) {
9526                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9527                    if (matcher.match(r1, r1.intent.getComponent())) {
9528                        activities.add(r1);
9529                    }
9530                }
9531            }
9532        }
9533
9534        if (activities.size() <= 0) {
9535            return false;
9536        }
9537
9538        String[] newArgs = new String[args.length - opti];
9539        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9540
9541        TaskRecord lastTask = null;
9542        boolean needSep = false;
9543        for (int i=activities.size()-1; i>=0; i--) {
9544            ActivityRecord r = (ActivityRecord)activities.get(i);
9545            if (needSep) {
9546                pw.println();
9547            }
9548            needSep = true;
9549            synchronized (this) {
9550                if (lastTask != r.task) {
9551                    lastTask = r.task;
9552                    pw.print("TASK "); pw.print(lastTask.affinity);
9553                            pw.print(" id="); pw.println(lastTask.taskId);
9554                    if (dumpAll) {
9555                        lastTask.dump(pw, "  ");
9556                    }
9557                }
9558            }
9559            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9560        }
9561        return true;
9562    }
9563
9564    /**
9565     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9566     * there is a thread associated with the activity.
9567     */
9568    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9569            final ActivityRecord r, String[] args, boolean dumpAll) {
9570        String innerPrefix = prefix + "  ";
9571        synchronized (this) {
9572            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9573                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9574                    pw.print(" pid=");
9575                    if (r.app != null) pw.println(r.app.pid);
9576                    else pw.println("(not running)");
9577            if (dumpAll) {
9578                r.dump(pw, innerPrefix);
9579            }
9580        }
9581        if (r.app != null && r.app.thread != null) {
9582            // flush anything that is already in the PrintWriter since the thread is going
9583            // to write to the file descriptor directly
9584            pw.flush();
9585            try {
9586                TransferPipe tp = new TransferPipe();
9587                try {
9588                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9589                            r.appToken, innerPrefix, args);
9590                    tp.go(fd);
9591                } finally {
9592                    tp.kill();
9593                }
9594            } catch (IOException e) {
9595                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9596            } catch (RemoteException e) {
9597                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9598            }
9599        }
9600    }
9601
9602    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9603            int opti, boolean dumpAll, String dumpPackage) {
9604        boolean needSep = false;
9605        boolean onlyHistory = false;
9606
9607        if ("history".equals(dumpPackage)) {
9608            onlyHistory = true;
9609            dumpPackage = null;
9610        }
9611
9612        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9613        if (!onlyHistory && dumpAll) {
9614            if (mRegisteredReceivers.size() > 0) {
9615                boolean printed = false;
9616                Iterator it = mRegisteredReceivers.values().iterator();
9617                while (it.hasNext()) {
9618                    ReceiverList r = (ReceiverList)it.next();
9619                    if (dumpPackage != null && (r.app == null ||
9620                            !dumpPackage.equals(r.app.info.packageName))) {
9621                        continue;
9622                    }
9623                    if (!printed) {
9624                        pw.println("  Registered Receivers:");
9625                        needSep = true;
9626                        printed = true;
9627                    }
9628                    pw.print("  * "); pw.println(r);
9629                    r.dump(pw, "    ");
9630                }
9631            }
9632
9633            if (mReceiverResolver.dump(pw, needSep ?
9634                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9635                    "    ", dumpPackage, false)) {
9636                needSep = true;
9637            }
9638        }
9639
9640        for (BroadcastQueue q : mBroadcastQueues) {
9641            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9642        }
9643
9644        needSep = true;
9645
9646        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
9647            for (int user=0; user<mStickyBroadcasts.size(); user++) {
9648                if (needSep) {
9649                    pw.println();
9650                }
9651                needSep = true;
9652                pw.print("  Sticky broadcasts for user ");
9653                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
9654                StringBuilder sb = new StringBuilder(128);
9655                for (Map.Entry<String, ArrayList<Intent>> ent
9656                        : mStickyBroadcasts.valueAt(user).entrySet()) {
9657                    pw.print("  * Sticky action "); pw.print(ent.getKey());
9658                    if (dumpAll) {
9659                        pw.println(":");
9660                        ArrayList<Intent> intents = ent.getValue();
9661                        final int N = intents.size();
9662                        for (int i=0; i<N; i++) {
9663                            sb.setLength(0);
9664                            sb.append("    Intent: ");
9665                            intents.get(i).toShortString(sb, false, true, false, false);
9666                            pw.println(sb.toString());
9667                            Bundle bundle = intents.get(i).getExtras();
9668                            if (bundle != null) {
9669                                pw.print("      ");
9670                                pw.println(bundle.toString());
9671                            }
9672                        }
9673                    } else {
9674                        pw.println("");
9675                    }
9676                }
9677            }
9678        }
9679
9680        if (!onlyHistory && dumpAll) {
9681            pw.println();
9682            for (BroadcastQueue queue : mBroadcastQueues) {
9683                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9684                        + queue.mBroadcastsScheduled);
9685            }
9686            pw.println("  mHandler:");
9687            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9688            needSep = true;
9689        }
9690
9691        return needSep;
9692    }
9693
9694    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9695            int opti, boolean dumpAll, String dumpPackage) {
9696        boolean needSep = true;
9697
9698        ItemMatcher matcher = new ItemMatcher();
9699        matcher.build(args, opti);
9700
9701        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9702
9703        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9704
9705        if (mLaunchingProviders.size() > 0) {
9706            boolean printed = false;
9707            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9708                ContentProviderRecord r = mLaunchingProviders.get(i);
9709                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9710                    continue;
9711                }
9712                if (!printed) {
9713                    if (needSep) pw.println(" ");
9714                    needSep = true;
9715                    pw.println("  Launching content providers:");
9716                    printed = true;
9717                }
9718                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9719                        pw.println(r);
9720            }
9721        }
9722
9723        if (mGrantedUriPermissions.size() > 0) {
9724            if (needSep) pw.println();
9725            needSep = true;
9726            pw.println("Granted Uri Permissions:");
9727            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9728                int uid = mGrantedUriPermissions.keyAt(i);
9729                HashMap<Uri, UriPermission> perms
9730                        = mGrantedUriPermissions.valueAt(i);
9731                pw.print("  * UID "); pw.print(uid);
9732                        pw.println(" holds:");
9733                for (UriPermission perm : perms.values()) {
9734                    pw.print("    "); pw.println(perm);
9735                    if (dumpAll) {
9736                        perm.dump(pw, "      ");
9737                    }
9738                }
9739            }
9740            needSep = true;
9741        }
9742
9743        return needSep;
9744    }
9745
9746    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9747            int opti, boolean dumpAll, String dumpPackage) {
9748        boolean needSep = false;
9749
9750        if (mIntentSenderRecords.size() > 0) {
9751            boolean printed = false;
9752            Iterator<WeakReference<PendingIntentRecord>> it
9753                    = mIntentSenderRecords.values().iterator();
9754            while (it.hasNext()) {
9755                WeakReference<PendingIntentRecord> ref = it.next();
9756                PendingIntentRecord rec = ref != null ? ref.get(): null;
9757                if (dumpPackage != null && (rec == null
9758                        || !dumpPackage.equals(rec.key.packageName))) {
9759                    continue;
9760                }
9761                if (!printed) {
9762                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9763                    printed = true;
9764                }
9765                needSep = true;
9766                if (rec != null) {
9767                    pw.print("  * "); pw.println(rec);
9768                    if (dumpAll) {
9769                        rec.dump(pw, "    ");
9770                    }
9771                } else {
9772                    pw.print("  * "); pw.println(ref);
9773                }
9774            }
9775        }
9776
9777        return needSep;
9778    }
9779
9780    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9781            String prefix, String label, boolean complete, boolean brief, boolean client,
9782            String dumpPackage) {
9783        TaskRecord lastTask = null;
9784        boolean needNL = false;
9785        final String innerPrefix = prefix + "      ";
9786        final String[] args = new String[0];
9787        for (int i=list.size()-1; i>=0; i--) {
9788            final ActivityRecord r = (ActivityRecord)list.get(i);
9789            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9790                continue;
9791            }
9792            final boolean full = !brief && (complete || !r.isInHistory());
9793            if (needNL) {
9794                pw.println(" ");
9795                needNL = false;
9796            }
9797            if (lastTask != r.task) {
9798                lastTask = r.task;
9799                pw.print(prefix);
9800                pw.print(full ? "* " : "  ");
9801                pw.println(lastTask);
9802                if (full) {
9803                    lastTask.dump(pw, prefix + "  ");
9804                } else if (complete) {
9805                    // Complete + brief == give a summary.  Isn't that obvious?!?
9806                    if (lastTask.intent != null) {
9807                        pw.print(prefix); pw.print("  ");
9808                                pw.println(lastTask.intent.toInsecureStringWithClip());
9809                    }
9810                }
9811            }
9812            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9813            pw.print(" #"); pw.print(i); pw.print(": ");
9814            pw.println(r);
9815            if (full) {
9816                r.dump(pw, innerPrefix);
9817            } else if (complete) {
9818                // Complete + brief == give a summary.  Isn't that obvious?!?
9819                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9820                if (r.app != null) {
9821                    pw.print(innerPrefix); pw.println(r.app);
9822                }
9823            }
9824            if (client && r.app != null && r.app.thread != null) {
9825                // flush anything that is already in the PrintWriter since the thread is going
9826                // to write to the file descriptor directly
9827                pw.flush();
9828                try {
9829                    TransferPipe tp = new TransferPipe();
9830                    try {
9831                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9832                                r.appToken, innerPrefix, args);
9833                        // Short timeout, since blocking here can
9834                        // deadlock with the application.
9835                        tp.go(fd, 2000);
9836                    } finally {
9837                        tp.kill();
9838                    }
9839                } catch (IOException e) {
9840                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9841                } catch (RemoteException e) {
9842                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9843                }
9844                needNL = true;
9845            }
9846        }
9847    }
9848
9849    private static String buildOomTag(String prefix, String space, int val, int base) {
9850        if (val == base) {
9851            if (space == null) return prefix;
9852            return prefix + "  ";
9853        }
9854        return prefix + "+" + Integer.toString(val-base);
9855    }
9856
9857    private static final int dumpProcessList(PrintWriter pw,
9858            ActivityManagerService service, List list,
9859            String prefix, String normalLabel, String persistentLabel,
9860            String dumpPackage) {
9861        int numPers = 0;
9862        final int N = list.size()-1;
9863        for (int i=N; i>=0; i--) {
9864            ProcessRecord r = (ProcessRecord)list.get(i);
9865            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9866                continue;
9867            }
9868            pw.println(String.format("%s%s #%2d: %s",
9869                    prefix, (r.persistent ? persistentLabel : normalLabel),
9870                    i, r.toString()));
9871            if (r.persistent) {
9872                numPers++;
9873            }
9874        }
9875        return numPers;
9876    }
9877
9878    private static final boolean dumpProcessOomList(PrintWriter pw,
9879            ActivityManagerService service, List<ProcessRecord> origList,
9880            String prefix, String normalLabel, String persistentLabel,
9881            boolean inclDetails, String dumpPackage) {
9882
9883        ArrayList<Pair<ProcessRecord, Integer>> list
9884                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9885        for (int i=0; i<origList.size(); i++) {
9886            ProcessRecord r = origList.get(i);
9887            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9888                continue;
9889            }
9890            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9891        }
9892
9893        if (list.size() <= 0) {
9894            return false;
9895        }
9896
9897        Comparator<Pair<ProcessRecord, Integer>> comparator
9898                = new Comparator<Pair<ProcessRecord, Integer>>() {
9899            @Override
9900            public int compare(Pair<ProcessRecord, Integer> object1,
9901                    Pair<ProcessRecord, Integer> object2) {
9902                if (object1.first.setAdj != object2.first.setAdj) {
9903                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9904                }
9905                if (object1.second.intValue() != object2.second.intValue()) {
9906                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9907                }
9908                return 0;
9909            }
9910        };
9911
9912        Collections.sort(list, comparator);
9913
9914        final long curRealtime = SystemClock.elapsedRealtime();
9915        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9916        final long curUptime = SystemClock.uptimeMillis();
9917        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9918
9919        for (int i=list.size()-1; i>=0; i--) {
9920            ProcessRecord r = list.get(i).first;
9921            String oomAdj;
9922            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9923                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9924            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9925                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
9926            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9927                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
9928            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9929                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
9930            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9931                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
9932            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9933                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9934            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9935                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9936            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9937                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9938            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9939                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9940            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9941                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
9942            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9943                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
9944            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9945                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
9946            } else {
9947                oomAdj = Integer.toString(r.setAdj);
9948            }
9949            String schedGroup;
9950            switch (r.setSchedGroup) {
9951                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9952                    schedGroup = "B";
9953                    break;
9954                case Process.THREAD_GROUP_DEFAULT:
9955                    schedGroup = "F";
9956                    break;
9957                default:
9958                    schedGroup = Integer.toString(r.setSchedGroup);
9959                    break;
9960            }
9961            String foreground;
9962            if (r.foregroundActivities) {
9963                foreground = "A";
9964            } else if (r.foregroundServices) {
9965                foreground = "S";
9966            } else {
9967                foreground = " ";
9968            }
9969            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
9970                    prefix, (r.persistent ? persistentLabel : normalLabel),
9971                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9972                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
9973            if (r.adjSource != null || r.adjTarget != null) {
9974                pw.print(prefix);
9975                pw.print("    ");
9976                if (r.adjTarget instanceof ComponentName) {
9977                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9978                } else if (r.adjTarget != null) {
9979                    pw.print(r.adjTarget.toString());
9980                } else {
9981                    pw.print("{null}");
9982                }
9983                pw.print("<=");
9984                if (r.adjSource instanceof ProcessRecord) {
9985                    pw.print("Proc{");
9986                    pw.print(((ProcessRecord)r.adjSource).toShortString());
9987                    pw.println("}");
9988                } else if (r.adjSource != null) {
9989                    pw.println(r.adjSource.toString());
9990                } else {
9991                    pw.println("{null}");
9992                }
9993            }
9994            if (inclDetails) {
9995                pw.print(prefix);
9996                pw.print("    ");
9997                pw.print("oom: max="); pw.print(r.maxAdj);
9998                pw.print(" hidden="); pw.print(r.hiddenAdj);
9999                pw.print(" empty="); pw.print(r.emptyAdj);
10000                pw.print(" curRaw="); pw.print(r.curRawAdj);
10001                pw.print(" setRaw="); pw.print(r.setRawAdj);
10002                pw.print(" cur="); pw.print(r.curAdj);
10003                pw.print(" set="); pw.println(r.setAdj);
10004                pw.print(prefix);
10005                pw.print("    ");
10006                pw.print("keeping="); pw.print(r.keeping);
10007                pw.print(" hidden="); pw.print(r.hidden);
10008                pw.print(" empty="); pw.print(r.empty);
10009                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
10010
10011                if (!r.keeping) {
10012                    if (r.lastWakeTime != 0) {
10013                        long wtime;
10014                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10015                        synchronized (stats) {
10016                            wtime = stats.getProcessWakeTime(r.info.uid,
10017                                    r.pid, curRealtime);
10018                        }
10019                        long timeUsed = wtime - r.lastWakeTime;
10020                        pw.print(prefix);
10021                        pw.print("    ");
10022                        pw.print("keep awake over ");
10023                        TimeUtils.formatDuration(realtimeSince, pw);
10024                        pw.print(" used ");
10025                        TimeUtils.formatDuration(timeUsed, pw);
10026                        pw.print(" (");
10027                        pw.print((timeUsed*100)/realtimeSince);
10028                        pw.println("%)");
10029                    }
10030                    if (r.lastCpuTime != 0) {
10031                        long timeUsed = r.curCpuTime - r.lastCpuTime;
10032                        pw.print(prefix);
10033                        pw.print("    ");
10034                        pw.print("run cpu over ");
10035                        TimeUtils.formatDuration(uptimeSince, pw);
10036                        pw.print(" used ");
10037                        TimeUtils.formatDuration(timeUsed, pw);
10038                        pw.print(" (");
10039                        pw.print((timeUsed*100)/uptimeSince);
10040                        pw.println("%)");
10041                    }
10042                }
10043            }
10044        }
10045        return true;
10046    }
10047
10048    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
10049        ArrayList<ProcessRecord> procs;
10050        synchronized (this) {
10051            if (args != null && args.length > start
10052                    && args[start].charAt(0) != '-') {
10053                procs = new ArrayList<ProcessRecord>();
10054                int pid = -1;
10055                try {
10056                    pid = Integer.parseInt(args[start]);
10057                } catch (NumberFormatException e) {
10058
10059                }
10060                for (int i=mLruProcesses.size()-1; i>=0; i--) {
10061                    ProcessRecord proc = mLruProcesses.get(i);
10062                    if (proc.pid == pid) {
10063                        procs.add(proc);
10064                    } else if (proc.processName.equals(args[start])) {
10065                        procs.add(proc);
10066                    }
10067                }
10068                if (procs.size() <= 0) {
10069                    pw.println("No process found for: " + args[start]);
10070                    return null;
10071                }
10072            } else {
10073                procs = new ArrayList<ProcessRecord>(mLruProcesses);
10074            }
10075        }
10076        return procs;
10077    }
10078
10079    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10080            PrintWriter pw, String[] args) {
10081        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10082        if (procs == null) {
10083            return;
10084        }
10085
10086        long uptime = SystemClock.uptimeMillis();
10087        long realtime = SystemClock.elapsedRealtime();
10088        pw.println("Applications Graphics Acceleration Info:");
10089        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10090
10091        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10092            ProcessRecord r = procs.get(i);
10093            if (r.thread != null) {
10094                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10095                pw.flush();
10096                try {
10097                    TransferPipe tp = new TransferPipe();
10098                    try {
10099                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10100                        tp.go(fd);
10101                    } finally {
10102                        tp.kill();
10103                    }
10104                } catch (IOException e) {
10105                    pw.println("Failure while dumping the app: " + r);
10106                    pw.flush();
10107                } catch (RemoteException e) {
10108                    pw.println("Got a RemoteException while dumping the app " + r);
10109                    pw.flush();
10110                }
10111            }
10112        }
10113    }
10114
10115    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10116        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10117        if (procs == null) {
10118            return;
10119        }
10120
10121        pw.println("Applications Database Info:");
10122
10123        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10124            ProcessRecord r = procs.get(i);
10125            if (r.thread != null) {
10126                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10127                pw.flush();
10128                try {
10129                    TransferPipe tp = new TransferPipe();
10130                    try {
10131                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10132                        tp.go(fd);
10133                    } finally {
10134                        tp.kill();
10135                    }
10136                } catch (IOException e) {
10137                    pw.println("Failure while dumping the app: " + r);
10138                    pw.flush();
10139                } catch (RemoteException e) {
10140                    pw.println("Got a RemoteException while dumping the app " + r);
10141                    pw.flush();
10142                }
10143            }
10144        }
10145    }
10146
10147    final static class MemItem {
10148        final String label;
10149        final String shortLabel;
10150        final long pss;
10151        final int id;
10152        ArrayList<MemItem> subitems;
10153
10154        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10155            label = _label;
10156            shortLabel = _shortLabel;
10157            pss = _pss;
10158            id = _id;
10159        }
10160    }
10161
10162    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10163            boolean sort) {
10164        if (sort) {
10165            Collections.sort(items, new Comparator<MemItem>() {
10166                @Override
10167                public int compare(MemItem lhs, MemItem rhs) {
10168                    if (lhs.pss < rhs.pss) {
10169                        return 1;
10170                    } else if (lhs.pss > rhs.pss) {
10171                        return -1;
10172                    }
10173                    return 0;
10174                }
10175            });
10176        }
10177
10178        for (int i=0; i<items.size(); i++) {
10179            MemItem mi = items.get(i);
10180            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10181            if (mi.subitems != null) {
10182                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10183            }
10184        }
10185    }
10186
10187    // These are in KB.
10188    static final long[] DUMP_MEM_BUCKETS = new long[] {
10189        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10190        120*1024, 160*1024, 200*1024,
10191        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10192        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10193    };
10194
10195    static final void appendMemBucket(StringBuilder out, long memKB, String label,
10196            boolean stackLike) {
10197        int start = label.lastIndexOf('.');
10198        if (start >= 0) start++;
10199        else start = 0;
10200        int end = label.length();
10201        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10202            if (DUMP_MEM_BUCKETS[i] >= memKB) {
10203                long bucket = DUMP_MEM_BUCKETS[i]/1024;
10204                out.append(bucket);
10205                out.append(stackLike ? "MB." : "MB ");
10206                out.append(label, start, end);
10207                return;
10208            }
10209        }
10210        out.append(memKB/1024);
10211        out.append(stackLike ? "MB." : "MB ");
10212        out.append(label, start, end);
10213    }
10214
10215    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10216            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10217            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10218            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10219            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10220    };
10221    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10222            "System", "Persistent", "Foreground",
10223            "Visible", "Perceptible", "Heavy Weight",
10224            "Backup", "A Services", "Home", "Previous",
10225            "B Services", "Background"
10226    };
10227
10228    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10229            PrintWriter pw, String prefix, String[] args, boolean brief,
10230            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10231        boolean dumpAll = false;
10232        boolean oomOnly = false;
10233
10234        int opti = 0;
10235        while (opti < args.length) {
10236            String opt = args[opti];
10237            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10238                break;
10239            }
10240            opti++;
10241            if ("-a".equals(opt)) {
10242                dumpAll = true;
10243            } else if ("--oom".equals(opt)) {
10244                oomOnly = true;
10245            } else if ("-h".equals(opt)) {
10246                pw.println("meminfo dump options: [-a] [--oom] [process]");
10247                pw.println("  -a: include all available information for each process.");
10248                pw.println("  --oom: only show processes organized by oom adj.");
10249                pw.println("If [process] is specified it can be the name or ");
10250                pw.println("pid of a specific process to dump.");
10251                return;
10252            } else {
10253                pw.println("Unknown argument: " + opt + "; use -h for help");
10254            }
10255        }
10256
10257        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10258        if (procs == null) {
10259            return;
10260        }
10261
10262        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10263        long uptime = SystemClock.uptimeMillis();
10264        long realtime = SystemClock.elapsedRealtime();
10265
10266        if (procs.size() == 1 || isCheckinRequest) {
10267            dumpAll = true;
10268        }
10269
10270        if (isCheckinRequest) {
10271            // short checkin version
10272            pw.println(uptime + "," + realtime);
10273            pw.flush();
10274        } else {
10275            pw.println("Applications Memory Usage (kB):");
10276            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10277        }
10278
10279        String[] innerArgs = new String[args.length-opti];
10280        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10281
10282        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10283        long nativePss=0, dalvikPss=0, otherPss=0;
10284        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10285
10286        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10287        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10288                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10289
10290        long totalPss = 0;
10291
10292        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10293            ProcessRecord r = procs.get(i);
10294            if (r.thread != null) {
10295                if (!isCheckinRequest && dumpAll) {
10296                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10297                    pw.flush();
10298                }
10299                Debug.MemoryInfo mi = null;
10300                if (dumpAll) {
10301                    try {
10302                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10303                    } catch (RemoteException e) {
10304                        if (!isCheckinRequest) {
10305                            pw.println("Got RemoteException!");
10306                            pw.flush();
10307                        }
10308                    }
10309                } else {
10310                    mi = new Debug.MemoryInfo();
10311                    Debug.getMemoryInfo(r.pid, mi);
10312                }
10313
10314                if (!isCheckinRequest && mi != null) {
10315                    long myTotalPss = mi.getTotalPss();
10316                    totalPss += myTotalPss;
10317                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10318                            r.processName, myTotalPss, 0);
10319                    procMems.add(pssItem);
10320
10321                    nativePss += mi.nativePss;
10322                    dalvikPss += mi.dalvikPss;
10323                    otherPss += mi.otherPss;
10324                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10325                        long mem = mi.getOtherPss(j);
10326                        miscPss[j] += mem;
10327                        otherPss -= mem;
10328                    }
10329
10330                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10331                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10332                                || oomIndex == (oomPss.length-1)) {
10333                            oomPss[oomIndex] += myTotalPss;
10334                            if (oomProcs[oomIndex] == null) {
10335                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10336                            }
10337                            oomProcs[oomIndex].add(pssItem);
10338                            break;
10339                        }
10340                    }
10341                }
10342            }
10343        }
10344
10345        if (!isCheckinRequest && procs.size() > 1) {
10346            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10347
10348            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10349            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10350            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10351            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10352                String label = Debug.MemoryInfo.getOtherLabel(j);
10353                catMems.add(new MemItem(label, label, miscPss[j], j));
10354            }
10355
10356            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10357            for (int j=0; j<oomPss.length; j++) {
10358                if (oomPss[j] != 0) {
10359                    String label = DUMP_MEM_OOM_LABEL[j];
10360                    MemItem item = new MemItem(label, label, oomPss[j],
10361                            DUMP_MEM_OOM_ADJ[j]);
10362                    item.subitems = oomProcs[j];
10363                    oomMems.add(item);
10364                }
10365            }
10366
10367            if (outTag != null || outStack != null) {
10368                if (outTag != null) {
10369                    appendMemBucket(outTag, totalPss, "total", false);
10370                }
10371                if (outStack != null) {
10372                    appendMemBucket(outStack, totalPss, "total", true);
10373                }
10374                boolean firstLine = true;
10375                for (int i=0; i<oomMems.size(); i++) {
10376                    MemItem miCat = oomMems.get(i);
10377                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10378                        continue;
10379                    }
10380                    if (miCat.id < ProcessList.SERVICE_ADJ
10381                            || miCat.id == ProcessList.HOME_APP_ADJ
10382                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10383                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10384                            outTag.append(" / ");
10385                        }
10386                        if (outStack != null) {
10387                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10388                                if (firstLine) {
10389                                    outStack.append(":");
10390                                    firstLine = false;
10391                                }
10392                                outStack.append("\n\t at ");
10393                            } else {
10394                                outStack.append("$");
10395                            }
10396                        }
10397                        for (int j=0; j<miCat.subitems.size(); j++) {
10398                            MemItem mi = miCat.subitems.get(j);
10399                            if (j > 0) {
10400                                if (outTag != null) {
10401                                    outTag.append(" ");
10402                                }
10403                                if (outStack != null) {
10404                                    outStack.append("$");
10405                                }
10406                            }
10407                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10408                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10409                            }
10410                            if (outStack != null) {
10411                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10412                            }
10413                        }
10414                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10415                            outStack.append("(");
10416                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10417                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10418                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10419                                    outStack.append(":");
10420                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10421                                }
10422                            }
10423                            outStack.append(")");
10424                        }
10425                    }
10426                }
10427            }
10428
10429            if (!brief && !oomOnly) {
10430                pw.println();
10431                pw.println("Total PSS by process:");
10432                dumpMemItems(pw, "  ", procMems, true);
10433                pw.println();
10434            }
10435            pw.println("Total PSS by OOM adjustment:");
10436            dumpMemItems(pw, "  ", oomMems, false);
10437            if (!oomOnly) {
10438                PrintWriter out = categoryPw != null ? categoryPw : pw;
10439                out.println();
10440                out.println("Total PSS by category:");
10441                dumpMemItems(out, "  ", catMems, true);
10442            }
10443            pw.println();
10444            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10445            final int[] SINGLE_LONG_FORMAT = new int[] {
10446                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10447            };
10448            long[] longOut = new long[1];
10449            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10450                    SINGLE_LONG_FORMAT, null, longOut, null);
10451            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10452            longOut[0] = 0;
10453            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10454                    SINGLE_LONG_FORMAT, null, longOut, null);
10455            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10456            longOut[0] = 0;
10457            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10458                    SINGLE_LONG_FORMAT, null, longOut, null);
10459            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10460            longOut[0] = 0;
10461            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10462                    SINGLE_LONG_FORMAT, null, longOut, null);
10463            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10464            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10465                    pw.print(shared); pw.println(" kB");
10466            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10467                    pw.print(voltile); pw.println(" kB volatile");
10468        }
10469    }
10470
10471    /**
10472     * Searches array of arguments for the specified string
10473     * @param args array of argument strings
10474     * @param value value to search for
10475     * @return true if the value is contained in the array
10476     */
10477    private static boolean scanArgs(String[] args, String value) {
10478        if (args != null) {
10479            for (String arg : args) {
10480                if (value.equals(arg)) {
10481                    return true;
10482                }
10483            }
10484        }
10485        return false;
10486    }
10487
10488    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10489            ContentProviderRecord cpr, boolean always) {
10490        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10491
10492        if (!inLaunching || always) {
10493            synchronized (cpr) {
10494                cpr.launchingApp = null;
10495                cpr.notifyAll();
10496            }
10497            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10498            String names[] = cpr.info.authority.split(";");
10499            for (int j = 0; j < names.length; j++) {
10500                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10501            }
10502        }
10503
10504        for (int i=0; i<cpr.connections.size(); i++) {
10505            ContentProviderConnection conn = cpr.connections.get(i);
10506            if (conn.waiting) {
10507                // If this connection is waiting for the provider, then we don't
10508                // need to mess with its process unless we are always removing
10509                // or for some reason the provider is not currently launching.
10510                if (inLaunching && !always) {
10511                    continue;
10512                }
10513            }
10514            ProcessRecord capp = conn.client;
10515            conn.dead = true;
10516            if (conn.stableCount > 0) {
10517                if (!capp.persistent && capp.thread != null
10518                        && capp.pid != 0
10519                        && capp.pid != MY_PID) {
10520                    Slog.i(TAG, "Kill " + capp.processName
10521                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10522                            + " in dying process " + (proc != null ? proc.processName : "??"));
10523                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10524                            capp.processName, capp.setAdj, "dying provider "
10525                                    + cpr.name.toShortString());
10526                    Process.killProcessQuiet(capp.pid);
10527                }
10528            } else if (capp.thread != null && conn.provider.provider != null) {
10529                try {
10530                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10531                } catch (RemoteException e) {
10532                }
10533                // In the protocol here, we don't expect the client to correctly
10534                // clean up this connection, we'll just remove it.
10535                cpr.connections.remove(i);
10536                conn.client.conProviders.remove(conn);
10537            }
10538        }
10539
10540        if (inLaunching && always) {
10541            mLaunchingProviders.remove(cpr);
10542        }
10543        return inLaunching;
10544    }
10545
10546    /**
10547     * Main code for cleaning up a process when it has gone away.  This is
10548     * called both as a result of the process dying, or directly when stopping
10549     * a process when running in single process mode.
10550     */
10551    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10552            boolean restarting, boolean allowRestart, int index) {
10553        if (index >= 0) {
10554            mLruProcesses.remove(index);
10555        }
10556
10557        mProcessesToGc.remove(app);
10558
10559        // Dismiss any open dialogs.
10560        if (app.crashDialog != null) {
10561            app.crashDialog.dismiss();
10562            app.crashDialog = null;
10563        }
10564        if (app.anrDialog != null) {
10565            app.anrDialog.dismiss();
10566            app.anrDialog = null;
10567        }
10568        if (app.waitDialog != null) {
10569            app.waitDialog.dismiss();
10570            app.waitDialog = null;
10571        }
10572
10573        app.crashing = false;
10574        app.notResponding = false;
10575
10576        app.resetPackageList();
10577        app.unlinkDeathRecipient();
10578        app.thread = null;
10579        app.forcingToForeground = null;
10580        app.foregroundServices = false;
10581        app.foregroundActivities = false;
10582        app.hasShownUi = false;
10583        app.hasAboveClient = false;
10584
10585        mServices.killServicesLocked(app, allowRestart);
10586
10587        boolean restart = false;
10588
10589        // Remove published content providers.
10590        if (!app.pubProviders.isEmpty()) {
10591            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10592            while (it.hasNext()) {
10593                ContentProviderRecord cpr = it.next();
10594
10595                final boolean always = app.bad || !allowRestart;
10596                if (removeDyingProviderLocked(app, cpr, always) || always) {
10597                    // We left the provider in the launching list, need to
10598                    // restart it.
10599                    restart = true;
10600                }
10601
10602                cpr.provider = null;
10603                cpr.proc = null;
10604            }
10605            app.pubProviders.clear();
10606        }
10607
10608        // Take care of any launching providers waiting for this process.
10609        if (checkAppInLaunchingProvidersLocked(app, false)) {
10610            restart = true;
10611        }
10612
10613        // Unregister from connected content providers.
10614        if (!app.conProviders.isEmpty()) {
10615            for (int i=0; i<app.conProviders.size(); i++) {
10616                ContentProviderConnection conn = app.conProviders.get(i);
10617                conn.provider.connections.remove(conn);
10618            }
10619            app.conProviders.clear();
10620        }
10621
10622        // At this point there may be remaining entries in mLaunchingProviders
10623        // where we were the only one waiting, so they are no longer of use.
10624        // Look for these and clean up if found.
10625        // XXX Commented out for now.  Trying to figure out a way to reproduce
10626        // the actual situation to identify what is actually going on.
10627        if (false) {
10628            for (int i=0; i<mLaunchingProviders.size(); i++) {
10629                ContentProviderRecord cpr = (ContentProviderRecord)
10630                        mLaunchingProviders.get(i);
10631                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10632                    synchronized (cpr) {
10633                        cpr.launchingApp = null;
10634                        cpr.notifyAll();
10635                    }
10636                }
10637            }
10638        }
10639
10640        skipCurrentReceiverLocked(app);
10641
10642        // Unregister any receivers.
10643        if (app.receivers.size() > 0) {
10644            Iterator<ReceiverList> it = app.receivers.iterator();
10645            while (it.hasNext()) {
10646                removeReceiverLocked(it.next());
10647            }
10648            app.receivers.clear();
10649        }
10650
10651        // If the app is undergoing backup, tell the backup manager about it
10652        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10653            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10654            try {
10655                IBackupManager bm = IBackupManager.Stub.asInterface(
10656                        ServiceManager.getService(Context.BACKUP_SERVICE));
10657                bm.agentDisconnected(app.info.packageName);
10658            } catch (RemoteException e) {
10659                // can't happen; backup manager is local
10660            }
10661        }
10662
10663        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10664            ProcessChangeItem item = mPendingProcessChanges.get(i);
10665            if (item.pid == app.pid) {
10666                mPendingProcessChanges.remove(i);
10667                mAvailProcessChanges.add(item);
10668            }
10669        }
10670        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10671
10672        // If the caller is restarting this app, then leave it in its
10673        // current lists and let the caller take care of it.
10674        if (restarting) {
10675            return;
10676        }
10677
10678        if (!app.persistent || app.isolated) {
10679            if (DEBUG_PROCESSES) Slog.v(TAG,
10680                    "Removing non-persistent process during cleanup: " + app);
10681            mProcessNames.remove(app.processName, app.uid);
10682            mIsolatedProcesses.remove(app.uid);
10683            if (mHeavyWeightProcess == app) {
10684                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
10685                        mHeavyWeightProcess.userId, 0));
10686                mHeavyWeightProcess = null;
10687            }
10688        } else if (!app.removed) {
10689            // This app is persistent, so we need to keep its record around.
10690            // If it is not already on the pending app list, add it there
10691            // and start a new process for it.
10692            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10693                mPersistentStartingProcesses.add(app);
10694                restart = true;
10695            }
10696        }
10697        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10698                "Clean-up removing on hold: " + app);
10699        mProcessesOnHold.remove(app);
10700
10701        if (app == mHomeProcess) {
10702            mHomeProcess = null;
10703        }
10704        if (app == mPreviousProcess) {
10705            mPreviousProcess = null;
10706        }
10707
10708        if (restart && !app.isolated) {
10709            // We have components that still need to be running in the
10710            // process, so re-launch it.
10711            mProcessNames.put(app.processName, app.uid, app);
10712            startProcessLocked(app, "restart", app.processName);
10713        } else if (app.pid > 0 && app.pid != MY_PID) {
10714            // Goodbye!
10715            synchronized (mPidsSelfLocked) {
10716                mPidsSelfLocked.remove(app.pid);
10717                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10718            }
10719            app.setPid(0);
10720        }
10721    }
10722
10723    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10724        // Look through the content providers we are waiting to have launched,
10725        // and if any run in this process then either schedule a restart of
10726        // the process or kill the client waiting for it if this process has
10727        // gone bad.
10728        int NL = mLaunchingProviders.size();
10729        boolean restart = false;
10730        for (int i=0; i<NL; i++) {
10731            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10732            if (cpr.launchingApp == app) {
10733                if (!alwaysBad && !app.bad) {
10734                    restart = true;
10735                } else {
10736                    removeDyingProviderLocked(app, cpr, true);
10737                    // cpr should have been removed from mLaunchingProviders
10738                    NL = mLaunchingProviders.size();
10739                    i--;
10740                }
10741            }
10742        }
10743        return restart;
10744    }
10745
10746    // =========================================================
10747    // SERVICES
10748    // =========================================================
10749
10750    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10751            int flags) {
10752        enforceNotIsolatedCaller("getServices");
10753        synchronized (this) {
10754            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10755        }
10756    }
10757
10758    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10759        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10760        synchronized (this) {
10761            return mServices.getRunningServiceControlPanelLocked(name);
10762        }
10763    }
10764
10765    public ComponentName startService(IApplicationThread caller, Intent service,
10766            String resolvedType, int userId) {
10767        enforceNotIsolatedCaller("startService");
10768        // Refuse possible leaked file descriptors
10769        if (service != null && service.hasFileDescriptors() == true) {
10770            throw new IllegalArgumentException("File descriptors passed in Intent");
10771        }
10772
10773        if (DEBUG_SERVICE)
10774            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10775        synchronized(this) {
10776            final int callingPid = Binder.getCallingPid();
10777            final int callingUid = Binder.getCallingUid();
10778            checkValidCaller(callingUid, userId);
10779            final long origId = Binder.clearCallingIdentity();
10780            ComponentName res = mServices.startServiceLocked(caller, service,
10781                    resolvedType, callingPid, callingUid, userId);
10782            Binder.restoreCallingIdentity(origId);
10783            return res;
10784        }
10785    }
10786
10787    ComponentName startServiceInPackage(int uid,
10788            Intent service, String resolvedType, int userId) {
10789        synchronized(this) {
10790            if (DEBUG_SERVICE)
10791                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10792            final long origId = Binder.clearCallingIdentity();
10793            ComponentName res = mServices.startServiceLocked(null, service,
10794                    resolvedType, -1, uid, userId);
10795            Binder.restoreCallingIdentity(origId);
10796            return res;
10797        }
10798    }
10799
10800    public int stopService(IApplicationThread caller, Intent service,
10801            String resolvedType, int userId) {
10802        enforceNotIsolatedCaller("stopService");
10803        // Refuse possible leaked file descriptors
10804        if (service != null && service.hasFileDescriptors() == true) {
10805            throw new IllegalArgumentException("File descriptors passed in Intent");
10806        }
10807
10808        checkValidCaller(Binder.getCallingUid(), userId);
10809
10810        synchronized(this) {
10811            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
10812        }
10813    }
10814
10815    public IBinder peekService(Intent service, String resolvedType) {
10816        enforceNotIsolatedCaller("peekService");
10817        // Refuse possible leaked file descriptors
10818        if (service != null && service.hasFileDescriptors() == true) {
10819            throw new IllegalArgumentException("File descriptors passed in Intent");
10820        }
10821        synchronized(this) {
10822            return mServices.peekServiceLocked(service, resolvedType);
10823        }
10824    }
10825
10826    public boolean stopServiceToken(ComponentName className, IBinder token,
10827            int startId) {
10828        synchronized(this) {
10829            return mServices.stopServiceTokenLocked(className, token, startId);
10830        }
10831    }
10832
10833    public void setServiceForeground(ComponentName className, IBinder token,
10834            int id, Notification notification, boolean removeNotification) {
10835        synchronized(this) {
10836            mServices.setServiceForegroundLocked(className, token, id, notification,
10837                    removeNotification);
10838        }
10839    }
10840
10841    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
10842            boolean requireFull, String name, String callerPackage) {
10843        synchronized(this) {
10844            return handleIncomingUserLocked(callingPid, callingUid, userId, allowAll,
10845                    requireFull, name, callerPackage);
10846        }
10847    }
10848
10849    int handleIncomingUserLocked(int callingPid, int callingUid, int userId, boolean allowAll,
10850            boolean requireFull, String name, String callerPackage) {
10851        final int callingUserId = UserHandle.getUserId(callingUid);
10852        if (callingUserId != userId) {
10853            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10854                if ((requireFull || checkComponentPermission(
10855                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10856                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
10857                        && checkComponentPermission(
10858                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10859                                callingPid, callingUid, -1, true)
10860                                != PackageManager.PERMISSION_GRANTED) {
10861                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
10862                        // In this case, they would like to just execute as their
10863                        // owner user instead of failing.
10864                        userId = callingUserId;
10865                    } else {
10866                        StringBuilder builder = new StringBuilder(128);
10867                        builder.append("Permission Denial: ");
10868                        builder.append(name);
10869                        if (callerPackage != null) {
10870                            builder.append(" from ");
10871                            builder.append(callerPackage);
10872                        }
10873                        builder.append(" asks to run as user ");
10874                        builder.append(userId);
10875                        builder.append(" but is calling from user ");
10876                        builder.append(UserHandle.getUserId(callingUid));
10877                        builder.append("; this requires ");
10878                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
10879                        if (!requireFull) {
10880                            builder.append(" or ");
10881                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
10882                        }
10883                        String msg = builder.toString();
10884                        Slog.w(TAG, msg);
10885                        throw new SecurityException(msg);
10886                    }
10887                }
10888            }
10889            if (userId == UserHandle.USER_CURRENT
10890                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
10891                userId = mCurrentUserId;
10892            }
10893            if (!allowAll && userId < 0) {
10894                throw new IllegalArgumentException(
10895                        "Call does not support special user #" + userId);
10896            }
10897        }
10898        return userId;
10899    }
10900
10901    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10902            String className, int flags) {
10903        boolean result = false;
10904        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
10905            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10906                if (ActivityManager.checkUidPermission(
10907                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10908                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10909                    ComponentName comp = new ComponentName(aInfo.packageName, className);
10910                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
10911                            + " requests FLAG_SINGLE_USER, but app does not hold "
10912                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10913                    Slog.w(TAG, msg);
10914                    throw new SecurityException(msg);
10915                }
10916                result = true;
10917            }
10918        } else if (componentProcessName == aInfo.packageName) {
10919            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
10920        } else if ("system".equals(componentProcessName)) {
10921            result = true;
10922        }
10923        if (DEBUG_MU) {
10924            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
10925                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
10926        }
10927        return result;
10928    }
10929
10930    public int bindService(IApplicationThread caller, IBinder token,
10931            Intent service, String resolvedType,
10932            IServiceConnection connection, int flags, int userId) {
10933        enforceNotIsolatedCaller("bindService");
10934        // Refuse possible leaked file descriptors
10935        if (service != null && service.hasFileDescriptors() == true) {
10936            throw new IllegalArgumentException("File descriptors passed in Intent");
10937        }
10938
10939        synchronized(this) {
10940            return mServices.bindServiceLocked(caller, token, service, resolvedType,
10941                    connection, flags, userId);
10942        }
10943    }
10944
10945    public boolean unbindService(IServiceConnection connection) {
10946        synchronized (this) {
10947            return mServices.unbindServiceLocked(connection);
10948        }
10949    }
10950
10951    public void publishService(IBinder token, Intent intent, IBinder service) {
10952        // Refuse possible leaked file descriptors
10953        if (intent != null && intent.hasFileDescriptors() == true) {
10954            throw new IllegalArgumentException("File descriptors passed in Intent");
10955        }
10956
10957        synchronized(this) {
10958            if (!(token instanceof ServiceRecord)) {
10959                throw new IllegalArgumentException("Invalid service token");
10960            }
10961            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
10962        }
10963    }
10964
10965    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10966        // Refuse possible leaked file descriptors
10967        if (intent != null && intent.hasFileDescriptors() == true) {
10968            throw new IllegalArgumentException("File descriptors passed in Intent");
10969        }
10970
10971        synchronized(this) {
10972            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
10973        }
10974    }
10975
10976    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
10977        synchronized(this) {
10978            if (!(token instanceof ServiceRecord)) {
10979                throw new IllegalArgumentException("Invalid service token");
10980            }
10981            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
10982        }
10983    }
10984
10985    // =========================================================
10986    // BACKUP AND RESTORE
10987    // =========================================================
10988
10989    // Cause the target app to be launched if necessary and its backup agent
10990    // instantiated.  The backup agent will invoke backupAgentCreated() on the
10991    // activity manager to announce its creation.
10992    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
10993        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
10994        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10995
10996        synchronized(this) {
10997            // !!! TODO: currently no check here that we're already bound
10998            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10999            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11000            synchronized (stats) {
11001                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11002            }
11003
11004            // Backup agent is now in use, its package can't be stopped.
11005            try {
11006                AppGlobals.getPackageManager().setPackageStoppedState(
11007                        app.packageName, false, UserHandle.getUserId(app.uid));
11008            } catch (RemoteException e) {
11009            } catch (IllegalArgumentException e) {
11010                Slog.w(TAG, "Failed trying to unstop package "
11011                        + app.packageName + ": " + e);
11012            }
11013
11014            BackupRecord r = new BackupRecord(ss, app, backupMode);
11015            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11016                    ? new ComponentName(app.packageName, app.backupAgentName)
11017                    : new ComponentName("android", "FullBackupAgent");
11018            // startProcessLocked() returns existing proc's record if it's already running
11019            ProcessRecord proc = startProcessLocked(app.processName, app,
11020                    false, 0, "backup", hostingName, false, false);
11021            if (proc == null) {
11022                Slog.e(TAG, "Unable to start backup agent process " + r);
11023                return false;
11024            }
11025
11026            r.app = proc;
11027            mBackupTarget = r;
11028            mBackupAppName = app.packageName;
11029
11030            // Try not to kill the process during backup
11031            updateOomAdjLocked(proc);
11032
11033            // If the process is already attached, schedule the creation of the backup agent now.
11034            // If it is not yet live, this will be done when it attaches to the framework.
11035            if (proc.thread != null) {
11036                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
11037                try {
11038                    proc.thread.scheduleCreateBackupAgent(app,
11039                            compatibilityInfoForPackageLocked(app), backupMode);
11040                } catch (RemoteException e) {
11041                    // Will time out on the backup manager side
11042                }
11043            } else {
11044                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
11045            }
11046            // Invariants: at this point, the target app process exists and the application
11047            // is either already running or in the process of coming up.  mBackupTarget and
11048            // mBackupAppName describe the app, so that when it binds back to the AM we
11049            // know that it's scheduled for a backup-agent operation.
11050        }
11051
11052        return true;
11053    }
11054
11055    // A backup agent has just come up
11056    public void backupAgentCreated(String agentPackageName, IBinder agent) {
11057        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
11058                + " = " + agent);
11059
11060        synchronized(this) {
11061            if (!agentPackageName.equals(mBackupAppName)) {
11062                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
11063                return;
11064            }
11065        }
11066
11067        long oldIdent = Binder.clearCallingIdentity();
11068        try {
11069            IBackupManager bm = IBackupManager.Stub.asInterface(
11070                    ServiceManager.getService(Context.BACKUP_SERVICE));
11071            bm.agentConnected(agentPackageName, agent);
11072        } catch (RemoteException e) {
11073            // can't happen; the backup manager service is local
11074        } catch (Exception e) {
11075            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11076            e.printStackTrace();
11077        } finally {
11078            Binder.restoreCallingIdentity(oldIdent);
11079        }
11080    }
11081
11082    // done with this agent
11083    public void unbindBackupAgent(ApplicationInfo appInfo) {
11084        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
11085        if (appInfo == null) {
11086            Slog.w(TAG, "unbind backup agent for null app");
11087            return;
11088        }
11089
11090        synchronized(this) {
11091            if (mBackupAppName == null) {
11092                Slog.w(TAG, "Unbinding backup agent with no active backup");
11093                return;
11094            }
11095
11096            if (!mBackupAppName.equals(appInfo.packageName)) {
11097                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11098                return;
11099            }
11100
11101            ProcessRecord proc = mBackupTarget.app;
11102            mBackupTarget = null;
11103            mBackupAppName = null;
11104
11105            // Not backing this app up any more; reset its OOM adjustment
11106            updateOomAdjLocked(proc);
11107
11108            // If the app crashed during backup, 'thread' will be null here
11109            if (proc.thread != null) {
11110                try {
11111                    proc.thread.scheduleDestroyBackupAgent(appInfo,
11112                            compatibilityInfoForPackageLocked(appInfo));
11113                } catch (Exception e) {
11114                    Slog.e(TAG, "Exception when unbinding backup agent:");
11115                    e.printStackTrace();
11116                }
11117            }
11118        }
11119    }
11120    // =========================================================
11121    // BROADCASTS
11122    // =========================================================
11123
11124    private final List getStickiesLocked(String action, IntentFilter filter,
11125            List cur, int userId) {
11126        final ContentResolver resolver = mContext.getContentResolver();
11127        HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11128        if (stickies == null) {
11129            return cur;
11130        }
11131        final ArrayList<Intent> list = stickies.get(action);
11132        if (list == null) {
11133            return cur;
11134        }
11135        int N = list.size();
11136        for (int i=0; i<N; i++) {
11137            Intent intent = list.get(i);
11138            if (filter.match(resolver, intent, true, TAG) >= 0) {
11139                if (cur == null) {
11140                    cur = new ArrayList<Intent>();
11141                }
11142                cur.add(intent);
11143            }
11144        }
11145        return cur;
11146    }
11147
11148    boolean isPendingBroadcastProcessLocked(int pid) {
11149        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
11150                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
11151    }
11152
11153    void skipPendingBroadcastLocked(int pid) {
11154            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
11155            for (BroadcastQueue queue : mBroadcastQueues) {
11156                queue.skipPendingBroadcastLocked(pid);
11157            }
11158    }
11159
11160    // The app just attached; send any pending broadcasts that it should receive
11161    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
11162        boolean didSomething = false;
11163        for (BroadcastQueue queue : mBroadcastQueues) {
11164            didSomething |= queue.sendPendingBroadcastsLocked(app);
11165        }
11166        return didSomething;
11167    }
11168
11169    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
11170            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
11171        enforceNotIsolatedCaller("registerReceiver");
11172        int callingUid;
11173        int callingPid;
11174        synchronized(this) {
11175            ProcessRecord callerApp = null;
11176            if (caller != null) {
11177                callerApp = getRecordForAppLocked(caller);
11178                if (callerApp == null) {
11179                    throw new SecurityException(
11180                            "Unable to find app for caller " + caller
11181                            + " (pid=" + Binder.getCallingPid()
11182                            + ") when registering receiver " + receiver);
11183                }
11184                if (callerApp.info.uid != Process.SYSTEM_UID &&
11185                        !callerApp.pkgList.contains(callerPackage)) {
11186                    throw new SecurityException("Given caller package " + callerPackage
11187                            + " is not running in process " + callerApp);
11188                }
11189                callingUid = callerApp.info.uid;
11190                callingPid = callerApp.pid;
11191            } else {
11192                callerPackage = null;
11193                callingUid = Binder.getCallingUid();
11194                callingPid = Binder.getCallingPid();
11195            }
11196
11197            userId = this.handleIncomingUserLocked(callingPid, callingUid, userId,
11198                    true, true, "registerReceiver", callerPackage);
11199
11200            List allSticky = null;
11201
11202            // Look for any matching sticky broadcasts...
11203            Iterator actions = filter.actionsIterator();
11204            if (actions != null) {
11205                while (actions.hasNext()) {
11206                    String action = (String)actions.next();
11207                    allSticky = getStickiesLocked(action, filter, allSticky,
11208                            UserHandle.USER_ALL);
11209                    allSticky = getStickiesLocked(action, filter, allSticky,
11210                            UserHandle.getUserId(callingUid));
11211                }
11212            } else {
11213                allSticky = getStickiesLocked(null, filter, allSticky,
11214                        UserHandle.USER_ALL);
11215                allSticky = getStickiesLocked(null, filter, allSticky,
11216                        UserHandle.getUserId(callingUid));
11217            }
11218
11219            // The first sticky in the list is returned directly back to
11220            // the client.
11221            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11222
11223            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
11224                    + ": " + sticky);
11225
11226            if (receiver == null) {
11227                return sticky;
11228            }
11229
11230            ReceiverList rl
11231                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11232            if (rl == null) {
11233                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
11234                        userId, receiver);
11235                if (rl.app != null) {
11236                    rl.app.receivers.add(rl);
11237                } else {
11238                    try {
11239                        receiver.asBinder().linkToDeath(rl, 0);
11240                    } catch (RemoteException e) {
11241                        return sticky;
11242                    }
11243                    rl.linkedToDeath = true;
11244                }
11245                mRegisteredReceivers.put(receiver.asBinder(), rl);
11246            } else if (rl.uid != callingUid) {
11247                throw new IllegalArgumentException(
11248                        "Receiver requested to register for uid " + callingUid
11249                        + " was previously registered for uid " + rl.uid);
11250            } else if (rl.pid != callingPid) {
11251                throw new IllegalArgumentException(
11252                        "Receiver requested to register for pid " + callingPid
11253                        + " was previously registered for pid " + rl.pid);
11254            } else if (rl.userId != userId) {
11255                throw new IllegalArgumentException(
11256                        "Receiver requested to register for user " + userId
11257                        + " was previously registered for user " + rl.userId);
11258            }
11259            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
11260                    permission, callingUid, userId);
11261            rl.add(bf);
11262            if (!bf.debugCheck()) {
11263                Slog.w(TAG, "==> For Dynamic broadast");
11264            }
11265            mReceiverResolver.addFilter(bf);
11266
11267            // Enqueue broadcasts for all existing stickies that match
11268            // this filter.
11269            if (allSticky != null) {
11270                ArrayList receivers = new ArrayList();
11271                receivers.add(bf);
11272
11273                int N = allSticky.size();
11274                for (int i=0; i<N; i++) {
11275                    Intent intent = (Intent)allSticky.get(i);
11276                    BroadcastQueue queue = broadcastQueueForIntent(intent);
11277                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
11278                            null, -1, -1, null, receivers, null, 0, null, null,
11279                            false, true, true, -1);
11280                    queue.enqueueParallelBroadcastLocked(r);
11281                    queue.scheduleBroadcastsLocked();
11282                }
11283            }
11284
11285            return sticky;
11286        }
11287    }
11288
11289    public void unregisterReceiver(IIntentReceiver receiver) {
11290        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11291
11292        final long origId = Binder.clearCallingIdentity();
11293        try {
11294            boolean doTrim = false;
11295
11296            synchronized(this) {
11297                ReceiverList rl
11298                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11299                if (rl != null) {
11300                    if (rl.curBroadcast != null) {
11301                        BroadcastRecord r = rl.curBroadcast;
11302                        final boolean doNext = finishReceiverLocked(
11303                                receiver.asBinder(), r.resultCode, r.resultData,
11304                                r.resultExtras, r.resultAbort, true);
11305                        if (doNext) {
11306                            doTrim = true;
11307                            r.queue.processNextBroadcast(false);
11308                        }
11309                    }
11310
11311                    if (rl.app != null) {
11312                        rl.app.receivers.remove(rl);
11313                    }
11314                    removeReceiverLocked(rl);
11315                    if (rl.linkedToDeath) {
11316                        rl.linkedToDeath = false;
11317                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
11318                    }
11319                }
11320            }
11321
11322            // If we actually concluded any broadcasts, we might now be able
11323            // to trim the recipients' apps from our working set
11324            if (doTrim) {
11325                trimApplications();
11326                return;
11327            }
11328
11329        } finally {
11330            Binder.restoreCallingIdentity(origId);
11331        }
11332    }
11333
11334    void removeReceiverLocked(ReceiverList rl) {
11335        mRegisteredReceivers.remove(rl.receiver.asBinder());
11336        int N = rl.size();
11337        for (int i=0; i<N; i++) {
11338            mReceiverResolver.removeFilter(rl.get(i));
11339        }
11340    }
11341
11342    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
11343        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11344            ProcessRecord r = mLruProcesses.get(i);
11345            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
11346                try {
11347                    r.thread.dispatchPackageBroadcast(cmd, packages);
11348                } catch (RemoteException ex) {
11349                }
11350            }
11351        }
11352    }
11353
11354    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
11355            int[] users) {
11356        List<ResolveInfo> receivers = null;
11357        try {
11358            HashSet<ComponentName> singleUserReceivers = null;
11359            boolean scannedFirstReceivers = false;
11360            for (int user : users) {
11361                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
11362                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
11363                if (newReceivers != null && newReceivers.size() == 0) {
11364                    newReceivers = null;
11365                }
11366                if (receivers == null) {
11367                    receivers = newReceivers;
11368                } else if (newReceivers != null) {
11369                    // We need to concatenate the additional receivers
11370                    // found with what we have do far.  This would be easy,
11371                    // but we also need to de-dup any receivers that are
11372                    // singleUser.
11373                    if (!scannedFirstReceivers) {
11374                        // Collect any single user receivers we had already retrieved.
11375                        scannedFirstReceivers = true;
11376                        for (int i=0; i<receivers.size(); i++) {
11377                            ResolveInfo ri = receivers.get(i);
11378                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11379                                ComponentName cn = new ComponentName(
11380                                        ri.activityInfo.packageName, ri.activityInfo.name);
11381                                if (singleUserReceivers == null) {
11382                                    singleUserReceivers = new HashSet<ComponentName>();
11383                                }
11384                                singleUserReceivers.add(cn);
11385                            }
11386                        }
11387                    }
11388                    // Add the new results to the existing results, tracking
11389                    // and de-dupping single user receivers.
11390                    for (int i=0; i<newReceivers.size(); i++) {
11391                        ResolveInfo ri = receivers.get(i);
11392                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11393                            ComponentName cn = new ComponentName(
11394                                    ri.activityInfo.packageName, ri.activityInfo.name);
11395                            if (singleUserReceivers == null) {
11396                                singleUserReceivers = new HashSet<ComponentName>();
11397                            }
11398                            if (!singleUserReceivers.contains(cn)) {
11399                                singleUserReceivers.add(cn);
11400                                receivers.add(ri);
11401                            }
11402                        } else {
11403                            receivers.add(ri);
11404                        }
11405                    }
11406                }
11407            }
11408        } catch (RemoteException ex) {
11409            // pm is in same process, this will never happen.
11410        }
11411        return receivers;
11412    }
11413
11414    private final int broadcastIntentLocked(ProcessRecord callerApp,
11415            String callerPackage, Intent intent, String resolvedType,
11416            IIntentReceiver resultTo, int resultCode, String resultData,
11417            Bundle map, String requiredPermission,
11418            boolean ordered, boolean sticky, int callingPid, int callingUid,
11419            int userId) {
11420        intent = new Intent(intent);
11421
11422        // By default broadcasts do not go to stopped apps.
11423        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11424
11425        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11426            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11427            + " ordered=" + ordered + " userid=" + userId);
11428        if ((resultTo != null) && !ordered) {
11429            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11430        }
11431
11432        userId = handleIncomingUserLocked(callingPid, callingUid, userId,
11433                true, false, "broadcast", callerPackage);
11434
11435        // Make sure that the user who is receiving this broadcast is started
11436        // If not, we will just skip it.
11437        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
11438            Slog.w(TAG, "Skipping broadcast of " + intent
11439                    + ": user " + userId + " is stopped");
11440            return ActivityManager.BROADCAST_SUCCESS;
11441        }
11442
11443        /*
11444         * Prevent non-system code (defined here to be non-persistent
11445         * processes) from sending protected broadcasts.
11446         */
11447        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11448            || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
11449            callingUid == 0) {
11450            // Always okay.
11451        } else if (callerApp == null || !callerApp.persistent) {
11452            try {
11453                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11454                        intent.getAction())) {
11455                    String msg = "Permission Denial: not allowed to send broadcast "
11456                            + intent.getAction() + " from pid="
11457                            + callingPid + ", uid=" + callingUid;
11458                    Slog.w(TAG, msg);
11459                    throw new SecurityException(msg);
11460                }
11461            } catch (RemoteException e) {
11462                Slog.w(TAG, "Remote exception", e);
11463                return ActivityManager.BROADCAST_SUCCESS;
11464            }
11465        }
11466
11467        // Handle special intents: if this broadcast is from the package
11468        // manager about a package being removed, we need to remove all of
11469        // its activities from the history stack.
11470        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11471                intent.getAction());
11472        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11473                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11474                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11475                || uidRemoved) {
11476            if (checkComponentPermission(
11477                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11478                    callingPid, callingUid, -1, true)
11479                    == PackageManager.PERMISSION_GRANTED) {
11480                if (uidRemoved) {
11481                    final Bundle intentExtras = intent.getExtras();
11482                    final int uid = intentExtras != null
11483                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11484                    if (uid >= 0) {
11485                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11486                        synchronized (bs) {
11487                            bs.removeUidStatsLocked(uid);
11488                        }
11489                    }
11490                } else {
11491                    // If resources are unavailable just force stop all
11492                    // those packages and flush the attribute cache as well.
11493                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11494                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11495                        if (list != null && (list.length > 0)) {
11496                            for (String pkg : list) {
11497                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11498                            }
11499                            sendPackageBroadcastLocked(
11500                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
11501                        }
11502                    } else {
11503                        Uri data = intent.getData();
11504                        String ssp;
11505                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11506                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11507                                forceStopPackageLocked(ssp,
11508                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11509                                        false, userId);
11510                            }
11511                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11512                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11513                                        new String[] {ssp}, userId);
11514                            }
11515                        }
11516                    }
11517                }
11518            } else {
11519                String msg = "Permission Denial: " + intent.getAction()
11520                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11521                        + ", uid=" + callingUid + ")"
11522                        + " requires "
11523                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11524                Slog.w(TAG, msg);
11525                throw new SecurityException(msg);
11526            }
11527
11528        // Special case for adding a package: by default turn on compatibility
11529        // mode.
11530        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11531            Uri data = intent.getData();
11532            String ssp;
11533            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11534                mCompatModePackages.handlePackageAddedLocked(ssp,
11535                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11536            }
11537        }
11538
11539        /*
11540         * If this is the time zone changed action, queue up a message that will reset the timezone
11541         * of all currently running processes. This message will get queued up before the broadcast
11542         * happens.
11543         */
11544        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11545            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11546        }
11547
11548        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11549            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11550        }
11551
11552        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11553            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11554            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11555        }
11556
11557        // Add to the sticky list if requested.
11558        if (sticky) {
11559            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11560                    callingPid, callingUid)
11561                    != PackageManager.PERMISSION_GRANTED) {
11562                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11563                        + callingPid + ", uid=" + callingUid
11564                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11565                Slog.w(TAG, msg);
11566                throw new SecurityException(msg);
11567            }
11568            if (requiredPermission != null) {
11569                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11570                        + " and enforce permission " + requiredPermission);
11571                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11572            }
11573            if (intent.getComponent() != null) {
11574                throw new SecurityException(
11575                        "Sticky broadcasts can't target a specific component");
11576            }
11577            // We use userId directly here, since the "all" target is maintained
11578            // as a separate set of sticky broadcasts.
11579            if (userId != UserHandle.USER_ALL) {
11580                // But first, if this is not a broadcast to all users, then
11581                // make sure it doesn't conflict with an existing broadcast to
11582                // all users.
11583                HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
11584                        UserHandle.USER_ALL);
11585                if (stickies != null) {
11586                    ArrayList<Intent> list = stickies.get(intent.getAction());
11587                    if (list != null) {
11588                        int N = list.size();
11589                        int i;
11590                        for (i=0; i<N; i++) {
11591                            if (intent.filterEquals(list.get(i))) {
11592                                throw new IllegalArgumentException(
11593                                        "Sticky broadcast " + intent + " for user "
11594                                        + userId + " conflicts with existing global broadcast");
11595                            }
11596                        }
11597                    }
11598                }
11599            }
11600            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11601            if (stickies == null) {
11602                stickies = new HashMap<String, ArrayList<Intent>>();
11603                mStickyBroadcasts.put(userId, stickies);
11604            }
11605            ArrayList<Intent> list = stickies.get(intent.getAction());
11606            if (list == null) {
11607                list = new ArrayList<Intent>();
11608                stickies.put(intent.getAction(), list);
11609            }
11610            int N = list.size();
11611            int i;
11612            for (i=0; i<N; i++) {
11613                if (intent.filterEquals(list.get(i))) {
11614                    // This sticky already exists, replace it.
11615                    list.set(i, new Intent(intent));
11616                    break;
11617                }
11618            }
11619            if (i >= N) {
11620                list.add(new Intent(intent));
11621            }
11622        }
11623
11624        int[] users;
11625        if (userId == UserHandle.USER_ALL) {
11626            // Caller wants broadcast to go to all started users.
11627            users = new int[mStartedUsers.size()];
11628            for (int i=0; i<mStartedUsers.size(); i++) {
11629                users[i] = mStartedUsers.keyAt(i);
11630            }
11631        } else {
11632            // Caller wants broadcast to go to one specific user.
11633            users = new int[] {userId};
11634        }
11635
11636        // Figure out who all will receive this broadcast.
11637        List receivers = null;
11638        List<BroadcastFilter> registeredReceivers = null;
11639        // Need to resolve the intent to interested receivers...
11640        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11641                 == 0) {
11642            receivers = collectReceiverComponents(intent, resolvedType, users);
11643        }
11644        if (intent.getComponent() == null) {
11645            registeredReceivers = mReceiverResolver.queryIntent(intent,
11646                    resolvedType, false, userId);
11647        }
11648
11649        final boolean replacePending =
11650                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11651
11652        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11653                + " replacePending=" + replacePending);
11654
11655        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11656        if (!ordered && NR > 0) {
11657            // If we are not serializing this broadcast, then send the
11658            // registered receivers separately so they don't wait for the
11659            // components to be launched.
11660            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11661            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11662                    callerPackage, callingPid, callingUid, requiredPermission,
11663                    registeredReceivers, resultTo, resultCode, resultData, map,
11664                    ordered, sticky, false, userId);
11665            if (DEBUG_BROADCAST) Slog.v(
11666                    TAG, "Enqueueing parallel broadcast " + r);
11667            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11668            if (!replaced) {
11669                queue.enqueueParallelBroadcastLocked(r);
11670                queue.scheduleBroadcastsLocked();
11671            }
11672            registeredReceivers = null;
11673            NR = 0;
11674        }
11675
11676        // Merge into one list.
11677        int ir = 0;
11678        if (receivers != null) {
11679            // A special case for PACKAGE_ADDED: do not allow the package
11680            // being added to see this broadcast.  This prevents them from
11681            // using this as a back door to get run as soon as they are
11682            // installed.  Maybe in the future we want to have a special install
11683            // broadcast or such for apps, but we'd like to deliberately make
11684            // this decision.
11685            String skipPackages[] = null;
11686            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11687                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11688                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11689                Uri data = intent.getData();
11690                if (data != null) {
11691                    String pkgName = data.getSchemeSpecificPart();
11692                    if (pkgName != null) {
11693                        skipPackages = new String[] { pkgName };
11694                    }
11695                }
11696            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11697                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11698            }
11699            if (skipPackages != null && (skipPackages.length > 0)) {
11700                for (String skipPackage : skipPackages) {
11701                    if (skipPackage != null) {
11702                        int NT = receivers.size();
11703                        for (int it=0; it<NT; it++) {
11704                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11705                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11706                                receivers.remove(it);
11707                                it--;
11708                                NT--;
11709                            }
11710                        }
11711                    }
11712                }
11713            }
11714
11715            int NT = receivers != null ? receivers.size() : 0;
11716            int it = 0;
11717            ResolveInfo curt = null;
11718            BroadcastFilter curr = null;
11719            while (it < NT && ir < NR) {
11720                if (curt == null) {
11721                    curt = (ResolveInfo)receivers.get(it);
11722                }
11723                if (curr == null) {
11724                    curr = registeredReceivers.get(ir);
11725                }
11726                if (curr.getPriority() >= curt.priority) {
11727                    // Insert this broadcast record into the final list.
11728                    receivers.add(it, curr);
11729                    ir++;
11730                    curr = null;
11731                    it++;
11732                    NT++;
11733                } else {
11734                    // Skip to the next ResolveInfo in the final list.
11735                    it++;
11736                    curt = null;
11737                }
11738            }
11739        }
11740        while (ir < NR) {
11741            if (receivers == null) {
11742                receivers = new ArrayList();
11743            }
11744            receivers.add(registeredReceivers.get(ir));
11745            ir++;
11746        }
11747
11748        if ((receivers != null && receivers.size() > 0)
11749                || resultTo != null) {
11750            BroadcastQueue queue = broadcastQueueForIntent(intent);
11751            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11752                    callerPackage, callingPid, callingUid, requiredPermission,
11753                    receivers, resultTo, resultCode, resultData, map, ordered,
11754                    sticky, false, userId);
11755            if (DEBUG_BROADCAST) Slog.v(
11756                    TAG, "Enqueueing ordered broadcast " + r
11757                    + ": prev had " + queue.mOrderedBroadcasts.size());
11758            if (DEBUG_BROADCAST) {
11759                int seq = r.intent.getIntExtra("seq", -1);
11760                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11761            }
11762            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11763            if (!replaced) {
11764                queue.enqueueOrderedBroadcastLocked(r);
11765                queue.scheduleBroadcastsLocked();
11766            }
11767        }
11768
11769        return ActivityManager.BROADCAST_SUCCESS;
11770    }
11771
11772    final Intent verifyBroadcastLocked(Intent intent) {
11773        // Refuse possible leaked file descriptors
11774        if (intent != null && intent.hasFileDescriptors() == true) {
11775            throw new IllegalArgumentException("File descriptors passed in Intent");
11776        }
11777
11778        int flags = intent.getFlags();
11779
11780        if (!mProcessesReady) {
11781            // if the caller really truly claims to know what they're doing, go
11782            // ahead and allow the broadcast without launching any receivers
11783            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11784                intent = new Intent(intent);
11785                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11786            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11787                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11788                        + " before boot completion");
11789                throw new IllegalStateException("Cannot broadcast before boot completed");
11790            }
11791        }
11792
11793        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11794            throw new IllegalArgumentException(
11795                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11796        }
11797
11798        return intent;
11799    }
11800
11801    public final int broadcastIntent(IApplicationThread caller,
11802            Intent intent, String resolvedType, IIntentReceiver resultTo,
11803            int resultCode, String resultData, Bundle map,
11804            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11805        enforceNotIsolatedCaller("broadcastIntent");
11806        synchronized(this) {
11807            intent = verifyBroadcastLocked(intent);
11808
11809            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11810            final int callingPid = Binder.getCallingPid();
11811            final int callingUid = Binder.getCallingUid();
11812            final long origId = Binder.clearCallingIdentity();
11813            int res = broadcastIntentLocked(callerApp,
11814                    callerApp != null ? callerApp.info.packageName : null,
11815                    intent, resolvedType, resultTo,
11816                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11817                    callingPid, callingUid, userId);
11818            Binder.restoreCallingIdentity(origId);
11819            return res;
11820        }
11821    }
11822
11823    int broadcastIntentInPackage(String packageName, int uid,
11824            Intent intent, String resolvedType, IIntentReceiver resultTo,
11825            int resultCode, String resultData, Bundle map,
11826            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11827        synchronized(this) {
11828            intent = verifyBroadcastLocked(intent);
11829
11830            final long origId = Binder.clearCallingIdentity();
11831            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11832                    resultTo, resultCode, resultData, map, requiredPermission,
11833                    serialized, sticky, -1, uid, userId);
11834            Binder.restoreCallingIdentity(origId);
11835            return res;
11836        }
11837    }
11838
11839    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11840        // Refuse possible leaked file descriptors
11841        if (intent != null && intent.hasFileDescriptors() == true) {
11842            throw new IllegalArgumentException("File descriptors passed in Intent");
11843        }
11844
11845        userId = handleIncomingUserLocked(Binder.getCallingPid(),
11846                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
11847
11848        synchronized(this) {
11849            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11850                    != PackageManager.PERMISSION_GRANTED) {
11851                String msg = "Permission Denial: unbroadcastIntent() from pid="
11852                        + Binder.getCallingPid()
11853                        + ", uid=" + Binder.getCallingUid()
11854                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11855                Slog.w(TAG, msg);
11856                throw new SecurityException(msg);
11857            }
11858            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11859            if (stickies != null) {
11860                ArrayList<Intent> list = stickies.get(intent.getAction());
11861                if (list != null) {
11862                    int N = list.size();
11863                    int i;
11864                    for (i=0; i<N; i++) {
11865                        if (intent.filterEquals(list.get(i))) {
11866                            list.remove(i);
11867                            break;
11868                        }
11869                    }
11870                    if (list.size() <= 0) {
11871                        stickies.remove(intent.getAction());
11872                    }
11873                }
11874                if (stickies.size() <= 0) {
11875                    mStickyBroadcasts.remove(userId);
11876                }
11877            }
11878        }
11879    }
11880
11881    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11882            String resultData, Bundle resultExtras, boolean resultAbort,
11883            boolean explicit) {
11884        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11885        if (r == null) {
11886            Slog.w(TAG, "finishReceiver called but not found on queue");
11887            return false;
11888        }
11889
11890        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11891                explicit);
11892    }
11893
11894    public void finishReceiver(IBinder who, int resultCode, String resultData,
11895            Bundle resultExtras, boolean resultAbort) {
11896        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11897
11898        // Refuse possible leaked file descriptors
11899        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11900            throw new IllegalArgumentException("File descriptors passed in Bundle");
11901        }
11902
11903        final long origId = Binder.clearCallingIdentity();
11904        try {
11905            boolean doNext = false;
11906            BroadcastRecord r = null;
11907
11908            synchronized(this) {
11909                r = broadcastRecordForReceiverLocked(who);
11910                if (r != null) {
11911                    doNext = r.queue.finishReceiverLocked(r, resultCode,
11912                        resultData, resultExtras, resultAbort, true);
11913                }
11914            }
11915
11916            if (doNext) {
11917                r.queue.processNextBroadcast(false);
11918            }
11919            trimApplications();
11920        } finally {
11921            Binder.restoreCallingIdentity(origId);
11922        }
11923    }
11924
11925    // =========================================================
11926    // INSTRUMENTATION
11927    // =========================================================
11928
11929    public boolean startInstrumentation(ComponentName className,
11930            String profileFile, int flags, Bundle arguments,
11931            IInstrumentationWatcher watcher, int userId) {
11932        enforceNotIsolatedCaller("startInstrumentation");
11933        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
11934                userId, false, true, "startInstrumentation", null);
11935        // Refuse possible leaked file descriptors
11936        if (arguments != null && arguments.hasFileDescriptors()) {
11937            throw new IllegalArgumentException("File descriptors passed in Bundle");
11938        }
11939
11940        synchronized(this) {
11941            InstrumentationInfo ii = null;
11942            ApplicationInfo ai = null;
11943            try {
11944                ii = mContext.getPackageManager().getInstrumentationInfo(
11945                    className, STOCK_PM_FLAGS);
11946                ai = AppGlobals.getPackageManager().getApplicationInfo(
11947                        ii.targetPackage, STOCK_PM_FLAGS, userId);
11948            } catch (PackageManager.NameNotFoundException e) {
11949            } catch (RemoteException e) {
11950            }
11951            if (ii == null) {
11952                reportStartInstrumentationFailure(watcher, className,
11953                        "Unable to find instrumentation info for: " + className);
11954                return false;
11955            }
11956            if (ai == null) {
11957                reportStartInstrumentationFailure(watcher, className,
11958                        "Unable to find instrumentation target package: " + ii.targetPackage);
11959                return false;
11960            }
11961
11962            int match = mContext.getPackageManager().checkSignatures(
11963                    ii.targetPackage, ii.packageName);
11964            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11965                String msg = "Permission Denial: starting instrumentation "
11966                        + className + " from pid="
11967                        + Binder.getCallingPid()
11968                        + ", uid=" + Binder.getCallingPid()
11969                        + " not allowed because package " + ii.packageName
11970                        + " does not have a signature matching the target "
11971                        + ii.targetPackage;
11972                reportStartInstrumentationFailure(watcher, className, msg);
11973                throw new SecurityException(msg);
11974            }
11975
11976            final long origId = Binder.clearCallingIdentity();
11977            // Instrumentation can kill and relaunch even persistent processes
11978            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
11979            ProcessRecord app = addAppLocked(ai, false);
11980            app.instrumentationClass = className;
11981            app.instrumentationInfo = ai;
11982            app.instrumentationProfileFile = profileFile;
11983            app.instrumentationArguments = arguments;
11984            app.instrumentationWatcher = watcher;
11985            app.instrumentationResultClass = className;
11986            Binder.restoreCallingIdentity(origId);
11987        }
11988
11989        return true;
11990    }
11991
11992    /**
11993     * Report errors that occur while attempting to start Instrumentation.  Always writes the
11994     * error to the logs, but if somebody is watching, send the report there too.  This enables
11995     * the "am" command to report errors with more information.
11996     *
11997     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
11998     * @param cn The component name of the instrumentation.
11999     * @param report The error report.
12000     */
12001    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12002            ComponentName cn, String report) {
12003        Slog.w(TAG, report);
12004        try {
12005            if (watcher != null) {
12006                Bundle results = new Bundle();
12007                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12008                results.putString("Error", report);
12009                watcher.instrumentationStatus(cn, -1, results);
12010            }
12011        } catch (RemoteException e) {
12012            Slog.w(TAG, e);
12013        }
12014    }
12015
12016    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12017        if (app.instrumentationWatcher != null) {
12018            try {
12019                // NOTE:  IInstrumentationWatcher *must* be oneway here
12020                app.instrumentationWatcher.instrumentationFinished(
12021                    app.instrumentationClass,
12022                    resultCode,
12023                    results);
12024            } catch (RemoteException e) {
12025            }
12026        }
12027        app.instrumentationWatcher = null;
12028        app.instrumentationClass = null;
12029        app.instrumentationInfo = null;
12030        app.instrumentationProfileFile = null;
12031        app.instrumentationArguments = null;
12032
12033        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
12034    }
12035
12036    public void finishInstrumentation(IApplicationThread target,
12037            int resultCode, Bundle results) {
12038        int userId = UserHandle.getCallingUserId();
12039        // Refuse possible leaked file descriptors
12040        if (results != null && results.hasFileDescriptors()) {
12041            throw new IllegalArgumentException("File descriptors passed in Intent");
12042        }
12043
12044        synchronized(this) {
12045            ProcessRecord app = getRecordForAppLocked(target);
12046            if (app == null) {
12047                Slog.w(TAG, "finishInstrumentation: no app for " + target);
12048                return;
12049            }
12050            final long origId = Binder.clearCallingIdentity();
12051            finishInstrumentationLocked(app, resultCode, results);
12052            Binder.restoreCallingIdentity(origId);
12053        }
12054    }
12055
12056    // =========================================================
12057    // CONFIGURATION
12058    // =========================================================
12059
12060    public ConfigurationInfo getDeviceConfigurationInfo() {
12061        ConfigurationInfo config = new ConfigurationInfo();
12062        synchronized (this) {
12063            config.reqTouchScreen = mConfiguration.touchscreen;
12064            config.reqKeyboardType = mConfiguration.keyboard;
12065            config.reqNavigation = mConfiguration.navigation;
12066            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12067                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
12068                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12069            }
12070            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12071                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
12072                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12073            }
12074            config.reqGlEsVersion = GL_ES_VERSION;
12075        }
12076        return config;
12077    }
12078
12079    public Configuration getConfiguration() {
12080        Configuration ci;
12081        synchronized(this) {
12082            ci = new Configuration(mConfiguration);
12083        }
12084        return ci;
12085    }
12086
12087    public void updatePersistentConfiguration(Configuration values) {
12088        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12089                "updateConfiguration()");
12090        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12091                "updateConfiguration()");
12092        if (values == null) {
12093            throw new NullPointerException("Configuration must not be null");
12094        }
12095
12096        synchronized(this) {
12097            final long origId = Binder.clearCallingIdentity();
12098            updateConfigurationLocked(values, null, true, false);
12099            Binder.restoreCallingIdentity(origId);
12100        }
12101    }
12102
12103    public void updateConfiguration(Configuration values) {
12104        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12105                "updateConfiguration()");
12106
12107        synchronized(this) {
12108            if (values == null && mWindowManager != null) {
12109                // sentinel: fetch the current configuration from the window manager
12110                values = mWindowManager.computeNewConfiguration();
12111            }
12112
12113            if (mWindowManager != null) {
12114                mProcessList.applyDisplaySize(mWindowManager);
12115            }
12116
12117            final long origId = Binder.clearCallingIdentity();
12118            if (values != null) {
12119                Settings.System.clearConfiguration(values);
12120            }
12121            updateConfigurationLocked(values, null, false, false);
12122            Binder.restoreCallingIdentity(origId);
12123        }
12124    }
12125
12126    /**
12127     * Do either or both things: (1) change the current configuration, and (2)
12128     * make sure the given activity is running with the (now) current
12129     * configuration.  Returns true if the activity has been left running, or
12130     * false if <var>starting</var> is being destroyed to match the new
12131     * configuration.
12132     * @param persistent TODO
12133     */
12134    boolean updateConfigurationLocked(Configuration values,
12135            ActivityRecord starting, boolean persistent, boolean initLocale) {
12136        // do nothing if we are headless
12137        if (mHeadless) return true;
12138
12139        int changes = 0;
12140
12141        boolean kept = true;
12142
12143        if (values != null) {
12144            Configuration newConfig = new Configuration(mConfiguration);
12145            changes = newConfig.updateFrom(values);
12146            if (changes != 0) {
12147                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12148                    Slog.i(TAG, "Updating configuration to: " + values);
12149                }
12150
12151                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
12152
12153                if (values.locale != null && !initLocale) {
12154                    saveLocaleLocked(values.locale,
12155                                     !values.locale.equals(mConfiguration.locale),
12156                                     values.userSetLocale);
12157                }
12158
12159                mConfigurationSeq++;
12160                if (mConfigurationSeq <= 0) {
12161                    mConfigurationSeq = 1;
12162                }
12163                newConfig.seq = mConfigurationSeq;
12164                mConfiguration = newConfig;
12165                Slog.i(TAG, "Config changed: " + newConfig);
12166
12167                final Configuration configCopy = new Configuration(mConfiguration);
12168
12169                // TODO: If our config changes, should we auto dismiss any currently
12170                // showing dialogs?
12171                mShowDialogs = shouldShowDialogs(newConfig);
12172
12173                AttributeCache ac = AttributeCache.instance();
12174                if (ac != null) {
12175                    ac.updateConfiguration(configCopy);
12176                }
12177
12178                // Make sure all resources in our process are updated
12179                // right now, so that anyone who is going to retrieve
12180                // resource values after we return will be sure to get
12181                // the new ones.  This is especially important during
12182                // boot, where the first config change needs to guarantee
12183                // all resources have that config before following boot
12184                // code is executed.
12185                mSystemThread.applyConfigurationToResources(configCopy);
12186
12187                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
12188                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12189                    msg.obj = new Configuration(configCopy);
12190                    mHandler.sendMessage(msg);
12191                }
12192
12193                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12194                    ProcessRecord app = mLruProcesses.get(i);
12195                    try {
12196                        if (app.thread != null) {
12197                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
12198                                    + app.processName + " new config " + mConfiguration);
12199                            app.thread.scheduleConfigurationChanged(configCopy);
12200                        }
12201                    } catch (Exception e) {
12202                    }
12203                }
12204                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12205                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12206                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
12207                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12208                        null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12209                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12210                    broadcastIntentLocked(null, null,
12211                            new Intent(Intent.ACTION_LOCALE_CHANGED),
12212                            null, null, 0, null, null,
12213                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12214                }
12215            }
12216        }
12217
12218        if (changes != 0 && starting == null) {
12219            // If the configuration changed, and the caller is not already
12220            // in the process of starting an activity, then find the top
12221            // activity to check if its configuration needs to change.
12222            starting = mMainStack.topRunningActivityLocked(null);
12223        }
12224
12225        if (starting != null) {
12226            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
12227            // And we need to make sure at this point that all other activities
12228            // are made visible with the correct configuration.
12229            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
12230        }
12231
12232        if (values != null && mWindowManager != null) {
12233            mWindowManager.setNewConfiguration(mConfiguration);
12234        }
12235
12236        return kept;
12237    }
12238
12239    /**
12240     * Decide based on the configuration whether we should shouw the ANR,
12241     * crash, etc dialogs.  The idea is that if there is no affordnace to
12242     * press the on-screen buttons, we shouldn't show the dialog.
12243     *
12244     * A thought: SystemUI might also want to get told about this, the Power
12245     * dialog / global actions also might want different behaviors.
12246     */
12247    private static final boolean shouldShowDialogs(Configuration config) {
12248        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
12249                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
12250    }
12251
12252    /**
12253     * Save the locale.  You must be inside a synchronized (this) block.
12254     */
12255    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12256        if(isDiff) {
12257            SystemProperties.set("user.language", l.getLanguage());
12258            SystemProperties.set("user.region", l.getCountry());
12259        }
12260
12261        if(isPersist) {
12262            SystemProperties.set("persist.sys.language", l.getLanguage());
12263            SystemProperties.set("persist.sys.country", l.getCountry());
12264            SystemProperties.set("persist.sys.localevar", l.getVariant());
12265        }
12266    }
12267
12268    @Override
12269    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
12270        ActivityRecord srec = ActivityRecord.forToken(token);
12271        return srec != null && srec.task.affinity != null &&
12272                srec.task.affinity.equals(destAffinity);
12273    }
12274
12275    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
12276            Intent resultData) {
12277        ComponentName dest = destIntent.getComponent();
12278
12279        synchronized (this) {
12280            ActivityRecord srec = ActivityRecord.forToken(token);
12281            if (srec == null) {
12282                return false;
12283            }
12284            ArrayList<ActivityRecord> history = srec.stack.mHistory;
12285            final int start = history.indexOf(srec);
12286            if (start < 0) {
12287                // Current activity is not in history stack; do nothing.
12288                return false;
12289            }
12290            int finishTo = start - 1;
12291            ActivityRecord parent = null;
12292            boolean foundParentInTask = false;
12293            if (dest != null) {
12294                TaskRecord tr = srec.task;
12295                for (int i = start - 1; i >= 0; i--) {
12296                    ActivityRecord r = history.get(i);
12297                    if (tr != r.task) {
12298                        // Couldn't find parent in the same task; stop at the one above this.
12299                        // (Root of current task; in-app "home" behavior)
12300                        // Always at least finish the current activity.
12301                        finishTo = Math.min(start - 1, i + 1);
12302                        parent = history.get(finishTo);
12303                        break;
12304                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
12305                            r.info.name.equals(dest.getClassName())) {
12306                        finishTo = i;
12307                        parent = r;
12308                        foundParentInTask = true;
12309                        break;
12310                    }
12311                }
12312            }
12313
12314            if (mController != null) {
12315                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
12316                if (next != null) {
12317                    // ask watcher if this is allowed
12318                    boolean resumeOK = true;
12319                    try {
12320                        resumeOK = mController.activityResuming(next.packageName);
12321                    } catch (RemoteException e) {
12322                        mController = null;
12323                    }
12324
12325                    if (!resumeOK) {
12326                        return false;
12327                    }
12328                }
12329            }
12330            final long origId = Binder.clearCallingIdentity();
12331            for (int i = start; i > finishTo; i--) {
12332                ActivityRecord r = history.get(i);
12333                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
12334                        "navigate-up", true);
12335                // Only return the supplied result for the first activity finished
12336                resultCode = Activity.RESULT_CANCELED;
12337                resultData = null;
12338            }
12339
12340            if (parent != null && foundParentInTask) {
12341                final int parentLaunchMode = parent.info.launchMode;
12342                final int destIntentFlags = destIntent.getFlags();
12343                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
12344                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
12345                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
12346                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
12347                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
12348                } else {
12349                    try {
12350                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
12351                                destIntent.getComponent(), 0, UserHandle.getCallingUserId());
12352                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
12353                                null, aInfo, parent.appToken, null,
12354                                0, -1, parent.launchedFromUid, 0, null, true, null);
12355                        foundParentInTask = res == ActivityManager.START_SUCCESS;
12356                    } catch (RemoteException e) {
12357                        foundParentInTask = false;
12358                    }
12359                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
12360                            resultData, "navigate-up", true);
12361                }
12362            }
12363            Binder.restoreCallingIdentity(origId);
12364            return foundParentInTask;
12365        }
12366    }
12367
12368    public int getLaunchedFromUid(IBinder activityToken) {
12369        ActivityRecord srec = ActivityRecord.forToken(activityToken);
12370        if (srec == null) {
12371            return -1;
12372        }
12373        return srec.launchedFromUid;
12374    }
12375
12376    // =========================================================
12377    // LIFETIME MANAGEMENT
12378    // =========================================================
12379
12380    // Returns which broadcast queue the app is the current [or imminent] receiver
12381    // on, or 'null' if the app is not an active broadcast recipient.
12382    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12383        BroadcastRecord r = app.curReceiver;
12384        if (r != null) {
12385            return r.queue;
12386        }
12387
12388        // It's not the current receiver, but it might be starting up to become one
12389        synchronized (this) {
12390            for (BroadcastQueue queue : mBroadcastQueues) {
12391                r = queue.mPendingBroadcast;
12392                if (r != null && r.curApp == app) {
12393                    // found it; report which queue it's in
12394                    return queue;
12395                }
12396            }
12397        }
12398
12399        return null;
12400    }
12401
12402    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12403            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12404        if (mAdjSeq == app.adjSeq) {
12405            // This adjustment has already been computed.  If we are calling
12406            // from the top, we may have already computed our adjustment with
12407            // an earlier hidden adjustment that isn't really for us... if
12408            // so, use the new hidden adjustment.
12409            if (!recursed && app.hidden) {
12410                app.curAdj = app.curRawAdj = app.nonStoppingAdj =
12411                        app.hasActivities ? hiddenAdj : emptyAdj;
12412            }
12413            return app.curRawAdj;
12414        }
12415
12416        if (app.thread == null) {
12417            app.adjSeq = mAdjSeq;
12418            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12419            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12420        }
12421
12422        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12423        app.adjSource = null;
12424        app.adjTarget = null;
12425        app.empty = false;
12426        app.hidden = false;
12427
12428        final int activitiesSize = app.activities.size();
12429
12430        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12431            // The max adjustment doesn't allow this app to be anything
12432            // below foreground, so it is not worth doing work for it.
12433            app.adjType = "fixed";
12434            app.adjSeq = mAdjSeq;
12435            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12436            app.hasActivities = false;
12437            app.foregroundActivities = false;
12438            app.keeping = true;
12439            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12440            // System process can do UI, and when they do we want to have
12441            // them trim their memory after the user leaves the UI.  To
12442            // facilitate this, here we need to determine whether or not it
12443            // is currently showing UI.
12444            app.systemNoUi = true;
12445            if (app == TOP_APP) {
12446                app.systemNoUi = false;
12447                app.hasActivities = true;
12448            } else if (activitiesSize > 0) {
12449                for (int j = 0; j < activitiesSize; j++) {
12450                    final ActivityRecord r = app.activities.get(j);
12451                    if (r.visible) {
12452                        app.systemNoUi = false;
12453                    }
12454                    if (r.app == app) {
12455                        app.hasActivities = true;
12456                    }
12457                }
12458            }
12459            return (app.curAdj=app.maxAdj);
12460        }
12461
12462        app.keeping = false;
12463        app.systemNoUi = false;
12464        app.hasActivities = false;
12465
12466        // Determine the importance of the process, starting with most
12467        // important to least, and assign an appropriate OOM adjustment.
12468        int adj;
12469        int schedGroup;
12470        boolean foregroundActivities = false;
12471        boolean interesting = false;
12472        BroadcastQueue queue;
12473        if (app == TOP_APP) {
12474            // The last app on the list is the foreground app.
12475            adj = ProcessList.FOREGROUND_APP_ADJ;
12476            schedGroup = Process.THREAD_GROUP_DEFAULT;
12477            app.adjType = "top-activity";
12478            foregroundActivities = true;
12479            interesting = true;
12480            app.hasActivities = true;
12481        } else if (app.instrumentationClass != null) {
12482            // Don't want to kill running instrumentation.
12483            adj = ProcessList.FOREGROUND_APP_ADJ;
12484            schedGroup = Process.THREAD_GROUP_DEFAULT;
12485            app.adjType = "instrumentation";
12486            interesting = true;
12487        } else if ((queue = isReceivingBroadcast(app)) != null) {
12488            // An app that is currently receiving a broadcast also
12489            // counts as being in the foreground for OOM killer purposes.
12490            // It's placed in a sched group based on the nature of the
12491            // broadcast as reflected by which queue it's active in.
12492            adj = ProcessList.FOREGROUND_APP_ADJ;
12493            schedGroup = (queue == mFgBroadcastQueue)
12494                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12495            app.adjType = "broadcast";
12496        } else if (app.executingServices.size() > 0) {
12497            // An app that is currently executing a service callback also
12498            // counts as being in the foreground.
12499            adj = ProcessList.FOREGROUND_APP_ADJ;
12500            schedGroup = Process.THREAD_GROUP_DEFAULT;
12501            app.adjType = "exec-service";
12502        } else {
12503            // Assume process is hidden (has activities); we will correct
12504            // later if this is not the case.
12505            adj = hiddenAdj;
12506            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12507            app.hidden = true;
12508            app.adjType = "bg-activities";
12509        }
12510
12511        boolean hasStoppingActivities = false;
12512
12513        // Examine all activities if not already foreground.
12514        if (!foregroundActivities && activitiesSize > 0) {
12515            for (int j = 0; j < activitiesSize; j++) {
12516                final ActivityRecord r = app.activities.get(j);
12517                if (r.visible) {
12518                    // App has a visible activity; only upgrade adjustment.
12519                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12520                        adj = ProcessList.VISIBLE_APP_ADJ;
12521                        app.adjType = "visible";
12522                    }
12523                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12524                    app.hidden = false;
12525                    app.hasActivities = true;
12526                    foregroundActivities = true;
12527                    break;
12528                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12529                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12530                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12531                        app.adjType = "pausing";
12532                    }
12533                    app.hidden = false;
12534                    foregroundActivities = true;
12535                } else if (r.state == ActivityState.STOPPING) {
12536                    // We will apply the actual adjustment later, because
12537                    // we want to allow this process to immediately go through
12538                    // any memory trimming that is in effect.
12539                    app.hidden = false;
12540                    foregroundActivities = true;
12541                    hasStoppingActivities = true;
12542                }
12543                if (r.app == app) {
12544                    app.hasActivities = true;
12545                }
12546            }
12547        }
12548
12549        if (adj == hiddenAdj && !app.hasActivities) {
12550            // Whoops, this process is completely empty as far as we know
12551            // at this point.
12552            adj = emptyAdj;
12553            app.empty = true;
12554            app.adjType = "bg-empty";
12555        }
12556
12557        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12558            if (app.foregroundServices) {
12559                // The user is aware of this app, so make it visible.
12560                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12561                app.hidden = false;
12562                app.adjType = "foreground-service";
12563                schedGroup = Process.THREAD_GROUP_DEFAULT;
12564            } else if (app.forcingToForeground != null) {
12565                // The user is aware of this app, so make it visible.
12566                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12567                app.hidden = false;
12568                app.adjType = "force-foreground";
12569                app.adjSource = app.forcingToForeground;
12570                schedGroup = Process.THREAD_GROUP_DEFAULT;
12571            }
12572        }
12573
12574        if (app.foregroundServices) {
12575            interesting = true;
12576        }
12577
12578        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12579            // We don't want to kill the current heavy-weight process.
12580            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12581            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12582            app.hidden = false;
12583            app.adjType = "heavy";
12584        }
12585
12586        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12587            // This process is hosting what we currently consider to be the
12588            // home app, so we don't want to let it go into the background.
12589            adj = ProcessList.HOME_APP_ADJ;
12590            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12591            app.hidden = false;
12592            app.adjType = "home";
12593        }
12594
12595        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12596                && app.activities.size() > 0) {
12597            // This was the previous process that showed UI to the user.
12598            // We want to try to keep it around more aggressively, to give
12599            // a good experience around switching between two apps.
12600            adj = ProcessList.PREVIOUS_APP_ADJ;
12601            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12602            app.hidden = false;
12603            app.adjType = "previous";
12604        }
12605
12606        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12607                + " reason=" + app.adjType);
12608
12609        // By default, we use the computed adjustment.  It may be changed if
12610        // there are applications dependent on our services or providers, but
12611        // this gives us a baseline and makes sure we don't get into an
12612        // infinite recursion.
12613        app.adjSeq = mAdjSeq;
12614        app.curRawAdj = app.nonStoppingAdj = adj;
12615
12616        if (mBackupTarget != null && app == mBackupTarget.app) {
12617            // If possible we want to avoid killing apps while they're being backed up
12618            if (adj > ProcessList.BACKUP_APP_ADJ) {
12619                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12620                adj = ProcessList.BACKUP_APP_ADJ;
12621                app.adjType = "backup";
12622                app.hidden = false;
12623            }
12624        }
12625
12626        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12627                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12628            final long now = SystemClock.uptimeMillis();
12629            // This process is more important if the top activity is
12630            // bound to the service.
12631            Iterator<ServiceRecord> jt = app.services.iterator();
12632            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12633                ServiceRecord s = jt.next();
12634                if (s.startRequested) {
12635                    if (app.hasShownUi && app != mHomeProcess) {
12636                        // If this process has shown some UI, let it immediately
12637                        // go to the LRU list because it may be pretty heavy with
12638                        // UI stuff.  We'll tag it with a label just to help
12639                        // debug and understand what is going on.
12640                        if (adj > ProcessList.SERVICE_ADJ) {
12641                            app.adjType = "started-bg-ui-services";
12642                        }
12643                    } else {
12644                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12645                            // This service has seen some activity within
12646                            // recent memory, so we will keep its process ahead
12647                            // of the background processes.
12648                            if (adj > ProcessList.SERVICE_ADJ) {
12649                                adj = ProcessList.SERVICE_ADJ;
12650                                app.adjType = "started-services";
12651                                app.hidden = false;
12652                            }
12653                        }
12654                        // If we have let the service slide into the background
12655                        // state, still have some text describing what it is doing
12656                        // even though the service no longer has an impact.
12657                        if (adj > ProcessList.SERVICE_ADJ) {
12658                            app.adjType = "started-bg-services";
12659                        }
12660                    }
12661                    // Don't kill this process because it is doing work; it
12662                    // has said it is doing work.
12663                    app.keeping = true;
12664                }
12665                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12666                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12667                    Iterator<ArrayList<ConnectionRecord>> kt
12668                            = s.connections.values().iterator();
12669                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12670                        ArrayList<ConnectionRecord> clist = kt.next();
12671                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12672                            // XXX should compute this based on the max of
12673                            // all connected clients.
12674                            ConnectionRecord cr = clist.get(i);
12675                            if (cr.binding.client == app) {
12676                                // Binding to ourself is not interesting.
12677                                continue;
12678                            }
12679                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12680                                ProcessRecord client = cr.binding.client;
12681                                int clientAdj = adj;
12682                                int myHiddenAdj = hiddenAdj;
12683                                if (myHiddenAdj > client.hiddenAdj) {
12684                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12685                                        myHiddenAdj = client.hiddenAdj;
12686                                    } else {
12687                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12688                                    }
12689                                }
12690                                int myEmptyAdj = emptyAdj;
12691                                if (myEmptyAdj > client.emptyAdj) {
12692                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12693                                        myEmptyAdj = client.emptyAdj;
12694                                    } else {
12695                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12696                                    }
12697                                }
12698                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12699                                        myEmptyAdj, TOP_APP, true, doingAll);
12700                                String adjType = null;
12701                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12702                                    // Not doing bind OOM management, so treat
12703                                    // this guy more like a started service.
12704                                    if (app.hasShownUi && app != mHomeProcess) {
12705                                        // If this process has shown some UI, let it immediately
12706                                        // go to the LRU list because it may be pretty heavy with
12707                                        // UI stuff.  We'll tag it with a label just to help
12708                                        // debug and understand what is going on.
12709                                        if (adj > clientAdj) {
12710                                            adjType = "bound-bg-ui-services";
12711                                        }
12712                                        app.hidden = false;
12713                                        clientAdj = adj;
12714                                    } else {
12715                                        if (now >= (s.lastActivity
12716                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12717                                            // This service has not seen activity within
12718                                            // recent memory, so allow it to drop to the
12719                                            // LRU list if there is no other reason to keep
12720                                            // it around.  We'll also tag it with a label just
12721                                            // to help debug and undertand what is going on.
12722                                            if (adj > clientAdj) {
12723                                                adjType = "bound-bg-services";
12724                                            }
12725                                            clientAdj = adj;
12726                                        }
12727                                    }
12728                                }
12729                                if (adj > clientAdj) {
12730                                    // If this process has recently shown UI, and
12731                                    // the process that is binding to it is less
12732                                    // important than being visible, then we don't
12733                                    // care about the binding as much as we care
12734                                    // about letting this process get into the LRU
12735                                    // list to be killed and restarted if needed for
12736                                    // memory.
12737                                    if (app.hasShownUi && app != mHomeProcess
12738                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12739                                        adjType = "bound-bg-ui-services";
12740                                    } else {
12741                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12742                                                |Context.BIND_IMPORTANT)) != 0) {
12743                                            adj = clientAdj;
12744                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12745                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12746                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12747                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12748                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12749                                            adj = clientAdj;
12750                                        } else {
12751                                            app.pendingUiClean = true;
12752                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12753                                                adj = ProcessList.VISIBLE_APP_ADJ;
12754                                            }
12755                                        }
12756                                        if (!client.hidden) {
12757                                            app.hidden = false;
12758                                        }
12759                                        if (client.keeping) {
12760                                            app.keeping = true;
12761                                        }
12762                                        adjType = "service";
12763                                    }
12764                                }
12765                                if (adjType != null) {
12766                                    app.adjType = adjType;
12767                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12768                                            .REASON_SERVICE_IN_USE;
12769                                    app.adjSource = cr.binding.client;
12770                                    app.adjSourceOom = clientAdj;
12771                                    app.adjTarget = s.name;
12772                                }
12773                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12774                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12775                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12776                                    }
12777                                }
12778                            }
12779                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12780                                ActivityRecord a = cr.activity;
12781                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12782                                        (a.visible || a.state == ActivityState.RESUMED
12783                                         || a.state == ActivityState.PAUSING)) {
12784                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12785                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12786                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12787                                    }
12788                                    app.hidden = false;
12789                                    app.adjType = "service";
12790                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12791                                            .REASON_SERVICE_IN_USE;
12792                                    app.adjSource = a;
12793                                    app.adjSourceOom = adj;
12794                                    app.adjTarget = s.name;
12795                                }
12796                            }
12797                        }
12798                    }
12799                }
12800            }
12801
12802            // Finally, if this process has active services running in it, we
12803            // would like to avoid killing it unless it would prevent the current
12804            // application from running.  By default we put the process in
12805            // with the rest of the background processes; as we scan through
12806            // its services we may bump it up from there.
12807            if (adj > hiddenAdj) {
12808                adj = hiddenAdj;
12809                app.hidden = false;
12810                app.adjType = "bg-services";
12811            }
12812        }
12813
12814        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12815                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12816            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12817            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12818                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12819                ContentProviderRecord cpr = jt.next();
12820                for (int i = cpr.connections.size()-1;
12821                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12822                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12823                        i--) {
12824                    ContentProviderConnection conn = cpr.connections.get(i);
12825                    ProcessRecord client = conn.client;
12826                    if (client == app) {
12827                        // Being our own client is not interesting.
12828                        continue;
12829                    }
12830                    int myHiddenAdj = hiddenAdj;
12831                    if (myHiddenAdj > client.hiddenAdj) {
12832                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12833                            myHiddenAdj = client.hiddenAdj;
12834                        } else {
12835                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12836                        }
12837                    }
12838                    int myEmptyAdj = emptyAdj;
12839                    if (myEmptyAdj > client.emptyAdj) {
12840                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
12841                            myEmptyAdj = client.emptyAdj;
12842                        } else {
12843                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
12844                        }
12845                    }
12846                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12847                            myEmptyAdj, TOP_APP, true, doingAll);
12848                    if (adj > clientAdj) {
12849                        if (app.hasShownUi && app != mHomeProcess
12850                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12851                            app.adjType = "bg-ui-provider";
12852                        } else {
12853                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12854                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12855                            app.adjType = "provider";
12856                        }
12857                        if (!client.hidden) {
12858                            app.hidden = false;
12859                        }
12860                        if (client.keeping) {
12861                            app.keeping = true;
12862                        }
12863                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12864                                .REASON_PROVIDER_IN_USE;
12865                        app.adjSource = client;
12866                        app.adjSourceOom = clientAdj;
12867                        app.adjTarget = cpr.name;
12868                    }
12869                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12870                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12871                    }
12872                }
12873                // If the provider has external (non-framework) process
12874                // dependencies, ensure that its adjustment is at least
12875                // FOREGROUND_APP_ADJ.
12876                if (cpr.hasExternalProcessHandles()) {
12877                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12878                        adj = ProcessList.FOREGROUND_APP_ADJ;
12879                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12880                        app.hidden = false;
12881                        app.keeping = true;
12882                        app.adjType = "provider";
12883                        app.adjTarget = cpr.name;
12884                    }
12885                }
12886            }
12887        }
12888
12889        if (adj == ProcessList.SERVICE_ADJ) {
12890            if (doingAll) {
12891                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
12892                mNewNumServiceProcs++;
12893            }
12894            if (app.serviceb) {
12895                adj = ProcessList.SERVICE_B_ADJ;
12896            }
12897        } else {
12898            app.serviceb = false;
12899        }
12900
12901        app.nonStoppingAdj = adj;
12902
12903        if (hasStoppingActivities) {
12904            // Only upgrade adjustment.
12905            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12906                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12907                app.adjType = "stopping";
12908            }
12909        }
12910
12911        app.curRawAdj = adj;
12912
12913        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
12914        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12915        if (adj > app.maxAdj) {
12916            adj = app.maxAdj;
12917            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12918                schedGroup = Process.THREAD_GROUP_DEFAULT;
12919            }
12920        }
12921        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12922            app.keeping = true;
12923        }
12924
12925        if (app.hasAboveClient) {
12926            // If this process has bound to any services with BIND_ABOVE_CLIENT,
12927            // then we need to drop its adjustment to be lower than the service's
12928            // in order to honor the request.  We want to drop it by one adjustment
12929            // level...  but there is special meaning applied to various levels so
12930            // we will skip some of them.
12931            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
12932                // System process will not get dropped, ever
12933            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
12934                adj = ProcessList.VISIBLE_APP_ADJ;
12935            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
12936                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12937            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12938                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
12939            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
12940                adj++;
12941            }
12942        }
12943
12944        int importance = app.memImportance;
12945        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
12946            app.curAdj = adj;
12947            app.curSchedGroup = schedGroup;
12948            if (!interesting) {
12949                // For this reporting, if there is not something explicitly
12950                // interesting in this process then we will push it to the
12951                // background importance.
12952                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12953            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
12954                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12955            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
12956                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12957            } else if (adj >= ProcessList.HOME_APP_ADJ) {
12958                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12959            } else if (adj >= ProcessList.SERVICE_ADJ) {
12960                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12961            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
12962                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
12963            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
12964                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
12965            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
12966                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
12967            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
12968                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
12969            } else {
12970                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
12971            }
12972        }
12973
12974        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
12975        if (foregroundActivities != app.foregroundActivities) {
12976            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
12977        }
12978        if (changes != 0) {
12979            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
12980            app.memImportance = importance;
12981            app.foregroundActivities = foregroundActivities;
12982            int i = mPendingProcessChanges.size()-1;
12983            ProcessChangeItem item = null;
12984            while (i >= 0) {
12985                item = mPendingProcessChanges.get(i);
12986                if (item.pid == app.pid) {
12987                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
12988                    break;
12989                }
12990                i--;
12991            }
12992            if (i < 0) {
12993                // No existing item in pending changes; need a new one.
12994                final int NA = mAvailProcessChanges.size();
12995                if (NA > 0) {
12996                    item = mAvailProcessChanges.remove(NA-1);
12997                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
12998                } else {
12999                    item = new ProcessChangeItem();
13000                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
13001                }
13002                item.changes = 0;
13003                item.pid = app.pid;
13004                item.uid = app.info.uid;
13005                if (mPendingProcessChanges.size() == 0) {
13006                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
13007                            "*** Enqueueing dispatch processes changed!");
13008                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
13009                }
13010                mPendingProcessChanges.add(item);
13011            }
13012            item.changes |= changes;
13013            item.importance = importance;
13014            item.foregroundActivities = foregroundActivities;
13015            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
13016                    + Integer.toHexString(System.identityHashCode(item))
13017                    + " " + app.toShortString() + ": changes=" + item.changes
13018                    + " importance=" + item.importance
13019                    + " foreground=" + item.foregroundActivities
13020                    + " type=" + app.adjType + " source=" + app.adjSource
13021                    + " target=" + app.adjTarget);
13022        }
13023
13024        return app.curRawAdj;
13025    }
13026
13027    /**
13028     * Ask a given process to GC right now.
13029     */
13030    final void performAppGcLocked(ProcessRecord app) {
13031        try {
13032            app.lastRequestedGc = SystemClock.uptimeMillis();
13033            if (app.thread != null) {
13034                if (app.reportLowMemory) {
13035                    app.reportLowMemory = false;
13036                    app.thread.scheduleLowMemory();
13037                } else {
13038                    app.thread.processInBackground();
13039                }
13040            }
13041        } catch (Exception e) {
13042            // whatever.
13043        }
13044    }
13045
13046    /**
13047     * Returns true if things are idle enough to perform GCs.
13048     */
13049    private final boolean canGcNowLocked() {
13050        boolean processingBroadcasts = false;
13051        for (BroadcastQueue q : mBroadcastQueues) {
13052            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
13053                processingBroadcasts = true;
13054            }
13055        }
13056        return !processingBroadcasts
13057                && (mSleeping || (mMainStack.mResumedActivity != null &&
13058                        mMainStack.mResumedActivity.idle));
13059    }
13060
13061    /**
13062     * Perform GCs on all processes that are waiting for it, but only
13063     * if things are idle.
13064     */
13065    final void performAppGcsLocked() {
13066        final int N = mProcessesToGc.size();
13067        if (N <= 0) {
13068            return;
13069        }
13070        if (canGcNowLocked()) {
13071            while (mProcessesToGc.size() > 0) {
13072                ProcessRecord proc = mProcessesToGc.remove(0);
13073                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
13074                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13075                            <= SystemClock.uptimeMillis()) {
13076                        // To avoid spamming the system, we will GC processes one
13077                        // at a time, waiting a few seconds between each.
13078                        performAppGcLocked(proc);
13079                        scheduleAppGcsLocked();
13080                        return;
13081                    } else {
13082                        // It hasn't been long enough since we last GCed this
13083                        // process...  put it in the list to wait for its time.
13084                        addProcessToGcListLocked(proc);
13085                        break;
13086                    }
13087                }
13088            }
13089
13090            scheduleAppGcsLocked();
13091        }
13092    }
13093
13094    /**
13095     * If all looks good, perform GCs on all processes waiting for them.
13096     */
13097    final void performAppGcsIfAppropriateLocked() {
13098        if (canGcNowLocked()) {
13099            performAppGcsLocked();
13100            return;
13101        }
13102        // Still not idle, wait some more.
13103        scheduleAppGcsLocked();
13104    }
13105
13106    /**
13107     * Schedule the execution of all pending app GCs.
13108     */
13109    final void scheduleAppGcsLocked() {
13110        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
13111
13112        if (mProcessesToGc.size() > 0) {
13113            // Schedule a GC for the time to the next process.
13114            ProcessRecord proc = mProcessesToGc.get(0);
13115            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13116
13117            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
13118            long now = SystemClock.uptimeMillis();
13119            if (when < (now+GC_TIMEOUT)) {
13120                when = now + GC_TIMEOUT;
13121            }
13122            mHandler.sendMessageAtTime(msg, when);
13123        }
13124    }
13125
13126    /**
13127     * Add a process to the array of processes waiting to be GCed.  Keeps the
13128     * list in sorted order by the last GC time.  The process can't already be
13129     * on the list.
13130     */
13131    final void addProcessToGcListLocked(ProcessRecord proc) {
13132        boolean added = false;
13133        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13134            if (mProcessesToGc.get(i).lastRequestedGc <
13135                    proc.lastRequestedGc) {
13136                added = true;
13137                mProcessesToGc.add(i+1, proc);
13138                break;
13139            }
13140        }
13141        if (!added) {
13142            mProcessesToGc.add(0, proc);
13143        }
13144    }
13145
13146    /**
13147     * Set up to ask a process to GC itself.  This will either do it
13148     * immediately, or put it on the list of processes to gc the next
13149     * time things are idle.
13150     */
13151    final void scheduleAppGcLocked(ProcessRecord app) {
13152        long now = SystemClock.uptimeMillis();
13153        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13154            return;
13155        }
13156        if (!mProcessesToGc.contains(app)) {
13157            addProcessToGcListLocked(app);
13158            scheduleAppGcsLocked();
13159        }
13160    }
13161
13162    final void checkExcessivePowerUsageLocked(boolean doKills) {
13163        updateCpuStatsNow();
13164
13165        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13166        boolean doWakeKills = doKills;
13167        boolean doCpuKills = doKills;
13168        if (mLastPowerCheckRealtime == 0) {
13169            doWakeKills = false;
13170        }
13171        if (mLastPowerCheckUptime == 0) {
13172            doCpuKills = false;
13173        }
13174        if (stats.isScreenOn()) {
13175            doWakeKills = false;
13176        }
13177        final long curRealtime = SystemClock.elapsedRealtime();
13178        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13179        final long curUptime = SystemClock.uptimeMillis();
13180        final long uptimeSince = curUptime - mLastPowerCheckUptime;
13181        mLastPowerCheckRealtime = curRealtime;
13182        mLastPowerCheckUptime = curUptime;
13183        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13184            doWakeKills = false;
13185        }
13186        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13187            doCpuKills = false;
13188        }
13189        int i = mLruProcesses.size();
13190        while (i > 0) {
13191            i--;
13192            ProcessRecord app = mLruProcesses.get(i);
13193            if (!app.keeping) {
13194                long wtime;
13195                synchronized (stats) {
13196                    wtime = stats.getProcessWakeTime(app.info.uid,
13197                            app.pid, curRealtime);
13198                }
13199                long wtimeUsed = wtime - app.lastWakeTime;
13200                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13201                if (DEBUG_POWER) {
13202                    StringBuilder sb = new StringBuilder(128);
13203                    sb.append("Wake for ");
13204                    app.toShortString(sb);
13205                    sb.append(": over ");
13206                    TimeUtils.formatDuration(realtimeSince, sb);
13207                    sb.append(" used ");
13208                    TimeUtils.formatDuration(wtimeUsed, sb);
13209                    sb.append(" (");
13210                    sb.append((wtimeUsed*100)/realtimeSince);
13211                    sb.append("%)");
13212                    Slog.i(TAG, sb.toString());
13213                    sb.setLength(0);
13214                    sb.append("CPU for ");
13215                    app.toShortString(sb);
13216                    sb.append(": over ");
13217                    TimeUtils.formatDuration(uptimeSince, sb);
13218                    sb.append(" used ");
13219                    TimeUtils.formatDuration(cputimeUsed, sb);
13220                    sb.append(" (");
13221                    sb.append((cputimeUsed*100)/uptimeSince);
13222                    sb.append("%)");
13223                    Slog.i(TAG, sb.toString());
13224                }
13225                // If a process has held a wake lock for more
13226                // than 50% of the time during this period,
13227                // that sounds bad.  Kill!
13228                if (doWakeKills && realtimeSince > 0
13229                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
13230                    synchronized (stats) {
13231                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13232                                realtimeSince, wtimeUsed);
13233                    }
13234                    Slog.w(TAG, "Excessive wake lock in " + app.processName
13235                            + " (pid " + app.pid + "): held " + wtimeUsed
13236                            + " during " + realtimeSince);
13237                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13238                            app.processName, app.setAdj, "excessive wake lock");
13239                    Process.killProcessQuiet(app.pid);
13240                } else if (doCpuKills && uptimeSince > 0
13241                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
13242                    synchronized (stats) {
13243                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13244                                uptimeSince, cputimeUsed);
13245                    }
13246                    Slog.w(TAG, "Excessive CPU in " + app.processName
13247                            + " (pid " + app.pid + "): used " + cputimeUsed
13248                            + " during " + uptimeSince);
13249                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13250                            app.processName, app.setAdj, "excessive cpu");
13251                    Process.killProcessQuiet(app.pid);
13252                } else {
13253                    app.lastWakeTime = wtime;
13254                    app.lastCpuTime = app.curCpuTime;
13255                }
13256            }
13257        }
13258    }
13259
13260    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
13261            int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
13262        app.hiddenAdj = hiddenAdj;
13263        app.emptyAdj = emptyAdj;
13264
13265        if (app.thread == null) {
13266            return false;
13267        }
13268
13269        final boolean wasKeeping = app.keeping;
13270
13271        boolean success = true;
13272
13273        computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll);
13274
13275        if (app.curRawAdj != app.setRawAdj) {
13276            if (wasKeeping && !app.keeping) {
13277                // This app is no longer something we want to keep.  Note
13278                // its current wake lock time to later know to kill it if
13279                // it is not behaving well.
13280                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13281                synchronized (stats) {
13282                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13283                            app.pid, SystemClock.elapsedRealtime());
13284                }
13285                app.lastCpuTime = app.curCpuTime;
13286            }
13287
13288            app.setRawAdj = app.curRawAdj;
13289        }
13290
13291        if (app.curAdj != app.setAdj) {
13292            if (Process.setOomAdj(app.pid, app.curAdj)) {
13293                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13294                    TAG, "Set " + app.pid + " " + app.processName +
13295                    " adj " + app.curAdj + ": " + app.adjType);
13296                app.setAdj = app.curAdj;
13297            } else {
13298                success = false;
13299                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
13300            }
13301        }
13302        if (app.setSchedGroup != app.curSchedGroup) {
13303            app.setSchedGroup = app.curSchedGroup;
13304            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13305                    "Setting process group of " + app.processName
13306                    + " to " + app.curSchedGroup);
13307            if (app.waitingToKill != null &&
13308                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13309                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13310                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13311                        app.processName, app.setAdj, app.waitingToKill);
13312                app.killedBackground = true;
13313                Process.killProcessQuiet(app.pid);
13314                success = false;
13315            } else {
13316                if (true) {
13317                    long oldId = Binder.clearCallingIdentity();
13318                    try {
13319                        Process.setProcessGroup(app.pid, app.curSchedGroup);
13320                    } catch (Exception e) {
13321                        Slog.w(TAG, "Failed setting process group of " + app.pid
13322                                + " to " + app.curSchedGroup);
13323                        e.printStackTrace();
13324                    } finally {
13325                        Binder.restoreCallingIdentity(oldId);
13326                    }
13327                } else {
13328                    if (app.thread != null) {
13329                        try {
13330                            app.thread.setSchedulingGroup(app.curSchedGroup);
13331                        } catch (RemoteException e) {
13332                        }
13333                    }
13334                }
13335            }
13336        }
13337        return success;
13338    }
13339
13340    private final ActivityRecord resumedAppLocked() {
13341        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
13342        if (resumedActivity == null || resumedActivity.app == null) {
13343            resumedActivity = mMainStack.mPausingActivity;
13344            if (resumedActivity == null || resumedActivity.app == null) {
13345                resumedActivity = mMainStack.topRunningActivityLocked(null);
13346            }
13347        }
13348        return resumedActivity;
13349    }
13350
13351    final boolean updateOomAdjLocked(ProcessRecord app) {
13352        final ActivityRecord TOP_ACT = resumedAppLocked();
13353        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13354        int curAdj = app.curAdj;
13355        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13356            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13357
13358        mAdjSeq++;
13359
13360        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj,
13361                TOP_APP, false);
13362        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13363            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13364        if (nowHidden != wasHidden) {
13365            // Changed to/from hidden state, so apps after it in the LRU
13366            // list may also be changed.
13367            updateOomAdjLocked();
13368        }
13369        return success;
13370    }
13371
13372    final void updateOomAdjLocked() {
13373        final ActivityRecord TOP_ACT = resumedAppLocked();
13374        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13375
13376        if (false) {
13377            RuntimeException e = new RuntimeException();
13378            e.fillInStackTrace();
13379            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13380        }
13381
13382        mAdjSeq++;
13383        mNewNumServiceProcs = 0;
13384
13385        // Let's determine how many processes we have running vs.
13386        // how many slots we have for background processes; we may want
13387        // to put multiple processes in a slot of there are enough of
13388        // them.
13389        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13390                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13391        int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots;
13392        if (emptyFactor < 1) emptyFactor = 1;
13393        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13394        if (hiddenFactor < 1) hiddenFactor = 1;
13395        int stepHidden = 0;
13396        int stepEmpty = 0;
13397        final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13398        final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13399        int numHidden = 0;
13400        int numEmpty = 0;
13401        int numTrimming = 0;
13402
13403        mNumNonHiddenProcs = 0;
13404        mNumHiddenProcs = 0;
13405
13406        // First update the OOM adjustment for each of the
13407        // application processes based on their current state.
13408        int i = mLruProcesses.size();
13409        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13410        int nextHiddenAdj = curHiddenAdj+1;
13411        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13412        int nextEmptyAdj = curEmptyAdj+2;
13413        while (i > 0) {
13414            i--;
13415            ProcessRecord app = mLruProcesses.get(i);
13416            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13417            updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true);
13418            if (!app.killedBackground) {
13419                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13420                    // This process was assigned as a hidden process...  step the
13421                    // hidden level.
13422                    mNumHiddenProcs++;
13423                    if (curHiddenAdj != nextHiddenAdj) {
13424                        stepHidden++;
13425                        if (stepHidden >= hiddenFactor) {
13426                            stepHidden = 0;
13427                            curHiddenAdj = nextHiddenAdj;
13428                            nextHiddenAdj += 2;
13429                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13430                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13431                            }
13432                        }
13433                    }
13434                    numHidden++;
13435                    if (numHidden > hiddenProcessLimit) {
13436                        Slog.i(TAG, "No longer want " + app.processName
13437                                + " (pid " + app.pid + "): hidden #" + numHidden);
13438                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13439                                app.processName, app.setAdj, "too many background");
13440                        app.killedBackground = true;
13441                        Process.killProcessQuiet(app.pid);
13442                    }
13443                } else {
13444                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13445                        // This process was assigned as an empty process...  step the
13446                        // empty level.
13447                        if (curEmptyAdj != nextEmptyAdj) {
13448                            stepEmpty++;
13449                            if (stepEmpty >= emptyFactor) {
13450                                stepEmpty = 0;
13451                                curEmptyAdj = nextEmptyAdj;
13452                                nextEmptyAdj += 2;
13453                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13454                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13455                                }
13456                            }
13457                        }
13458                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13459                        mNumNonHiddenProcs++;
13460                    }
13461                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13462                        numEmpty++;
13463                        if (numEmpty > emptyProcessLimit) {
13464                            Slog.i(TAG, "No longer want " + app.processName
13465                                    + " (pid " + app.pid + "): empty #" + numEmpty);
13466                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13467                                    app.processName, app.setAdj, "too many background");
13468                            app.killedBackground = true;
13469                            Process.killProcessQuiet(app.pid);
13470                        }
13471                    }
13472                }
13473                if (app.isolated && app.services.size() <= 0) {
13474                    // If this is an isolated process, and there are no
13475                    // services running in it, then the process is no longer
13476                    // needed.  We agressively kill these because we can by
13477                    // definition not re-use the same process again, and it is
13478                    // good to avoid having whatever code was running in them
13479                    // left sitting around after no longer needed.
13480                    Slog.i(TAG, "Isolated process " + app.processName
13481                            + " (pid " + app.pid + ") no longer needed");
13482                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13483                            app.processName, app.setAdj, "isolated not needed");
13484                    app.killedBackground = true;
13485                    Process.killProcessQuiet(app.pid);
13486                }
13487                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13488                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13489                        && !app.killedBackground) {
13490                    numTrimming++;
13491                }
13492            }
13493        }
13494
13495        mNumServiceProcs = mNewNumServiceProcs;
13496
13497        // Now determine the memory trimming level of background processes.
13498        // Unfortunately we need to start at the back of the list to do this
13499        // properly.  We only do this if the number of background apps we
13500        // are managing to keep around is less than half the maximum we desire;
13501        // if we are keeping a good number around, we'll let them use whatever
13502        // memory they want.
13503        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4)
13504                && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) {
13505            final int numHiddenAndEmpty = numHidden + numEmpty;
13506            final int N = mLruProcesses.size();
13507            int factor = numTrimming/3;
13508            int minFactor = 2;
13509            if (mHomeProcess != null) minFactor++;
13510            if (mPreviousProcess != null) minFactor++;
13511            if (factor < minFactor) factor = minFactor;
13512            int step = 0;
13513            int fgTrimLevel;
13514            if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) {
13515                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13516            } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) {
13517                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13518            } else {
13519                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13520            }
13521            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13522            for (i=0; i<N; i++) {
13523                ProcessRecord app = mLruProcesses.get(i);
13524                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13525                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13526                        && !app.killedBackground) {
13527                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13528                        try {
13529                            app.thread.scheduleTrimMemory(curLevel);
13530                        } catch (RemoteException e) {
13531                        }
13532                        if (false) {
13533                            // For now we won't do this; our memory trimming seems
13534                            // to be good enough at this point that destroying
13535                            // activities causes more harm than good.
13536                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13537                                    && app != mHomeProcess && app != mPreviousProcess) {
13538                                // Need to do this on its own message because the stack may not
13539                                // be in a consistent state at this point.
13540                                // For these apps we will also finish their activities
13541                                // to help them free memory.
13542                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13543                            }
13544                        }
13545                    }
13546                    app.trimMemoryLevel = curLevel;
13547                    step++;
13548                    if (step >= factor) {
13549                        step = 0;
13550                        switch (curLevel) {
13551                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13552                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13553                                break;
13554                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13555                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13556                                break;
13557                        }
13558                    }
13559                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13560                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13561                            && app.thread != null) {
13562                        try {
13563                            app.thread.scheduleTrimMemory(
13564                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13565                        } catch (RemoteException e) {
13566                        }
13567                    }
13568                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13569                } else {
13570                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13571                            && app.pendingUiClean) {
13572                        // If this application is now in the background and it
13573                        // had done UI, then give it the special trim level to
13574                        // have it free UI resources.
13575                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13576                        if (app.trimMemoryLevel < level && app.thread != null) {
13577                            try {
13578                                app.thread.scheduleTrimMemory(level);
13579                            } catch (RemoteException e) {
13580                            }
13581                        }
13582                        app.pendingUiClean = false;
13583                    }
13584                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13585                        try {
13586                            app.thread.scheduleTrimMemory(fgTrimLevel);
13587                        } catch (RemoteException e) {
13588                        }
13589                    }
13590                    app.trimMemoryLevel = fgTrimLevel;
13591                }
13592            }
13593        } else {
13594            final int N = mLruProcesses.size();
13595            for (i=0; i<N; i++) {
13596                ProcessRecord app = mLruProcesses.get(i);
13597                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13598                        && app.pendingUiClean) {
13599                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13600                            && app.thread != null) {
13601                        try {
13602                            app.thread.scheduleTrimMemory(
13603                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13604                        } catch (RemoteException e) {
13605                        }
13606                    }
13607                    app.pendingUiClean = false;
13608                }
13609                app.trimMemoryLevel = 0;
13610            }
13611        }
13612
13613        if (mAlwaysFinishActivities) {
13614            // Need to do this on its own message because the stack may not
13615            // be in a consistent state at this point.
13616            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13617        }
13618    }
13619
13620    final void trimApplications() {
13621        synchronized (this) {
13622            int i;
13623
13624            // First remove any unused application processes whose package
13625            // has been removed.
13626            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13627                final ProcessRecord app = mRemovedProcesses.get(i);
13628                if (app.activities.size() == 0
13629                        && app.curReceiver == null && app.services.size() == 0) {
13630                    Slog.i(
13631                        TAG, "Exiting empty application process "
13632                        + app.processName + " ("
13633                        + (app.thread != null ? app.thread.asBinder() : null)
13634                        + ")\n");
13635                    if (app.pid > 0 && app.pid != MY_PID) {
13636                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13637                                app.processName, app.setAdj, "empty");
13638                        Process.killProcessQuiet(app.pid);
13639                    } else {
13640                        try {
13641                            app.thread.scheduleExit();
13642                        } catch (Exception e) {
13643                            // Ignore exceptions.
13644                        }
13645                    }
13646                    cleanUpApplicationRecordLocked(app, false, true, -1);
13647                    mRemovedProcesses.remove(i);
13648
13649                    if (app.persistent) {
13650                        if (app.persistent) {
13651                            addAppLocked(app.info, false);
13652                        }
13653                    }
13654                }
13655            }
13656
13657            // Now update the oom adj for all processes.
13658            updateOomAdjLocked();
13659        }
13660    }
13661
13662    /** This method sends the specified signal to each of the persistent apps */
13663    public void signalPersistentProcesses(int sig) throws RemoteException {
13664        if (sig != Process.SIGNAL_USR1) {
13665            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13666        }
13667
13668        synchronized (this) {
13669            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13670                    != PackageManager.PERMISSION_GRANTED) {
13671                throw new SecurityException("Requires permission "
13672                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13673            }
13674
13675            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13676                ProcessRecord r = mLruProcesses.get(i);
13677                if (r.thread != null && r.persistent) {
13678                    Process.sendSignal(r.pid, sig);
13679                }
13680            }
13681        }
13682    }
13683
13684    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13685        if (proc == null || proc == mProfileProc) {
13686            proc = mProfileProc;
13687            path = mProfileFile;
13688            profileType = mProfileType;
13689            clearProfilerLocked();
13690        }
13691        if (proc == null) {
13692            return;
13693        }
13694        try {
13695            proc.thread.profilerControl(false, path, null, profileType);
13696        } catch (RemoteException e) {
13697            throw new IllegalStateException("Process disappeared");
13698        }
13699    }
13700
13701    private void clearProfilerLocked() {
13702        if (mProfileFd != null) {
13703            try {
13704                mProfileFd.close();
13705            } catch (IOException e) {
13706            }
13707        }
13708        mProfileApp = null;
13709        mProfileProc = null;
13710        mProfileFile = null;
13711        mProfileType = 0;
13712        mAutoStopProfiler = false;
13713    }
13714
13715    public boolean profileControl(String process, int userId, boolean start,
13716            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13717
13718        try {
13719            synchronized (this) {
13720                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13721                // its own permission.
13722                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13723                        != PackageManager.PERMISSION_GRANTED) {
13724                    throw new SecurityException("Requires permission "
13725                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13726                }
13727
13728                if (start && fd == null) {
13729                    throw new IllegalArgumentException("null fd");
13730                }
13731
13732                ProcessRecord proc = null;
13733                if (process != null) {
13734                    proc = findProcessLocked(process, userId, "profileControl");
13735                }
13736
13737                if (start && (proc == null || proc.thread == null)) {
13738                    throw new IllegalArgumentException("Unknown process: " + process);
13739                }
13740
13741                if (start) {
13742                    stopProfilerLocked(null, null, 0);
13743                    setProfileApp(proc.info, proc.processName, path, fd, false);
13744                    mProfileProc = proc;
13745                    mProfileType = profileType;
13746                    try {
13747                        fd = fd.dup();
13748                    } catch (IOException e) {
13749                        fd = null;
13750                    }
13751                    proc.thread.profilerControl(start, path, fd, profileType);
13752                    fd = null;
13753                    mProfileFd = null;
13754                } else {
13755                    stopProfilerLocked(proc, path, profileType);
13756                    if (fd != null) {
13757                        try {
13758                            fd.close();
13759                        } catch (IOException e) {
13760                        }
13761                    }
13762                }
13763
13764                return true;
13765            }
13766        } catch (RemoteException e) {
13767            throw new IllegalStateException("Process disappeared");
13768        } finally {
13769            if (fd != null) {
13770                try {
13771                    fd.close();
13772                } catch (IOException e) {
13773                }
13774            }
13775        }
13776    }
13777
13778    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
13779        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
13780                userId, true, true, callName, null);
13781        ProcessRecord proc = null;
13782        try {
13783            int pid = Integer.parseInt(process);
13784            synchronized (mPidsSelfLocked) {
13785                proc = mPidsSelfLocked.get(pid);
13786            }
13787        } catch (NumberFormatException e) {
13788        }
13789
13790        if (proc == null) {
13791            HashMap<String, SparseArray<ProcessRecord>> all
13792                    = mProcessNames.getMap();
13793            SparseArray<ProcessRecord> procs = all.get(process);
13794            if (procs != null && procs.size() > 0) {
13795                proc = procs.valueAt(0);
13796                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
13797                    for (int i=1; i<procs.size(); i++) {
13798                        ProcessRecord thisProc = procs.valueAt(i);
13799                        if (thisProc.userId == userId) {
13800                            proc = thisProc;
13801                            break;
13802                        }
13803                    }
13804                }
13805            }
13806        }
13807
13808        return proc;
13809    }
13810
13811    public boolean dumpHeap(String process, int userId, boolean managed,
13812            String path, ParcelFileDescriptor fd) throws RemoteException {
13813
13814        try {
13815            synchronized (this) {
13816                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13817                // its own permission (same as profileControl).
13818                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13819                        != PackageManager.PERMISSION_GRANTED) {
13820                    throw new SecurityException("Requires permission "
13821                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13822                }
13823
13824                if (fd == null) {
13825                    throw new IllegalArgumentException("null fd");
13826                }
13827
13828                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
13829                if (proc == null || proc.thread == null) {
13830                    throw new IllegalArgumentException("Unknown process: " + process);
13831                }
13832
13833                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13834                if (!isDebuggable) {
13835                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13836                        throw new SecurityException("Process not debuggable: " + proc);
13837                    }
13838                }
13839
13840                proc.thread.dumpHeap(managed, path, fd);
13841                fd = null;
13842                return true;
13843            }
13844        } catch (RemoteException e) {
13845            throw new IllegalStateException("Process disappeared");
13846        } finally {
13847            if (fd != null) {
13848                try {
13849                    fd.close();
13850                } catch (IOException e) {
13851                }
13852            }
13853        }
13854    }
13855
13856    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13857    public void monitor() {
13858        synchronized (this) { }
13859    }
13860
13861    void onCoreSettingsChange(Bundle settings) {
13862        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13863            ProcessRecord processRecord = mLruProcesses.get(i);
13864            try {
13865                if (processRecord.thread != null) {
13866                    processRecord.thread.setCoreSettings(settings);
13867                }
13868            } catch (RemoteException re) {
13869                /* ignore */
13870            }
13871        }
13872    }
13873
13874    // Multi-user methods
13875
13876    @Override
13877    public boolean switchUser(int userId) {
13878        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13879                != PackageManager.PERMISSION_GRANTED) {
13880            String msg = "Permission Denial: switchUser() from pid="
13881                    + Binder.getCallingPid()
13882                    + ", uid=" + Binder.getCallingUid()
13883                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13884            Slog.w(TAG, msg);
13885            throw new SecurityException(msg);
13886        }
13887        synchronized (this) {
13888            if (mCurrentUserId == userId) {
13889                return true;
13890            }
13891
13892            mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
13893                    R.anim.screen_user_enter);
13894
13895            // If the user we are switching to is not currently started, then
13896            // we need to start it now.
13897            if (mStartedUsers.get(userId) == null) {
13898                mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
13899            }
13900
13901            mCurrentUserId = userId;
13902            Integer userIdInt = Integer.valueOf(userId);
13903            mUserLru.remove(userIdInt);
13904            mUserLru.add(userIdInt);
13905            boolean haveActivities = mMainStack.switchUser(userId);
13906            if (!haveActivities) {
13907                startHomeActivityLocked(userId, mStartedUsers.get(userId));
13908            } else {
13909                mMainStack.addStartingUserLocked(mStartedUsers.get(userId));
13910            }
13911        }
13912
13913        long ident = Binder.clearCallingIdentity();
13914        try {
13915            // Inform of user switch
13916            Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
13917            addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
13918            mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL,
13919                    android.Manifest.permission.MANAGE_USERS);
13920        } finally {
13921            Binder.restoreCallingIdentity(ident);
13922        }
13923
13924        return true;
13925    }
13926
13927    void finishUserSwitch(UserStartedState uss) {
13928        synchronized (this) {
13929            if (uss.mState == UserStartedState.STATE_BOOTING
13930                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
13931                uss.mState = UserStartedState.STATE_RUNNING;
13932                final int userId = uss.mHandle.getIdentifier();
13933                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
13934                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
13935                broadcastIntentLocked(null, null, intent,
13936                        null, null, 0, null, null,
13937                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
13938                        false, false, MY_PID, Process.SYSTEM_UID, userId);
13939            }
13940            mWindowManager.stopFreezingScreen();
13941        }
13942    }
13943
13944    @Override
13945    public int stopUser(final int userId, final IStopUserCallback callback) {
13946        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13947                != PackageManager.PERMISSION_GRANTED) {
13948            String msg = "Permission Denial: switchUser() from pid="
13949                    + Binder.getCallingPid()
13950                    + ", uid=" + Binder.getCallingUid()
13951                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13952            Slog.w(TAG, msg);
13953            throw new SecurityException(msg);
13954        }
13955        if (userId <= 0) {
13956            throw new IllegalArgumentException("Can't stop primary user " + userId);
13957        }
13958        synchronized (this) {
13959            if (mCurrentUserId == userId) {
13960                return ActivityManager.USER_OP_IS_CURRENT;
13961            }
13962
13963            final UserStartedState uss = mStartedUsers.get(userId);
13964            if (uss == null) {
13965                // User is not started, nothing to do...  but we do need to
13966                // callback if requested.
13967                if (callback != null) {
13968                    mHandler.post(new Runnable() {
13969                        @Override
13970                        public void run() {
13971                            try {
13972                                callback.userStopped(userId);
13973                            } catch (RemoteException e) {
13974                            }
13975                        }
13976                    });
13977                }
13978                return ActivityManager.USER_OP_SUCCESS;
13979            }
13980
13981            if (callback != null) {
13982                uss.mStopCallbacks.add(callback);
13983            }
13984
13985            if (uss.mState != UserStartedState.STATE_STOPPING) {
13986                uss.mState = UserStartedState.STATE_STOPPING;
13987
13988                long ident = Binder.clearCallingIdentity();
13989                try {
13990                    // Inform of user switch
13991                    Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13992                    final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() {
13993                        @Override
13994                        public void performReceive(Intent intent, int resultCode, String data,
13995                                Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
13996                            finishUserStop(uss);
13997                        }
13998                    };
13999                    broadcastIntentLocked(null, null, intent,
14000                            null, resultReceiver, 0, null, null, null,
14001                            true, false, MY_PID, Process.SYSTEM_UID, userId);
14002                } finally {
14003                    Binder.restoreCallingIdentity(ident);
14004                }
14005            }
14006        }
14007
14008        return ActivityManager.USER_OP_SUCCESS;
14009    }
14010
14011    void finishUserStop(UserStartedState uss) {
14012        final int userId = uss.mHandle.getIdentifier();
14013        boolean stopped;
14014        ArrayList<IStopUserCallback> callbacks;
14015        synchronized (this) {
14016            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
14017            if (uss.mState != UserStartedState.STATE_STOPPING
14018                    || mStartedUsers.get(userId) != uss) {
14019                stopped = false;
14020            } else {
14021                stopped = true;
14022                // User can no longer run.
14023                mStartedUsers.remove(userId);
14024
14025                // Clean up all state and processes associated with the user.
14026                // Kill all the processes for the user.
14027                forceStopUserLocked(userId);
14028            }
14029        }
14030
14031        for (int i=0; i<callbacks.size(); i++) {
14032            try {
14033                if (stopped) callbacks.get(i).userStopped(userId);
14034                else callbacks.get(i).userStopAborted(userId);
14035            } catch (RemoteException e) {
14036            }
14037        }
14038    }
14039
14040    @Override
14041    public UserInfo getCurrentUser() {
14042        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14043                != PackageManager.PERMISSION_GRANTED) {
14044            String msg = "Permission Denial: getCurrentUser() from pid="
14045                    + Binder.getCallingPid()
14046                    + ", uid=" + Binder.getCallingUid()
14047                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14048            Slog.w(TAG, msg);
14049            throw new SecurityException(msg);
14050        }
14051        synchronized (this) {
14052            return getUserManagerLocked().getUserInfo(mCurrentUserId);
14053        }
14054    }
14055
14056    @Override
14057    public boolean isUserRunning(int userId) {
14058        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14059                != PackageManager.PERMISSION_GRANTED) {
14060            String msg = "Permission Denial: isUserRunning() from pid="
14061                    + Binder.getCallingPid()
14062                    + ", uid=" + Binder.getCallingUid()
14063                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14064            Slog.w(TAG, msg);
14065            throw new SecurityException(msg);
14066        }
14067        synchronized (this) {
14068            return isUserRunningLocked(userId);
14069        }
14070    }
14071
14072    boolean isUserRunningLocked(int userId) {
14073        UserStartedState state = mStartedUsers.get(userId);
14074        return state != null && state.mState != UserStartedState.STATE_STOPPING;
14075    }
14076
14077    private boolean userExists(int userId) {
14078        if (userId == 0) {
14079            return true;
14080        }
14081        UserManagerService ums = getUserManagerLocked();
14082        return ums != null ? (ums.getUserInfo(userId) != null) : false;
14083    }
14084
14085    int[] getUsersLocked() {
14086        UserManagerService ums = getUserManagerLocked();
14087        return ums != null ? ums.getUserIds() : new int[] { 0 };
14088    }
14089
14090    UserManagerService getUserManagerLocked() {
14091        if (mUserManager == null) {
14092            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
14093            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
14094        }
14095        return mUserManager;
14096    }
14097
14098    private void checkValidCaller(int uid, int userId) {
14099        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
14100
14101        throw new SecurityException("Caller uid=" + uid
14102                + " is not privileged to communicate with user=" + userId);
14103    }
14104
14105    private int applyUserId(int uid, int userId) {
14106        return UserHandle.getUid(userId, uid);
14107    }
14108
14109    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
14110        if (info == null) return null;
14111        ApplicationInfo newInfo = new ApplicationInfo(info);
14112        newInfo.uid = applyUserId(info.uid, userId);
14113        newInfo.dataDir = USER_DATA_DIR + userId + "/"
14114                + info.packageName;
14115        return newInfo;
14116    }
14117
14118    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
14119        if (aInfo == null
14120                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
14121            return aInfo;
14122        }
14123
14124        ActivityInfo info = new ActivityInfo(aInfo);
14125        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
14126        return info;
14127    }
14128}
14129