ActivityManagerService.java revision 36d337adffa6d1c4c953e83730ad58747f554877
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.internal.widget.LockPatternUtils;
25import com.android.server.AttributeCache;
26import com.android.server.IntentResolver;
27import com.android.server.ProcessMap;
28import com.android.server.SystemServer;
29import com.android.server.Watchdog;
30import com.android.server.am.ActivityStack.ActivityState;
31import com.android.server.pm.UserManagerService;
32import com.android.server.wm.WindowManagerService;
33
34import dalvik.system.Zygote;
35
36import android.app.Activity;
37import android.app.ActivityManager;
38import android.app.ActivityManagerNative;
39import android.app.ActivityOptions;
40import android.app.ActivityThread;
41import android.app.AlertDialog;
42import android.app.AppGlobals;
43import android.app.ApplicationErrorReport;
44import android.app.Dialog;
45import android.app.IActivityController;
46import android.app.IApplicationThread;
47import android.app.IInstrumentationWatcher;
48import android.app.INotificationManager;
49import android.app.IProcessObserver;
50import android.app.IServiceConnection;
51import android.app.IStopUserCallback;
52import android.app.IThumbnailReceiver;
53import android.app.IUserSwitchObserver;
54import android.app.Instrumentation;
55import android.app.Notification;
56import android.app.NotificationManager;
57import android.app.PendingIntent;
58import android.app.backup.IBackupManager;
59import android.content.ActivityNotFoundException;
60import android.content.BroadcastReceiver;
61import android.content.ClipData;
62import android.content.ComponentCallbacks2;
63import android.content.ComponentName;
64import android.content.ContentProvider;
65import android.content.ContentResolver;
66import android.content.Context;
67import android.content.DialogInterface;
68import android.content.IContentProvider;
69import android.content.IIntentReceiver;
70import android.content.IIntentSender;
71import android.content.Intent;
72import android.content.IntentFilter;
73import android.content.IntentSender;
74import android.content.pm.ActivityInfo;
75import android.content.pm.ApplicationInfo;
76import android.content.pm.ConfigurationInfo;
77import android.content.pm.IPackageDataObserver;
78import android.content.pm.IPackageManager;
79import android.content.pm.InstrumentationInfo;
80import android.content.pm.PackageInfo;
81import android.content.pm.PackageManager;
82import android.content.pm.UserInfo;
83import android.content.pm.PackageManager.NameNotFoundException;
84import android.content.pm.PathPermission;
85import android.content.pm.ProviderInfo;
86import android.content.pm.ResolveInfo;
87import android.content.pm.ServiceInfo;
88import android.content.res.CompatibilityInfo;
89import android.content.res.Configuration;
90import android.graphics.Bitmap;
91import android.net.Proxy;
92import android.net.ProxyProperties;
93import android.net.Uri;
94import android.os.Binder;
95import android.os.Build;
96import android.os.Bundle;
97import android.os.Debug;
98import android.os.DropBoxManager;
99import android.os.Environment;
100import android.os.FileObserver;
101import android.os.FileUtils;
102import android.os.Handler;
103import android.os.IBinder;
104import android.os.IPermissionController;
105import android.os.IRemoteCallback;
106import android.os.IUserManager;
107import android.os.Looper;
108import android.os.Message;
109import android.os.Parcel;
110import android.os.ParcelFileDescriptor;
111import android.os.Process;
112import android.os.RemoteCallbackList;
113import android.os.RemoteException;
114import android.os.SELinux;
115import android.os.ServiceManager;
116import android.os.StrictMode;
117import android.os.SystemClock;
118import android.os.SystemProperties;
119import android.os.UserHandle;
120import android.provider.Settings;
121import android.text.format.Time;
122import android.util.EventLog;
123import android.util.Log;
124import android.util.Pair;
125import android.util.PrintWriterPrinter;
126import android.util.Slog;
127import android.util.SparseArray;
128import android.util.TimeUtils;
129import android.view.Gravity;
130import android.view.LayoutInflater;
131import android.view.View;
132import android.view.WindowManager;
133import android.view.WindowManagerPolicy;
134
135import java.io.BufferedInputStream;
136import java.io.BufferedOutputStream;
137import java.io.BufferedReader;
138import java.io.DataInputStream;
139import java.io.DataOutputStream;
140import java.io.File;
141import java.io.FileDescriptor;
142import java.io.FileInputStream;
143import java.io.FileNotFoundException;
144import java.io.FileOutputStream;
145import java.io.IOException;
146import java.io.InputStreamReader;
147import java.io.PrintWriter;
148import java.io.StringWriter;
149import java.lang.ref.WeakReference;
150import java.util.ArrayList;
151import java.util.Arrays;
152import java.util.Collections;
153import java.util.Comparator;
154import java.util.HashMap;
155import java.util.HashSet;
156import java.util.Iterator;
157import java.util.List;
158import java.util.Locale;
159import java.util.Map;
160import java.util.Set;
161import java.util.concurrent.atomic.AtomicBoolean;
162import java.util.concurrent.atomic.AtomicLong;
163
164public final class ActivityManagerService extends ActivityManagerNative
165        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
166    private static final String USER_DATA_DIR = "/data/user/";
167    static final String TAG = "ActivityManager";
168    static final String TAG_MU = "ActivityManagerServiceMU";
169    static final boolean DEBUG = false;
170    static final boolean localLOGV = DEBUG;
171    static final boolean DEBUG_SWITCH = localLOGV || false;
172    static final boolean DEBUG_TASKS = localLOGV || false;
173    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
174    static final boolean DEBUG_PAUSE = localLOGV || false;
175    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
176    static final boolean DEBUG_TRANSITION = localLOGV || false;
177    static final boolean DEBUG_BROADCAST = localLOGV || false;
178    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
179    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
180    static final boolean DEBUG_SERVICE = localLOGV || false;
181    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
182    static final boolean DEBUG_VISBILITY = localLOGV || false;
183    static final boolean DEBUG_PROCESSES = localLOGV || false;
184    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
185    static final boolean DEBUG_CLEANUP = localLOGV || false;
186    static final boolean DEBUG_PROVIDER = localLOGV || false;
187    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
188    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
189    static final boolean DEBUG_RESULTS = localLOGV || false;
190    static final boolean DEBUG_BACKUP = localLOGV || false;
191    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
192    static final boolean DEBUG_POWER = localLOGV || false;
193    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
194    static final boolean DEBUG_MU = localLOGV || false;
195    static final boolean VALIDATE_TOKENS = false;
196    static final boolean SHOW_ACTIVITY_START_TIME = true;
197
198    // Control over CPU and battery monitoring.
199    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
200    static final boolean MONITOR_CPU_USAGE = true;
201    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
202    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
203    static final boolean MONITOR_THREAD_CPU_USAGE = false;
204
205    // The flags that are set for all calls we make to the package manager.
206    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
207
208    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
209
210    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
211
212    // Maximum number of recent tasks that we can remember.
213    static final int MAX_RECENT_TASKS = 20;
214
215    // Amount of time after a call to stopAppSwitches() during which we will
216    // prevent further untrusted switches from happening.
217    static final long APP_SWITCH_DELAY_TIME = 5*1000;
218
219    // How long we wait for a launched process to attach to the activity manager
220    // before we decide it's never going to come up for real.
221    static final int PROC_START_TIMEOUT = 10*1000;
222
223    // How long we wait for a launched process to attach to the activity manager
224    // before we decide it's never going to come up for real, when the process was
225    // started with a wrapper for instrumentation (such as Valgrind) because it
226    // could take much longer than usual.
227    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
228
229    // How long to wait after going idle before forcing apps to GC.
230    static final int GC_TIMEOUT = 5*1000;
231
232    // The minimum amount of time between successive GC requests for a process.
233    static final int GC_MIN_INTERVAL = 60*1000;
234
235    // The rate at which we check for apps using excessive power -- 15 mins.
236    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
237
238    // The minimum sample duration we will allow before deciding we have
239    // enough data on wake locks to start killing things.
240    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
241
242    // The minimum sample duration we will allow before deciding we have
243    // enough data on CPU usage to start killing things.
244    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
245
246    // How long we allow a receiver to run before giving up on it.
247    static final int BROADCAST_FG_TIMEOUT = 10*1000;
248    static final int BROADCAST_BG_TIMEOUT = 60*1000;
249
250    // How long we wait until we timeout on key dispatching.
251    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
252
253    // How long we wait until we timeout on key dispatching during instrumentation.
254    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
255
256    // Amount of time we wait for observers to handle a user switch before
257    // giving up on them and unfreezing the screen.
258    static final int USER_SWITCH_TIMEOUT = 2*1000;
259
260    // Maximum number of users we allow to be running at a time.
261    static final int MAX_RUNNING_USERS = 3;
262
263    static final int MY_PID = Process.myPid();
264
265    static final String[] EMPTY_STRING_ARRAY = new String[0];
266
267    public ActivityStack mMainStack;
268
269    private final boolean mHeadless;
270
271    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
272    // default actuion automatically.  Important for devices without direct input
273    // devices.
274    private boolean mShowDialogs = true;
275
276    /**
277     * Description of a request to start a new activity, which has been held
278     * due to app switches being disabled.
279     */
280    static class PendingActivityLaunch {
281        ActivityRecord r;
282        ActivityRecord sourceRecord;
283        int startFlags;
284    }
285
286    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
287            = new ArrayList<PendingActivityLaunch>();
288
289
290    BroadcastQueue mFgBroadcastQueue;
291    BroadcastQueue mBgBroadcastQueue;
292    // Convenient for easy iteration over the queues. Foreground is first
293    // so that dispatch of foreground broadcasts gets precedence.
294    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
295
296    BroadcastQueue broadcastQueueForIntent(Intent intent) {
297        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
298        if (DEBUG_BACKGROUND_BROADCAST) {
299            Slog.i(TAG, "Broadcast intent " + intent + " on "
300                    + (isFg ? "foreground" : "background")
301                    + " queue");
302        }
303        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
304    }
305
306    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
307        for (BroadcastQueue queue : mBroadcastQueues) {
308            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
309            if (r != null) {
310                return r;
311            }
312        }
313        return null;
314    }
315
316    /**
317     * Activity we have told the window manager to have key focus.
318     */
319    ActivityRecord mFocusedActivity = null;
320    /**
321     * List of intents that were used to start the most recent tasks.
322     */
323    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
324
325    /**
326     * Process management.
327     */
328    final ProcessList mProcessList = new ProcessList();
329
330    /**
331     * All of the applications we currently have running organized by name.
332     * The keys are strings of the application package name (as
333     * returned by the package manager), and the keys are ApplicationRecord
334     * objects.
335     */
336    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
337
338    /**
339     * The currently running isolated processes.
340     */
341    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
342
343    /**
344     * Counter for assigning isolated process uids, to avoid frequently reusing the
345     * same ones.
346     */
347    int mNextIsolatedProcessUid = 0;
348
349    /**
350     * The currently running heavy-weight process, if any.
351     */
352    ProcessRecord mHeavyWeightProcess = null;
353
354    /**
355     * The last time that various processes have crashed.
356     */
357    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
358
359    /**
360     * Set of applications that we consider to be bad, and will reject
361     * incoming broadcasts from (which the user has no control over).
362     * Processes are added to this set when they have crashed twice within
363     * a minimum amount of time; they are removed from it when they are
364     * later restarted (hopefully due to some user action).  The value is the
365     * time it was added to the list.
366     */
367    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
368
369    /**
370     * All of the processes we currently have running organized by pid.
371     * The keys are the pid running the application.
372     *
373     * <p>NOTE: This object is protected by its own lock, NOT the global
374     * activity manager lock!
375     */
376    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
377
378    /**
379     * All of the processes that have been forced to be foreground.  The key
380     * is the pid of the caller who requested it (we hold a death
381     * link on it).
382     */
383    abstract class ForegroundToken implements IBinder.DeathRecipient {
384        int pid;
385        IBinder token;
386    }
387    final SparseArray<ForegroundToken> mForegroundProcesses
388            = new SparseArray<ForegroundToken>();
389
390    /**
391     * List of records for processes that someone had tried to start before the
392     * system was ready.  We don't start them at that point, but ensure they
393     * are started by the time booting is complete.
394     */
395    final ArrayList<ProcessRecord> mProcessesOnHold
396            = new ArrayList<ProcessRecord>();
397
398    /**
399     * List of persistent applications that are in the process
400     * of being started.
401     */
402    final ArrayList<ProcessRecord> mPersistentStartingProcesses
403            = new ArrayList<ProcessRecord>();
404
405    /**
406     * Processes that are being forcibly torn down.
407     */
408    final ArrayList<ProcessRecord> mRemovedProcesses
409            = new ArrayList<ProcessRecord>();
410
411    /**
412     * List of running applications, sorted by recent usage.
413     * The first entry in the list is the least recently used.
414     * It contains ApplicationRecord objects.  This list does NOT include
415     * any persistent application records (since we never want to exit them).
416     */
417    final ArrayList<ProcessRecord> mLruProcesses
418            = new ArrayList<ProcessRecord>();
419
420    /**
421     * List of processes that should gc as soon as things are idle.
422     */
423    final ArrayList<ProcessRecord> mProcessesToGc
424            = new ArrayList<ProcessRecord>();
425
426    /**
427     * This is the process holding what we currently consider to be
428     * the "home" activity.
429     */
430    ProcessRecord mHomeProcess;
431
432    /**
433     * This is the process holding the activity the user last visited that
434     * is in a different process from the one they are currently in.
435     */
436    ProcessRecord mPreviousProcess;
437
438    /**
439     * The time at which the previous process was last visible.
440     */
441    long mPreviousProcessVisibleTime;
442
443    /**
444     * Which uses have been started, so are allowed to run code.
445     */
446    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
447
448    /**
449     * LRU list of history of current users.  Most recently current is at the end.
450     */
451    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
452
453    /**
454     * Constant array of the users that are currently started.
455     */
456    int[] mStartedUserArray = new int[] { 0 };
457
458    /**
459     * Registered observers of the user switching mechanics.
460     */
461    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
462            = new RemoteCallbackList<IUserSwitchObserver>();
463
464    /**
465     * Currently active user switch.
466     */
467    Object mCurUserSwitchCallback;
468
469    /**
470     * Packages that the user has asked to have run in screen size
471     * compatibility mode instead of filling the screen.
472     */
473    final CompatModePackages mCompatModePackages;
474
475    /**
476     * Set of PendingResultRecord objects that are currently active.
477     */
478    final HashSet mPendingResultRecords = new HashSet();
479
480    /**
481     * Set of IntentSenderRecord objects that are currently active.
482     */
483    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
484            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
485
486    /**
487     * Fingerprints (hashCode()) of stack traces that we've
488     * already logged DropBox entries for.  Guarded by itself.  If
489     * something (rogue user app) forces this over
490     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
491     */
492    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
493    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
494
495    /**
496     * Strict Mode background batched logging state.
497     *
498     * The string buffer is guarded by itself, and its lock is also
499     * used to determine if another batched write is already
500     * in-flight.
501     */
502    private final StringBuilder mStrictModeBuffer = new StringBuilder();
503
504    /**
505     * Keeps track of all IIntentReceivers that have been registered for
506     * broadcasts.  Hash keys are the receiver IBinder, hash value is
507     * a ReceiverList.
508     */
509    final HashMap mRegisteredReceivers = new HashMap();
510
511    /**
512     * Resolver for broadcast intents to registered receivers.
513     * Holds BroadcastFilter (subclass of IntentFilter).
514     */
515    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
516            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
517        @Override
518        protected boolean allowFilterResult(
519                BroadcastFilter filter, List<BroadcastFilter> dest) {
520            IBinder target = filter.receiverList.receiver.asBinder();
521            for (int i=dest.size()-1; i>=0; i--) {
522                if (dest.get(i).receiverList.receiver.asBinder() == target) {
523                    return false;
524                }
525            }
526            return true;
527        }
528
529        @Override
530        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
531            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
532                    || userId == filter.owningUserId) {
533                return super.newResult(filter, match, userId);
534            }
535            return null;
536        }
537
538        @Override
539        protected BroadcastFilter[] newArray(int size) {
540            return new BroadcastFilter[size];
541        }
542
543        @Override
544        protected String packageForFilter(BroadcastFilter filter) {
545            return filter.packageName;
546        }
547    };
548
549    /**
550     * State of all active sticky broadcasts per user.  Keys are the action of the
551     * sticky Intent, values are an ArrayList of all broadcasted intents with
552     * that action (which should usually be one).  The SparseArray is keyed
553     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
554     * for stickies that are sent to all users.
555     */
556    final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts =
557            new SparseArray<HashMap<String, ArrayList<Intent>>>();
558
559    final ActiveServices mServices;
560
561    /**
562     * Backup/restore process management
563     */
564    String mBackupAppName = null;
565    BackupRecord mBackupTarget = null;
566
567    /**
568     * List of PendingThumbnailsRecord objects of clients who are still
569     * waiting to receive all of the thumbnails for a task.
570     */
571    final ArrayList mPendingThumbnails = new ArrayList();
572
573    /**
574     * List of HistoryRecord objects that have been finished and must
575     * still report back to a pending thumbnail receiver.
576     */
577    final ArrayList mCancelledThumbnails = new ArrayList();
578
579    final ProviderMap mProviderMap;
580
581    /**
582     * List of content providers who have clients waiting for them.  The
583     * application is currently being launched and the provider will be
584     * removed from this list once it is published.
585     */
586    final ArrayList<ContentProviderRecord> mLaunchingProviders
587            = new ArrayList<ContentProviderRecord>();
588
589    /**
590     * Global set of specific Uri permissions that have been granted.
591     */
592    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
593            = new SparseArray<HashMap<Uri, UriPermission>>();
594
595    CoreSettingsObserver mCoreSettingsObserver;
596
597    /**
598     * Thread-local storage used to carry caller permissions over through
599     * indirect content-provider access.
600     * @see #ActivityManagerService.openContentUri()
601     */
602    private class Identity {
603        public int pid;
604        public int uid;
605
606        Identity(int _pid, int _uid) {
607            pid = _pid;
608            uid = _uid;
609        }
610    }
611
612    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
613
614    /**
615     * All information we have collected about the runtime performance of
616     * any user id that can impact battery performance.
617     */
618    final BatteryStatsService mBatteryStatsService;
619
620    /**
621     * information about component usage
622     */
623    final UsageStatsService mUsageStatsService;
624
625    /**
626     * Current configuration information.  HistoryRecord objects are given
627     * a reference to this object to indicate which configuration they are
628     * currently running in, so this object must be kept immutable.
629     */
630    Configuration mConfiguration = new Configuration();
631
632    /**
633     * Current sequencing integer of the configuration, for skipping old
634     * configurations.
635     */
636    int mConfigurationSeq = 0;
637
638    /**
639     * Hardware-reported OpenGLES version.
640     */
641    final int GL_ES_VERSION;
642
643    /**
644     * List of initialization arguments to pass to all processes when binding applications to them.
645     * For example, references to the commonly used services.
646     */
647    HashMap<String, IBinder> mAppBindArgs;
648
649    /**
650     * Temporary to avoid allocations.  Protected by main lock.
651     */
652    final StringBuilder mStringBuilder = new StringBuilder(256);
653
654    /**
655     * Used to control how we initialize the service.
656     */
657    boolean mStartRunning = false;
658    ComponentName mTopComponent;
659    String mTopAction;
660    String mTopData;
661    boolean mProcessesReady = false;
662    boolean mSystemReady = false;
663    boolean mBooting = false;
664    boolean mWaitingUpdate = false;
665    boolean mDidUpdate = false;
666    boolean mOnBattery = false;
667    boolean mLaunchWarningShown = false;
668
669    Context mContext;
670
671    int mFactoryTest;
672
673    boolean mCheckedForSetup;
674
675    /**
676     * The time at which we will allow normal application switches again,
677     * after a call to {@link #stopAppSwitches()}.
678     */
679    long mAppSwitchesAllowedTime;
680
681    /**
682     * This is set to true after the first switch after mAppSwitchesAllowedTime
683     * is set; any switches after that will clear the time.
684     */
685    boolean mDidAppSwitch;
686
687    /**
688     * Last time (in realtime) at which we checked for power usage.
689     */
690    long mLastPowerCheckRealtime;
691
692    /**
693     * Last time (in uptime) at which we checked for power usage.
694     */
695    long mLastPowerCheckUptime;
696
697    /**
698     * Set while we are wanting to sleep, to prevent any
699     * activities from being started/resumed.
700     */
701    boolean mSleeping = false;
702
703    /**
704     * State of external calls telling us if the device is asleep.
705     */
706    boolean mWentToSleep = false;
707
708    /**
709     * State of external call telling us if the lock screen is shown.
710     */
711    boolean mLockScreenShown = false;
712
713    /**
714     * Set if we are shutting down the system, similar to sleeping.
715     */
716    boolean mShuttingDown = false;
717
718    /**
719     * Task identifier that activities are currently being started
720     * in.  Incremented each time a new task is created.
721     * todo: Replace this with a TokenSpace class that generates non-repeating
722     * integers that won't wrap.
723     */
724    int mCurTask = 1;
725
726    /**
727     * Current sequence id for oom_adj computation traversal.
728     */
729    int mAdjSeq = 0;
730
731    /**
732     * Current sequence id for process LRU updating.
733     */
734    int mLruSeq = 0;
735
736    /**
737     * Keep track of the non-hidden/empty process we last found, to help
738     * determine how to distribute hidden/empty processes next time.
739     */
740    int mNumNonHiddenProcs = 0;
741
742    /**
743     * Keep track of the number of hidden procs, to balance oom adj
744     * distribution between those and empty procs.
745     */
746    int mNumHiddenProcs = 0;
747
748    /**
749     * Keep track of the number of service processes we last found, to
750     * determine on the next iteration which should be B services.
751     */
752    int mNumServiceProcs = 0;
753    int mNewNumServiceProcs = 0;
754
755    /**
756     * System monitoring: number of processes that died since the last
757     * N procs were started.
758     */
759    int[] mProcDeaths = new int[20];
760
761    /**
762     * This is set if we had to do a delayed dexopt of an app before launching
763     * it, to increasing the ANR timeouts in that case.
764     */
765    boolean mDidDexOpt;
766
767    String mDebugApp = null;
768    boolean mWaitForDebugger = false;
769    boolean mDebugTransient = false;
770    String mOrigDebugApp = null;
771    boolean mOrigWaitForDebugger = false;
772    boolean mAlwaysFinishActivities = false;
773    IActivityController mController = null;
774    String mProfileApp = null;
775    ProcessRecord mProfileProc = null;
776    String mProfileFile;
777    ParcelFileDescriptor mProfileFd;
778    int mProfileType = 0;
779    boolean mAutoStopProfiler = false;
780    String mOpenGlTraceApp = null;
781
782    static class ProcessChangeItem {
783        static final int CHANGE_ACTIVITIES = 1<<0;
784        static final int CHANGE_IMPORTANCE= 1<<1;
785        int changes;
786        int uid;
787        int pid;
788        int importance;
789        boolean foregroundActivities;
790    }
791
792    final RemoteCallbackList<IProcessObserver> mProcessObservers
793            = new RemoteCallbackList<IProcessObserver>();
794    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
795
796    final ArrayList<ProcessChangeItem> mPendingProcessChanges
797            = new ArrayList<ProcessChangeItem>();
798    final ArrayList<ProcessChangeItem> mAvailProcessChanges
799            = new ArrayList<ProcessChangeItem>();
800
801    /**
802     * Callback of last caller to {@link #requestPss}.
803     */
804    Runnable mRequestPssCallback;
805
806    /**
807     * Remaining processes for which we are waiting results from the last
808     * call to {@link #requestPss}.
809     */
810    final ArrayList<ProcessRecord> mRequestPssList
811            = new ArrayList<ProcessRecord>();
812
813    /**
814     * Runtime statistics collection thread.  This object's lock is used to
815     * protect all related state.
816     */
817    final Thread mProcessStatsThread;
818
819    /**
820     * Used to collect process stats when showing not responding dialog.
821     * Protected by mProcessStatsThread.
822     */
823    final ProcessStats mProcessStats = new ProcessStats(
824            MONITOR_THREAD_CPU_USAGE);
825    final AtomicLong mLastCpuTime = new AtomicLong(0);
826    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
827
828    long mLastWriteTime = 0;
829
830    /**
831     * Set to true after the system has finished booting.
832     */
833    boolean mBooted = false;
834
835    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
836    int mProcessLimitOverride = -1;
837
838    WindowManagerService mWindowManager;
839
840    static ActivityManagerService mSelf;
841    static ActivityThread mSystemThread;
842
843    private int mCurrentUserId = 0;
844    private int[] mCurrentUserArray = new int[] { 0 };
845    private UserManagerService mUserManager;
846
847    private final class AppDeathRecipient implements IBinder.DeathRecipient {
848        final ProcessRecord mApp;
849        final int mPid;
850        final IApplicationThread mAppThread;
851
852        AppDeathRecipient(ProcessRecord app, int pid,
853                IApplicationThread thread) {
854            if (localLOGV) Slog.v(
855                TAG, "New death recipient " + this
856                + " for thread " + thread.asBinder());
857            mApp = app;
858            mPid = pid;
859            mAppThread = thread;
860        }
861
862        public void binderDied() {
863            if (localLOGV) Slog.v(
864                TAG, "Death received in " + this
865                + " for thread " + mAppThread.asBinder());
866            synchronized(ActivityManagerService.this) {
867                appDiedLocked(mApp, mPid, mAppThread);
868            }
869        }
870    }
871
872    static final int SHOW_ERROR_MSG = 1;
873    static final int SHOW_NOT_RESPONDING_MSG = 2;
874    static final int SHOW_FACTORY_ERROR_MSG = 3;
875    static final int UPDATE_CONFIGURATION_MSG = 4;
876    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
877    static final int WAIT_FOR_DEBUGGER_MSG = 6;
878    static final int SERVICE_TIMEOUT_MSG = 12;
879    static final int UPDATE_TIME_ZONE = 13;
880    static final int SHOW_UID_ERROR_MSG = 14;
881    static final int IM_FEELING_LUCKY_MSG = 15;
882    static final int PROC_START_TIMEOUT_MSG = 20;
883    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
884    static final int KILL_APPLICATION_MSG = 22;
885    static final int FINALIZE_PENDING_INTENT_MSG = 23;
886    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
887    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
888    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
889    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
890    static final int CLEAR_DNS_CACHE = 28;
891    static final int UPDATE_HTTP_PROXY = 29;
892    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
893    static final int DISPATCH_PROCESSES_CHANGED = 31;
894    static final int DISPATCH_PROCESS_DIED = 32;
895    static final int REPORT_MEM_USAGE = 33;
896    static final int REPORT_USER_SWITCH_MSG = 34;
897    static final int CONTINUE_USER_SWITCH_MSG = 35;
898    static final int USER_SWITCH_TIMEOUT_MSG = 36;
899
900    static final int FIRST_ACTIVITY_STACK_MSG = 100;
901    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
902    static final int FIRST_COMPAT_MODE_MSG = 300;
903
904    AlertDialog mUidAlert;
905    CompatModeDialog mCompatModeDialog;
906    long mLastMemUsageReportTime = 0;
907
908    final Handler mHandler = new Handler() {
909        //public Handler() {
910        //    if (localLOGV) Slog.v(TAG, "Handler started!");
911        //}
912
913        public void handleMessage(Message msg) {
914            switch (msg.what) {
915            case SHOW_ERROR_MSG: {
916                HashMap data = (HashMap) msg.obj;
917                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
918                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
919                synchronized (ActivityManagerService.this) {
920                    ProcessRecord proc = (ProcessRecord)data.get("app");
921                    AppErrorResult res = (AppErrorResult) data.get("result");
922                    if (proc != null && proc.crashDialog != null) {
923                        Slog.e(TAG, "App already has crash dialog: " + proc);
924                        if (res != null) {
925                            res.set(0);
926                        }
927                        return;
928                    }
929                    if (!showBackground && UserHandle.getAppId(proc.uid)
930                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
931                            && proc.pid != MY_PID) {
932                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
933                        if (res != null) {
934                            res.set(0);
935                        }
936                        return;
937                    }
938                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
939                        Dialog d = new AppErrorDialog(mContext,
940                                ActivityManagerService.this, res, proc);
941                        d.show();
942                        proc.crashDialog = d;
943                    } else {
944                        // The device is asleep, so just pretend that the user
945                        // saw a crash dialog and hit "force quit".
946                        if (res != null) {
947                            res.set(0);
948                        }
949                    }
950                }
951
952                ensureBootCompleted();
953            } break;
954            case SHOW_NOT_RESPONDING_MSG: {
955                synchronized (ActivityManagerService.this) {
956                    HashMap data = (HashMap) msg.obj;
957                    ProcessRecord proc = (ProcessRecord)data.get("app");
958                    if (proc != null && proc.anrDialog != null) {
959                        Slog.e(TAG, "App already has anr dialog: " + proc);
960                        return;
961                    }
962
963                    Intent intent = new Intent("android.intent.action.ANR");
964                    if (!mProcessesReady) {
965                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
966                                | Intent.FLAG_RECEIVER_FOREGROUND);
967                    }
968                    broadcastIntentLocked(null, null, intent,
969                            null, null, 0, null, null, null,
970                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
971
972                    if (mShowDialogs) {
973                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
974                                mContext, proc, (ActivityRecord)data.get("activity"),
975                                msg.arg1 != 0);
976                        d.show();
977                        proc.anrDialog = d;
978                    } else {
979                        // Just kill the app if there is no dialog to be shown.
980                        killAppAtUsersRequest(proc, null);
981                    }
982                }
983
984                ensureBootCompleted();
985            } break;
986            case SHOW_STRICT_MODE_VIOLATION_MSG: {
987                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
988                synchronized (ActivityManagerService.this) {
989                    ProcessRecord proc = (ProcessRecord) data.get("app");
990                    if (proc == null) {
991                        Slog.e(TAG, "App not found when showing strict mode dialog.");
992                        break;
993                    }
994                    if (proc.crashDialog != null) {
995                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
996                        return;
997                    }
998                    AppErrorResult res = (AppErrorResult) data.get("result");
999                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1000                        Dialog d = new StrictModeViolationDialog(mContext,
1001                                ActivityManagerService.this, res, proc);
1002                        d.show();
1003                        proc.crashDialog = d;
1004                    } else {
1005                        // The device is asleep, so just pretend that the user
1006                        // saw a crash dialog and hit "force quit".
1007                        res.set(0);
1008                    }
1009                }
1010                ensureBootCompleted();
1011            } break;
1012            case SHOW_FACTORY_ERROR_MSG: {
1013                Dialog d = new FactoryErrorDialog(
1014                    mContext, msg.getData().getCharSequence("msg"));
1015                d.show();
1016                ensureBootCompleted();
1017            } break;
1018            case UPDATE_CONFIGURATION_MSG: {
1019                final ContentResolver resolver = mContext.getContentResolver();
1020                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1021            } break;
1022            case GC_BACKGROUND_PROCESSES_MSG: {
1023                synchronized (ActivityManagerService.this) {
1024                    performAppGcsIfAppropriateLocked();
1025                }
1026            } break;
1027            case WAIT_FOR_DEBUGGER_MSG: {
1028                synchronized (ActivityManagerService.this) {
1029                    ProcessRecord app = (ProcessRecord)msg.obj;
1030                    if (msg.arg1 != 0) {
1031                        if (!app.waitedForDebugger) {
1032                            Dialog d = new AppWaitingForDebuggerDialog(
1033                                    ActivityManagerService.this,
1034                                    mContext, app);
1035                            app.waitDialog = d;
1036                            app.waitedForDebugger = true;
1037                            d.show();
1038                        }
1039                    } else {
1040                        if (app.waitDialog != null) {
1041                            app.waitDialog.dismiss();
1042                            app.waitDialog = null;
1043                        }
1044                    }
1045                }
1046            } break;
1047            case SERVICE_TIMEOUT_MSG: {
1048                if (mDidDexOpt) {
1049                    mDidDexOpt = false;
1050                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1051                    nmsg.obj = msg.obj;
1052                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1053                    return;
1054                }
1055                mServices.serviceTimeout((ProcessRecord)msg.obj);
1056            } break;
1057            case UPDATE_TIME_ZONE: {
1058                synchronized (ActivityManagerService.this) {
1059                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1060                        ProcessRecord r = mLruProcesses.get(i);
1061                        if (r.thread != null) {
1062                            try {
1063                                r.thread.updateTimeZone();
1064                            } catch (RemoteException ex) {
1065                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1066                            }
1067                        }
1068                    }
1069                }
1070            } break;
1071            case CLEAR_DNS_CACHE: {
1072                synchronized (ActivityManagerService.this) {
1073                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1074                        ProcessRecord r = mLruProcesses.get(i);
1075                        if (r.thread != null) {
1076                            try {
1077                                r.thread.clearDnsCache();
1078                            } catch (RemoteException ex) {
1079                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1080                            }
1081                        }
1082                    }
1083                }
1084            } break;
1085            case UPDATE_HTTP_PROXY: {
1086                ProxyProperties proxy = (ProxyProperties)msg.obj;
1087                String host = "";
1088                String port = "";
1089                String exclList = "";
1090                if (proxy != null) {
1091                    host = proxy.getHost();
1092                    port = Integer.toString(proxy.getPort());
1093                    exclList = proxy.getExclusionList();
1094                }
1095                synchronized (ActivityManagerService.this) {
1096                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1097                        ProcessRecord r = mLruProcesses.get(i);
1098                        if (r.thread != null) {
1099                            try {
1100                                r.thread.setHttpProxy(host, port, exclList);
1101                            } catch (RemoteException ex) {
1102                                Slog.w(TAG, "Failed to update http proxy for: " +
1103                                        r.info.processName);
1104                            }
1105                        }
1106                    }
1107                }
1108            } break;
1109            case SHOW_UID_ERROR_MSG: {
1110                String title = "System UIDs Inconsistent";
1111                String text = "UIDs on the system are inconsistent, you need to wipe your"
1112                        + " data partition or your device will be unstable.";
1113                Log.e(TAG, title + ": " + text);
1114                if (mShowDialogs) {
1115                    // XXX This is a temporary dialog, no need to localize.
1116                    AlertDialog d = new BaseErrorDialog(mContext);
1117                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1118                    d.setCancelable(false);
1119                    d.setTitle(title);
1120                    d.setMessage(text);
1121                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1122                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1123                    mUidAlert = d;
1124                    d.show();
1125                }
1126            } break;
1127            case IM_FEELING_LUCKY_MSG: {
1128                if (mUidAlert != null) {
1129                    mUidAlert.dismiss();
1130                    mUidAlert = null;
1131                }
1132            } break;
1133            case PROC_START_TIMEOUT_MSG: {
1134                if (mDidDexOpt) {
1135                    mDidDexOpt = false;
1136                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1137                    nmsg.obj = msg.obj;
1138                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1139                    return;
1140                }
1141                ProcessRecord app = (ProcessRecord)msg.obj;
1142                synchronized (ActivityManagerService.this) {
1143                    processStartTimedOutLocked(app);
1144                }
1145            } break;
1146            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1147                synchronized (ActivityManagerService.this) {
1148                    doPendingActivityLaunchesLocked(true);
1149                }
1150            } break;
1151            case KILL_APPLICATION_MSG: {
1152                synchronized (ActivityManagerService.this) {
1153                    int appid = msg.arg1;
1154                    boolean restart = (msg.arg2 == 1);
1155                    String pkg = (String) msg.obj;
1156                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1157                            UserHandle.USER_ALL);
1158                }
1159            } break;
1160            case FINALIZE_PENDING_INTENT_MSG: {
1161                ((PendingIntentRecord)msg.obj).completeFinalize();
1162            } break;
1163            case POST_HEAVY_NOTIFICATION_MSG: {
1164                INotificationManager inm = NotificationManager.getService();
1165                if (inm == null) {
1166                    return;
1167                }
1168
1169                ActivityRecord root = (ActivityRecord)msg.obj;
1170                ProcessRecord process = root.app;
1171                if (process == null) {
1172                    return;
1173                }
1174
1175                try {
1176                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1177                    String text = mContext.getString(R.string.heavy_weight_notification,
1178                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1179                    Notification notification = new Notification();
1180                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1181                    notification.when = 0;
1182                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1183                    notification.tickerText = text;
1184                    notification.defaults = 0; // please be quiet
1185                    notification.sound = null;
1186                    notification.vibrate = null;
1187                    notification.setLatestEventInfo(context, text,
1188                            mContext.getText(R.string.heavy_weight_notification_detail),
1189                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1190                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1191                                    new UserHandle(root.userId)));
1192
1193                    try {
1194                        int[] outId = new int[1];
1195                        inm.enqueueNotificationWithTag("android", null,
1196                                R.string.heavy_weight_notification,
1197                                notification, outId, root.userId);
1198                    } catch (RuntimeException e) {
1199                        Slog.w(ActivityManagerService.TAG,
1200                                "Error showing notification for heavy-weight app", e);
1201                    } catch (RemoteException e) {
1202                    }
1203                } catch (NameNotFoundException e) {
1204                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1205                }
1206            } break;
1207            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1208                INotificationManager inm = NotificationManager.getService();
1209                if (inm == null) {
1210                    return;
1211                }
1212                try {
1213                    inm.cancelNotificationWithTag("android", null,
1214                            R.string.heavy_weight_notification,  msg.arg1);
1215                } catch (RuntimeException e) {
1216                    Slog.w(ActivityManagerService.TAG,
1217                            "Error canceling notification for service", e);
1218                } catch (RemoteException e) {
1219                }
1220            } break;
1221            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1222                synchronized (ActivityManagerService.this) {
1223                    checkExcessivePowerUsageLocked(true);
1224                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1225                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1226                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1227                }
1228            } break;
1229            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1230                synchronized (ActivityManagerService.this) {
1231                    ActivityRecord ar = (ActivityRecord)msg.obj;
1232                    if (mCompatModeDialog != null) {
1233                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1234                                ar.info.applicationInfo.packageName)) {
1235                            return;
1236                        }
1237                        mCompatModeDialog.dismiss();
1238                        mCompatModeDialog = null;
1239                    }
1240                    if (ar != null && false) {
1241                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1242                                ar.packageName)) {
1243                            int mode = mCompatModePackages.computeCompatModeLocked(
1244                                    ar.info.applicationInfo);
1245                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1246                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1247                                mCompatModeDialog = new CompatModeDialog(
1248                                        ActivityManagerService.this, mContext,
1249                                        ar.info.applicationInfo);
1250                                mCompatModeDialog.show();
1251                            }
1252                        }
1253                    }
1254                }
1255                break;
1256            }
1257            case DISPATCH_PROCESSES_CHANGED: {
1258                dispatchProcessesChanged();
1259                break;
1260            }
1261            case DISPATCH_PROCESS_DIED: {
1262                final int pid = msg.arg1;
1263                final int uid = msg.arg2;
1264                dispatchProcessDied(pid, uid);
1265                break;
1266            }
1267            case REPORT_MEM_USAGE: {
1268                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1269                if (!isDebuggable) {
1270                    return;
1271                }
1272                synchronized (ActivityManagerService.this) {
1273                    long now = SystemClock.uptimeMillis();
1274                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1275                        // Don't report more than every 5 minutes to somewhat
1276                        // avoid spamming.
1277                        return;
1278                    }
1279                    mLastMemUsageReportTime = now;
1280                }
1281                Thread thread = new Thread() {
1282                    @Override public void run() {
1283                        StringBuilder dropBuilder = new StringBuilder(1024);
1284                        StringBuilder logBuilder = new StringBuilder(1024);
1285                        StringWriter oomSw = new StringWriter();
1286                        PrintWriter oomPw = new PrintWriter(oomSw);
1287                        StringWriter catSw = new StringWriter();
1288                        PrintWriter catPw = new PrintWriter(catSw);
1289                        String[] emptyArgs = new String[] { };
1290                        StringBuilder tag = new StringBuilder(128);
1291                        StringBuilder stack = new StringBuilder(128);
1292                        tag.append("Low on memory -- ");
1293                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1294                                tag, stack);
1295                        dropBuilder.append(stack);
1296                        dropBuilder.append('\n');
1297                        dropBuilder.append('\n');
1298                        String oomString = oomSw.toString();
1299                        dropBuilder.append(oomString);
1300                        dropBuilder.append('\n');
1301                        logBuilder.append(oomString);
1302                        try {
1303                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1304                                    "procrank", });
1305                            final InputStreamReader converter = new InputStreamReader(
1306                                    proc.getInputStream());
1307                            BufferedReader in = new BufferedReader(converter);
1308                            String line;
1309                            while (true) {
1310                                line = in.readLine();
1311                                if (line == null) {
1312                                    break;
1313                                }
1314                                if (line.length() > 0) {
1315                                    logBuilder.append(line);
1316                                    logBuilder.append('\n');
1317                                }
1318                                dropBuilder.append(line);
1319                                dropBuilder.append('\n');
1320                            }
1321                            converter.close();
1322                        } catch (IOException e) {
1323                        }
1324                        synchronized (ActivityManagerService.this) {
1325                            catPw.println();
1326                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1327                            catPw.println();
1328                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1329                                    false, false, null);
1330                            catPw.println();
1331                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1332                        }
1333                        dropBuilder.append(catSw.toString());
1334                        addErrorToDropBox("lowmem", null, "system_server", null,
1335                                null, tag.toString(), dropBuilder.toString(), null, null);
1336                        Slog.i(TAG, logBuilder.toString());
1337                        synchronized (ActivityManagerService.this) {
1338                            long now = SystemClock.uptimeMillis();
1339                            if (mLastMemUsageReportTime < now) {
1340                                mLastMemUsageReportTime = now;
1341                            }
1342                        }
1343                    }
1344                };
1345                thread.start();
1346                break;
1347            }
1348            case REPORT_USER_SWITCH_MSG: {
1349                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1350                break;
1351            }
1352            case CONTINUE_USER_SWITCH_MSG: {
1353                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1354                break;
1355            }
1356            case USER_SWITCH_TIMEOUT_MSG: {
1357                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1358                break;
1359            }
1360            }
1361        }
1362    };
1363
1364    public static void setSystemProcess() {
1365        try {
1366            ActivityManagerService m = mSelf;
1367
1368            ServiceManager.addService("activity", m, true);
1369            ServiceManager.addService("meminfo", new MemBinder(m));
1370            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1371            ServiceManager.addService("dbinfo", new DbBinder(m));
1372            if (MONITOR_CPU_USAGE) {
1373                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1374            }
1375            ServiceManager.addService("permission", new PermissionController(m));
1376
1377            ApplicationInfo info =
1378                mSelf.mContext.getPackageManager().getApplicationInfo(
1379                            "android", STOCK_PM_FLAGS);
1380            mSystemThread.installSystemApplicationInfo(info);
1381
1382            synchronized (mSelf) {
1383                ProcessRecord app = mSelf.newProcessRecordLocked(
1384                        mSystemThread.getApplicationThread(), info,
1385                        info.processName, false);
1386                app.persistent = true;
1387                app.pid = MY_PID;
1388                app.maxAdj = ProcessList.SYSTEM_ADJ;
1389                mSelf.mProcessNames.put(app.processName, app.uid, app);
1390                synchronized (mSelf.mPidsSelfLocked) {
1391                    mSelf.mPidsSelfLocked.put(app.pid, app);
1392                }
1393                mSelf.updateLruProcessLocked(app, true);
1394            }
1395        } catch (PackageManager.NameNotFoundException e) {
1396            throw new RuntimeException(
1397                    "Unable to find android system package", e);
1398        }
1399    }
1400
1401    public void setWindowManager(WindowManagerService wm) {
1402        mWindowManager = wm;
1403    }
1404
1405    public static final Context main(int factoryTest) {
1406        AThread thr = new AThread();
1407        thr.start();
1408
1409        synchronized (thr) {
1410            while (thr.mService == null) {
1411                try {
1412                    thr.wait();
1413                } catch (InterruptedException e) {
1414                }
1415            }
1416        }
1417
1418        ActivityManagerService m = thr.mService;
1419        mSelf = m;
1420        ActivityThread at = ActivityThread.systemMain();
1421        mSystemThread = at;
1422        Context context = at.getSystemContext();
1423        context.setTheme(android.R.style.Theme_Holo);
1424        m.mContext = context;
1425        m.mFactoryTest = factoryTest;
1426        m.mMainStack = new ActivityStack(m, context, true);
1427
1428        m.mBatteryStatsService.publish(context);
1429        m.mUsageStatsService.publish(context);
1430
1431        synchronized (thr) {
1432            thr.mReady = true;
1433            thr.notifyAll();
1434        }
1435
1436        m.startRunning(null, null, null, null);
1437
1438        return context;
1439    }
1440
1441    public static ActivityManagerService self() {
1442        return mSelf;
1443    }
1444
1445    static class AThread extends Thread {
1446        ActivityManagerService mService;
1447        boolean mReady = false;
1448
1449        public AThread() {
1450            super("ActivityManager");
1451        }
1452
1453        public void run() {
1454            Looper.prepare();
1455
1456            android.os.Process.setThreadPriority(
1457                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1458            android.os.Process.setCanSelfBackground(false);
1459
1460            ActivityManagerService m = new ActivityManagerService();
1461
1462            synchronized (this) {
1463                mService = m;
1464                notifyAll();
1465            }
1466
1467            synchronized (this) {
1468                while (!mReady) {
1469                    try {
1470                        wait();
1471                    } catch (InterruptedException e) {
1472                    }
1473                }
1474            }
1475
1476            // For debug builds, log event loop stalls to dropbox for analysis.
1477            if (StrictMode.conditionallyEnableDebugLogging()) {
1478                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1479            }
1480
1481            Looper.loop();
1482        }
1483    }
1484
1485    static class MemBinder extends Binder {
1486        ActivityManagerService mActivityManagerService;
1487        MemBinder(ActivityManagerService activityManagerService) {
1488            mActivityManagerService = activityManagerService;
1489        }
1490
1491        @Override
1492        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1493            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1494                    != PackageManager.PERMISSION_GRANTED) {
1495                pw.println("Permission Denial: can't dump meminfo from from pid="
1496                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1497                        + " without permission " + android.Manifest.permission.DUMP);
1498                return;
1499            }
1500
1501            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1502                    false, null, null, null);
1503        }
1504    }
1505
1506    static class GraphicsBinder extends Binder {
1507        ActivityManagerService mActivityManagerService;
1508        GraphicsBinder(ActivityManagerService activityManagerService) {
1509            mActivityManagerService = activityManagerService;
1510        }
1511
1512        @Override
1513        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1514            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1515                    != PackageManager.PERMISSION_GRANTED) {
1516                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1517                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1518                        + " without permission " + android.Manifest.permission.DUMP);
1519                return;
1520            }
1521
1522            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1523        }
1524    }
1525
1526    static class DbBinder extends Binder {
1527        ActivityManagerService mActivityManagerService;
1528        DbBinder(ActivityManagerService activityManagerService) {
1529            mActivityManagerService = activityManagerService;
1530        }
1531
1532        @Override
1533        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1534            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1535                    != PackageManager.PERMISSION_GRANTED) {
1536                pw.println("Permission Denial: can't dump dbinfo from from pid="
1537                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1538                        + " without permission " + android.Manifest.permission.DUMP);
1539                return;
1540            }
1541
1542            mActivityManagerService.dumpDbInfo(fd, pw, args);
1543        }
1544    }
1545
1546    static class CpuBinder extends Binder {
1547        ActivityManagerService mActivityManagerService;
1548        CpuBinder(ActivityManagerService activityManagerService) {
1549            mActivityManagerService = activityManagerService;
1550        }
1551
1552        @Override
1553        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1554            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1555                    != PackageManager.PERMISSION_GRANTED) {
1556                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1557                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1558                        + " without permission " + android.Manifest.permission.DUMP);
1559                return;
1560            }
1561
1562            synchronized (mActivityManagerService.mProcessStatsThread) {
1563                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1564                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1565                        SystemClock.uptimeMillis()));
1566            }
1567        }
1568    }
1569
1570    private ActivityManagerService() {
1571        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1572
1573        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1574        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1575        mBroadcastQueues[0] = mFgBroadcastQueue;
1576        mBroadcastQueues[1] = mBgBroadcastQueue;
1577
1578        mServices = new ActiveServices(this);
1579        mProviderMap = new ProviderMap(this);
1580
1581        File dataDir = Environment.getDataDirectory();
1582        File systemDir = new File(dataDir, "system");
1583        systemDir.mkdirs();
1584        mBatteryStatsService = new BatteryStatsService(new File(
1585                systemDir, "batterystats.bin").toString());
1586        mBatteryStatsService.getActiveStatistics().readLocked();
1587        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1588        mOnBattery = DEBUG_POWER ? true
1589                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1590        mBatteryStatsService.getActiveStatistics().setCallback(this);
1591
1592        mUsageStatsService = new UsageStatsService(new File(
1593                systemDir, "usagestats").toString());
1594        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1595
1596        // User 0 is the first and only user that runs at boot.
1597        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1598        mUserLru.add(Integer.valueOf(0));
1599        updateStartedUserArrayLocked();
1600
1601        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1602            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1603
1604        mConfiguration.setToDefaults();
1605        mConfiguration.setLocale(Locale.getDefault());
1606
1607        mConfigurationSeq = mConfiguration.seq = 1;
1608        mProcessStats.init();
1609
1610        mCompatModePackages = new CompatModePackages(this, systemDir);
1611
1612        // Add ourself to the Watchdog monitors.
1613        Watchdog.getInstance().addMonitor(this);
1614
1615        mProcessStatsThread = new Thread("ProcessStats") {
1616            public void run() {
1617                while (true) {
1618                    try {
1619                        try {
1620                            synchronized(this) {
1621                                final long now = SystemClock.uptimeMillis();
1622                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1623                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1624                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1625                                //        + ", write delay=" + nextWriteDelay);
1626                                if (nextWriteDelay < nextCpuDelay) {
1627                                    nextCpuDelay = nextWriteDelay;
1628                                }
1629                                if (nextCpuDelay > 0) {
1630                                    mProcessStatsMutexFree.set(true);
1631                                    this.wait(nextCpuDelay);
1632                                }
1633                            }
1634                        } catch (InterruptedException e) {
1635                        }
1636                        updateCpuStatsNow();
1637                    } catch (Exception e) {
1638                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1639                    }
1640                }
1641            }
1642        };
1643        mProcessStatsThread.start();
1644    }
1645
1646    @Override
1647    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1648            throws RemoteException {
1649        if (code == SYSPROPS_TRANSACTION) {
1650            // We need to tell all apps about the system property change.
1651            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1652            synchronized(this) {
1653                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1654                    final int NA = apps.size();
1655                    for (int ia=0; ia<NA; ia++) {
1656                        ProcessRecord app = apps.valueAt(ia);
1657                        if (app.thread != null) {
1658                            procs.add(app.thread.asBinder());
1659                        }
1660                    }
1661                }
1662            }
1663
1664            int N = procs.size();
1665            for (int i=0; i<N; i++) {
1666                Parcel data2 = Parcel.obtain();
1667                try {
1668                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1669                } catch (RemoteException e) {
1670                }
1671                data2.recycle();
1672            }
1673        }
1674        try {
1675            return super.onTransact(code, data, reply, flags);
1676        } catch (RuntimeException e) {
1677            // The activity manager only throws security exceptions, so let's
1678            // log all others.
1679            if (!(e instanceof SecurityException)) {
1680                Slog.e(TAG, "Activity Manager Crash", e);
1681            }
1682            throw e;
1683        }
1684    }
1685
1686    void updateCpuStats() {
1687        final long now = SystemClock.uptimeMillis();
1688        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1689            return;
1690        }
1691        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1692            synchronized (mProcessStatsThread) {
1693                mProcessStatsThread.notify();
1694            }
1695        }
1696    }
1697
1698    void updateCpuStatsNow() {
1699        synchronized (mProcessStatsThread) {
1700            mProcessStatsMutexFree.set(false);
1701            final long now = SystemClock.uptimeMillis();
1702            boolean haveNewCpuStats = false;
1703
1704            if (MONITOR_CPU_USAGE &&
1705                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1706                mLastCpuTime.set(now);
1707                haveNewCpuStats = true;
1708                mProcessStats.update();
1709                //Slog.i(TAG, mProcessStats.printCurrentState());
1710                //Slog.i(TAG, "Total CPU usage: "
1711                //        + mProcessStats.getTotalCpuPercent() + "%");
1712
1713                // Slog the cpu usage if the property is set.
1714                if ("true".equals(SystemProperties.get("events.cpu"))) {
1715                    int user = mProcessStats.getLastUserTime();
1716                    int system = mProcessStats.getLastSystemTime();
1717                    int iowait = mProcessStats.getLastIoWaitTime();
1718                    int irq = mProcessStats.getLastIrqTime();
1719                    int softIrq = mProcessStats.getLastSoftIrqTime();
1720                    int idle = mProcessStats.getLastIdleTime();
1721
1722                    int total = user + system + iowait + irq + softIrq + idle;
1723                    if (total == 0) total = 1;
1724
1725                    EventLog.writeEvent(EventLogTags.CPU,
1726                            ((user+system+iowait+irq+softIrq) * 100) / total,
1727                            (user * 100) / total,
1728                            (system * 100) / total,
1729                            (iowait * 100) / total,
1730                            (irq * 100) / total,
1731                            (softIrq * 100) / total);
1732                }
1733            }
1734
1735            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1736            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1737            synchronized(bstats) {
1738                synchronized(mPidsSelfLocked) {
1739                    if (haveNewCpuStats) {
1740                        if (mOnBattery) {
1741                            int perc = bstats.startAddingCpuLocked();
1742                            int totalUTime = 0;
1743                            int totalSTime = 0;
1744                            final int N = mProcessStats.countStats();
1745                            for (int i=0; i<N; i++) {
1746                                ProcessStats.Stats st = mProcessStats.getStats(i);
1747                                if (!st.working) {
1748                                    continue;
1749                                }
1750                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1751                                int otherUTime = (st.rel_utime*perc)/100;
1752                                int otherSTime = (st.rel_stime*perc)/100;
1753                                totalUTime += otherUTime;
1754                                totalSTime += otherSTime;
1755                                if (pr != null) {
1756                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1757                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1758                                            st.rel_stime-otherSTime);
1759                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1760                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1761                                } else {
1762                                    BatteryStatsImpl.Uid.Proc ps =
1763                                            bstats.getProcessStatsLocked(st.name, st.pid);
1764                                    if (ps != null) {
1765                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1766                                                st.rel_stime-otherSTime);
1767                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1768                                    }
1769                                }
1770                            }
1771                            bstats.finishAddingCpuLocked(perc, totalUTime,
1772                                    totalSTime, cpuSpeedTimes);
1773                        }
1774                    }
1775                }
1776
1777                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1778                    mLastWriteTime = now;
1779                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1780                }
1781            }
1782        }
1783    }
1784
1785    @Override
1786    public void batteryNeedsCpuUpdate() {
1787        updateCpuStatsNow();
1788    }
1789
1790    @Override
1791    public void batteryPowerChanged(boolean onBattery) {
1792        // When plugging in, update the CPU stats first before changing
1793        // the plug state.
1794        updateCpuStatsNow();
1795        synchronized (this) {
1796            synchronized(mPidsSelfLocked) {
1797                mOnBattery = DEBUG_POWER ? true : onBattery;
1798            }
1799        }
1800    }
1801
1802    /**
1803     * Initialize the application bind args. These are passed to each
1804     * process when the bindApplication() IPC is sent to the process. They're
1805     * lazily setup to make sure the services are running when they're asked for.
1806     */
1807    private HashMap<String, IBinder> getCommonServicesLocked() {
1808        if (mAppBindArgs == null) {
1809            mAppBindArgs = new HashMap<String, IBinder>();
1810
1811            // Setup the application init args
1812            mAppBindArgs.put("package", ServiceManager.getService("package"));
1813            mAppBindArgs.put("window", ServiceManager.getService("window"));
1814            mAppBindArgs.put(Context.ALARM_SERVICE,
1815                    ServiceManager.getService(Context.ALARM_SERVICE));
1816        }
1817        return mAppBindArgs;
1818    }
1819
1820    final void setFocusedActivityLocked(ActivityRecord r) {
1821        if (mFocusedActivity != r) {
1822            mFocusedActivity = r;
1823            if (r != null) {
1824                mWindowManager.setFocusedApp(r.appToken, true);
1825            }
1826        }
1827    }
1828
1829    private final void updateLruProcessInternalLocked(ProcessRecord app, int bestPos) {
1830        // put it on the LRU to keep track of when it should be exited.
1831        int lrui = mLruProcesses.indexOf(app);
1832        if (lrui >= 0) mLruProcesses.remove(lrui);
1833
1834        int i = mLruProcesses.size()-1;
1835        int skipTop = 0;
1836
1837        app.lruSeq = mLruSeq;
1838
1839        // compute the new weight for this process.
1840        app.lastActivityTime = SystemClock.uptimeMillis();
1841        if (app.activities.size() > 0) {
1842            // If this process has activities, we more strongly want to keep
1843            // it around.
1844            app.lruWeight = app.lastActivityTime;
1845        } else if (app.pubProviders.size() > 0) {
1846            // If this process contains content providers, we want to keep
1847            // it a little more strongly.
1848            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1849            // Also don't let it kick out the first few "real" hidden processes.
1850            skipTop = ProcessList.MIN_HIDDEN_APPS;
1851        } else {
1852            // If this process doesn't have activities, we less strongly
1853            // want to keep it around, and generally want to avoid getting
1854            // in front of any very recently used activities.
1855            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1856            // Also don't let it kick out the first few "real" hidden processes.
1857            skipTop = ProcessList.MIN_HIDDEN_APPS;
1858        }
1859
1860        while (i >= 0) {
1861            ProcessRecord p = mLruProcesses.get(i);
1862            // If this app shouldn't be in front of the first N background
1863            // apps, then skip over that many that are currently hidden.
1864            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1865                skipTop--;
1866            }
1867            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1868                mLruProcesses.add(i+1, app);
1869                break;
1870            }
1871            i--;
1872        }
1873        if (i < 0) {
1874            mLruProcesses.add(0, app);
1875        }
1876
1877        // If the app is currently using a content provider or service,
1878        // bump those processes as well.
1879        if (app.connections.size() > 0) {
1880            for (ConnectionRecord cr : app.connections) {
1881                if (cr.binding != null && cr.binding.service != null
1882                        && cr.binding.service.app != null
1883                        && cr.binding.service.app.lruSeq != mLruSeq) {
1884                    updateLruProcessInternalLocked(cr.binding.service.app, i+1);
1885                }
1886            }
1887        }
1888        for (int j=app.conProviders.size()-1; j>=0; j--) {
1889            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1890            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1891                updateLruProcessInternalLocked(cpr.proc, i+1);
1892            }
1893        }
1894    }
1895
1896    final void updateLruProcessLocked(ProcessRecord app,
1897            boolean oomAdj) {
1898        mLruSeq++;
1899        updateLruProcessInternalLocked(app, 0);
1900
1901        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1902        if (oomAdj) {
1903            updateOomAdjLocked();
1904        }
1905    }
1906
1907    final ProcessRecord getProcessRecordLocked(
1908            String processName, int uid) {
1909        if (uid == Process.SYSTEM_UID) {
1910            // The system gets to run in any process.  If there are multiple
1911            // processes with the same uid, just pick the first (this
1912            // should never happen).
1913            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1914                    processName);
1915            if (procs == null) return null;
1916            final int N = procs.size();
1917            for (int i = 0; i < N; i++) {
1918                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1919            }
1920        }
1921        ProcessRecord proc = mProcessNames.get(processName, uid);
1922        return proc;
1923    }
1924
1925    void ensurePackageDexOpt(String packageName) {
1926        IPackageManager pm = AppGlobals.getPackageManager();
1927        try {
1928            if (pm.performDexOpt(packageName)) {
1929                mDidDexOpt = true;
1930            }
1931        } catch (RemoteException e) {
1932        }
1933    }
1934
1935    boolean isNextTransitionForward() {
1936        int transit = mWindowManager.getPendingAppTransition();
1937        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1938                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1939                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1940    }
1941
1942    final ProcessRecord startProcessLocked(String processName,
1943            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1944            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1945            boolean isolated) {
1946        ProcessRecord app;
1947        if (!isolated) {
1948            app = getProcessRecordLocked(processName, info.uid);
1949        } else {
1950            // If this is an isolated process, it can't re-use an existing process.
1951            app = null;
1952        }
1953        // We don't have to do anything more if:
1954        // (1) There is an existing application record; and
1955        // (2) The caller doesn't think it is dead, OR there is no thread
1956        //     object attached to it so we know it couldn't have crashed; and
1957        // (3) There is a pid assigned to it, so it is either starting or
1958        //     already running.
1959        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1960                + " app=" + app + " knownToBeDead=" + knownToBeDead
1961                + " thread=" + (app != null ? app.thread : null)
1962                + " pid=" + (app != null ? app.pid : -1));
1963        if (app != null && app.pid > 0) {
1964            if (!knownToBeDead || app.thread == null) {
1965                // We already have the app running, or are waiting for it to
1966                // come up (we have a pid but not yet its thread), so keep it.
1967                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1968                // If this is a new package in the process, add the package to the list
1969                app.addPackage(info.packageName);
1970                return app;
1971            } else {
1972                // An application record is attached to a previous process,
1973                // clean it up now.
1974                if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
1975                handleAppDiedLocked(app, true, true);
1976            }
1977        }
1978
1979        String hostingNameStr = hostingName != null
1980                ? hostingName.flattenToShortString() : null;
1981
1982        if (!isolated) {
1983            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1984                // If we are in the background, then check to see if this process
1985                // is bad.  If so, we will just silently fail.
1986                if (mBadProcesses.get(info.processName, info.uid) != null) {
1987                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1988                            + "/" + info.processName);
1989                    return null;
1990                }
1991            } else {
1992                // When the user is explicitly starting a process, then clear its
1993                // crash count so that we won't make it bad until they see at
1994                // least one crash dialog again, and make the process good again
1995                // if it had been bad.
1996                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1997                        + "/" + info.processName);
1998                mProcessCrashTimes.remove(info.processName, info.uid);
1999                if (mBadProcesses.get(info.processName, info.uid) != null) {
2000                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2001                            UserHandle.getUserId(info.uid), info.uid,
2002                            info.processName);
2003                    mBadProcesses.remove(info.processName, info.uid);
2004                    if (app != null) {
2005                        app.bad = false;
2006                    }
2007                }
2008            }
2009        }
2010
2011        if (app == null) {
2012            app = newProcessRecordLocked(null, info, processName, isolated);
2013            if (app == null) {
2014                Slog.w(TAG, "Failed making new process record for "
2015                        + processName + "/" + info.uid + " isolated=" + isolated);
2016                return null;
2017            }
2018            mProcessNames.put(processName, app.uid, app);
2019            if (isolated) {
2020                mIsolatedProcesses.put(app.uid, app);
2021            }
2022        } else {
2023            // If this is a new package in the process, add the package to the list
2024            app.addPackage(info.packageName);
2025        }
2026
2027        // If the system is not ready yet, then hold off on starting this
2028        // process until it is.
2029        if (!mProcessesReady
2030                && !isAllowedWhileBooting(info)
2031                && !allowWhileBooting) {
2032            if (!mProcessesOnHold.contains(app)) {
2033                mProcessesOnHold.add(app);
2034            }
2035            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2036            return app;
2037        }
2038
2039        startProcessLocked(app, hostingType, hostingNameStr);
2040        return (app.pid != 0) ? app : null;
2041    }
2042
2043    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2044        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2045    }
2046
2047    private final void startProcessLocked(ProcessRecord app,
2048            String hostingType, String hostingNameStr) {
2049        if (app.pid > 0 && app.pid != MY_PID) {
2050            synchronized (mPidsSelfLocked) {
2051                mPidsSelfLocked.remove(app.pid);
2052                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2053            }
2054            app.setPid(0);
2055        }
2056
2057        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2058                "startProcessLocked removing on hold: " + app);
2059        mProcessesOnHold.remove(app);
2060
2061        updateCpuStats();
2062
2063        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
2064        mProcDeaths[0] = 0;
2065
2066        try {
2067            int uid = app.uid;
2068
2069            int[] gids = null;
2070            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2071            if (!app.isolated) {
2072                int[] permGids = null;
2073                try {
2074                    final PackageManager pm = mContext.getPackageManager();
2075                    permGids = pm.getPackageGids(app.info.packageName);
2076
2077                    if (Environment.isExternalStorageEmulated()) {
2078                        if (pm.checkPermission(
2079                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2080                                app.info.packageName) == PERMISSION_GRANTED) {
2081                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2082                        } else {
2083                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2084                        }
2085                    }
2086                } catch (PackageManager.NameNotFoundException e) {
2087                    Slog.w(TAG, "Unable to retrieve gids", e);
2088                }
2089
2090                /*
2091                 * Add shared application GID so applications can share some
2092                 * resources like shared libraries
2093                 */
2094                if (permGids == null) {
2095                    gids = new int[1];
2096                } else {
2097                    gids = new int[permGids.length + 1];
2098                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2099                }
2100                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2101            }
2102            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2103                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2104                        && mTopComponent != null
2105                        && app.processName.equals(mTopComponent.getPackageName())) {
2106                    uid = 0;
2107                }
2108                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2109                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2110                    uid = 0;
2111                }
2112            }
2113            int debugFlags = 0;
2114            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2115                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2116                // Also turn on CheckJNI for debuggable apps. It's quite
2117                // awkward to turn on otherwise.
2118                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2119            }
2120            // Run the app in safe mode if its manifest requests so or the
2121            // system is booted in safe mode.
2122            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2123                Zygote.systemInSafeMode == true) {
2124                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2125            }
2126            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2127                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2128            }
2129            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2130                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2131            }
2132            if ("1".equals(SystemProperties.get("debug.assert"))) {
2133                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2134            }
2135
2136            // Start the process.  It will either succeed and return a result containing
2137            // the PID of the new process, or else throw a RuntimeException.
2138            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2139                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2140                    app.info.targetSdkVersion, null, null);
2141
2142            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2143            synchronized (bs) {
2144                if (bs.isOnBattery()) {
2145                    app.batteryStats.incStartsLocked();
2146                }
2147            }
2148
2149            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2150                    UserHandle.getUserId(uid), startResult.pid, uid,
2151                    app.processName, hostingType,
2152                    hostingNameStr != null ? hostingNameStr : "");
2153
2154            if (app.persistent) {
2155                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2156            }
2157
2158            StringBuilder buf = mStringBuilder;
2159            buf.setLength(0);
2160            buf.append("Start proc ");
2161            buf.append(app.processName);
2162            buf.append(" for ");
2163            buf.append(hostingType);
2164            if (hostingNameStr != null) {
2165                buf.append(" ");
2166                buf.append(hostingNameStr);
2167            }
2168            buf.append(": pid=");
2169            buf.append(startResult.pid);
2170            buf.append(" uid=");
2171            buf.append(uid);
2172            buf.append(" gids={");
2173            if (gids != null) {
2174                for (int gi=0; gi<gids.length; gi++) {
2175                    if (gi != 0) buf.append(", ");
2176                    buf.append(gids[gi]);
2177
2178                }
2179            }
2180            buf.append("}");
2181            Slog.i(TAG, buf.toString());
2182            app.setPid(startResult.pid);
2183            app.usingWrapper = startResult.usingWrapper;
2184            app.removed = false;
2185            synchronized (mPidsSelfLocked) {
2186                this.mPidsSelfLocked.put(startResult.pid, app);
2187                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2188                msg.obj = app;
2189                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2190                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2191            }
2192        } catch (RuntimeException e) {
2193            // XXX do better error recovery.
2194            app.setPid(0);
2195            Slog.e(TAG, "Failure starting process " + app.processName, e);
2196        }
2197    }
2198
2199    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2200        if (resumed) {
2201            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2202        } else {
2203            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2204        }
2205    }
2206
2207    boolean startHomeActivityLocked(int userId) {
2208        if (mHeadless) {
2209            // Added because none of the other calls to ensureBootCompleted seem to fire
2210            // when running headless.
2211            ensureBootCompleted();
2212            return false;
2213        }
2214
2215        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2216                && mTopAction == null) {
2217            // We are running in factory test mode, but unable to find
2218            // the factory test app, so just sit around displaying the
2219            // error message and don't try to start anything.
2220            return false;
2221        }
2222        Intent intent = new Intent(
2223            mTopAction,
2224            mTopData != null ? Uri.parse(mTopData) : null);
2225        intent.setComponent(mTopComponent);
2226        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2227            intent.addCategory(Intent.CATEGORY_HOME);
2228        }
2229        ActivityInfo aInfo =
2230            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2231        if (aInfo != null) {
2232            intent.setComponent(new ComponentName(
2233                    aInfo.applicationInfo.packageName, aInfo.name));
2234            // Don't do this if the home app is currently being
2235            // instrumented.
2236            aInfo = new ActivityInfo(aInfo);
2237            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2238            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2239                    aInfo.applicationInfo.uid);
2240            if (app == null || app.instrumentationClass == null) {
2241                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2242                mMainStack.startActivityLocked(null, intent, null, aInfo,
2243                        null, null, 0, 0, 0, 0, null, false, null);
2244            }
2245        }
2246
2247        return true;
2248    }
2249
2250    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2251        ActivityInfo ai = null;
2252        ComponentName comp = intent.getComponent();
2253        try {
2254            if (comp != null) {
2255                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2256            } else {
2257                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2258                        intent,
2259                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2260                            flags, userId);
2261
2262                if (info != null) {
2263                    ai = info.activityInfo;
2264                }
2265            }
2266        } catch (RemoteException e) {
2267            // ignore
2268        }
2269
2270        return ai;
2271    }
2272
2273    /**
2274     * Starts the "new version setup screen" if appropriate.
2275     */
2276    void startSetupActivityLocked() {
2277        // Only do this once per boot.
2278        if (mCheckedForSetup) {
2279            return;
2280        }
2281
2282        // We will show this screen if the current one is a different
2283        // version than the last one shown, and we are not running in
2284        // low-level factory test mode.
2285        final ContentResolver resolver = mContext.getContentResolver();
2286        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2287                Settings.Global.getInt(resolver,
2288                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2289            mCheckedForSetup = true;
2290
2291            // See if we should be showing the platform update setup UI.
2292            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2293            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2294                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2295
2296            // We don't allow third party apps to replace this.
2297            ResolveInfo ri = null;
2298            for (int i=0; ris != null && i<ris.size(); i++) {
2299                if ((ris.get(i).activityInfo.applicationInfo.flags
2300                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2301                    ri = ris.get(i);
2302                    break;
2303                }
2304            }
2305
2306            if (ri != null) {
2307                String vers = ri.activityInfo.metaData != null
2308                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2309                        : null;
2310                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2311                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2312                            Intent.METADATA_SETUP_VERSION);
2313                }
2314                String lastVers = Settings.Secure.getString(
2315                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2316                if (vers != null && !vers.equals(lastVers)) {
2317                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2318                    intent.setComponent(new ComponentName(
2319                            ri.activityInfo.packageName, ri.activityInfo.name));
2320                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2321                            null, null, 0, 0, 0, 0, null, false, null);
2322                }
2323            }
2324        }
2325    }
2326
2327    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2328        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2329    }
2330
2331    void enforceNotIsolatedCaller(String caller) {
2332        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2333            throw new SecurityException("Isolated process not allowed to call " + caller);
2334        }
2335    }
2336
2337    public int getFrontActivityScreenCompatMode() {
2338        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2339        synchronized (this) {
2340            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2341        }
2342    }
2343
2344    public void setFrontActivityScreenCompatMode(int mode) {
2345        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2346                "setFrontActivityScreenCompatMode");
2347        synchronized (this) {
2348            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2349        }
2350    }
2351
2352    public int getPackageScreenCompatMode(String packageName) {
2353        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2354        synchronized (this) {
2355            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2356        }
2357    }
2358
2359    public void setPackageScreenCompatMode(String packageName, int mode) {
2360        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2361                "setPackageScreenCompatMode");
2362        synchronized (this) {
2363            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2364        }
2365    }
2366
2367    public boolean getPackageAskScreenCompat(String packageName) {
2368        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2369        synchronized (this) {
2370            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2371        }
2372    }
2373
2374    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2375        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2376                "setPackageAskScreenCompat");
2377        synchronized (this) {
2378            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2379        }
2380    }
2381
2382    void reportResumedActivityLocked(ActivityRecord r) {
2383        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2384        updateUsageStats(r, true);
2385    }
2386
2387    private void dispatchProcessesChanged() {
2388        int N;
2389        synchronized (this) {
2390            N = mPendingProcessChanges.size();
2391            if (mActiveProcessChanges.length < N) {
2392                mActiveProcessChanges = new ProcessChangeItem[N];
2393            }
2394            mPendingProcessChanges.toArray(mActiveProcessChanges);
2395            mAvailProcessChanges.addAll(mPendingProcessChanges);
2396            mPendingProcessChanges.clear();
2397            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2398        }
2399        int i = mProcessObservers.beginBroadcast();
2400        while (i > 0) {
2401            i--;
2402            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2403            if (observer != null) {
2404                try {
2405                    for (int j=0; j<N; j++) {
2406                        ProcessChangeItem item = mActiveProcessChanges[j];
2407                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2408                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2409                                    + item.pid + " uid=" + item.uid + ": "
2410                                    + item.foregroundActivities);
2411                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2412                                    item.foregroundActivities);
2413                        }
2414                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2415                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2416                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2417                            observer.onImportanceChanged(item.pid, item.uid,
2418                                    item.importance);
2419                        }
2420                    }
2421                } catch (RemoteException e) {
2422                }
2423            }
2424        }
2425        mProcessObservers.finishBroadcast();
2426    }
2427
2428    private void dispatchProcessDied(int pid, int uid) {
2429        int i = mProcessObservers.beginBroadcast();
2430        while (i > 0) {
2431            i--;
2432            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2433            if (observer != null) {
2434                try {
2435                    observer.onProcessDied(pid, uid);
2436                } catch (RemoteException e) {
2437                }
2438            }
2439        }
2440        mProcessObservers.finishBroadcast();
2441    }
2442
2443    final void doPendingActivityLaunchesLocked(boolean doResume) {
2444        final int N = mPendingActivityLaunches.size();
2445        if (N <= 0) {
2446            return;
2447        }
2448        for (int i=0; i<N; i++) {
2449            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2450            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2451                    pal.startFlags, doResume && i == (N-1), null);
2452        }
2453        mPendingActivityLaunches.clear();
2454    }
2455
2456    public final int startActivity(IApplicationThread caller,
2457            Intent intent, String resolvedType, IBinder resultTo,
2458            String resultWho, int requestCode, int startFlags,
2459            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2460        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2461                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2462    }
2463
2464    public final int startActivityAsUser(IApplicationThread caller,
2465            Intent intent, String resolvedType, IBinder resultTo,
2466            String resultWho, int requestCode, int startFlags,
2467            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2468        enforceNotIsolatedCaller("startActivity");
2469        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2470                false, true, "startActivity", null);
2471        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2472                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2473                null, null, options, userId);
2474    }
2475
2476    public final WaitResult startActivityAndWait(IApplicationThread caller,
2477            Intent intent, String resolvedType, IBinder resultTo,
2478            String resultWho, int requestCode, int startFlags, String profileFile,
2479            ParcelFileDescriptor profileFd, Bundle options, int userId) {
2480        enforceNotIsolatedCaller("startActivityAndWait");
2481        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2482                false, true, "startActivityAndWait", null);
2483        WaitResult res = new WaitResult();
2484        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2485                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2486                res, null, options, UserHandle.getCallingUserId());
2487        return res;
2488    }
2489
2490    public final int startActivityWithConfig(IApplicationThread caller,
2491            Intent intent, String resolvedType, IBinder resultTo,
2492            String resultWho, int requestCode, int startFlags, Configuration config,
2493            Bundle options, int userId) {
2494        enforceNotIsolatedCaller("startActivityWithConfig");
2495        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2496                false, true, "startActivityWithConfig", null);
2497        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2498                resultTo, resultWho, requestCode, startFlags,
2499                null, null, null, config, options, userId);
2500        return ret;
2501    }
2502
2503    public int startActivityIntentSender(IApplicationThread caller,
2504            IntentSender intent, Intent fillInIntent, String resolvedType,
2505            IBinder resultTo, String resultWho, int requestCode,
2506            int flagsMask, int flagsValues, Bundle options) {
2507        enforceNotIsolatedCaller("startActivityIntentSender");
2508        // Refuse possible leaked file descriptors
2509        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2510            throw new IllegalArgumentException("File descriptors passed in Intent");
2511        }
2512
2513        IIntentSender sender = intent.getTarget();
2514        if (!(sender instanceof PendingIntentRecord)) {
2515            throw new IllegalArgumentException("Bad PendingIntent object");
2516        }
2517
2518        PendingIntentRecord pir = (PendingIntentRecord)sender;
2519
2520        synchronized (this) {
2521            // If this is coming from the currently resumed activity, it is
2522            // effectively saying that app switches are allowed at this point.
2523            if (mMainStack.mResumedActivity != null
2524                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2525                            Binder.getCallingUid()) {
2526                mAppSwitchesAllowedTime = 0;
2527            }
2528        }
2529        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2530                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2531        return ret;
2532    }
2533
2534    public boolean startNextMatchingActivity(IBinder callingActivity,
2535            Intent intent, Bundle options) {
2536        // Refuse possible leaked file descriptors
2537        if (intent != null && intent.hasFileDescriptors() == true) {
2538            throw new IllegalArgumentException("File descriptors passed in Intent");
2539        }
2540
2541        synchronized (this) {
2542            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2543            if (r == null) {
2544                ActivityOptions.abort(options);
2545                return false;
2546            }
2547            if (r.app == null || r.app.thread == null) {
2548                // The caller is not running...  d'oh!
2549                ActivityOptions.abort(options);
2550                return false;
2551            }
2552            intent = new Intent(intent);
2553            // The caller is not allowed to change the data.
2554            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2555            // And we are resetting to find the next component...
2556            intent.setComponent(null);
2557
2558            ActivityInfo aInfo = null;
2559            try {
2560                List<ResolveInfo> resolves =
2561                    AppGlobals.getPackageManager().queryIntentActivities(
2562                            intent, r.resolvedType,
2563                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2564                            UserHandle.getCallingUserId());
2565
2566                // Look for the original activity in the list...
2567                final int N = resolves != null ? resolves.size() : 0;
2568                for (int i=0; i<N; i++) {
2569                    ResolveInfo rInfo = resolves.get(i);
2570                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2571                            && rInfo.activityInfo.name.equals(r.info.name)) {
2572                        // We found the current one...  the next matching is
2573                        // after it.
2574                        i++;
2575                        if (i<N) {
2576                            aInfo = resolves.get(i).activityInfo;
2577                        }
2578                        break;
2579                    }
2580                }
2581            } catch (RemoteException e) {
2582            }
2583
2584            if (aInfo == null) {
2585                // Nobody who is next!
2586                ActivityOptions.abort(options);
2587                return false;
2588            }
2589
2590            intent.setComponent(new ComponentName(
2591                    aInfo.applicationInfo.packageName, aInfo.name));
2592            intent.setFlags(intent.getFlags()&~(
2593                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2594                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2595                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2596                    Intent.FLAG_ACTIVITY_NEW_TASK));
2597
2598            // Okay now we need to start the new activity, replacing the
2599            // currently running activity.  This is a little tricky because
2600            // we want to start the new one as if the current one is finished,
2601            // but not finish the current one first so that there is no flicker.
2602            // And thus...
2603            final boolean wasFinishing = r.finishing;
2604            r.finishing = true;
2605
2606            // Propagate reply information over to the new activity.
2607            final ActivityRecord resultTo = r.resultTo;
2608            final String resultWho = r.resultWho;
2609            final int requestCode = r.requestCode;
2610            r.resultTo = null;
2611            if (resultTo != null) {
2612                resultTo.removeResultsLocked(r, resultWho, requestCode);
2613            }
2614
2615            final long origId = Binder.clearCallingIdentity();
2616            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2617                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2618                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2619                    options, false, null);
2620            Binder.restoreCallingIdentity(origId);
2621
2622            r.finishing = wasFinishing;
2623            if (res != ActivityManager.START_SUCCESS) {
2624                return false;
2625            }
2626            return true;
2627        }
2628    }
2629
2630    final int startActivityInPackage(int uid,
2631            Intent intent, String resolvedType, IBinder resultTo,
2632            String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
2633
2634        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2635                false, true, "startActivityInPackage", null);
2636
2637        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2638                resultTo, resultWho, requestCode, startFlags,
2639                null, null, null, null, options, userId);
2640        return ret;
2641    }
2642
2643    public final int startActivities(IApplicationThread caller,
2644            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
2645            int userId) {
2646        enforceNotIsolatedCaller("startActivities");
2647        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2648                false, true, "startActivity", null);
2649        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2650                options, userId);
2651        return ret;
2652    }
2653
2654    final int startActivitiesInPackage(int uid,
2655            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2656            Bundle options, int userId) {
2657
2658        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2659                false, true, "startActivityInPackage", null);
2660        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2661                options, userId);
2662        return ret;
2663    }
2664
2665    final void addRecentTaskLocked(TaskRecord task) {
2666        int N = mRecentTasks.size();
2667        // Quick case: check if the top-most recent task is the same.
2668        if (N > 0 && mRecentTasks.get(0) == task) {
2669            return;
2670        }
2671        // Remove any existing entries that are the same kind of task.
2672        for (int i=0; i<N; i++) {
2673            TaskRecord tr = mRecentTasks.get(i);
2674            if (task.userId == tr.userId
2675                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2676                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2677                mRecentTasks.remove(i);
2678                i--;
2679                N--;
2680                if (task.intent == null) {
2681                    // If the new recent task we are adding is not fully
2682                    // specified, then replace it with the existing recent task.
2683                    task = tr;
2684                }
2685            }
2686        }
2687        if (N >= MAX_RECENT_TASKS) {
2688            mRecentTasks.remove(N-1);
2689        }
2690        mRecentTasks.add(0, task);
2691    }
2692
2693    public void setRequestedOrientation(IBinder token,
2694            int requestedOrientation) {
2695        synchronized (this) {
2696            ActivityRecord r = mMainStack.isInStackLocked(token);
2697            if (r == null) {
2698                return;
2699            }
2700            final long origId = Binder.clearCallingIdentity();
2701            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2702            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2703                    mConfiguration,
2704                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2705            if (config != null) {
2706                r.frozenBeforeDestroy = true;
2707                if (!updateConfigurationLocked(config, r, false, false)) {
2708                    mMainStack.resumeTopActivityLocked(null);
2709                }
2710            }
2711            Binder.restoreCallingIdentity(origId);
2712        }
2713    }
2714
2715    public int getRequestedOrientation(IBinder token) {
2716        synchronized (this) {
2717            ActivityRecord r = mMainStack.isInStackLocked(token);
2718            if (r == null) {
2719                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2720            }
2721            return mWindowManager.getAppOrientation(r.appToken);
2722        }
2723    }
2724
2725    /**
2726     * This is the internal entry point for handling Activity.finish().
2727     *
2728     * @param token The Binder token referencing the Activity we want to finish.
2729     * @param resultCode Result code, if any, from this Activity.
2730     * @param resultData Result data (Intent), if any, from this Activity.
2731     *
2732     * @return Returns true if the activity successfully finished, or false if it is still running.
2733     */
2734    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2735        // Refuse possible leaked file descriptors
2736        if (resultData != null && resultData.hasFileDescriptors() == true) {
2737            throw new IllegalArgumentException("File descriptors passed in Intent");
2738        }
2739
2740        synchronized(this) {
2741            if (mController != null) {
2742                // Find the first activity that is not finishing.
2743                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2744                if (next != null) {
2745                    // ask watcher if this is allowed
2746                    boolean resumeOK = true;
2747                    try {
2748                        resumeOK = mController.activityResuming(next.packageName);
2749                    } catch (RemoteException e) {
2750                        mController = null;
2751                    }
2752
2753                    if (!resumeOK) {
2754                        return false;
2755                    }
2756                }
2757            }
2758            final long origId = Binder.clearCallingIdentity();
2759            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2760                    resultData, "app-request", true);
2761            Binder.restoreCallingIdentity(origId);
2762            return res;
2763        }
2764    }
2765
2766    public final void finishHeavyWeightApp() {
2767        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2768                != PackageManager.PERMISSION_GRANTED) {
2769            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2770                    + Binder.getCallingPid()
2771                    + ", uid=" + Binder.getCallingUid()
2772                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2773            Slog.w(TAG, msg);
2774            throw new SecurityException(msg);
2775        }
2776
2777        synchronized(this) {
2778            if (mHeavyWeightProcess == null) {
2779                return;
2780            }
2781
2782            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2783                    mHeavyWeightProcess.activities);
2784            for (int i=0; i<activities.size(); i++) {
2785                ActivityRecord r = activities.get(i);
2786                if (!r.finishing) {
2787                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2788                    if (index >= 0) {
2789                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2790                                null, "finish-heavy", true);
2791                    }
2792                }
2793            }
2794
2795            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
2796                    mHeavyWeightProcess.userId, 0));
2797            mHeavyWeightProcess = null;
2798        }
2799    }
2800
2801    public void crashApplication(int uid, int initialPid, String packageName,
2802            String message) {
2803        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2804                != PackageManager.PERMISSION_GRANTED) {
2805            String msg = "Permission Denial: crashApplication() from pid="
2806                    + Binder.getCallingPid()
2807                    + ", uid=" + Binder.getCallingUid()
2808                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2809            Slog.w(TAG, msg);
2810            throw new SecurityException(msg);
2811        }
2812
2813        synchronized(this) {
2814            ProcessRecord proc = null;
2815
2816            // Figure out which process to kill.  We don't trust that initialPid
2817            // still has any relation to current pids, so must scan through the
2818            // list.
2819            synchronized (mPidsSelfLocked) {
2820                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2821                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2822                    if (p.uid != uid) {
2823                        continue;
2824                    }
2825                    if (p.pid == initialPid) {
2826                        proc = p;
2827                        break;
2828                    }
2829                    for (String str : p.pkgList) {
2830                        if (str.equals(packageName)) {
2831                            proc = p;
2832                        }
2833                    }
2834                }
2835            }
2836
2837            if (proc == null) {
2838                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2839                        + " initialPid=" + initialPid
2840                        + " packageName=" + packageName);
2841                return;
2842            }
2843
2844            if (proc.thread != null) {
2845                if (proc.pid == Process.myPid()) {
2846                    Log.w(TAG, "crashApplication: trying to crash self!");
2847                    return;
2848                }
2849                long ident = Binder.clearCallingIdentity();
2850                try {
2851                    proc.thread.scheduleCrash(message);
2852                } catch (RemoteException e) {
2853                }
2854                Binder.restoreCallingIdentity(ident);
2855            }
2856        }
2857    }
2858
2859    public final void finishSubActivity(IBinder token, String resultWho,
2860            int requestCode) {
2861        synchronized(this) {
2862            final long origId = Binder.clearCallingIdentity();
2863            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2864            Binder.restoreCallingIdentity(origId);
2865        }
2866    }
2867
2868    public boolean finishActivityAffinity(IBinder token) {
2869        synchronized(this) {
2870            final long origId = Binder.clearCallingIdentity();
2871            boolean res = mMainStack.finishActivityAffinityLocked(token);
2872            Binder.restoreCallingIdentity(origId);
2873            return res;
2874        }
2875    }
2876
2877    public boolean willActivityBeVisible(IBinder token) {
2878        synchronized(this) {
2879            int i;
2880            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2881                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2882                if (r.appToken == token) {
2883                    return true;
2884                }
2885                if (r.fullscreen && !r.finishing) {
2886                    return false;
2887                }
2888            }
2889            return true;
2890        }
2891    }
2892
2893    public void overridePendingTransition(IBinder token, String packageName,
2894            int enterAnim, int exitAnim) {
2895        synchronized(this) {
2896            ActivityRecord self = mMainStack.isInStackLocked(token);
2897            if (self == null) {
2898                return;
2899            }
2900
2901            final long origId = Binder.clearCallingIdentity();
2902
2903            if (self.state == ActivityState.RESUMED
2904                    || self.state == ActivityState.PAUSING) {
2905                mWindowManager.overridePendingAppTransition(packageName,
2906                        enterAnim, exitAnim, null);
2907            }
2908
2909            Binder.restoreCallingIdentity(origId);
2910        }
2911    }
2912
2913    /**
2914     * Main function for removing an existing process from the activity manager
2915     * as a result of that process going away.  Clears out all connections
2916     * to the process.
2917     */
2918    private final void handleAppDiedLocked(ProcessRecord app,
2919            boolean restarting, boolean allowRestart) {
2920        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2921        if (!restarting) {
2922            mLruProcesses.remove(app);
2923        }
2924
2925        if (mProfileProc == app) {
2926            clearProfilerLocked();
2927        }
2928
2929        // Just in case...
2930        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2931            if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG,
2932                    "App died while pausing: " + mMainStack.mPausingActivity);
2933            mMainStack.mPausingActivity = null;
2934        }
2935        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2936            mMainStack.mLastPausedActivity = null;
2937        }
2938
2939        // Remove this application's activities from active lists.
2940        boolean hasVisibleActivities = mMainStack.removeHistoryRecordsForAppLocked(app);
2941
2942        app.activities.clear();
2943
2944        if (app.instrumentationClass != null) {
2945            Slog.w(TAG, "Crash of app " + app.processName
2946                  + " running instrumentation " + app.instrumentationClass);
2947            Bundle info = new Bundle();
2948            info.putString("shortMsg", "Process crashed.");
2949            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2950        }
2951
2952        if (!restarting) {
2953            if (!mMainStack.resumeTopActivityLocked(null)) {
2954                // If there was nothing to resume, and we are not already
2955                // restarting this process, but there is a visible activity that
2956                // is hosted by the process...  then make sure all visible
2957                // activities are running, taking care of restarting this
2958                // process.
2959                if (hasVisibleActivities) {
2960                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2961                }
2962            }
2963        }
2964    }
2965
2966    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2967        IBinder threadBinder = thread.asBinder();
2968        // Find the application record.
2969        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2970            ProcessRecord rec = mLruProcesses.get(i);
2971            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2972                return i;
2973            }
2974        }
2975        return -1;
2976    }
2977
2978    final ProcessRecord getRecordForAppLocked(
2979            IApplicationThread thread) {
2980        if (thread == null) {
2981            return null;
2982        }
2983
2984        int appIndex = getLRURecordIndexForAppLocked(thread);
2985        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2986    }
2987
2988    final void appDiedLocked(ProcessRecord app, int pid,
2989            IApplicationThread thread) {
2990
2991        mProcDeaths[0]++;
2992
2993        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2994        synchronized (stats) {
2995            stats.noteProcessDiedLocked(app.info.uid, pid);
2996        }
2997
2998        // Clean up already done if the process has been re-started.
2999        if (app.pid == pid && app.thread != null &&
3000                app.thread.asBinder() == thread.asBinder()) {
3001            if (!app.killedBackground) {
3002                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3003                        + ") has died.");
3004            }
3005            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3006            if (DEBUG_CLEANUP) Slog.v(
3007                TAG, "Dying app: " + app + ", pid: " + pid
3008                + ", thread: " + thread.asBinder());
3009            boolean doLowMem = app.instrumentationClass == null;
3010            handleAppDiedLocked(app, false, true);
3011
3012            if (doLowMem) {
3013                // If there are no longer any background processes running,
3014                // and the app that died was not running instrumentation,
3015                // then tell everyone we are now low on memory.
3016                boolean haveBg = false;
3017                for (int i=mLruProcesses.size()-1; i>=0; i--) {
3018                    ProcessRecord rec = mLruProcesses.get(i);
3019                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3020                        haveBg = true;
3021                        break;
3022                    }
3023                }
3024
3025                if (!haveBg) {
3026                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3027                    long now = SystemClock.uptimeMillis();
3028                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
3029                        ProcessRecord rec = mLruProcesses.get(i);
3030                        if (rec != app && rec.thread != null &&
3031                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3032                            // The low memory report is overriding any current
3033                            // state for a GC request.  Make sure to do
3034                            // heavy/important/visible/foreground processes first.
3035                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3036                                rec.lastRequestedGc = 0;
3037                            } else {
3038                                rec.lastRequestedGc = rec.lastLowMemory;
3039                            }
3040                            rec.reportLowMemory = true;
3041                            rec.lastLowMemory = now;
3042                            mProcessesToGc.remove(rec);
3043                            addProcessToGcListLocked(rec);
3044                        }
3045                    }
3046                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3047                    scheduleAppGcsLocked();
3048                }
3049            }
3050        } else if (app.pid != pid) {
3051            // A new process has already been started.
3052            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3053                    + ") has died and restarted (pid " + app.pid + ").");
3054            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3055        } else if (DEBUG_PROCESSES) {
3056            Slog.d(TAG, "Received spurious death notification for thread "
3057                    + thread.asBinder());
3058        }
3059    }
3060
3061    /**
3062     * If a stack trace dump file is configured, dump process stack traces.
3063     * @param clearTraces causes the dump file to be erased prior to the new
3064     *    traces being written, if true; when false, the new traces will be
3065     *    appended to any existing file content.
3066     * @param firstPids of dalvik VM processes to dump stack traces for first
3067     * @param lastPids of dalvik VM processes to dump stack traces for last
3068     * @param nativeProcs optional list of native process names to dump stack crawls
3069     * @return file containing stack traces, or null if no dump file is configured
3070     */
3071    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3072            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3073        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3074        if (tracesPath == null || tracesPath.length() == 0) {
3075            return null;
3076        }
3077
3078        File tracesFile = new File(tracesPath);
3079        try {
3080            File tracesDir = tracesFile.getParentFile();
3081            if (!tracesDir.exists()) {
3082                tracesFile.mkdirs();
3083                if (!SELinux.restorecon(tracesDir)) {
3084                    return null;
3085                }
3086            }
3087            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3088
3089            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3090            tracesFile.createNewFile();
3091            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3092        } catch (IOException e) {
3093            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3094            return null;
3095        }
3096
3097        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3098        return tracesFile;
3099    }
3100
3101    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3102            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3103        // Use a FileObserver to detect when traces finish writing.
3104        // The order of traces is considered important to maintain for legibility.
3105        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3106            public synchronized void onEvent(int event, String path) { notify(); }
3107        };
3108
3109        try {
3110            observer.startWatching();
3111
3112            // First collect all of the stacks of the most important pids.
3113            if (firstPids != null) {
3114                try {
3115                    int num = firstPids.size();
3116                    for (int i = 0; i < num; i++) {
3117                        synchronized (observer) {
3118                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3119                            observer.wait(200);  // Wait for write-close, give up after 200msec
3120                        }
3121                    }
3122                } catch (InterruptedException e) {
3123                    Log.wtf(TAG, e);
3124                }
3125            }
3126
3127            // Next measure CPU usage.
3128            if (processStats != null) {
3129                processStats.init();
3130                System.gc();
3131                processStats.update();
3132                try {
3133                    synchronized (processStats) {
3134                        processStats.wait(500); // measure over 1/2 second.
3135                    }
3136                } catch (InterruptedException e) {
3137                }
3138                processStats.update();
3139
3140                // We'll take the stack crawls of just the top apps using CPU.
3141                final int N = processStats.countWorkingStats();
3142                int numProcs = 0;
3143                for (int i=0; i<N && numProcs<5; i++) {
3144                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3145                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3146                        numProcs++;
3147                        try {
3148                            synchronized (observer) {
3149                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3150                                observer.wait(200);  // Wait for write-close, give up after 200msec
3151                            }
3152                        } catch (InterruptedException e) {
3153                            Log.wtf(TAG, e);
3154                        }
3155
3156                    }
3157                }
3158            }
3159
3160        } finally {
3161            observer.stopWatching();
3162        }
3163
3164        if (nativeProcs != null) {
3165            int[] pids = Process.getPidsForCommands(nativeProcs);
3166            if (pids != null) {
3167                for (int pid : pids) {
3168                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3169                }
3170            }
3171        }
3172    }
3173
3174    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3175        if (true || IS_USER_BUILD) {
3176            return;
3177        }
3178        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3179        if (tracesPath == null || tracesPath.length() == 0) {
3180            return;
3181        }
3182
3183        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3184        StrictMode.allowThreadDiskWrites();
3185        try {
3186            final File tracesFile = new File(tracesPath);
3187            final File tracesDir = tracesFile.getParentFile();
3188            final File tracesTmp = new File(tracesDir, "__tmp__");
3189            try {
3190                if (!tracesDir.exists()) {
3191                    tracesFile.mkdirs();
3192                    if (!SELinux.restorecon(tracesDir.getPath())) {
3193                        return;
3194                    }
3195                }
3196                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3197
3198                if (tracesFile.exists()) {
3199                    tracesTmp.delete();
3200                    tracesFile.renameTo(tracesTmp);
3201                }
3202                StringBuilder sb = new StringBuilder();
3203                Time tobj = new Time();
3204                tobj.set(System.currentTimeMillis());
3205                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3206                sb.append(": ");
3207                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3208                sb.append(" since ");
3209                sb.append(msg);
3210                FileOutputStream fos = new FileOutputStream(tracesFile);
3211                fos.write(sb.toString().getBytes());
3212                if (app == null) {
3213                    fos.write("\n*** No application process!".getBytes());
3214                }
3215                fos.close();
3216                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3217            } catch (IOException e) {
3218                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3219                return;
3220            }
3221
3222            if (app != null) {
3223                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3224                firstPids.add(app.pid);
3225                dumpStackTraces(tracesPath, firstPids, null, null, null);
3226            }
3227
3228            File lastTracesFile = null;
3229            File curTracesFile = null;
3230            for (int i=9; i>=0; i--) {
3231                String name = String.format("slow%02d.txt", i);
3232                curTracesFile = new File(tracesDir, name);
3233                if (curTracesFile.exists()) {
3234                    if (lastTracesFile != null) {
3235                        curTracesFile.renameTo(lastTracesFile);
3236                    } else {
3237                        curTracesFile.delete();
3238                    }
3239                }
3240                lastTracesFile = curTracesFile;
3241            }
3242            tracesFile.renameTo(curTracesFile);
3243            if (tracesTmp.exists()) {
3244                tracesTmp.renameTo(tracesFile);
3245            }
3246        } finally {
3247            StrictMode.setThreadPolicy(oldPolicy);
3248        }
3249    }
3250
3251    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3252            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3253        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3254        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3255
3256        if (mController != null) {
3257            try {
3258                // 0 == continue, -1 = kill process immediately
3259                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3260                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3261            } catch (RemoteException e) {
3262                mController = null;
3263            }
3264        }
3265
3266        long anrTime = SystemClock.uptimeMillis();
3267        if (MONITOR_CPU_USAGE) {
3268            updateCpuStatsNow();
3269        }
3270
3271        synchronized (this) {
3272            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3273            if (mShuttingDown) {
3274                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3275                return;
3276            } else if (app.notResponding) {
3277                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3278                return;
3279            } else if (app.crashing) {
3280                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3281                return;
3282            }
3283
3284            // In case we come through here for the same app before completing
3285            // this one, mark as anring now so we will bail out.
3286            app.notResponding = true;
3287
3288            // Log the ANR to the event log.
3289            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3290                    app.processName, app.info.flags, annotation);
3291
3292            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3293            firstPids.add(app.pid);
3294
3295            int parentPid = app.pid;
3296            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3297            if (parentPid != app.pid) firstPids.add(parentPid);
3298
3299            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3300
3301            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3302                ProcessRecord r = mLruProcesses.get(i);
3303                if (r != null && r.thread != null) {
3304                    int pid = r.pid;
3305                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3306                        if (r.persistent) {
3307                            firstPids.add(pid);
3308                        } else {
3309                            lastPids.put(pid, Boolean.TRUE);
3310                        }
3311                    }
3312                }
3313            }
3314        }
3315
3316        // Log the ANR to the main log.
3317        StringBuilder info = new StringBuilder();
3318        info.setLength(0);
3319        info.append("ANR in ").append(app.processName);
3320        if (activity != null && activity.shortComponentName != null) {
3321            info.append(" (").append(activity.shortComponentName).append(")");
3322        }
3323        info.append("\n");
3324        if (annotation != null) {
3325            info.append("Reason: ").append(annotation).append("\n");
3326        }
3327        if (parent != null && parent != activity) {
3328            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3329        }
3330
3331        final ProcessStats processStats = new ProcessStats(true);
3332
3333        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3334
3335        String cpuInfo = null;
3336        if (MONITOR_CPU_USAGE) {
3337            updateCpuStatsNow();
3338            synchronized (mProcessStatsThread) {
3339                cpuInfo = mProcessStats.printCurrentState(anrTime);
3340            }
3341            info.append(processStats.printCurrentLoad());
3342            info.append(cpuInfo);
3343        }
3344
3345        info.append(processStats.printCurrentState(anrTime));
3346
3347        Slog.e(TAG, info.toString());
3348        if (tracesFile == null) {
3349            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3350            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3351        }
3352
3353        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3354                cpuInfo, tracesFile, null);
3355
3356        if (mController != null) {
3357            try {
3358                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3359                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3360                if (res != 0) {
3361                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3362                    return;
3363                }
3364            } catch (RemoteException e) {
3365                mController = null;
3366            }
3367        }
3368
3369        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3370        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3371                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3372
3373        synchronized (this) {
3374            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3375                Slog.w(TAG, "Killing " + app + ": background ANR");
3376                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
3377                        app.processName, app.setAdj, "background ANR");
3378                Process.killProcessQuiet(app.pid);
3379                return;
3380            }
3381
3382            // Set the app's notResponding state, and look up the errorReportReceiver
3383            makeAppNotRespondingLocked(app,
3384                    activity != null ? activity.shortComponentName : null,
3385                    annotation != null ? "ANR " + annotation : "ANR",
3386                    info.toString());
3387
3388            // Bring up the infamous App Not Responding dialog
3389            Message msg = Message.obtain();
3390            HashMap map = new HashMap();
3391            msg.what = SHOW_NOT_RESPONDING_MSG;
3392            msg.obj = map;
3393            msg.arg1 = aboveSystem ? 1 : 0;
3394            map.put("app", app);
3395            if (activity != null) {
3396                map.put("activity", activity);
3397            }
3398
3399            mHandler.sendMessage(msg);
3400        }
3401    }
3402
3403    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3404        if (!mLaunchWarningShown) {
3405            mLaunchWarningShown = true;
3406            mHandler.post(new Runnable() {
3407                @Override
3408                public void run() {
3409                    synchronized (ActivityManagerService.this) {
3410                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3411                        d.show();
3412                        mHandler.postDelayed(new Runnable() {
3413                            @Override
3414                            public void run() {
3415                                synchronized (ActivityManagerService.this) {
3416                                    d.dismiss();
3417                                    mLaunchWarningShown = false;
3418                                }
3419                            }
3420                        }, 4000);
3421                    }
3422                }
3423            });
3424        }
3425    }
3426
3427    public boolean clearApplicationUserData(final String packageName,
3428            final IPackageDataObserver observer, int userId) {
3429        enforceNotIsolatedCaller("clearApplicationUserData");
3430        int uid = Binder.getCallingUid();
3431        int pid = Binder.getCallingPid();
3432        userId = handleIncomingUser(pid, uid,
3433                userId, false, true, "clearApplicationUserData", null);
3434        long callingId = Binder.clearCallingIdentity();
3435        try {
3436            IPackageManager pm = AppGlobals.getPackageManager();
3437            int pkgUid = -1;
3438            synchronized(this) {
3439                try {
3440                    pkgUid = pm.getPackageUid(packageName, userId);
3441                } catch (RemoteException e) {
3442                }
3443                if (pkgUid == -1) {
3444                    Slog.w(TAG, "Invalid packageName:" + packageName);
3445                    return false;
3446                }
3447                if (uid == pkgUid || checkComponentPermission(
3448                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3449                        pid, uid, -1, true)
3450                        == PackageManager.PERMISSION_GRANTED) {
3451                    forceStopPackageLocked(packageName, pkgUid);
3452                } else {
3453                    throw new SecurityException(pid+" does not have permission:"+
3454                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3455                                    "for process:"+packageName);
3456                }
3457            }
3458
3459            try {
3460                //clear application user data
3461                pm.clearApplicationUserData(packageName, observer, userId);
3462                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3463                        Uri.fromParts("package", packageName, null));
3464                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3465                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3466                        null, null, 0, null, null, null, false, false, userId);
3467            } catch (RemoteException e) {
3468            }
3469        } finally {
3470            Binder.restoreCallingIdentity(callingId);
3471        }
3472        return true;
3473    }
3474
3475    public void killBackgroundProcesses(final String packageName, int userId) {
3476        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3477                != PackageManager.PERMISSION_GRANTED &&
3478                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3479                        != PackageManager.PERMISSION_GRANTED) {
3480            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3481                    + Binder.getCallingPid()
3482                    + ", uid=" + Binder.getCallingUid()
3483                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3484            Slog.w(TAG, msg);
3485            throw new SecurityException(msg);
3486        }
3487
3488        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3489                userId, true, true, "killBackgroundProcesses", null);
3490        long callingId = Binder.clearCallingIdentity();
3491        try {
3492            IPackageManager pm = AppGlobals.getPackageManager();
3493            synchronized(this) {
3494                int appId = -1;
3495                try {
3496                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
3497                } catch (RemoteException e) {
3498                }
3499                if (appId == -1) {
3500                    Slog.w(TAG, "Invalid packageName: " + packageName);
3501                    return;
3502                }
3503                killPackageProcessesLocked(packageName, appId, userId,
3504                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3505            }
3506        } finally {
3507            Binder.restoreCallingIdentity(callingId);
3508        }
3509    }
3510
3511    public void killAllBackgroundProcesses() {
3512        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3513                != PackageManager.PERMISSION_GRANTED) {
3514            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3515                    + Binder.getCallingPid()
3516                    + ", uid=" + Binder.getCallingUid()
3517                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3518            Slog.w(TAG, msg);
3519            throw new SecurityException(msg);
3520        }
3521
3522        long callingId = Binder.clearCallingIdentity();
3523        try {
3524            synchronized(this) {
3525                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3526                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3527                    final int NA = apps.size();
3528                    for (int ia=0; ia<NA; ia++) {
3529                        ProcessRecord app = apps.valueAt(ia);
3530                        if (app.persistent) {
3531                            // we don't kill persistent processes
3532                            continue;
3533                        }
3534                        if (app.removed) {
3535                            procs.add(app);
3536                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3537                            app.removed = true;
3538                            procs.add(app);
3539                        }
3540                    }
3541                }
3542
3543                int N = procs.size();
3544                for (int i=0; i<N; i++) {
3545                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3546                }
3547            }
3548        } finally {
3549            Binder.restoreCallingIdentity(callingId);
3550        }
3551    }
3552
3553    public void forceStopPackage(final String packageName, int userId) {
3554        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3555                != PackageManager.PERMISSION_GRANTED) {
3556            String msg = "Permission Denial: forceStopPackage() from pid="
3557                    + Binder.getCallingPid()
3558                    + ", uid=" + Binder.getCallingUid()
3559                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3560            Slog.w(TAG, msg);
3561            throw new SecurityException(msg);
3562        }
3563        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3564                userId, true, true, "forceStopPackage", null);
3565        long callingId = Binder.clearCallingIdentity();
3566        try {
3567            IPackageManager pm = AppGlobals.getPackageManager();
3568            synchronized(this) {
3569                int[] users = userId == UserHandle.USER_ALL
3570                        ? getUsersLocked() : new int[] { userId };
3571                for (int user : users) {
3572                    int pkgUid = -1;
3573                    try {
3574                        pkgUid = pm.getPackageUid(packageName, user);
3575                    } catch (RemoteException e) {
3576                    }
3577                    if (pkgUid == -1) {
3578                        Slog.w(TAG, "Invalid packageName: " + packageName);
3579                        continue;
3580                    }
3581                    try {
3582                        pm.setPackageStoppedState(packageName, true, user);
3583                    } catch (RemoteException e) {
3584                    } catch (IllegalArgumentException e) {
3585                        Slog.w(TAG, "Failed trying to unstop package "
3586                                + packageName + ": " + e);
3587                    }
3588                    if (isUserRunningLocked(user)) {
3589                        forceStopPackageLocked(packageName, pkgUid);
3590                    }
3591                }
3592            }
3593        } finally {
3594            Binder.restoreCallingIdentity(callingId);
3595        }
3596    }
3597
3598    /*
3599     * The pkg name and app id have to be specified.
3600     */
3601    public void killApplicationWithAppId(String pkg, int appid) {
3602        if (pkg == null) {
3603            return;
3604        }
3605        // Make sure the uid is valid.
3606        if (appid < 0) {
3607            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
3608            return;
3609        }
3610        int callerUid = Binder.getCallingUid();
3611        // Only the system server can kill an application
3612        if (callerUid == Process.SYSTEM_UID) {
3613            // Post an aysnc message to kill the application
3614            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3615            msg.arg1 = appid;
3616            msg.arg2 = 0;
3617            msg.obj = pkg;
3618            mHandler.sendMessage(msg);
3619        } else {
3620            throw new SecurityException(callerUid + " cannot kill pkg: " +
3621                    pkg);
3622        }
3623    }
3624
3625    public void closeSystemDialogs(String reason) {
3626        enforceNotIsolatedCaller("closeSystemDialogs");
3627
3628        final int pid = Binder.getCallingPid();
3629        final int uid = Binder.getCallingUid();
3630        final long origId = Binder.clearCallingIdentity();
3631        try {
3632            synchronized (this) {
3633                // Only allow this from foreground processes, so that background
3634                // applications can't abuse it to prevent system UI from being shown.
3635                if (uid >= Process.FIRST_APPLICATION_UID) {
3636                    ProcessRecord proc;
3637                    synchronized (mPidsSelfLocked) {
3638                        proc = mPidsSelfLocked.get(pid);
3639                    }
3640                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
3641                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
3642                                + " from background process " + proc);
3643                        return;
3644                    }
3645                }
3646                closeSystemDialogsLocked(reason);
3647            }
3648        } finally {
3649            Binder.restoreCallingIdentity(origId);
3650        }
3651    }
3652
3653    void closeSystemDialogsLocked(String reason) {
3654        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3655        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3656                | Intent.FLAG_RECEIVER_FOREGROUND);
3657        if (reason != null) {
3658            intent.putExtra("reason", reason);
3659        }
3660        mWindowManager.closeSystemDialogs(reason);
3661
3662        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3663            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3664            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3665                r.stack.finishActivityLocked(r, i,
3666                        Activity.RESULT_CANCELED, null, "close-sys", true);
3667            }
3668        }
3669
3670        broadcastIntentLocked(null, null, intent, null,
3671                null, 0, null, null, null, false, false, -1,
3672                Process.SYSTEM_UID, UserHandle.USER_ALL);
3673    }
3674
3675    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3676            throws RemoteException {
3677        enforceNotIsolatedCaller("getProcessMemoryInfo");
3678        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3679        for (int i=pids.length-1; i>=0; i--) {
3680            infos[i] = new Debug.MemoryInfo();
3681            Debug.getMemoryInfo(pids[i], infos[i]);
3682        }
3683        return infos;
3684    }
3685
3686    public long[] getProcessPss(int[] pids) throws RemoteException {
3687        enforceNotIsolatedCaller("getProcessPss");
3688        long[] pss = new long[pids.length];
3689        for (int i=pids.length-1; i>=0; i--) {
3690            pss[i] = Debug.getPss(pids[i]);
3691        }
3692        return pss;
3693    }
3694
3695    public void killApplicationProcess(String processName, int uid) {
3696        if (processName == null) {
3697            return;
3698        }
3699
3700        int callerUid = Binder.getCallingUid();
3701        // Only the system server can kill an application
3702        if (callerUid == Process.SYSTEM_UID) {
3703            synchronized (this) {
3704                ProcessRecord app = getProcessRecordLocked(processName, uid);
3705                if (app != null && app.thread != null) {
3706                    try {
3707                        app.thread.scheduleSuicide();
3708                    } catch (RemoteException e) {
3709                        // If the other end already died, then our work here is done.
3710                    }
3711                } else {
3712                    Slog.w(TAG, "Process/uid not found attempting kill of "
3713                            + processName + " / " + uid);
3714                }
3715            }
3716        } else {
3717            throw new SecurityException(callerUid + " cannot kill app process: " +
3718                    processName);
3719        }
3720    }
3721
3722    private void forceStopPackageLocked(final String packageName, int uid) {
3723        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
3724                false, true, false, UserHandle.getUserId(uid));
3725        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3726                Uri.fromParts("package", packageName, null));
3727        if (!mProcessesReady) {
3728            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3729                    | Intent.FLAG_RECEIVER_FOREGROUND);
3730        }
3731        intent.putExtra(Intent.EXTRA_UID, uid);
3732        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
3733        broadcastIntentLocked(null, null, intent,
3734                null, null, 0, null, null, null,
3735                false, false,
3736                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3737    }
3738
3739    private void forceStopUserLocked(int userId) {
3740        forceStopPackageLocked(null, -1, false, false, true, false, userId);
3741        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
3742        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3743        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3744        broadcastIntentLocked(null, null, intent,
3745                null, null, 0, null, null, null,
3746                false, false,
3747                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
3748    }
3749
3750    private final boolean killPackageProcessesLocked(String packageName, int appId,
3751            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
3752            boolean doit, boolean evenPersistent, String reason) {
3753        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3754
3755        // Remove all processes this package may have touched: all with the
3756        // same UID (except for the system or root user), and all whose name
3757        // matches the package name.
3758        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
3759        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3760            final int NA = apps.size();
3761            for (int ia=0; ia<NA; ia++) {
3762                ProcessRecord app = apps.valueAt(ia);
3763                if (app.persistent && !evenPersistent) {
3764                    // we don't kill persistent processes
3765                    continue;
3766                }
3767                if (app.removed) {
3768                    if (doit) {
3769                        procs.add(app);
3770                    }
3771                    continue;
3772                }
3773
3774                // Skip process if it doesn't meet our oom adj requirement.
3775                if (app.setAdj < minOomAdj) {
3776                    continue;
3777                }
3778
3779                // If no package is specified, we call all processes under the
3780                // give user id.
3781                if (packageName == null) {
3782                    if (app.userId != userId) {
3783                        continue;
3784                    }
3785                // Package has been specified, we want to hit all processes
3786                // that match it.  We need to qualify this by the processes
3787                // that are running under the specified app and user ID.
3788                } else {
3789                    if (UserHandle.getAppId(app.uid) != appId) {
3790                        continue;
3791                    }
3792                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
3793                        continue;
3794                    }
3795                    if (!app.pkgList.contains(packageName)) {
3796                        continue;
3797                    }
3798                }
3799
3800                // Process has passed all conditions, kill it!
3801                if (!doit) {
3802                    return true;
3803                }
3804                app.removed = true;
3805                procs.add(app);
3806            }
3807        }
3808
3809        int N = procs.size();
3810        for (int i=0; i<N; i++) {
3811            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3812        }
3813        return N > 0;
3814    }
3815
3816    private final boolean forceStopPackageLocked(String name, int appId,
3817            boolean callerWillRestart, boolean purgeCache, boolean doit,
3818            boolean evenPersistent, int userId) {
3819        int i;
3820        int N;
3821
3822        if (userId == UserHandle.USER_ALL && name == null) {
3823            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
3824        }
3825
3826        if (appId < 0 && name != null) {
3827            try {
3828                appId = UserHandle.getAppId(
3829                        AppGlobals.getPackageManager().getPackageUid(name, 0));
3830            } catch (RemoteException e) {
3831            }
3832        }
3833
3834        if (doit) {
3835            if (name != null) {
3836                Slog.i(TAG, "Force stopping package " + name + " appid=" + appId
3837                        + " user=" + userId);
3838            } else {
3839                Slog.i(TAG, "Force stopping user " + userId);
3840            }
3841
3842            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3843            while (badApps.hasNext()) {
3844                SparseArray<Long> ba = badApps.next();
3845                for (i=ba.size()-1; i>=0; i--) {
3846                    boolean remove = false;
3847                    final int entUid = ba.keyAt(i);
3848                    if (name != null) {
3849                        if (userId == UserHandle.USER_ALL) {
3850                            if (UserHandle.getAppId(entUid) == appId) {
3851                                remove = true;
3852                            }
3853                        } else {
3854                            if (entUid == UserHandle.getUid(userId, appId)) {
3855                                remove = true;
3856                            }
3857                        }
3858                    } else if (UserHandle.getUserId(entUid) == userId) {
3859                        remove = true;
3860                    }
3861                    if (remove) {
3862                        ba.removeAt(i);
3863                    }
3864                }
3865                if (ba.size() == 0) {
3866                    badApps.remove();
3867                }
3868            }
3869        }
3870
3871        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
3872                -100, callerWillRestart, false, doit, evenPersistent,
3873                name == null ? ("force stop user " + userId) : ("force stop " + name));
3874
3875        TaskRecord lastTask = null;
3876        for (i=0; i<mMainStack.mHistory.size(); i++) {
3877            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3878            final boolean samePackage = r.packageName.equals(name)
3879                    || (name == null && r.userId == userId);
3880            if ((userId == UserHandle.USER_ALL || r.userId == userId)
3881                    && (samePackage || r.task == lastTask)
3882                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3883                if (!doit) {
3884                    if (r.finishing) {
3885                        // If this activity is just finishing, then it is not
3886                        // interesting as far as something to stop.
3887                        continue;
3888                    }
3889                    return true;
3890                }
3891                didSomething = true;
3892                Slog.i(TAG, "  Force finishing activity " + r);
3893                if (samePackage) {
3894                    if (r.app != null) {
3895                        r.app.removed = true;
3896                    }
3897                    r.app = null;
3898                }
3899                lastTask = r.task;
3900                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3901                        null, "force-stop", true)) {
3902                    i--;
3903                }
3904            }
3905        }
3906
3907        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3908            if (!doit) {
3909                return true;
3910            }
3911            didSomething = true;
3912        }
3913
3914        if (name == null) {
3915            // Remove all sticky broadcasts from this user.
3916            mStickyBroadcasts.remove(userId);
3917        }
3918
3919        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3920        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
3921                userId, providers)) {
3922            if (!doit) {
3923                return true;
3924            }
3925            didSomething = true;
3926        }
3927        N = providers.size();
3928        for (i=0; i<N; i++) {
3929            removeDyingProviderLocked(null, providers.get(i), true);
3930        }
3931
3932        if (mIntentSenderRecords.size() > 0) {
3933            Iterator<WeakReference<PendingIntentRecord>> it
3934                    = mIntentSenderRecords.values().iterator();
3935            while (it.hasNext()) {
3936                WeakReference<PendingIntentRecord> wpir = it.next();
3937                if (wpir == null) {
3938                    it.remove();
3939                    continue;
3940                }
3941                PendingIntentRecord pir = wpir.get();
3942                if (pir == null) {
3943                    it.remove();
3944                    continue;
3945                }
3946                if (name == null) {
3947                    // Stopping user, remove all objects for the user.
3948                    if (pir.key.userId != userId) {
3949                        // Not the same user, skip it.
3950                        continue;
3951                    }
3952                } else {
3953                    if (UserHandle.getAppId(pir.uid) != appId) {
3954                        // Different app id, skip it.
3955                        continue;
3956                    }
3957                    if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
3958                        // Different user, skip it.
3959                        continue;
3960                    }
3961                    if (!pir.key.packageName.equals(name)) {
3962                        // Different package, skip it.
3963                        continue;
3964                    }
3965                }
3966                if (!doit) {
3967                    return true;
3968                }
3969                didSomething = true;
3970                it.remove();
3971                pir.canceled = true;
3972                if (pir.key.activity != null) {
3973                    pir.key.activity.pendingResults.remove(pir.ref);
3974                }
3975            }
3976        }
3977
3978        if (doit) {
3979            if (purgeCache && name != null) {
3980                AttributeCache ac = AttributeCache.instance();
3981                if (ac != null) {
3982                    ac.removePackage(name);
3983                }
3984            }
3985            if (mBooted) {
3986                mMainStack.resumeTopActivityLocked(null);
3987                mMainStack.scheduleIdleLocked();
3988            }
3989        }
3990
3991        return didSomething;
3992    }
3993
3994    private final boolean removeProcessLocked(ProcessRecord app,
3995            boolean callerWillRestart, boolean allowRestart, String reason) {
3996        final String name = app.processName;
3997        final int uid = app.uid;
3998        if (DEBUG_PROCESSES) Slog.d(
3999            TAG, "Force removing proc " + app.toShortString() + " (" + name
4000            + "/" + uid + ")");
4001
4002        mProcessNames.remove(name, uid);
4003        mIsolatedProcesses.remove(app.uid);
4004        if (mHeavyWeightProcess == app) {
4005            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4006                    mHeavyWeightProcess.userId, 0));
4007            mHeavyWeightProcess = null;
4008        }
4009        boolean needRestart = false;
4010        if (app.pid > 0 && app.pid != MY_PID) {
4011            int pid = app.pid;
4012            synchronized (mPidsSelfLocked) {
4013                mPidsSelfLocked.remove(pid);
4014                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4015            }
4016            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
4017            handleAppDiedLocked(app, true, allowRestart);
4018            mLruProcesses.remove(app);
4019            Process.killProcessQuiet(pid);
4020
4021            if (app.persistent && !app.isolated) {
4022                if (!callerWillRestart) {
4023                    addAppLocked(app.info, false);
4024                } else {
4025                    needRestart = true;
4026                }
4027            }
4028        } else {
4029            mRemovedProcesses.add(app);
4030        }
4031
4032        return needRestart;
4033    }
4034
4035    private final void processStartTimedOutLocked(ProcessRecord app) {
4036        final int pid = app.pid;
4037        boolean gone = false;
4038        synchronized (mPidsSelfLocked) {
4039            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4040            if (knownApp != null && knownApp.thread == null) {
4041                mPidsSelfLocked.remove(pid);
4042                gone = true;
4043            }
4044        }
4045
4046        if (gone) {
4047            Slog.w(TAG, "Process " + app + " failed to attach");
4048            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4049                    pid, app.uid, app.processName);
4050            mProcessNames.remove(app.processName, app.uid);
4051            mIsolatedProcesses.remove(app.uid);
4052            if (mHeavyWeightProcess == app) {
4053                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4054                        mHeavyWeightProcess.userId, 0));
4055                mHeavyWeightProcess = null;
4056            }
4057            // Take care of any launching providers waiting for this process.
4058            checkAppInLaunchingProvidersLocked(app, true);
4059            // Take care of any services that are waiting for the process.
4060            mServices.processStartTimedOutLocked(app);
4061            EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, pid,
4062                    app.processName, app.setAdj, "start timeout");
4063            Process.killProcessQuiet(pid);
4064            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4065                Slog.w(TAG, "Unattached app died before backup, skipping");
4066                try {
4067                    IBackupManager bm = IBackupManager.Stub.asInterface(
4068                            ServiceManager.getService(Context.BACKUP_SERVICE));
4069                    bm.agentDisconnected(app.info.packageName);
4070                } catch (RemoteException e) {
4071                    // Can't happen; the backup manager is local
4072                }
4073            }
4074            if (isPendingBroadcastProcessLocked(pid)) {
4075                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4076                skipPendingBroadcastLocked(pid);
4077            }
4078        } else {
4079            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4080        }
4081    }
4082
4083    private final boolean attachApplicationLocked(IApplicationThread thread,
4084            int pid) {
4085
4086        // Find the application record that is being attached...  either via
4087        // the pid if we are running in multiple processes, or just pull the
4088        // next app record if we are emulating process with anonymous threads.
4089        ProcessRecord app;
4090        if (pid != MY_PID && pid >= 0) {
4091            synchronized (mPidsSelfLocked) {
4092                app = mPidsSelfLocked.get(pid);
4093            }
4094        } else {
4095            app = null;
4096        }
4097
4098        if (app == null) {
4099            Slog.w(TAG, "No pending application record for pid " + pid
4100                    + " (IApplicationThread " + thread + "); dropping process");
4101            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4102            if (pid > 0 && pid != MY_PID) {
4103                Process.killProcessQuiet(pid);
4104            } else {
4105                try {
4106                    thread.scheduleExit();
4107                } catch (Exception e) {
4108                    // Ignore exceptions.
4109                }
4110            }
4111            return false;
4112        }
4113
4114        // If this application record is still attached to a previous
4115        // process, clean it up now.
4116        if (app.thread != null) {
4117            handleAppDiedLocked(app, true, true);
4118        }
4119
4120        // Tell the process all about itself.
4121
4122        if (localLOGV) Slog.v(
4123                TAG, "Binding process pid " + pid + " to record " + app);
4124
4125        String processName = app.processName;
4126        try {
4127            AppDeathRecipient adr = new AppDeathRecipient(
4128                    app, pid, thread);
4129            thread.asBinder().linkToDeath(adr, 0);
4130            app.deathRecipient = adr;
4131        } catch (RemoteException e) {
4132            app.resetPackageList();
4133            startProcessLocked(app, "link fail", processName);
4134            return false;
4135        }
4136
4137        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4138
4139        app.thread = thread;
4140        app.curAdj = app.setAdj = -100;
4141        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4142        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
4143        app.forcingToForeground = null;
4144        app.foregroundServices = false;
4145        app.hasShownUi = false;
4146        app.debugging = false;
4147
4148        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4149
4150        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4151        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4152
4153        if (!normalMode) {
4154            Slog.i(TAG, "Launching preboot mode app: " + app);
4155        }
4156
4157        if (localLOGV) Slog.v(
4158            TAG, "New app record " + app
4159            + " thread=" + thread.asBinder() + " pid=" + pid);
4160        try {
4161            int testMode = IApplicationThread.DEBUG_OFF;
4162            if (mDebugApp != null && mDebugApp.equals(processName)) {
4163                testMode = mWaitForDebugger
4164                    ? IApplicationThread.DEBUG_WAIT
4165                    : IApplicationThread.DEBUG_ON;
4166                app.debugging = true;
4167                if (mDebugTransient) {
4168                    mDebugApp = mOrigDebugApp;
4169                    mWaitForDebugger = mOrigWaitForDebugger;
4170                }
4171            }
4172            String profileFile = app.instrumentationProfileFile;
4173            ParcelFileDescriptor profileFd = null;
4174            boolean profileAutoStop = false;
4175            if (mProfileApp != null && mProfileApp.equals(processName)) {
4176                mProfileProc = app;
4177                profileFile = mProfileFile;
4178                profileFd = mProfileFd;
4179                profileAutoStop = mAutoStopProfiler;
4180            }
4181            boolean enableOpenGlTrace = false;
4182            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4183                enableOpenGlTrace = true;
4184                mOpenGlTraceApp = null;
4185            }
4186
4187            // If the app is being launched for restore or full backup, set it up specially
4188            boolean isRestrictedBackupMode = false;
4189            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4190                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4191                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4192                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4193            }
4194
4195            ensurePackageDexOpt(app.instrumentationInfo != null
4196                    ? app.instrumentationInfo.packageName
4197                    : app.info.packageName);
4198            if (app.instrumentationClass != null) {
4199                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4200            }
4201            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4202                    + processName + " with config " + mConfiguration);
4203            ApplicationInfo appInfo = app.instrumentationInfo != null
4204                    ? app.instrumentationInfo : app.info;
4205            app.compat = compatibilityInfoForPackageLocked(appInfo);
4206            if (profileFd != null) {
4207                profileFd = profileFd.dup();
4208            }
4209            thread.bindApplication(processName, appInfo, providers,
4210                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4211                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4212                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4213                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4214                    mCoreSettingsObserver.getCoreSettingsLocked());
4215            updateLruProcessLocked(app, false);
4216            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4217        } catch (Exception e) {
4218            // todo: Yikes!  What should we do?  For now we will try to
4219            // start another process, but that could easily get us in
4220            // an infinite loop of restarting processes...
4221            Slog.w(TAG, "Exception thrown during bind!", e);
4222
4223            app.resetPackageList();
4224            app.unlinkDeathRecipient();
4225            startProcessLocked(app, "bind fail", processName);
4226            return false;
4227        }
4228
4229        // Remove this record from the list of starting applications.
4230        mPersistentStartingProcesses.remove(app);
4231        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4232                "Attach application locked removing on hold: " + app);
4233        mProcessesOnHold.remove(app);
4234
4235        boolean badApp = false;
4236        boolean didSomething = false;
4237
4238        // See if the top visible activity is waiting to run in this process...
4239        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4240        if (hr != null && normalMode) {
4241            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4242                    && processName.equals(hr.processName)) {
4243                try {
4244                    if (mHeadless) {
4245                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4246                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4247                        didSomething = true;
4248                    }
4249                } catch (Exception e) {
4250                    Slog.w(TAG, "Exception in new application when starting activity "
4251                          + hr.intent.getComponent().flattenToShortString(), e);
4252                    badApp = true;
4253                }
4254            } else {
4255                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4256            }
4257        }
4258
4259        // Find any services that should be running in this process...
4260        if (!badApp) {
4261            try {
4262                didSomething |= mServices.attachApplicationLocked(app, processName);
4263            } catch (Exception e) {
4264                badApp = true;
4265            }
4266        }
4267
4268        // Check if a next-broadcast receiver is in this process...
4269        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4270            try {
4271                didSomething = sendPendingBroadcastsLocked(app);
4272            } catch (Exception e) {
4273                // If the app died trying to launch the receiver we declare it 'bad'
4274                badApp = true;
4275            }
4276        }
4277
4278        // Check whether the next backup agent is in this process...
4279        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4280            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4281            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4282            try {
4283                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4284                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4285                        mBackupTarget.backupMode);
4286            } catch (Exception e) {
4287                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4288                e.printStackTrace();
4289            }
4290        }
4291
4292        if (badApp) {
4293            // todo: Also need to kill application to deal with all
4294            // kinds of exceptions.
4295            handleAppDiedLocked(app, false, true);
4296            return false;
4297        }
4298
4299        if (!didSomething) {
4300            updateOomAdjLocked();
4301        }
4302
4303        return true;
4304    }
4305
4306    public final void attachApplication(IApplicationThread thread) {
4307        synchronized (this) {
4308            int callingPid = Binder.getCallingPid();
4309            final long origId = Binder.clearCallingIdentity();
4310            attachApplicationLocked(thread, callingPid);
4311            Binder.restoreCallingIdentity(origId);
4312        }
4313    }
4314
4315    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4316        final long origId = Binder.clearCallingIdentity();
4317        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4318        if (stopProfiling) {
4319            synchronized (this) {
4320                if (mProfileProc == r.app) {
4321                    if (mProfileFd != null) {
4322                        try {
4323                            mProfileFd.close();
4324                        } catch (IOException e) {
4325                        }
4326                        clearProfilerLocked();
4327                    }
4328                }
4329            }
4330        }
4331        Binder.restoreCallingIdentity(origId);
4332    }
4333
4334    void enableScreenAfterBoot() {
4335        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4336                SystemClock.uptimeMillis());
4337        mWindowManager.enableScreenAfterBoot();
4338
4339        synchronized (this) {
4340            updateEventDispatchingLocked();
4341        }
4342    }
4343
4344    public void showBootMessage(final CharSequence msg, final boolean always) {
4345        enforceNotIsolatedCaller("showBootMessage");
4346        mWindowManager.showBootMessage(msg, always);
4347    }
4348
4349    public void dismissKeyguardOnNextActivity() {
4350        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4351        final long token = Binder.clearCallingIdentity();
4352        try {
4353            synchronized (this) {
4354                if (mLockScreenShown) {
4355                    mLockScreenShown = false;
4356                    comeOutOfSleepIfNeededLocked();
4357                }
4358                mMainStack.dismissKeyguardOnNextActivityLocked();
4359            }
4360        } finally {
4361            Binder.restoreCallingIdentity(token);
4362        }
4363    }
4364
4365    final void finishBooting() {
4366        IntentFilter pkgFilter = new IntentFilter();
4367        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4368        pkgFilter.addDataScheme("package");
4369        mContext.registerReceiver(new BroadcastReceiver() {
4370            @Override
4371            public void onReceive(Context context, Intent intent) {
4372                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4373                if (pkgs != null) {
4374                    for (String pkg : pkgs) {
4375                        synchronized (ActivityManagerService.this) {
4376                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4377                                setResultCode(Activity.RESULT_OK);
4378                                return;
4379                            }
4380                        }
4381                    }
4382                }
4383            }
4384        }, pkgFilter);
4385
4386        synchronized (this) {
4387            // Ensure that any processes we had put on hold are now started
4388            // up.
4389            final int NP = mProcessesOnHold.size();
4390            if (NP > 0) {
4391                ArrayList<ProcessRecord> procs =
4392                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4393                for (int ip=0; ip<NP; ip++) {
4394                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4395                            + procs.get(ip));
4396                    startProcessLocked(procs.get(ip), "on-hold", null);
4397                }
4398            }
4399
4400            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4401                // Start looking for apps that are abusing wake locks.
4402                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4403                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4404                // Tell anyone interested that we are done booting!
4405                SystemProperties.set("sys.boot_completed", "1");
4406                SystemProperties.set("dev.bootcomplete", "1");
4407                for (int i=0; i<mStartedUsers.size(); i++) {
4408                    UserStartedState uss = mStartedUsers.valueAt(i);
4409                    if (uss.mState == UserStartedState.STATE_BOOTING) {
4410                        uss.mState = UserStartedState.STATE_RUNNING;
4411                        final int userId = mStartedUsers.keyAt(i);
4412                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
4413                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4414                        broadcastIntentLocked(null, null, intent,
4415                                null, null, 0, null, null,
4416                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4417                                false, false, MY_PID, Process.SYSTEM_UID, userId);
4418                    }
4419                }
4420            }
4421        }
4422    }
4423
4424    final void ensureBootCompleted() {
4425        boolean booting;
4426        boolean enableScreen;
4427        synchronized (this) {
4428            booting = mBooting;
4429            mBooting = false;
4430            enableScreen = !mBooted;
4431            mBooted = true;
4432        }
4433
4434        if (booting) {
4435            finishBooting();
4436        }
4437
4438        if (enableScreen) {
4439            enableScreenAfterBoot();
4440        }
4441    }
4442
4443    public final void activityResumed(IBinder token) {
4444        final long origId = Binder.clearCallingIdentity();
4445        mMainStack.activityResumed(token);
4446        Binder.restoreCallingIdentity(origId);
4447    }
4448
4449    public final void activityPaused(IBinder token) {
4450        final long origId = Binder.clearCallingIdentity();
4451        mMainStack.activityPaused(token, false);
4452        Binder.restoreCallingIdentity(origId);
4453    }
4454
4455    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4456            CharSequence description) {
4457        if (localLOGV) Slog.v(
4458            TAG, "Activity stopped: token=" + token);
4459
4460        // Refuse possible leaked file descriptors
4461        if (icicle != null && icicle.hasFileDescriptors()) {
4462            throw new IllegalArgumentException("File descriptors passed in Bundle");
4463        }
4464
4465        ActivityRecord r = null;
4466
4467        final long origId = Binder.clearCallingIdentity();
4468
4469        synchronized (this) {
4470            r = mMainStack.isInStackLocked(token);
4471            if (r != null) {
4472                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4473            }
4474        }
4475
4476        if (r != null) {
4477            sendPendingThumbnail(r, null, null, null, false);
4478        }
4479
4480        trimApplications();
4481
4482        Binder.restoreCallingIdentity(origId);
4483    }
4484
4485    public final void activityDestroyed(IBinder token) {
4486        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4487        mMainStack.activityDestroyed(token);
4488    }
4489
4490    public String getCallingPackage(IBinder token) {
4491        synchronized (this) {
4492            ActivityRecord r = getCallingRecordLocked(token);
4493            return r != null && r.app != null ? r.info.packageName : null;
4494        }
4495    }
4496
4497    public ComponentName getCallingActivity(IBinder token) {
4498        synchronized (this) {
4499            ActivityRecord r = getCallingRecordLocked(token);
4500            return r != null ? r.intent.getComponent() : null;
4501        }
4502    }
4503
4504    private ActivityRecord getCallingRecordLocked(IBinder token) {
4505        ActivityRecord r = mMainStack.isInStackLocked(token);
4506        if (r == null) {
4507            return null;
4508        }
4509        return r.resultTo;
4510    }
4511
4512    public ComponentName getActivityClassForToken(IBinder token) {
4513        synchronized(this) {
4514            ActivityRecord r = mMainStack.isInStackLocked(token);
4515            if (r == null) {
4516                return null;
4517            }
4518            return r.intent.getComponent();
4519        }
4520    }
4521
4522    public String getPackageForToken(IBinder token) {
4523        synchronized(this) {
4524            ActivityRecord r = mMainStack.isInStackLocked(token);
4525            if (r == null) {
4526                return null;
4527            }
4528            return r.packageName;
4529        }
4530    }
4531
4532    public IIntentSender getIntentSender(int type,
4533            String packageName, IBinder token, String resultWho,
4534            int requestCode, Intent[] intents, String[] resolvedTypes,
4535            int flags, Bundle options, int userId) {
4536        enforceNotIsolatedCaller("getIntentSender");
4537        // Refuse possible leaked file descriptors
4538        if (intents != null) {
4539            if (intents.length < 1) {
4540                throw new IllegalArgumentException("Intents array length must be >= 1");
4541            }
4542            for (int i=0; i<intents.length; i++) {
4543                Intent intent = intents[i];
4544                if (intent != null) {
4545                    if (intent.hasFileDescriptors()) {
4546                        throw new IllegalArgumentException("File descriptors passed in Intent");
4547                    }
4548                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4549                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4550                        throw new IllegalArgumentException(
4551                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4552                    }
4553                    intents[i] = new Intent(intent);
4554                }
4555            }
4556            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4557                throw new IllegalArgumentException(
4558                        "Intent array length does not match resolvedTypes length");
4559            }
4560        }
4561        if (options != null) {
4562            if (options.hasFileDescriptors()) {
4563                throw new IllegalArgumentException("File descriptors passed in options");
4564            }
4565        }
4566
4567        synchronized(this) {
4568            int callingUid = Binder.getCallingUid();
4569            int origUserId = userId;
4570            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
4571                    type == ActivityManager.INTENT_SENDER_BROADCAST, true,
4572                    "getIntentSender", null);
4573            if (origUserId == UserHandle.USER_CURRENT) {
4574                // We don't want to evaluate this until the pending intent is
4575                // actually executed.  However, we do want to always do the
4576                // security checking for it above.
4577                userId = UserHandle.USER_CURRENT;
4578            }
4579            try {
4580                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4581                    int uid = AppGlobals.getPackageManager()
4582                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4583                    if (!UserHandle.isSameApp(callingUid, uid)) {
4584                        String msg = "Permission Denial: getIntentSender() from pid="
4585                            + Binder.getCallingPid()
4586                            + ", uid=" + Binder.getCallingUid()
4587                            + ", (need uid=" + uid + ")"
4588                            + " is not allowed to send as package " + packageName;
4589                        Slog.w(TAG, msg);
4590                        throw new SecurityException(msg);
4591                    }
4592                }
4593
4594                return getIntentSenderLocked(type, packageName, callingUid, userId,
4595                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4596
4597            } catch (RemoteException e) {
4598                throw new SecurityException(e);
4599            }
4600        }
4601    }
4602
4603    IIntentSender getIntentSenderLocked(int type, String packageName,
4604            int callingUid, int userId, IBinder token, String resultWho,
4605            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4606            Bundle options) {
4607        if (DEBUG_MU)
4608            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4609        ActivityRecord activity = null;
4610        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4611            activity = mMainStack.isInStackLocked(token);
4612            if (activity == null) {
4613                return null;
4614            }
4615            if (activity.finishing) {
4616                return null;
4617            }
4618        }
4619
4620        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4621        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4622        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4623        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4624                |PendingIntent.FLAG_UPDATE_CURRENT);
4625
4626        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4627                type, packageName, activity, resultWho,
4628                requestCode, intents, resolvedTypes, flags, options, userId);
4629        WeakReference<PendingIntentRecord> ref;
4630        ref = mIntentSenderRecords.get(key);
4631        PendingIntentRecord rec = ref != null ? ref.get() : null;
4632        if (rec != null) {
4633            if (!cancelCurrent) {
4634                if (updateCurrent) {
4635                    if (rec.key.requestIntent != null) {
4636                        rec.key.requestIntent.replaceExtras(intents != null ?
4637                                intents[intents.length - 1] : null);
4638                    }
4639                    if (intents != null) {
4640                        intents[intents.length-1] = rec.key.requestIntent;
4641                        rec.key.allIntents = intents;
4642                        rec.key.allResolvedTypes = resolvedTypes;
4643                    } else {
4644                        rec.key.allIntents = null;
4645                        rec.key.allResolvedTypes = null;
4646                    }
4647                }
4648                return rec;
4649            }
4650            rec.canceled = true;
4651            mIntentSenderRecords.remove(key);
4652        }
4653        if (noCreate) {
4654            return rec;
4655        }
4656        rec = new PendingIntentRecord(this, key, callingUid);
4657        mIntentSenderRecords.put(key, rec.ref);
4658        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4659            if (activity.pendingResults == null) {
4660                activity.pendingResults
4661                        = new HashSet<WeakReference<PendingIntentRecord>>();
4662            }
4663            activity.pendingResults.add(rec.ref);
4664        }
4665        return rec;
4666    }
4667
4668    public void cancelIntentSender(IIntentSender sender) {
4669        if (!(sender instanceof PendingIntentRecord)) {
4670            return;
4671        }
4672        synchronized(this) {
4673            PendingIntentRecord rec = (PendingIntentRecord)sender;
4674            try {
4675                int uid = AppGlobals.getPackageManager()
4676                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4677                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4678                    String msg = "Permission Denial: cancelIntentSender() from pid="
4679                        + Binder.getCallingPid()
4680                        + ", uid=" + Binder.getCallingUid()
4681                        + " is not allowed to cancel packges "
4682                        + rec.key.packageName;
4683                    Slog.w(TAG, msg);
4684                    throw new SecurityException(msg);
4685                }
4686            } catch (RemoteException e) {
4687                throw new SecurityException(e);
4688            }
4689            cancelIntentSenderLocked(rec, true);
4690        }
4691    }
4692
4693    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4694        rec.canceled = true;
4695        mIntentSenderRecords.remove(rec.key);
4696        if (cleanActivity && rec.key.activity != null) {
4697            rec.key.activity.pendingResults.remove(rec.ref);
4698        }
4699    }
4700
4701    public String getPackageForIntentSender(IIntentSender pendingResult) {
4702        if (!(pendingResult instanceof PendingIntentRecord)) {
4703            return null;
4704        }
4705        try {
4706            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4707            return res.key.packageName;
4708        } catch (ClassCastException e) {
4709        }
4710        return null;
4711    }
4712
4713    public int getUidForIntentSender(IIntentSender sender) {
4714        if (sender instanceof PendingIntentRecord) {
4715            try {
4716                PendingIntentRecord res = (PendingIntentRecord)sender;
4717                return res.uid;
4718            } catch (ClassCastException e) {
4719            }
4720        }
4721        return -1;
4722    }
4723
4724    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4725        if (!(pendingResult instanceof PendingIntentRecord)) {
4726            return false;
4727        }
4728        try {
4729            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4730            if (res.key.allIntents == null) {
4731                return false;
4732            }
4733            for (int i=0; i<res.key.allIntents.length; i++) {
4734                Intent intent = res.key.allIntents[i];
4735                if (intent.getPackage() != null && intent.getComponent() != null) {
4736                    return false;
4737                }
4738            }
4739            return true;
4740        } catch (ClassCastException e) {
4741        }
4742        return false;
4743    }
4744
4745    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4746        if (!(pendingResult instanceof PendingIntentRecord)) {
4747            return false;
4748        }
4749        try {
4750            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4751            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4752                return true;
4753            }
4754            return false;
4755        } catch (ClassCastException e) {
4756        }
4757        return false;
4758    }
4759
4760    public void setProcessLimit(int max) {
4761        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4762                "setProcessLimit()");
4763        synchronized (this) {
4764            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4765            mProcessLimitOverride = max;
4766        }
4767        trimApplications();
4768    }
4769
4770    public int getProcessLimit() {
4771        synchronized (this) {
4772            return mProcessLimitOverride;
4773        }
4774    }
4775
4776    void foregroundTokenDied(ForegroundToken token) {
4777        synchronized (ActivityManagerService.this) {
4778            synchronized (mPidsSelfLocked) {
4779                ForegroundToken cur
4780                    = mForegroundProcesses.get(token.pid);
4781                if (cur != token) {
4782                    return;
4783                }
4784                mForegroundProcesses.remove(token.pid);
4785                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4786                if (pr == null) {
4787                    return;
4788                }
4789                pr.forcingToForeground = null;
4790                pr.foregroundServices = false;
4791            }
4792            updateOomAdjLocked();
4793        }
4794    }
4795
4796    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4797        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4798                "setProcessForeground()");
4799        synchronized(this) {
4800            boolean changed = false;
4801
4802            synchronized (mPidsSelfLocked) {
4803                ProcessRecord pr = mPidsSelfLocked.get(pid);
4804                if (pr == null && isForeground) {
4805                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4806                    return;
4807                }
4808                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4809                if (oldToken != null) {
4810                    oldToken.token.unlinkToDeath(oldToken, 0);
4811                    mForegroundProcesses.remove(pid);
4812                    if (pr != null) {
4813                        pr.forcingToForeground = null;
4814                    }
4815                    changed = true;
4816                }
4817                if (isForeground && token != null) {
4818                    ForegroundToken newToken = new ForegroundToken() {
4819                        public void binderDied() {
4820                            foregroundTokenDied(this);
4821                        }
4822                    };
4823                    newToken.pid = pid;
4824                    newToken.token = token;
4825                    try {
4826                        token.linkToDeath(newToken, 0);
4827                        mForegroundProcesses.put(pid, newToken);
4828                        pr.forcingToForeground = token;
4829                        changed = true;
4830                    } catch (RemoteException e) {
4831                        // If the process died while doing this, we will later
4832                        // do the cleanup with the process death link.
4833                    }
4834                }
4835            }
4836
4837            if (changed) {
4838                updateOomAdjLocked();
4839            }
4840        }
4841    }
4842
4843    // =========================================================
4844    // PERMISSIONS
4845    // =========================================================
4846
4847    static class PermissionController extends IPermissionController.Stub {
4848        ActivityManagerService mActivityManagerService;
4849        PermissionController(ActivityManagerService activityManagerService) {
4850            mActivityManagerService = activityManagerService;
4851        }
4852
4853        public boolean checkPermission(String permission, int pid, int uid) {
4854            return mActivityManagerService.checkPermission(permission, pid,
4855                    uid) == PackageManager.PERMISSION_GRANTED;
4856        }
4857    }
4858
4859    /**
4860     * This can be called with or without the global lock held.
4861     */
4862    int checkComponentPermission(String permission, int pid, int uid,
4863            int owningUid, boolean exported) {
4864        // We might be performing an operation on behalf of an indirect binder
4865        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4866        // client identity accordingly before proceeding.
4867        Identity tlsIdentity = sCallerIdentity.get();
4868        if (tlsIdentity != null) {
4869            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4870                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4871            uid = tlsIdentity.uid;
4872            pid = tlsIdentity.pid;
4873        }
4874
4875        if (pid == MY_PID) {
4876            return PackageManager.PERMISSION_GRANTED;
4877        }
4878
4879        return ActivityManager.checkComponentPermission(permission, uid,
4880                owningUid, exported);
4881    }
4882
4883    /**
4884     * As the only public entry point for permissions checking, this method
4885     * can enforce the semantic that requesting a check on a null global
4886     * permission is automatically denied.  (Internally a null permission
4887     * string is used when calling {@link #checkComponentPermission} in cases
4888     * when only uid-based security is needed.)
4889     *
4890     * This can be called with or without the global lock held.
4891     */
4892    public int checkPermission(String permission, int pid, int uid) {
4893        if (permission == null) {
4894            return PackageManager.PERMISSION_DENIED;
4895        }
4896        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4897    }
4898
4899    /**
4900     * Binder IPC calls go through the public entry point.
4901     * This can be called with or without the global lock held.
4902     */
4903    int checkCallingPermission(String permission) {
4904        return checkPermission(permission,
4905                Binder.getCallingPid(),
4906                UserHandle.getAppId(Binder.getCallingUid()));
4907    }
4908
4909    /**
4910     * This can be called with or without the global lock held.
4911     */
4912    void enforceCallingPermission(String permission, String func) {
4913        if (checkCallingPermission(permission)
4914                == PackageManager.PERMISSION_GRANTED) {
4915            return;
4916        }
4917
4918        String msg = "Permission Denial: " + func + " from pid="
4919                + Binder.getCallingPid()
4920                + ", uid=" + Binder.getCallingUid()
4921                + " requires " + permission;
4922        Slog.w(TAG, msg);
4923        throw new SecurityException(msg);
4924    }
4925
4926    /**
4927     * Determine if UID is holding permissions required to access {@link Uri} in
4928     * the given {@link ProviderInfo}. Final permission checking is always done
4929     * in {@link ContentProvider}.
4930     */
4931    private final boolean checkHoldingPermissionsLocked(
4932            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4933        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4934                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4935
4936        if (pi.applicationInfo.uid == uid) {
4937            return true;
4938        } else if (!pi.exported) {
4939            return false;
4940        }
4941
4942        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4943        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4944        try {
4945            // check if target holds top-level <provider> permissions
4946            if (!readMet && pi.readPermission != null
4947                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4948                readMet = true;
4949            }
4950            if (!writeMet && pi.writePermission != null
4951                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4952                writeMet = true;
4953            }
4954
4955            // track if unprotected read/write is allowed; any denied
4956            // <path-permission> below removes this ability
4957            boolean allowDefaultRead = pi.readPermission == null;
4958            boolean allowDefaultWrite = pi.writePermission == null;
4959
4960            // check if target holds any <path-permission> that match uri
4961            final PathPermission[] pps = pi.pathPermissions;
4962            if (pps != null) {
4963                final String path = uri.getPath();
4964                int i = pps.length;
4965                while (i > 0 && (!readMet || !writeMet)) {
4966                    i--;
4967                    PathPermission pp = pps[i];
4968                    if (pp.match(path)) {
4969                        if (!readMet) {
4970                            final String pprperm = pp.getReadPermission();
4971                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4972                                    + pprperm + " for " + pp.getPath()
4973                                    + ": match=" + pp.match(path)
4974                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4975                            if (pprperm != null) {
4976                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4977                                    readMet = true;
4978                                } else {
4979                                    allowDefaultRead = false;
4980                                }
4981                            }
4982                        }
4983                        if (!writeMet) {
4984                            final String ppwperm = pp.getWritePermission();
4985                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4986                                    + ppwperm + " for " + pp.getPath()
4987                                    + ": match=" + pp.match(path)
4988                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4989                            if (ppwperm != null) {
4990                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4991                                    writeMet = true;
4992                                } else {
4993                                    allowDefaultWrite = false;
4994                                }
4995                            }
4996                        }
4997                    }
4998                }
4999            }
5000
5001            // grant unprotected <provider> read/write, if not blocked by
5002            // <path-permission> above
5003            if (allowDefaultRead) readMet = true;
5004            if (allowDefaultWrite) writeMet = true;
5005
5006        } catch (RemoteException e) {
5007            return false;
5008        }
5009
5010        return readMet && writeMet;
5011    }
5012
5013    private final boolean checkUriPermissionLocked(Uri uri, int uid,
5014            int modeFlags) {
5015        // Root gets to do everything.
5016        if (uid == 0) {
5017            return true;
5018        }
5019        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5020        if (perms == null) return false;
5021        UriPermission perm = perms.get(uri);
5022        if (perm == null) return false;
5023        return (modeFlags&perm.modeFlags) == modeFlags;
5024    }
5025
5026    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5027        enforceNotIsolatedCaller("checkUriPermission");
5028
5029        // Another redirected-binder-call permissions check as in
5030        // {@link checkComponentPermission}.
5031        Identity tlsIdentity = sCallerIdentity.get();
5032        if (tlsIdentity != null) {
5033            uid = tlsIdentity.uid;
5034            pid = tlsIdentity.pid;
5035        }
5036
5037        // Our own process gets to do everything.
5038        if (pid == MY_PID) {
5039            return PackageManager.PERMISSION_GRANTED;
5040        }
5041        synchronized(this) {
5042            return checkUriPermissionLocked(uri, uid, modeFlags)
5043                    ? PackageManager.PERMISSION_GRANTED
5044                    : PackageManager.PERMISSION_DENIED;
5045        }
5046    }
5047
5048    /**
5049     * Check if the targetPkg can be granted permission to access uri by
5050     * the callingUid using the given modeFlags.  Throws a security exception
5051     * if callingUid is not allowed to do this.  Returns the uid of the target
5052     * if the URI permission grant should be performed; returns -1 if it is not
5053     * needed (for example targetPkg already has permission to access the URI).
5054     * If you already know the uid of the target, you can supply it in
5055     * lastTargetUid else set that to -1.
5056     */
5057    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5058            Uri uri, int modeFlags, int lastTargetUid) {
5059        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5060                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5061        if (modeFlags == 0) {
5062            return -1;
5063        }
5064
5065        if (targetPkg != null) {
5066            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5067                    "Checking grant " + targetPkg + " permission to " + uri);
5068        }
5069
5070        final IPackageManager pm = AppGlobals.getPackageManager();
5071
5072        // If this is not a content: uri, we can't do anything with it.
5073        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5074            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5075                    "Can't grant URI permission for non-content URI: " + uri);
5076            return -1;
5077        }
5078
5079        String name = uri.getAuthority();
5080        ProviderInfo pi = null;
5081        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
5082                UserHandle.getUserId(callingUid));
5083        if (cpr != null) {
5084            pi = cpr.info;
5085        } else {
5086            try {
5087                pi = pm.resolveContentProvider(name,
5088                        PackageManager.GET_URI_PERMISSION_PATTERNS,
5089                        UserHandle.getUserId(callingUid));
5090            } catch (RemoteException ex) {
5091            }
5092        }
5093        if (pi == null) {
5094            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5095            return -1;
5096        }
5097
5098        int targetUid = lastTargetUid;
5099        if (targetUid < 0 && targetPkg != null) {
5100            try {
5101                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5102                if (targetUid < 0) {
5103                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5104                            "Can't grant URI permission no uid for: " + targetPkg);
5105                    return -1;
5106                }
5107            } catch (RemoteException ex) {
5108                return -1;
5109            }
5110        }
5111
5112        if (targetUid >= 0) {
5113            // First...  does the target actually need this permission?
5114            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5115                // No need to grant the target this permission.
5116                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5117                        "Target " + targetPkg + " already has full permission to " + uri);
5118                return -1;
5119            }
5120        } else {
5121            // First...  there is no target package, so can anyone access it?
5122            boolean allowed = pi.exported;
5123            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5124                if (pi.readPermission != null) {
5125                    allowed = false;
5126                }
5127            }
5128            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5129                if (pi.writePermission != null) {
5130                    allowed = false;
5131                }
5132            }
5133            if (allowed) {
5134                return -1;
5135            }
5136        }
5137
5138        // Second...  is the provider allowing granting of URI permissions?
5139        if (!pi.grantUriPermissions) {
5140            throw new SecurityException("Provider " + pi.packageName
5141                    + "/" + pi.name
5142                    + " does not allow granting of Uri permissions (uri "
5143                    + uri + ")");
5144        }
5145        if (pi.uriPermissionPatterns != null) {
5146            final int N = pi.uriPermissionPatterns.length;
5147            boolean allowed = false;
5148            for (int i=0; i<N; i++) {
5149                if (pi.uriPermissionPatterns[i] != null
5150                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5151                    allowed = true;
5152                    break;
5153                }
5154            }
5155            if (!allowed) {
5156                throw new SecurityException("Provider " + pi.packageName
5157                        + "/" + pi.name
5158                        + " does not allow granting of permission to path of Uri "
5159                        + uri);
5160            }
5161        }
5162
5163        // Third...  does the caller itself have permission to access
5164        // this uri?
5165        if (callingUid != Process.myUid()) {
5166            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5167                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5168                    throw new SecurityException("Uid " + callingUid
5169                            + " does not have permission to uri " + uri);
5170                }
5171            }
5172        }
5173
5174        return targetUid;
5175    }
5176
5177    public int checkGrantUriPermission(int callingUid, String targetPkg,
5178            Uri uri, int modeFlags) {
5179        enforceNotIsolatedCaller("checkGrantUriPermission");
5180        synchronized(this) {
5181            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5182        }
5183    }
5184
5185    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5186            Uri uri, int modeFlags, UriPermissionOwner owner) {
5187        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5188                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5189        if (modeFlags == 0) {
5190            return;
5191        }
5192
5193        // So here we are: the caller has the assumed permission
5194        // to the uri, and the target doesn't.  Let's now give this to
5195        // the target.
5196
5197        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5198                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5199
5200        HashMap<Uri, UriPermission> targetUris
5201                = mGrantedUriPermissions.get(targetUid);
5202        if (targetUris == null) {
5203            targetUris = new HashMap<Uri, UriPermission>();
5204            mGrantedUriPermissions.put(targetUid, targetUris);
5205        }
5206
5207        UriPermission perm = targetUris.get(uri);
5208        if (perm == null) {
5209            perm = new UriPermission(targetUid, uri);
5210            targetUris.put(uri, perm);
5211        }
5212
5213        perm.modeFlags |= modeFlags;
5214        if (owner == null) {
5215            perm.globalModeFlags |= modeFlags;
5216        } else {
5217            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5218                 perm.readOwners.add(owner);
5219                 owner.addReadPermission(perm);
5220            }
5221            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5222                 perm.writeOwners.add(owner);
5223                 owner.addWritePermission(perm);
5224            }
5225        }
5226    }
5227
5228    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5229            int modeFlags, UriPermissionOwner owner) {
5230        if (targetPkg == null) {
5231            throw new NullPointerException("targetPkg");
5232        }
5233
5234        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5235        if (targetUid < 0) {
5236            return;
5237        }
5238
5239        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5240    }
5241
5242    static class NeededUriGrants extends ArrayList<Uri> {
5243        final String targetPkg;
5244        final int targetUid;
5245        final int flags;
5246
5247        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5248            targetPkg = _targetPkg;
5249            targetUid = _targetUid;
5250            flags = _flags;
5251        }
5252    }
5253
5254    /**
5255     * Like checkGrantUriPermissionLocked, but takes an Intent.
5256     */
5257    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5258            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5259        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5260                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5261                + " clip=" + (intent != null ? intent.getClipData() : null)
5262                + " from " + intent + "; flags=0x"
5263                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5264
5265        if (targetPkg == null) {
5266            throw new NullPointerException("targetPkg");
5267        }
5268
5269        if (intent == null) {
5270            return null;
5271        }
5272        Uri data = intent.getData();
5273        ClipData clip = intent.getClipData();
5274        if (data == null && clip == null) {
5275            return null;
5276        }
5277        if (data != null) {
5278            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5279                mode, needed != null ? needed.targetUid : -1);
5280            if (target > 0) {
5281                if (needed == null) {
5282                    needed = new NeededUriGrants(targetPkg, target, mode);
5283                }
5284                needed.add(data);
5285            }
5286        }
5287        if (clip != null) {
5288            for (int i=0; i<clip.getItemCount(); i++) {
5289                Uri uri = clip.getItemAt(i).getUri();
5290                if (uri != null) {
5291                    int target = -1;
5292                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5293                            mode, needed != null ? needed.targetUid : -1);
5294                    if (target > 0) {
5295                        if (needed == null) {
5296                            needed = new NeededUriGrants(targetPkg, target, mode);
5297                        }
5298                        needed.add(uri);
5299                    }
5300                } else {
5301                    Intent clipIntent = clip.getItemAt(i).getIntent();
5302                    if (clipIntent != null) {
5303                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5304                                callingUid, targetPkg, clipIntent, mode, needed);
5305                        if (newNeeded != null) {
5306                            needed = newNeeded;
5307                        }
5308                    }
5309                }
5310            }
5311        }
5312
5313        return needed;
5314    }
5315
5316    /**
5317     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5318     */
5319    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5320            UriPermissionOwner owner) {
5321        if (needed != null) {
5322            for (int i=0; i<needed.size(); i++) {
5323                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5324                        needed.get(i), needed.flags, owner);
5325            }
5326        }
5327    }
5328
5329    void grantUriPermissionFromIntentLocked(int callingUid,
5330            String targetPkg, Intent intent, UriPermissionOwner owner) {
5331        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5332                intent, intent != null ? intent.getFlags() : 0, null);
5333        if (needed == null) {
5334            return;
5335        }
5336
5337        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5338    }
5339
5340    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5341            Uri uri, int modeFlags) {
5342        enforceNotIsolatedCaller("grantUriPermission");
5343        synchronized(this) {
5344            final ProcessRecord r = getRecordForAppLocked(caller);
5345            if (r == null) {
5346                throw new SecurityException("Unable to find app for caller "
5347                        + caller
5348                        + " when granting permission to uri " + uri);
5349            }
5350            if (targetPkg == null) {
5351                throw new IllegalArgumentException("null target");
5352            }
5353            if (uri == null) {
5354                throw new IllegalArgumentException("null uri");
5355            }
5356
5357            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5358                    null);
5359        }
5360    }
5361
5362    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5363        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5364                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5365            HashMap<Uri, UriPermission> perms
5366                    = mGrantedUriPermissions.get(perm.uid);
5367            if (perms != null) {
5368                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5369                        "Removing " + perm.uid + " permission to " + perm.uri);
5370                perms.remove(perm.uri);
5371                if (perms.size() == 0) {
5372                    mGrantedUriPermissions.remove(perm.uid);
5373                }
5374            }
5375        }
5376    }
5377
5378    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5379            int modeFlags) {
5380        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5381                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5382        if (modeFlags == 0) {
5383            return;
5384        }
5385
5386        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5387                "Revoking all granted permissions to " + uri);
5388
5389        final IPackageManager pm = AppGlobals.getPackageManager();
5390
5391        final String authority = uri.getAuthority();
5392        ProviderInfo pi = null;
5393        int userId = UserHandle.getUserId(callingUid);
5394        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5395        if (cpr != null) {
5396            pi = cpr.info;
5397        } else {
5398            try {
5399                pi = pm.resolveContentProvider(authority,
5400                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5401            } catch (RemoteException ex) {
5402            }
5403        }
5404        if (pi == null) {
5405            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5406            return;
5407        }
5408
5409        // Does the caller have this permission on the URI?
5410        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5411            // Right now, if you are not the original owner of the permission,
5412            // you are not allowed to revoke it.
5413            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5414                throw new SecurityException("Uid " + callingUid
5415                        + " does not have permission to uri " + uri);
5416            //}
5417        }
5418
5419        // Go through all of the permissions and remove any that match.
5420        final List<String> SEGMENTS = uri.getPathSegments();
5421        if (SEGMENTS != null) {
5422            final int NS = SEGMENTS.size();
5423            int N = mGrantedUriPermissions.size();
5424            for (int i=0; i<N; i++) {
5425                HashMap<Uri, UriPermission> perms
5426                        = mGrantedUriPermissions.valueAt(i);
5427                Iterator<UriPermission> it = perms.values().iterator();
5428            toploop:
5429                while (it.hasNext()) {
5430                    UriPermission perm = it.next();
5431                    Uri targetUri = perm.uri;
5432                    if (!authority.equals(targetUri.getAuthority())) {
5433                        continue;
5434                    }
5435                    List<String> targetSegments = targetUri.getPathSegments();
5436                    if (targetSegments == null) {
5437                        continue;
5438                    }
5439                    if (targetSegments.size() < NS) {
5440                        continue;
5441                    }
5442                    for (int j=0; j<NS; j++) {
5443                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5444                            continue toploop;
5445                        }
5446                    }
5447                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5448                            "Revoking " + perm.uid + " permission to " + perm.uri);
5449                    perm.clearModes(modeFlags);
5450                    if (perm.modeFlags == 0) {
5451                        it.remove();
5452                    }
5453                }
5454                if (perms.size() == 0) {
5455                    mGrantedUriPermissions.remove(
5456                            mGrantedUriPermissions.keyAt(i));
5457                    N--;
5458                    i--;
5459                }
5460            }
5461        }
5462    }
5463
5464    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5465            int modeFlags) {
5466        enforceNotIsolatedCaller("revokeUriPermission");
5467        synchronized(this) {
5468            final ProcessRecord r = getRecordForAppLocked(caller);
5469            if (r == null) {
5470                throw new SecurityException("Unable to find app for caller "
5471                        + caller
5472                        + " when revoking permission to uri " + uri);
5473            }
5474            if (uri == null) {
5475                Slog.w(TAG, "revokeUriPermission: null uri");
5476                return;
5477            }
5478
5479            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5480                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5481            if (modeFlags == 0) {
5482                return;
5483            }
5484
5485            final IPackageManager pm = AppGlobals.getPackageManager();
5486
5487            final String authority = uri.getAuthority();
5488            ProviderInfo pi = null;
5489            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5490            if (cpr != null) {
5491                pi = cpr.info;
5492            } else {
5493                try {
5494                    pi = pm.resolveContentProvider(authority,
5495                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5496                } catch (RemoteException ex) {
5497                }
5498            }
5499            if (pi == null) {
5500                Slog.w(TAG, "No content provider found for permission revoke: "
5501                        + uri.toSafeString());
5502                return;
5503            }
5504
5505            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5506        }
5507    }
5508
5509    @Override
5510    public IBinder newUriPermissionOwner(String name) {
5511        enforceNotIsolatedCaller("newUriPermissionOwner");
5512        synchronized(this) {
5513            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5514            return owner.getExternalTokenLocked();
5515        }
5516    }
5517
5518    @Override
5519    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5520            Uri uri, int modeFlags) {
5521        synchronized(this) {
5522            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5523            if (owner == null) {
5524                throw new IllegalArgumentException("Unknown owner: " + token);
5525            }
5526            if (fromUid != Binder.getCallingUid()) {
5527                if (Binder.getCallingUid() != Process.myUid()) {
5528                    // Only system code can grant URI permissions on behalf
5529                    // of other users.
5530                    throw new SecurityException("nice try");
5531                }
5532            }
5533            if (targetPkg == null) {
5534                throw new IllegalArgumentException("null target");
5535            }
5536            if (uri == null) {
5537                throw new IllegalArgumentException("null uri");
5538            }
5539
5540            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5541        }
5542    }
5543
5544    @Override
5545    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5546        synchronized(this) {
5547            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5548            if (owner == null) {
5549                throw new IllegalArgumentException("Unknown owner: " + token);
5550            }
5551
5552            if (uri == null) {
5553                owner.removeUriPermissionsLocked(mode);
5554            } else {
5555                owner.removeUriPermissionLocked(uri, mode);
5556            }
5557        }
5558    }
5559
5560    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5561        synchronized (this) {
5562            ProcessRecord app =
5563                who != null ? getRecordForAppLocked(who) : null;
5564            if (app == null) return;
5565
5566            Message msg = Message.obtain();
5567            msg.what = WAIT_FOR_DEBUGGER_MSG;
5568            msg.obj = app;
5569            msg.arg1 = waiting ? 1 : 0;
5570            mHandler.sendMessage(msg);
5571        }
5572    }
5573
5574    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5575        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5576        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5577        outInfo.availMem = Process.getFreeMemory();
5578        outInfo.totalMem = Process.getTotalMemory();
5579        outInfo.threshold = homeAppMem;
5580        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5581        outInfo.hiddenAppThreshold = hiddenAppMem;
5582        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5583                ProcessList.SERVICE_ADJ);
5584        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5585                ProcessList.VISIBLE_APP_ADJ);
5586        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5587                ProcessList.FOREGROUND_APP_ADJ);
5588    }
5589
5590    // =========================================================
5591    // TASK MANAGEMENT
5592    // =========================================================
5593
5594    public List getTasks(int maxNum, int flags,
5595                         IThumbnailReceiver receiver) {
5596        ArrayList list = new ArrayList();
5597
5598        PendingThumbnailsRecord pending = null;
5599        IApplicationThread topThumbnail = null;
5600        ActivityRecord topRecord = null;
5601
5602        synchronized(this) {
5603            if (localLOGV) Slog.v(
5604                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5605                + ", receiver=" + receiver);
5606
5607            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5608                    != PackageManager.PERMISSION_GRANTED) {
5609                if (receiver != null) {
5610                    // If the caller wants to wait for pending thumbnails,
5611                    // it ain't gonna get them.
5612                    try {
5613                        receiver.finished();
5614                    } catch (RemoteException ex) {
5615                    }
5616                }
5617                String msg = "Permission Denial: getTasks() from pid="
5618                        + Binder.getCallingPid()
5619                        + ", uid=" + Binder.getCallingUid()
5620                        + " requires " + android.Manifest.permission.GET_TASKS;
5621                Slog.w(TAG, msg);
5622                throw new SecurityException(msg);
5623            }
5624
5625            int pos = mMainStack.mHistory.size()-1;
5626            ActivityRecord next =
5627                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5628            ActivityRecord top = null;
5629            TaskRecord curTask = null;
5630            int numActivities = 0;
5631            int numRunning = 0;
5632            while (pos >= 0 && maxNum > 0) {
5633                final ActivityRecord r = next;
5634                pos--;
5635                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5636
5637                // Initialize state for next task if needed.
5638                if (top == null ||
5639                        (top.state == ActivityState.INITIALIZING
5640                            && top.task == r.task)) {
5641                    top = r;
5642                    curTask = r.task;
5643                    numActivities = numRunning = 0;
5644                }
5645
5646                // Add 'r' into the current task.
5647                numActivities++;
5648                if (r.app != null && r.app.thread != null) {
5649                    numRunning++;
5650                }
5651
5652                if (localLOGV) Slog.v(
5653                    TAG, r.intent.getComponent().flattenToShortString()
5654                    + ": task=" + r.task);
5655
5656                // If the next one is a different task, generate a new
5657                // TaskInfo entry for what we have.
5658                if (next == null || next.task != curTask) {
5659                    ActivityManager.RunningTaskInfo ci
5660                            = new ActivityManager.RunningTaskInfo();
5661                    ci.id = curTask.taskId;
5662                    ci.baseActivity = r.intent.getComponent();
5663                    ci.topActivity = top.intent.getComponent();
5664                    if (top.thumbHolder != null) {
5665                        ci.description = top.thumbHolder.lastDescription;
5666                    }
5667                    ci.numActivities = numActivities;
5668                    ci.numRunning = numRunning;
5669                    //System.out.println(
5670                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5671                    if (ci.thumbnail == null && receiver != null) {
5672                        if (localLOGV) Slog.v(
5673                            TAG, "State=" + top.state + "Idle=" + top.idle
5674                            + " app=" + top.app
5675                            + " thr=" + (top.app != null ? top.app.thread : null));
5676                        if (top.state == ActivityState.RESUMED
5677                                || top.state == ActivityState.PAUSING) {
5678                            if (top.idle && top.app != null
5679                                && top.app.thread != null) {
5680                                topRecord = top;
5681                                topThumbnail = top.app.thread;
5682                            } else {
5683                                top.thumbnailNeeded = true;
5684                            }
5685                        }
5686                        if (pending == null) {
5687                            pending = new PendingThumbnailsRecord(receiver);
5688                        }
5689                        pending.pendingRecords.add(top);
5690                    }
5691                    list.add(ci);
5692                    maxNum--;
5693                    top = null;
5694                }
5695            }
5696
5697            if (pending != null) {
5698                mPendingThumbnails.add(pending);
5699            }
5700        }
5701
5702        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5703
5704        if (topThumbnail != null) {
5705            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5706            try {
5707                topThumbnail.requestThumbnail(topRecord.appToken);
5708            } catch (Exception e) {
5709                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5710                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5711            }
5712        }
5713
5714        if (pending == null && receiver != null) {
5715            // In this case all thumbnails were available and the client
5716            // is being asked to be told when the remaining ones come in...
5717            // which is unusually, since the top-most currently running
5718            // activity should never have a canned thumbnail!  Oh well.
5719            try {
5720                receiver.finished();
5721            } catch (RemoteException ex) {
5722            }
5723        }
5724
5725        return list;
5726    }
5727
5728    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5729            int flags, int userId) {
5730        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
5731                false, true, "getRecentTasks", null);
5732
5733        synchronized (this) {
5734            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5735                    "getRecentTasks()");
5736            final boolean detailed = checkCallingPermission(
5737                    android.Manifest.permission.GET_DETAILED_TASKS)
5738                    == PackageManager.PERMISSION_GRANTED;
5739
5740            IPackageManager pm = AppGlobals.getPackageManager();
5741
5742            final int N = mRecentTasks.size();
5743            ArrayList<ActivityManager.RecentTaskInfo> res
5744                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5745                            maxNum < N ? maxNum : N);
5746            for (int i=0; i<N && maxNum > 0; i++) {
5747                TaskRecord tr = mRecentTasks.get(i);
5748                // Only add calling user's recent tasks
5749                if (tr.userId != userId) continue;
5750                // Return the entry if desired by the caller.  We always return
5751                // the first entry, because callers always expect this to be the
5752                // foreground app.  We may filter others if the caller has
5753                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5754                // we should exclude the entry.
5755
5756                if (i == 0
5757                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5758                        || (tr.intent == null)
5759                        || ((tr.intent.getFlags()
5760                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5761                    ActivityManager.RecentTaskInfo rti
5762                            = new ActivityManager.RecentTaskInfo();
5763                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5764                    rti.persistentId = tr.taskId;
5765                    rti.baseIntent = new Intent(
5766                            tr.intent != null ? tr.intent : tr.affinityIntent);
5767                    if (!detailed) {
5768                        rti.baseIntent.replaceExtras((Bundle)null);
5769                    }
5770                    rti.origActivity = tr.origActivity;
5771                    rti.description = tr.lastDescription;
5772
5773                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5774                        // Check whether this activity is currently available.
5775                        try {
5776                            if (rti.origActivity != null) {
5777                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5778                                        == null) {
5779                                    continue;
5780                                }
5781                            } else if (rti.baseIntent != null) {
5782                                if (pm.queryIntentActivities(rti.baseIntent,
5783                                        null, 0, userId) == null) {
5784                                    continue;
5785                                }
5786                            }
5787                        } catch (RemoteException e) {
5788                            // Will never happen.
5789                        }
5790                    }
5791
5792                    res.add(rti);
5793                    maxNum--;
5794                }
5795            }
5796            return res;
5797        }
5798    }
5799
5800    private TaskRecord taskForIdLocked(int id) {
5801        final int N = mRecentTasks.size();
5802        for (int i=0; i<N; i++) {
5803            TaskRecord tr = mRecentTasks.get(i);
5804            if (tr.taskId == id) {
5805                return tr;
5806            }
5807        }
5808        return null;
5809    }
5810
5811    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5812        synchronized (this) {
5813            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5814                    "getTaskThumbnails()");
5815            TaskRecord tr = taskForIdLocked(id);
5816            if (tr != null) {
5817                return mMainStack.getTaskThumbnailsLocked(tr);
5818            }
5819        }
5820        return null;
5821    }
5822
5823    public Bitmap getTaskTopThumbnail(int id) {
5824        synchronized (this) {
5825            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5826                    "getTaskTopThumbnail()");
5827            TaskRecord tr = taskForIdLocked(id);
5828            if (tr != null) {
5829                return mMainStack.getTaskTopThumbnailLocked(tr);
5830            }
5831        }
5832        return null;
5833    }
5834
5835    public boolean removeSubTask(int taskId, int subTaskIndex) {
5836        synchronized (this) {
5837            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5838                    "removeSubTask()");
5839            long ident = Binder.clearCallingIdentity();
5840            try {
5841                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5842                        true) != null;
5843            } finally {
5844                Binder.restoreCallingIdentity(ident);
5845            }
5846        }
5847    }
5848
5849    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5850        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5851        Intent baseIntent = new Intent(
5852                tr.intent != null ? tr.intent : tr.affinityIntent);
5853        ComponentName component = baseIntent.getComponent();
5854        if (component == null) {
5855            Slog.w(TAG, "Now component for base intent of task: " + tr);
5856            return;
5857        }
5858
5859        // Find any running services associated with this app.
5860        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5861
5862        if (killProcesses) {
5863            // Find any running processes associated with this app.
5864            final String pkg = component.getPackageName();
5865            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5866            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5867            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5868                for (int i=0; i<uids.size(); i++) {
5869                    ProcessRecord proc = uids.valueAt(i);
5870                    if (proc.userId != tr.userId) {
5871                        continue;
5872                    }
5873                    if (!proc.pkgList.contains(pkg)) {
5874                        continue;
5875                    }
5876                    procs.add(proc);
5877                }
5878            }
5879
5880            // Kill the running processes.
5881            for (int i=0; i<procs.size(); i++) {
5882                ProcessRecord pr = procs.get(i);
5883                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5884                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5885                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
5886                            pr.processName, pr.setAdj, "remove task");
5887                    pr.killedBackground = true;
5888                    Process.killProcessQuiet(pr.pid);
5889                } else {
5890                    pr.waitingToKill = "remove task";
5891                }
5892            }
5893        }
5894    }
5895
5896    public boolean removeTask(int taskId, int flags) {
5897        synchronized (this) {
5898            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5899                    "removeTask()");
5900            long ident = Binder.clearCallingIdentity();
5901            try {
5902                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5903                        false);
5904                if (r != null) {
5905                    mRecentTasks.remove(r.task);
5906                    cleanUpRemovedTaskLocked(r.task, flags);
5907                    return true;
5908                } else {
5909                    TaskRecord tr = null;
5910                    int i=0;
5911                    while (i < mRecentTasks.size()) {
5912                        TaskRecord t = mRecentTasks.get(i);
5913                        if (t.taskId == taskId) {
5914                            tr = t;
5915                            break;
5916                        }
5917                        i++;
5918                    }
5919                    if (tr != null) {
5920                        if (tr.numActivities <= 0) {
5921                            // Caller is just removing a recent task that is
5922                            // not actively running.  That is easy!
5923                            mRecentTasks.remove(i);
5924                            cleanUpRemovedTaskLocked(tr, flags);
5925                            return true;
5926                        } else {
5927                            Slog.w(TAG, "removeTask: task " + taskId
5928                                    + " does not have activities to remove, "
5929                                    + " but numActivities=" + tr.numActivities
5930                                    + ": " + tr);
5931                        }
5932                    }
5933                }
5934            } finally {
5935                Binder.restoreCallingIdentity(ident);
5936            }
5937        }
5938        return false;
5939    }
5940
5941    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5942        int j;
5943        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5944        TaskRecord jt = startTask;
5945
5946        // First look backwards
5947        for (j=startIndex-1; j>=0; j--) {
5948            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5949            if (r.task != jt) {
5950                jt = r.task;
5951                if (affinity.equals(jt.affinity)) {
5952                    return j;
5953                }
5954            }
5955        }
5956
5957        // Now look forwards
5958        final int N = mMainStack.mHistory.size();
5959        jt = startTask;
5960        for (j=startIndex+1; j<N; j++) {
5961            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5962            if (r.task != jt) {
5963                if (affinity.equals(jt.affinity)) {
5964                    return j;
5965                }
5966                jt = r.task;
5967            }
5968        }
5969
5970        // Might it be at the top?
5971        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5972            return N-1;
5973        }
5974
5975        return -1;
5976    }
5977
5978    /**
5979     * TODO: Add mController hook
5980     */
5981    public void moveTaskToFront(int task, int flags, Bundle options) {
5982        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5983                "moveTaskToFront()");
5984
5985        synchronized(this) {
5986            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5987                    Binder.getCallingUid(), "Task to front")) {
5988                ActivityOptions.abort(options);
5989                return;
5990            }
5991            final long origId = Binder.clearCallingIdentity();
5992            try {
5993                TaskRecord tr = taskForIdLocked(task);
5994                if (tr != null) {
5995                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5996                        mMainStack.mUserLeaving = true;
5997                    }
5998                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5999                        // Caller wants the home activity moved with it.  To accomplish this,
6000                        // we'll just move the home task to the top first.
6001                        mMainStack.moveHomeToFrontLocked();
6002                    }
6003                    mMainStack.moveTaskToFrontLocked(tr, null, options);
6004                    return;
6005                }
6006                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6007                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
6008                    if (hr.task.taskId == task) {
6009                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6010                            mMainStack.mUserLeaving = true;
6011                        }
6012                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6013                            // Caller wants the home activity moved with it.  To accomplish this,
6014                            // we'll just move the home task to the top first.
6015                            mMainStack.moveHomeToFrontLocked();
6016                        }
6017                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
6018                        return;
6019                    }
6020                }
6021            } finally {
6022                Binder.restoreCallingIdentity(origId);
6023            }
6024            ActivityOptions.abort(options);
6025        }
6026    }
6027
6028    public void moveTaskToBack(int task) {
6029        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6030                "moveTaskToBack()");
6031
6032        synchronized(this) {
6033            if (mMainStack.mResumedActivity != null
6034                    && mMainStack.mResumedActivity.task.taskId == task) {
6035                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6036                        Binder.getCallingUid(), "Task to back")) {
6037                    return;
6038                }
6039            }
6040            final long origId = Binder.clearCallingIdentity();
6041            mMainStack.moveTaskToBackLocked(task, null);
6042            Binder.restoreCallingIdentity(origId);
6043        }
6044    }
6045
6046    /**
6047     * Moves an activity, and all of the other activities within the same task, to the bottom
6048     * of the history stack.  The activity's order within the task is unchanged.
6049     *
6050     * @param token A reference to the activity we wish to move
6051     * @param nonRoot If false then this only works if the activity is the root
6052     *                of a task; if true it will work for any activity in a task.
6053     * @return Returns true if the move completed, false if not.
6054     */
6055    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
6056        enforceNotIsolatedCaller("moveActivityTaskToBack");
6057        synchronized(this) {
6058            final long origId = Binder.clearCallingIdentity();
6059            int taskId = getTaskForActivityLocked(token, !nonRoot);
6060            if (taskId >= 0) {
6061                return mMainStack.moveTaskToBackLocked(taskId, null);
6062            }
6063            Binder.restoreCallingIdentity(origId);
6064        }
6065        return false;
6066    }
6067
6068    public void moveTaskBackwards(int task) {
6069        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6070                "moveTaskBackwards()");
6071
6072        synchronized(this) {
6073            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6074                    Binder.getCallingUid(), "Task backwards")) {
6075                return;
6076            }
6077            final long origId = Binder.clearCallingIdentity();
6078            moveTaskBackwardsLocked(task);
6079            Binder.restoreCallingIdentity(origId);
6080        }
6081    }
6082
6083    private final void moveTaskBackwardsLocked(int task) {
6084        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
6085    }
6086
6087    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6088        synchronized(this) {
6089            return getTaskForActivityLocked(token, onlyRoot);
6090        }
6091    }
6092
6093    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
6094        final int N = mMainStack.mHistory.size();
6095        TaskRecord lastTask = null;
6096        for (int i=0; i<N; i++) {
6097            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
6098            if (r.appToken == token) {
6099                if (!onlyRoot || lastTask != r.task) {
6100                    return r.task.taskId;
6101                }
6102                return -1;
6103            }
6104            lastTask = r.task;
6105        }
6106
6107        return -1;
6108    }
6109
6110    // =========================================================
6111    // THUMBNAILS
6112    // =========================================================
6113
6114    public void reportThumbnail(IBinder token,
6115            Bitmap thumbnail, CharSequence description) {
6116        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6117        final long origId = Binder.clearCallingIdentity();
6118        sendPendingThumbnail(null, token, thumbnail, description, true);
6119        Binder.restoreCallingIdentity(origId);
6120    }
6121
6122    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
6123            Bitmap thumbnail, CharSequence description, boolean always) {
6124        TaskRecord task = null;
6125        ArrayList receivers = null;
6126
6127        //System.out.println("Send pending thumbnail: " + r);
6128
6129        synchronized(this) {
6130            if (r == null) {
6131                r = mMainStack.isInStackLocked(token);
6132                if (r == null) {
6133                    return;
6134                }
6135            }
6136            if (thumbnail == null && r.thumbHolder != null) {
6137                thumbnail = r.thumbHolder.lastThumbnail;
6138                description = r.thumbHolder.lastDescription;
6139            }
6140            if (thumbnail == null && !always) {
6141                // If there is no thumbnail, and this entry is not actually
6142                // going away, then abort for now and pick up the next
6143                // thumbnail we get.
6144                return;
6145            }
6146            task = r.task;
6147
6148            int N = mPendingThumbnails.size();
6149            int i=0;
6150            while (i<N) {
6151                PendingThumbnailsRecord pr =
6152                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6153                //System.out.println("Looking in " + pr.pendingRecords);
6154                if (pr.pendingRecords.remove(r)) {
6155                    if (receivers == null) {
6156                        receivers = new ArrayList();
6157                    }
6158                    receivers.add(pr);
6159                    if (pr.pendingRecords.size() == 0) {
6160                        pr.finished = true;
6161                        mPendingThumbnails.remove(i);
6162                        N--;
6163                        continue;
6164                    }
6165                }
6166                i++;
6167            }
6168        }
6169
6170        if (receivers != null) {
6171            final int N = receivers.size();
6172            for (int i=0; i<N; i++) {
6173                try {
6174                    PendingThumbnailsRecord pr =
6175                        (PendingThumbnailsRecord)receivers.get(i);
6176                    pr.receiver.newThumbnail(
6177                        task != null ? task.taskId : -1, thumbnail, description);
6178                    if (pr.finished) {
6179                        pr.receiver.finished();
6180                    }
6181                } catch (Exception e) {
6182                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6183                }
6184            }
6185        }
6186    }
6187
6188    // =========================================================
6189    // CONTENT PROVIDERS
6190    // =========================================================
6191
6192    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6193        List<ProviderInfo> providers = null;
6194        try {
6195            providers = AppGlobals.getPackageManager().
6196                queryContentProviders(app.processName, app.uid,
6197                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6198        } catch (RemoteException ex) {
6199        }
6200        if (DEBUG_MU)
6201            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6202        int userId = app.userId;
6203        if (providers != null) {
6204            int N = providers.size();
6205            for (int i=0; i<N; i++) {
6206                ProviderInfo cpi =
6207                    (ProviderInfo)providers.get(i);
6208                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6209                        cpi.name, cpi.flags);
6210                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6211                    // This is a singleton provider, but a user besides the
6212                    // default user is asking to initialize a process it runs
6213                    // in...  well, no, it doesn't actually run in this process,
6214                    // it runs in the process of the default user.  Get rid of it.
6215                    providers.remove(i);
6216                    N--;
6217                    continue;
6218                }
6219
6220                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6221                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6222                if (cpr == null) {
6223                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6224                    mProviderMap.putProviderByClass(comp, cpr);
6225                }
6226                if (DEBUG_MU)
6227                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6228                app.pubProviders.put(cpi.name, cpr);
6229                app.addPackage(cpi.applicationInfo.packageName);
6230                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6231            }
6232        }
6233        return providers;
6234    }
6235
6236    /**
6237     * Check if {@link ProcessRecord} has a possible chance at accessing the
6238     * given {@link ProviderInfo}. Final permission checking is always done
6239     * in {@link ContentProvider}.
6240     */
6241    private final String checkContentProviderPermissionLocked(
6242            ProviderInfo cpi, ProcessRecord r) {
6243        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6244        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6245        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6246                cpi.applicationInfo.uid, cpi.exported)
6247                == PackageManager.PERMISSION_GRANTED) {
6248            return null;
6249        }
6250        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6251                cpi.applicationInfo.uid, cpi.exported)
6252                == PackageManager.PERMISSION_GRANTED) {
6253            return null;
6254        }
6255
6256        PathPermission[] pps = cpi.pathPermissions;
6257        if (pps != null) {
6258            int i = pps.length;
6259            while (i > 0) {
6260                i--;
6261                PathPermission pp = pps[i];
6262                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6263                        cpi.applicationInfo.uid, cpi.exported)
6264                        == PackageManager.PERMISSION_GRANTED) {
6265                    return null;
6266                }
6267                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6268                        cpi.applicationInfo.uid, cpi.exported)
6269                        == PackageManager.PERMISSION_GRANTED) {
6270                    return null;
6271                }
6272            }
6273        }
6274
6275        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6276        if (perms != null) {
6277            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6278                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6279                    return null;
6280                }
6281            }
6282        }
6283
6284        String msg;
6285        if (!cpi.exported) {
6286            msg = "Permission Denial: opening provider " + cpi.name
6287                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6288                    + ", uid=" + callingUid + ") that is not exported from uid "
6289                    + cpi.applicationInfo.uid;
6290        } else {
6291            msg = "Permission Denial: opening provider " + cpi.name
6292                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6293                    + ", uid=" + callingUid + ") requires "
6294                    + cpi.readPermission + " or " + cpi.writePermission;
6295        }
6296        Slog.w(TAG, msg);
6297        return msg;
6298    }
6299
6300    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6301            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6302        if (r != null) {
6303            for (int i=0; i<r.conProviders.size(); i++) {
6304                ContentProviderConnection conn = r.conProviders.get(i);
6305                if (conn.provider == cpr) {
6306                    if (DEBUG_PROVIDER) Slog.v(TAG,
6307                            "Adding provider requested by "
6308                            + r.processName + " from process "
6309                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6310                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6311                    if (stable) {
6312                        conn.stableCount++;
6313                        conn.numStableIncs++;
6314                    } else {
6315                        conn.unstableCount++;
6316                        conn.numUnstableIncs++;
6317                    }
6318                    return conn;
6319                }
6320            }
6321            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6322            if (stable) {
6323                conn.stableCount = 1;
6324                conn.numStableIncs = 1;
6325            } else {
6326                conn.unstableCount = 1;
6327                conn.numUnstableIncs = 1;
6328            }
6329            cpr.connections.add(conn);
6330            r.conProviders.add(conn);
6331            return conn;
6332        }
6333        cpr.addExternalProcessHandleLocked(externalProcessToken);
6334        return null;
6335    }
6336
6337    boolean decProviderCountLocked(ContentProviderConnection conn,
6338            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6339        if (conn != null) {
6340            cpr = conn.provider;
6341            if (DEBUG_PROVIDER) Slog.v(TAG,
6342                    "Removing provider requested by "
6343                    + conn.client.processName + " from process "
6344                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6345                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6346            if (stable) {
6347                conn.stableCount--;
6348            } else {
6349                conn.unstableCount--;
6350            }
6351            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6352                cpr.connections.remove(conn);
6353                conn.client.conProviders.remove(conn);
6354                return true;
6355            }
6356            return false;
6357        }
6358        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6359        return false;
6360    }
6361
6362    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6363            String name, IBinder token, boolean stable, int userId) {
6364        ContentProviderRecord cpr;
6365        ContentProviderConnection conn = null;
6366        ProviderInfo cpi = null;
6367
6368        synchronized(this) {
6369            ProcessRecord r = null;
6370            if (caller != null) {
6371                r = getRecordForAppLocked(caller);
6372                if (r == null) {
6373                    throw new SecurityException(
6374                            "Unable to find app for caller " + caller
6375                          + " (pid=" + Binder.getCallingPid()
6376                          + ") when getting content provider " + name);
6377                }
6378            }
6379
6380            // First check if this content provider has been published...
6381            cpr = mProviderMap.getProviderByName(name, userId);
6382            boolean providerRunning = cpr != null;
6383            if (providerRunning) {
6384                cpi = cpr.info;
6385                String msg;
6386                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6387                    throw new SecurityException(msg);
6388                }
6389
6390                if (r != null && cpr.canRunHere(r)) {
6391                    // This provider has been published or is in the process
6392                    // of being published...  but it is also allowed to run
6393                    // in the caller's process, so don't make a connection
6394                    // and just let the caller instantiate its own instance.
6395                    ContentProviderHolder holder = cpr.newHolder(null);
6396                    // don't give caller the provider object, it needs
6397                    // to make its own.
6398                    holder.provider = null;
6399                    return holder;
6400                }
6401
6402                final long origId = Binder.clearCallingIdentity();
6403
6404                // In this case the provider instance already exists, so we can
6405                // return it right away.
6406                conn = incProviderCountLocked(r, cpr, token, stable);
6407                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6408                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6409                        // If this is a perceptible app accessing the provider,
6410                        // make sure to count it as being accessed and thus
6411                        // back up on the LRU list.  This is good because
6412                        // content providers are often expensive to start.
6413                        updateLruProcessLocked(cpr.proc, false);
6414                    }
6415                }
6416
6417                if (cpr.proc != null) {
6418                    if (false) {
6419                        if (cpr.name.flattenToShortString().equals(
6420                                "com.android.providers.calendar/.CalendarProvider2")) {
6421                            Slog.v(TAG, "****************** KILLING "
6422                                + cpr.name.flattenToShortString());
6423                            Process.killProcess(cpr.proc.pid);
6424                        }
6425                    }
6426                    boolean success = updateOomAdjLocked(cpr.proc);
6427                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6428                    // NOTE: there is still a race here where a signal could be
6429                    // pending on the process even though we managed to update its
6430                    // adj level.  Not sure what to do about this, but at least
6431                    // the race is now smaller.
6432                    if (!success) {
6433                        // Uh oh...  it looks like the provider's process
6434                        // has been killed on us.  We need to wait for a new
6435                        // process to be started, and make sure its death
6436                        // doesn't kill our process.
6437                        Slog.i(TAG,
6438                                "Existing provider " + cpr.name.flattenToShortString()
6439                                + " is crashing; detaching " + r);
6440                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6441                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6442                        if (!lastRef) {
6443                            // This wasn't the last ref our process had on
6444                            // the provider...  we have now been killed, bail.
6445                            return null;
6446                        }
6447                        providerRunning = false;
6448                        conn = null;
6449                    }
6450                }
6451
6452                Binder.restoreCallingIdentity(origId);
6453            }
6454
6455            boolean singleton;
6456            if (!providerRunning) {
6457                try {
6458                    cpi = AppGlobals.getPackageManager().
6459                        resolveContentProvider(name,
6460                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6461                } catch (RemoteException ex) {
6462                }
6463                if (cpi == null) {
6464                    return null;
6465                }
6466                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6467                        cpi.name, cpi.flags);
6468                if (singleton) {
6469                    userId = 0;
6470                }
6471                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6472
6473                String msg;
6474                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6475                    throw new SecurityException(msg);
6476                }
6477
6478                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6479                        && !cpi.processName.equals("system")) {
6480                    // If this content provider does not run in the system
6481                    // process, and the system is not yet ready to run other
6482                    // processes, then fail fast instead of hanging.
6483                    throw new IllegalArgumentException(
6484                            "Attempt to launch content provider before system ready");
6485                }
6486
6487                // Make sure that the user who owns this provider is started.  If not,
6488                // we don't want to allow it to run.
6489                if (mStartedUsers.get(userId) == null) {
6490                    Slog.w(TAG, "Unable to launch app "
6491                            + cpi.applicationInfo.packageName + "/"
6492                            + cpi.applicationInfo.uid + " for provider "
6493                            + name + ": user " + userId + " is stopped");
6494                    return null;
6495                }
6496
6497                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6498                cpr = mProviderMap.getProviderByClass(comp, userId);
6499                final boolean firstClass = cpr == null;
6500                if (firstClass) {
6501                    try {
6502                        ApplicationInfo ai =
6503                            AppGlobals.getPackageManager().
6504                                getApplicationInfo(
6505                                        cpi.applicationInfo.packageName,
6506                                        STOCK_PM_FLAGS, userId);
6507                        if (ai == null) {
6508                            Slog.w(TAG, "No package info for content provider "
6509                                    + cpi.name);
6510                            return null;
6511                        }
6512                        ai = getAppInfoForUser(ai, userId);
6513                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6514                    } catch (RemoteException ex) {
6515                        // pm is in same process, this will never happen.
6516                    }
6517                }
6518
6519                if (r != null && cpr.canRunHere(r)) {
6520                    // If this is a multiprocess provider, then just return its
6521                    // info and allow the caller to instantiate it.  Only do
6522                    // this if the provider is the same user as the caller's
6523                    // process, or can run as root (so can be in any process).
6524                    return cpr.newHolder(null);
6525                }
6526
6527                if (DEBUG_PROVIDER) {
6528                    RuntimeException e = new RuntimeException("here");
6529                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6530                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6531                }
6532
6533                // This is single process, and our app is now connecting to it.
6534                // See if we are already in the process of launching this
6535                // provider.
6536                final int N = mLaunchingProviders.size();
6537                int i;
6538                for (i=0; i<N; i++) {
6539                    if (mLaunchingProviders.get(i) == cpr) {
6540                        break;
6541                    }
6542                }
6543
6544                // If the provider is not already being launched, then get it
6545                // started.
6546                if (i >= N) {
6547                    final long origId = Binder.clearCallingIdentity();
6548
6549                    try {
6550                        // Content provider is now in use, its package can't be stopped.
6551                        try {
6552                            AppGlobals.getPackageManager().setPackageStoppedState(
6553                                    cpr.appInfo.packageName, false, userId);
6554                        } catch (RemoteException e) {
6555                        } catch (IllegalArgumentException e) {
6556                            Slog.w(TAG, "Failed trying to unstop package "
6557                                    + cpr.appInfo.packageName + ": " + e);
6558                        }
6559
6560                        ProcessRecord proc = startProcessLocked(cpi.processName,
6561                                cpr.appInfo, false, 0, "content provider",
6562                                new ComponentName(cpi.applicationInfo.packageName,
6563                                        cpi.name), false, false);
6564                        if (proc == null) {
6565                            Slog.w(TAG, "Unable to launch app "
6566                                    + cpi.applicationInfo.packageName + "/"
6567                                    + cpi.applicationInfo.uid + " for provider "
6568                                    + name + ": process is bad");
6569                            return null;
6570                        }
6571                        cpr.launchingApp = proc;
6572                        mLaunchingProviders.add(cpr);
6573                    } finally {
6574                        Binder.restoreCallingIdentity(origId);
6575                    }
6576                }
6577
6578                // Make sure the provider is published (the same provider class
6579                // may be published under multiple names).
6580                if (firstClass) {
6581                    mProviderMap.putProviderByClass(comp, cpr);
6582                }
6583
6584                mProviderMap.putProviderByName(name, cpr);
6585                conn = incProviderCountLocked(r, cpr, token, stable);
6586                if (conn != null) {
6587                    conn.waiting = true;
6588                }
6589            }
6590        }
6591
6592        // Wait for the provider to be published...
6593        synchronized (cpr) {
6594            while (cpr.provider == null) {
6595                if (cpr.launchingApp == null) {
6596                    Slog.w(TAG, "Unable to launch app "
6597                            + cpi.applicationInfo.packageName + "/"
6598                            + cpi.applicationInfo.uid + " for provider "
6599                            + name + ": launching app became null");
6600                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6601                            UserHandle.getUserId(cpi.applicationInfo.uid),
6602                            cpi.applicationInfo.packageName,
6603                            cpi.applicationInfo.uid, name);
6604                    return null;
6605                }
6606                try {
6607                    if (DEBUG_MU) {
6608                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6609                                + cpr.launchingApp);
6610                    }
6611                    if (conn != null) {
6612                        conn.waiting = true;
6613                    }
6614                    cpr.wait();
6615                } catch (InterruptedException ex) {
6616                } finally {
6617                    if (conn != null) {
6618                        conn.waiting = false;
6619                    }
6620                }
6621            }
6622        }
6623        return cpr != null ? cpr.newHolder(conn) : null;
6624    }
6625
6626    public final ContentProviderHolder getContentProvider(
6627            IApplicationThread caller, String name, int userId, boolean stable) {
6628        enforceNotIsolatedCaller("getContentProvider");
6629        if (caller == null) {
6630            String msg = "null IApplicationThread when getting content provider "
6631                    + name;
6632            Slog.w(TAG, msg);
6633            throw new SecurityException(msg);
6634        }
6635
6636        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6637                false, true, "getContentProvider", null);
6638        return getContentProviderImpl(caller, name, null, stable, userId);
6639    }
6640
6641    public ContentProviderHolder getContentProviderExternal(
6642            String name, int userId, IBinder token) {
6643        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6644            "Do not have permission in call getContentProviderExternal()");
6645        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6646                false, true, "getContentProvider", null);
6647        return getContentProviderExternalUnchecked(name, token, userId);
6648    }
6649
6650    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
6651            IBinder token, int userId) {
6652        return getContentProviderImpl(null, name, token, true, userId);
6653    }
6654
6655    /**
6656     * Drop a content provider from a ProcessRecord's bookkeeping
6657     * @param cpr
6658     */
6659    public void removeContentProvider(IBinder connection, boolean stable) {
6660        enforceNotIsolatedCaller("removeContentProvider");
6661        synchronized (this) {
6662            ContentProviderConnection conn;
6663            try {
6664                conn = (ContentProviderConnection)connection;
6665            } catch (ClassCastException e) {
6666                String msg ="removeContentProvider: " + connection
6667                        + " not a ContentProviderConnection";
6668                Slog.w(TAG, msg);
6669                throw new IllegalArgumentException(msg);
6670            }
6671            if (conn == null) {
6672                throw new NullPointerException("connection is null");
6673            }
6674            if (decProviderCountLocked(conn, null, null, stable)) {
6675                updateOomAdjLocked();
6676            }
6677        }
6678    }
6679
6680    public void removeContentProviderExternal(String name, IBinder token) {
6681        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6682            "Do not have permission in call removeContentProviderExternal()");
6683        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6684    }
6685
6686    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
6687        synchronized (this) {
6688            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
6689            if(cpr == null) {
6690                //remove from mProvidersByClass
6691                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6692                return;
6693            }
6694
6695            //update content provider record entry info
6696            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6697            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
6698            if (localCpr.hasExternalProcessHandles()) {
6699                if (localCpr.removeExternalProcessHandleLocked(token)) {
6700                    updateOomAdjLocked();
6701                } else {
6702                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6703                            + " with no external reference for token: "
6704                            + token + ".");
6705                }
6706            } else {
6707                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6708                        + " with no external references.");
6709            }
6710        }
6711    }
6712
6713    public final void publishContentProviders(IApplicationThread caller,
6714            List<ContentProviderHolder> providers) {
6715        if (providers == null) {
6716            return;
6717        }
6718
6719        enforceNotIsolatedCaller("publishContentProviders");
6720        synchronized (this) {
6721            final ProcessRecord r = getRecordForAppLocked(caller);
6722            if (DEBUG_MU)
6723                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6724            if (r == null) {
6725                throw new SecurityException(
6726                        "Unable to find app for caller " + caller
6727                      + " (pid=" + Binder.getCallingPid()
6728                      + ") when publishing content providers");
6729            }
6730
6731            final long origId = Binder.clearCallingIdentity();
6732
6733            final int N = providers.size();
6734            for (int i=0; i<N; i++) {
6735                ContentProviderHolder src = providers.get(i);
6736                if (src == null || src.info == null || src.provider == null) {
6737                    continue;
6738                }
6739                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6740                if (DEBUG_MU)
6741                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6742                if (dst != null) {
6743                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6744                    mProviderMap.putProviderByClass(comp, dst);
6745                    String names[] = dst.info.authority.split(";");
6746                    for (int j = 0; j < names.length; j++) {
6747                        mProviderMap.putProviderByName(names[j], dst);
6748                    }
6749
6750                    int NL = mLaunchingProviders.size();
6751                    int j;
6752                    for (j=0; j<NL; j++) {
6753                        if (mLaunchingProviders.get(j) == dst) {
6754                            mLaunchingProviders.remove(j);
6755                            j--;
6756                            NL--;
6757                        }
6758                    }
6759                    synchronized (dst) {
6760                        dst.provider = src.provider;
6761                        dst.proc = r;
6762                        dst.notifyAll();
6763                    }
6764                    updateOomAdjLocked(r);
6765                }
6766            }
6767
6768            Binder.restoreCallingIdentity(origId);
6769        }
6770    }
6771
6772    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6773        ContentProviderConnection conn;
6774        try {
6775            conn = (ContentProviderConnection)connection;
6776        } catch (ClassCastException e) {
6777            String msg ="refContentProvider: " + connection
6778                    + " not a ContentProviderConnection";
6779            Slog.w(TAG, msg);
6780            throw new IllegalArgumentException(msg);
6781        }
6782        if (conn == null) {
6783            throw new NullPointerException("connection is null");
6784        }
6785
6786        synchronized (this) {
6787            if (stable > 0) {
6788                conn.numStableIncs += stable;
6789            }
6790            stable = conn.stableCount + stable;
6791            if (stable < 0) {
6792                throw new IllegalStateException("stableCount < 0: " + stable);
6793            }
6794
6795            if (unstable > 0) {
6796                conn.numUnstableIncs += unstable;
6797            }
6798            unstable = conn.unstableCount + unstable;
6799            if (unstable < 0) {
6800                throw new IllegalStateException("unstableCount < 0: " + unstable);
6801            }
6802
6803            if ((stable+unstable) <= 0) {
6804                throw new IllegalStateException("ref counts can't go to zero here: stable="
6805                        + stable + " unstable=" + unstable);
6806            }
6807            conn.stableCount = stable;
6808            conn.unstableCount = unstable;
6809            return !conn.dead;
6810        }
6811    }
6812
6813    public void unstableProviderDied(IBinder connection) {
6814        ContentProviderConnection conn;
6815        try {
6816            conn = (ContentProviderConnection)connection;
6817        } catch (ClassCastException e) {
6818            String msg ="refContentProvider: " + connection
6819                    + " not a ContentProviderConnection";
6820            Slog.w(TAG, msg);
6821            throw new IllegalArgumentException(msg);
6822        }
6823        if (conn == null) {
6824            throw new NullPointerException("connection is null");
6825        }
6826
6827        // Safely retrieve the content provider associated with the connection.
6828        IContentProvider provider;
6829        synchronized (this) {
6830            provider = conn.provider.provider;
6831        }
6832
6833        if (provider == null) {
6834            // Um, yeah, we're way ahead of you.
6835            return;
6836        }
6837
6838        // Make sure the caller is being honest with us.
6839        if (provider.asBinder().pingBinder()) {
6840            // Er, no, still looks good to us.
6841            synchronized (this) {
6842                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6843                        + " says " + conn + " died, but we don't agree");
6844                return;
6845            }
6846        }
6847
6848        // Well look at that!  It's dead!
6849        synchronized (this) {
6850            if (conn.provider.provider != provider) {
6851                // But something changed...  good enough.
6852                return;
6853            }
6854
6855            ProcessRecord proc = conn.provider.proc;
6856            if (proc == null || proc.thread == null) {
6857                // Seems like the process is already cleaned up.
6858                return;
6859            }
6860
6861            // As far as we're concerned, this is just like receiving a
6862            // death notification...  just a bit prematurely.
6863            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6864                    + ") early provider death");
6865            final long ident = Binder.clearCallingIdentity();
6866            try {
6867                appDiedLocked(proc, proc.pid, proc.thread);
6868            } finally {
6869                Binder.restoreCallingIdentity(ident);
6870            }
6871        }
6872    }
6873
6874    public static final void installSystemProviders() {
6875        List<ProviderInfo> providers;
6876        synchronized (mSelf) {
6877            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6878            providers = mSelf.generateApplicationProvidersLocked(app);
6879            if (providers != null) {
6880                for (int i=providers.size()-1; i>=0; i--) {
6881                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6882                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6883                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6884                                + ": not system .apk");
6885                        providers.remove(i);
6886                    }
6887                }
6888            }
6889        }
6890        if (providers != null) {
6891            mSystemThread.installSystemProviders(providers);
6892        }
6893
6894        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6895
6896        mSelf.mUsageStatsService.monitorPackages();
6897    }
6898
6899    /**
6900     * Allows app to retrieve the MIME type of a URI without having permission
6901     * to access its content provider.
6902     *
6903     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6904     *
6905     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6906     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6907     */
6908    public String getProviderMimeType(Uri uri, int userId) {
6909        enforceNotIsolatedCaller("getProviderMimeType");
6910        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6911                userId, false, true, "getProviderMimeType", null);
6912        final String name = uri.getAuthority();
6913        final long ident = Binder.clearCallingIdentity();
6914        ContentProviderHolder holder = null;
6915
6916        try {
6917            holder = getContentProviderExternalUnchecked(name, null, userId);
6918            if (holder != null) {
6919                return holder.provider.getType(uri);
6920            }
6921        } catch (RemoteException e) {
6922            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6923            return null;
6924        } finally {
6925            if (holder != null) {
6926                removeContentProviderExternalUnchecked(name, null, userId);
6927            }
6928            Binder.restoreCallingIdentity(ident);
6929        }
6930
6931        return null;
6932    }
6933
6934    // =========================================================
6935    // GLOBAL MANAGEMENT
6936    // =========================================================
6937
6938    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6939            ApplicationInfo info, String customProcess, boolean isolated) {
6940        String proc = customProcess != null ? customProcess : info.processName;
6941        BatteryStatsImpl.Uid.Proc ps = null;
6942        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6943        int uid = info.uid;
6944        if (isolated) {
6945            int userId = UserHandle.getUserId(uid);
6946            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6947            uid = 0;
6948            while (true) {
6949                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6950                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6951                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6952                }
6953                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
6954                mNextIsolatedProcessUid++;
6955                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6956                    // No process for this uid, use it.
6957                    break;
6958                }
6959                stepsLeft--;
6960                if (stepsLeft <= 0) {
6961                    return null;
6962                }
6963            }
6964        }
6965        synchronized (stats) {
6966            ps = stats.getProcessStatsLocked(info.uid, proc);
6967        }
6968        return new ProcessRecord(ps, thread, info, proc, uid);
6969    }
6970
6971    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6972        ProcessRecord app;
6973        if (!isolated) {
6974            app = getProcessRecordLocked(info.processName, info.uid);
6975        } else {
6976            app = null;
6977        }
6978
6979        if (app == null) {
6980            app = newProcessRecordLocked(null, info, null, isolated);
6981            mProcessNames.put(info.processName, app.uid, app);
6982            if (isolated) {
6983                mIsolatedProcesses.put(app.uid, app);
6984            }
6985            updateLruProcessLocked(app, true);
6986        }
6987
6988        // This package really, really can not be stopped.
6989        try {
6990            AppGlobals.getPackageManager().setPackageStoppedState(
6991                    info.packageName, false, UserHandle.getUserId(app.uid));
6992        } catch (RemoteException e) {
6993        } catch (IllegalArgumentException e) {
6994            Slog.w(TAG, "Failed trying to unstop package "
6995                    + info.packageName + ": " + e);
6996        }
6997
6998        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6999                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7000            app.persistent = true;
7001            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
7002        }
7003        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7004            mPersistentStartingProcesses.add(app);
7005            startProcessLocked(app, "added application", app.processName);
7006        }
7007
7008        return app;
7009    }
7010
7011    public void unhandledBack() {
7012        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7013                "unhandledBack()");
7014
7015        synchronized(this) {
7016            int count = mMainStack.mHistory.size();
7017            if (DEBUG_SWITCH) Slog.d(
7018                TAG, "Performing unhandledBack(): stack size = " + count);
7019            if (count > 1) {
7020                final long origId = Binder.clearCallingIdentity();
7021                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
7022                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true);
7023                Binder.restoreCallingIdentity(origId);
7024            }
7025        }
7026    }
7027
7028    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
7029        enforceNotIsolatedCaller("openContentUri");
7030        final int userId = UserHandle.getCallingUserId();
7031        String name = uri.getAuthority();
7032        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
7033        ParcelFileDescriptor pfd = null;
7034        if (cph != null) {
7035            // We record the binder invoker's uid in thread-local storage before
7036            // going to the content provider to open the file.  Later, in the code
7037            // that handles all permissions checks, we look for this uid and use
7038            // that rather than the Activity Manager's own uid.  The effect is that
7039            // we do the check against the caller's permissions even though it looks
7040            // to the content provider like the Activity Manager itself is making
7041            // the request.
7042            sCallerIdentity.set(new Identity(
7043                    Binder.getCallingPid(), Binder.getCallingUid()));
7044            try {
7045                pfd = cph.provider.openFile(uri, "r");
7046            } catch (FileNotFoundException e) {
7047                // do nothing; pfd will be returned null
7048            } finally {
7049                // Ensure that whatever happens, we clean up the identity state
7050                sCallerIdentity.remove();
7051            }
7052
7053            // We've got the fd now, so we're done with the provider.
7054            removeContentProviderExternalUnchecked(name, null, userId);
7055        } else {
7056            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
7057        }
7058        return pfd;
7059    }
7060
7061    // Actually is sleeping or shutting down or whatever else in the future
7062    // is an inactive state.
7063    public boolean isSleeping() {
7064        return mSleeping || mShuttingDown;
7065    }
7066
7067    public void goingToSleep() {
7068        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7069                != PackageManager.PERMISSION_GRANTED) {
7070            throw new SecurityException("Requires permission "
7071                    + android.Manifest.permission.DEVICE_POWER);
7072        }
7073
7074        synchronized(this) {
7075            mWentToSleep = true;
7076            updateEventDispatchingLocked();
7077
7078            if (!mSleeping) {
7079                mSleeping = true;
7080                mMainStack.stopIfSleepingLocked();
7081
7082                // Initialize the wake times of all processes.
7083                checkExcessivePowerUsageLocked(false);
7084                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7085                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7086                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
7087            }
7088        }
7089    }
7090
7091    public boolean shutdown(int timeout) {
7092        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7093                != PackageManager.PERMISSION_GRANTED) {
7094            throw new SecurityException("Requires permission "
7095                    + android.Manifest.permission.SHUTDOWN);
7096        }
7097
7098        boolean timedout = false;
7099
7100        synchronized(this) {
7101            mShuttingDown = true;
7102            updateEventDispatchingLocked();
7103
7104            if (mMainStack.mResumedActivity != null) {
7105                mMainStack.stopIfSleepingLocked();
7106                final long endTime = System.currentTimeMillis() + timeout;
7107                while (mMainStack.mResumedActivity != null
7108                        || mMainStack.mPausingActivity != null) {
7109                    long delay = endTime - System.currentTimeMillis();
7110                    if (delay <= 0) {
7111                        Slog.w(TAG, "Activity manager shutdown timed out");
7112                        timedout = true;
7113                        break;
7114                    }
7115                    try {
7116                        this.wait();
7117                    } catch (InterruptedException e) {
7118                    }
7119                }
7120            }
7121        }
7122
7123        mUsageStatsService.shutdown();
7124        mBatteryStatsService.shutdown();
7125
7126        return timedout;
7127    }
7128
7129    public final void activitySlept(IBinder token) {
7130        if (localLOGV) Slog.v(
7131            TAG, "Activity slept: token=" + token);
7132
7133        ActivityRecord r = null;
7134
7135        final long origId = Binder.clearCallingIdentity();
7136
7137        synchronized (this) {
7138            r = mMainStack.isInStackLocked(token);
7139            if (r != null) {
7140                mMainStack.activitySleptLocked(r);
7141            }
7142        }
7143
7144        Binder.restoreCallingIdentity(origId);
7145    }
7146
7147    private void comeOutOfSleepIfNeededLocked() {
7148        if (!mWentToSleep && !mLockScreenShown) {
7149            if (mSleeping) {
7150                mSleeping = false;
7151                mMainStack.awakeFromSleepingLocked();
7152                mMainStack.resumeTopActivityLocked(null);
7153            }
7154        }
7155    }
7156
7157    public void wakingUp() {
7158        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7159                != PackageManager.PERMISSION_GRANTED) {
7160            throw new SecurityException("Requires permission "
7161                    + android.Manifest.permission.DEVICE_POWER);
7162        }
7163
7164        synchronized(this) {
7165            mWentToSleep = false;
7166            updateEventDispatchingLocked();
7167            comeOutOfSleepIfNeededLocked();
7168        }
7169    }
7170
7171    private void updateEventDispatchingLocked() {
7172        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
7173    }
7174
7175    public void setLockScreenShown(boolean shown) {
7176        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7177                != PackageManager.PERMISSION_GRANTED) {
7178            throw new SecurityException("Requires permission "
7179                    + android.Manifest.permission.DEVICE_POWER);
7180        }
7181
7182        synchronized(this) {
7183            mLockScreenShown = shown;
7184            comeOutOfSleepIfNeededLocked();
7185        }
7186    }
7187
7188    public void stopAppSwitches() {
7189        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7190                != PackageManager.PERMISSION_GRANTED) {
7191            throw new SecurityException("Requires permission "
7192                    + android.Manifest.permission.STOP_APP_SWITCHES);
7193        }
7194
7195        synchronized(this) {
7196            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7197                    + APP_SWITCH_DELAY_TIME;
7198            mDidAppSwitch = false;
7199            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7200            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7201            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7202        }
7203    }
7204
7205    public void resumeAppSwitches() {
7206        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7207                != PackageManager.PERMISSION_GRANTED) {
7208            throw new SecurityException("Requires permission "
7209                    + android.Manifest.permission.STOP_APP_SWITCHES);
7210        }
7211
7212        synchronized(this) {
7213            // Note that we don't execute any pending app switches... we will
7214            // let those wait until either the timeout, or the next start
7215            // activity request.
7216            mAppSwitchesAllowedTime = 0;
7217        }
7218    }
7219
7220    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7221            String name) {
7222        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7223            return true;
7224        }
7225
7226        final int perm = checkComponentPermission(
7227                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7228                callingUid, -1, true);
7229        if (perm == PackageManager.PERMISSION_GRANTED) {
7230            return true;
7231        }
7232
7233        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7234        return false;
7235    }
7236
7237    public void setDebugApp(String packageName, boolean waitForDebugger,
7238            boolean persistent) {
7239        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7240                "setDebugApp()");
7241
7242        // Note that this is not really thread safe if there are multiple
7243        // callers into it at the same time, but that's not a situation we
7244        // care about.
7245        if (persistent) {
7246            final ContentResolver resolver = mContext.getContentResolver();
7247            Settings.System.putString(
7248                resolver, Settings.System.DEBUG_APP,
7249                packageName);
7250            Settings.System.putInt(
7251                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7252                waitForDebugger ? 1 : 0);
7253        }
7254
7255        synchronized (this) {
7256            if (!persistent) {
7257                mOrigDebugApp = mDebugApp;
7258                mOrigWaitForDebugger = mWaitForDebugger;
7259            }
7260            mDebugApp = packageName;
7261            mWaitForDebugger = waitForDebugger;
7262            mDebugTransient = !persistent;
7263            if (packageName != null) {
7264                final long origId = Binder.clearCallingIdentity();
7265                forceStopPackageLocked(packageName, -1, false, false, true, true,
7266                        UserHandle.USER_ALL);
7267                Binder.restoreCallingIdentity(origId);
7268            }
7269        }
7270    }
7271
7272    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7273        synchronized (this) {
7274            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7275            if (!isDebuggable) {
7276                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7277                    throw new SecurityException("Process not debuggable: " + app.packageName);
7278                }
7279            }
7280
7281            mOpenGlTraceApp = processName;
7282        }
7283    }
7284
7285    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7286            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7287        synchronized (this) {
7288            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7289            if (!isDebuggable) {
7290                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7291                    throw new SecurityException("Process not debuggable: " + app.packageName);
7292                }
7293            }
7294            mProfileApp = processName;
7295            mProfileFile = profileFile;
7296            if (mProfileFd != null) {
7297                try {
7298                    mProfileFd.close();
7299                } catch (IOException e) {
7300                }
7301                mProfileFd = null;
7302            }
7303            mProfileFd = profileFd;
7304            mProfileType = 0;
7305            mAutoStopProfiler = autoStopProfiler;
7306        }
7307    }
7308
7309    public void setAlwaysFinish(boolean enabled) {
7310        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7311                "setAlwaysFinish()");
7312
7313        Settings.System.putInt(
7314                mContext.getContentResolver(),
7315                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7316
7317        synchronized (this) {
7318            mAlwaysFinishActivities = enabled;
7319        }
7320    }
7321
7322    public void setActivityController(IActivityController controller) {
7323        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7324                "setActivityController()");
7325        synchronized (this) {
7326            mController = controller;
7327        }
7328    }
7329
7330    public boolean isUserAMonkey() {
7331        // For now the fact that there is a controller implies
7332        // we have a monkey.
7333        synchronized (this) {
7334            return mController != null;
7335        }
7336    }
7337
7338    public void requestBugReport() {
7339        // No permission check because this can't do anything harmful --
7340        // it will just eventually cause the user to be presented with
7341        // a UI to select where the bug report goes.
7342        SystemProperties.set("ctl.start", "bugreport");
7343    }
7344
7345    public long inputDispatchingTimedOut(int pid, boolean aboveSystem) {
7346        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
7347                != PackageManager.PERMISSION_GRANTED) {
7348            throw new SecurityException("Requires permission "
7349                    + android.Manifest.permission.FILTER_EVENTS);
7350        }
7351
7352        ProcessRecord proc;
7353
7354        // TODO: Unify this code with ActivityRecord.keyDispatchingTimedOut().
7355        synchronized (this) {
7356            synchronized (mPidsSelfLocked) {
7357                proc = mPidsSelfLocked.get(pid);
7358            }
7359            if (proc != null) {
7360                if (proc.debugging) {
7361                    return -1;
7362                }
7363
7364                if (mDidDexOpt) {
7365                    // Give more time since we were dexopting.
7366                    mDidDexOpt = false;
7367                    return -1;
7368                }
7369
7370                if (proc.instrumentationClass != null) {
7371                    Bundle info = new Bundle();
7372                    info.putString("shortMsg", "keyDispatchingTimedOut");
7373                    info.putString("longMsg", "Timed out while dispatching key event");
7374                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
7375                    proc = null;
7376                }
7377            }
7378        }
7379
7380        if (proc != null) {
7381            appNotResponding(proc, null, null, aboveSystem, "keyDispatchingTimedOut");
7382            if (proc.instrumentationClass != null || proc.usingWrapper) {
7383                return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
7384            }
7385        }
7386
7387        return KEY_DISPATCHING_TIMEOUT;
7388    }
7389
7390    public void registerProcessObserver(IProcessObserver observer) {
7391        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7392                "registerProcessObserver()");
7393        synchronized (this) {
7394            mProcessObservers.register(observer);
7395        }
7396    }
7397
7398    public void unregisterProcessObserver(IProcessObserver observer) {
7399        synchronized (this) {
7400            mProcessObservers.unregister(observer);
7401        }
7402    }
7403
7404    public void setImmersive(IBinder token, boolean immersive) {
7405        synchronized(this) {
7406            ActivityRecord r = mMainStack.isInStackLocked(token);
7407            if (r == null) {
7408                throw new IllegalArgumentException();
7409            }
7410            r.immersive = immersive;
7411        }
7412    }
7413
7414    public boolean isImmersive(IBinder token) {
7415        synchronized (this) {
7416            ActivityRecord r = mMainStack.isInStackLocked(token);
7417            if (r == null) {
7418                throw new IllegalArgumentException();
7419            }
7420            return r.immersive;
7421        }
7422    }
7423
7424    public boolean isTopActivityImmersive() {
7425        enforceNotIsolatedCaller("startActivity");
7426        synchronized (this) {
7427            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7428            return (r != null) ? r.immersive : false;
7429        }
7430    }
7431
7432    public final void enterSafeMode() {
7433        synchronized(this) {
7434            // It only makes sense to do this before the system is ready
7435            // and started launching other packages.
7436            if (!mSystemReady) {
7437                try {
7438                    AppGlobals.getPackageManager().enterSafeMode();
7439                } catch (RemoteException e) {
7440                }
7441            }
7442        }
7443    }
7444
7445    public final void showSafeModeOverlay() {
7446        View v = LayoutInflater.from(mContext).inflate(
7447                com.android.internal.R.layout.safe_mode, null);
7448        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7449        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7450        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7451        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7452        lp.gravity = Gravity.BOTTOM | Gravity.START;
7453        lp.format = v.getBackground().getOpacity();
7454        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7455                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7456        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
7457        ((WindowManager)mContext.getSystemService(
7458                Context.WINDOW_SERVICE)).addView(v, lp);
7459    }
7460
7461    public void noteWakeupAlarm(IIntentSender sender) {
7462        if (!(sender instanceof PendingIntentRecord)) {
7463            return;
7464        }
7465        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7466        synchronized (stats) {
7467            if (mBatteryStatsService.isOnBattery()) {
7468                mBatteryStatsService.enforceCallingPermission();
7469                PendingIntentRecord rec = (PendingIntentRecord)sender;
7470                int MY_UID = Binder.getCallingUid();
7471                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7472                BatteryStatsImpl.Uid.Pkg pkg =
7473                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7474                pkg.incWakeupsLocked();
7475            }
7476        }
7477    }
7478
7479    public boolean killPids(int[] pids, String pReason, boolean secure) {
7480        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7481            throw new SecurityException("killPids only available to the system");
7482        }
7483        String reason = (pReason == null) ? "Unknown" : pReason;
7484        // XXX Note: don't acquire main activity lock here, because the window
7485        // manager calls in with its locks held.
7486
7487        boolean killed = false;
7488        synchronized (mPidsSelfLocked) {
7489            int[] types = new int[pids.length];
7490            int worstType = 0;
7491            for (int i=0; i<pids.length; i++) {
7492                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7493                if (proc != null) {
7494                    int type = proc.setAdj;
7495                    types[i] = type;
7496                    if (type > worstType) {
7497                        worstType = type;
7498                    }
7499                }
7500            }
7501
7502            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7503            // then constrain it so we will kill all hidden procs.
7504            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7505                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7506                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7507            }
7508
7509            // If this is not a secure call, don't let it kill processes that
7510            // are important.
7511            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7512                worstType = ProcessList.SERVICE_ADJ;
7513            }
7514
7515            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7516            for (int i=0; i<pids.length; i++) {
7517                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7518                if (proc == null) {
7519                    continue;
7520                }
7521                int adj = proc.setAdj;
7522                if (adj >= worstType && !proc.killedBackground) {
7523                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7524                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, proc.pid,
7525                            proc.processName, adj, reason);
7526                    killed = true;
7527                    proc.killedBackground = true;
7528                    Process.killProcessQuiet(pids[i]);
7529                }
7530            }
7531        }
7532        return killed;
7533    }
7534
7535    @Override
7536    public boolean killProcessesBelowForeground(String reason) {
7537        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7538            throw new SecurityException("killProcessesBelowForeground() only available to system");
7539        }
7540
7541        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7542    }
7543
7544    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7545        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7546            throw new SecurityException("killProcessesBelowAdj() only available to system");
7547        }
7548
7549        boolean killed = false;
7550        synchronized (mPidsSelfLocked) {
7551            final int size = mPidsSelfLocked.size();
7552            for (int i = 0; i < size; i++) {
7553                final int pid = mPidsSelfLocked.keyAt(i);
7554                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7555                if (proc == null) continue;
7556
7557                final int adj = proc.setAdj;
7558                if (adj > belowAdj && !proc.killedBackground) {
7559                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7560                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId,
7561                            proc.pid, proc.processName, adj, reason);
7562                    killed = true;
7563                    proc.killedBackground = true;
7564                    Process.killProcessQuiet(pid);
7565                }
7566            }
7567        }
7568        return killed;
7569    }
7570
7571    public final void startRunning(String pkg, String cls, String action,
7572            String data) {
7573        synchronized(this) {
7574            if (mStartRunning) {
7575                return;
7576            }
7577            mStartRunning = true;
7578            mTopComponent = pkg != null && cls != null
7579                    ? new ComponentName(pkg, cls) : null;
7580            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7581            mTopData = data;
7582            if (!mSystemReady) {
7583                return;
7584            }
7585        }
7586
7587        systemReady(null);
7588    }
7589
7590    private void retrieveSettings() {
7591        final ContentResolver resolver = mContext.getContentResolver();
7592        String debugApp = Settings.System.getString(
7593            resolver, Settings.System.DEBUG_APP);
7594        boolean waitForDebugger = Settings.System.getInt(
7595            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7596        boolean alwaysFinishActivities = Settings.System.getInt(
7597            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7598
7599        Configuration configuration = new Configuration();
7600        Settings.System.getConfiguration(resolver, configuration);
7601
7602        synchronized (this) {
7603            mDebugApp = mOrigDebugApp = debugApp;
7604            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7605            mAlwaysFinishActivities = alwaysFinishActivities;
7606            // This happens before any activities are started, so we can
7607            // change mConfiguration in-place.
7608            updateConfigurationLocked(configuration, null, false, true);
7609            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7610        }
7611    }
7612
7613    public boolean testIsSystemReady() {
7614        // no need to synchronize(this) just to read & return the value
7615        return mSystemReady;
7616    }
7617
7618    private static File getCalledPreBootReceiversFile() {
7619        File dataDir = Environment.getDataDirectory();
7620        File systemDir = new File(dataDir, "system");
7621        File fname = new File(systemDir, "called_pre_boots.dat");
7622        return fname;
7623    }
7624
7625    static final int LAST_DONE_VERSION = 10000;
7626
7627    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7628        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7629        File file = getCalledPreBootReceiversFile();
7630        FileInputStream fis = null;
7631        try {
7632            fis = new FileInputStream(file);
7633            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7634            int fvers = dis.readInt();
7635            if (fvers == LAST_DONE_VERSION) {
7636                String vers = dis.readUTF();
7637                String codename = dis.readUTF();
7638                String build = dis.readUTF();
7639                if (android.os.Build.VERSION.RELEASE.equals(vers)
7640                        && android.os.Build.VERSION.CODENAME.equals(codename)
7641                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7642                    int num = dis.readInt();
7643                    while (num > 0) {
7644                        num--;
7645                        String pkg = dis.readUTF();
7646                        String cls = dis.readUTF();
7647                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7648                    }
7649                }
7650            }
7651        } catch (FileNotFoundException e) {
7652        } catch (IOException e) {
7653            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7654        } finally {
7655            if (fis != null) {
7656                try {
7657                    fis.close();
7658                } catch (IOException e) {
7659                }
7660            }
7661        }
7662        return lastDoneReceivers;
7663    }
7664
7665    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7666        File file = getCalledPreBootReceiversFile();
7667        FileOutputStream fos = null;
7668        DataOutputStream dos = null;
7669        try {
7670            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7671            fos = new FileOutputStream(file);
7672            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7673            dos.writeInt(LAST_DONE_VERSION);
7674            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7675            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7676            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7677            dos.writeInt(list.size());
7678            for (int i=0; i<list.size(); i++) {
7679                dos.writeUTF(list.get(i).getPackageName());
7680                dos.writeUTF(list.get(i).getClassName());
7681            }
7682        } catch (IOException e) {
7683            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7684            file.delete();
7685        } finally {
7686            FileUtils.sync(fos);
7687            if (dos != null) {
7688                try {
7689                    dos.close();
7690                } catch (IOException e) {
7691                    // TODO Auto-generated catch block
7692                    e.printStackTrace();
7693                }
7694            }
7695        }
7696    }
7697
7698    public void systemReady(final Runnable goingCallback) {
7699        synchronized(this) {
7700            if (mSystemReady) {
7701                if (goingCallback != null) goingCallback.run();
7702                return;
7703            }
7704
7705            // Check to see if there are any update receivers to run.
7706            if (!mDidUpdate) {
7707                if (mWaitingUpdate) {
7708                    return;
7709                }
7710                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7711                List<ResolveInfo> ris = null;
7712                try {
7713                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7714                            intent, null, 0, 0);
7715                } catch (RemoteException e) {
7716                }
7717                if (ris != null) {
7718                    for (int i=ris.size()-1; i>=0; i--) {
7719                        if ((ris.get(i).activityInfo.applicationInfo.flags
7720                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7721                            ris.remove(i);
7722                        }
7723                    }
7724                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7725
7726                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7727
7728                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7729                    for (int i=0; i<ris.size(); i++) {
7730                        ActivityInfo ai = ris.get(i).activityInfo;
7731                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7732                        if (lastDoneReceivers.contains(comp)) {
7733                            ris.remove(i);
7734                            i--;
7735                        }
7736                    }
7737
7738                    final int[] users = getUsersLocked();
7739                    for (int i=0; i<ris.size(); i++) {
7740                        ActivityInfo ai = ris.get(i).activityInfo;
7741                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7742                        doneReceivers.add(comp);
7743                        intent.setComponent(comp);
7744                        for (int j=0; j<users.length; j++) {
7745                            IIntentReceiver finisher = null;
7746                            if (i == ris.size()-1 && j == users.length-1) {
7747                                finisher = new IIntentReceiver.Stub() {
7748                                    public void performReceive(Intent intent, int resultCode,
7749                                            String data, Bundle extras, boolean ordered,
7750                                            boolean sticky, int sendingUser) {
7751                                        // The raw IIntentReceiver interface is called
7752                                        // with the AM lock held, so redispatch to
7753                                        // execute our code without the lock.
7754                                        mHandler.post(new Runnable() {
7755                                            public void run() {
7756                                                synchronized (ActivityManagerService.this) {
7757                                                    mDidUpdate = true;
7758                                                }
7759                                                writeLastDonePreBootReceivers(doneReceivers);
7760                                                showBootMessage(mContext.getText(
7761                                                        R.string.android_upgrading_complete),
7762                                                        false);
7763                                                systemReady(goingCallback);
7764                                            }
7765                                        });
7766                                    }
7767                                };
7768                            }
7769                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
7770                                    + " for user " + users[j]);
7771                            broadcastIntentLocked(null, null, intent, null, finisher,
7772                                    0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7773                                    users[j]);
7774                            if (finisher != null) {
7775                                mWaitingUpdate = true;
7776                            }
7777                        }
7778                    }
7779                }
7780                if (mWaitingUpdate) {
7781                    return;
7782                }
7783                mDidUpdate = true;
7784            }
7785
7786            mSystemReady = true;
7787            if (!mStartRunning) {
7788                return;
7789            }
7790        }
7791
7792        ArrayList<ProcessRecord> procsToKill = null;
7793        synchronized(mPidsSelfLocked) {
7794            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7795                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7796                if (!isAllowedWhileBooting(proc.info)){
7797                    if (procsToKill == null) {
7798                        procsToKill = new ArrayList<ProcessRecord>();
7799                    }
7800                    procsToKill.add(proc);
7801                }
7802            }
7803        }
7804
7805        synchronized(this) {
7806            if (procsToKill != null) {
7807                for (int i=procsToKill.size()-1; i>=0; i--) {
7808                    ProcessRecord proc = procsToKill.get(i);
7809                    Slog.i(TAG, "Removing system update proc: " + proc);
7810                    removeProcessLocked(proc, true, false, "system update done");
7811                }
7812            }
7813
7814            // Now that we have cleaned up any update processes, we
7815            // are ready to start launching real processes and know that
7816            // we won't trample on them any more.
7817            mProcessesReady = true;
7818        }
7819
7820        Slog.i(TAG, "System now ready");
7821        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7822            SystemClock.uptimeMillis());
7823
7824        synchronized(this) {
7825            // Make sure we have no pre-ready processes sitting around.
7826
7827            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7828                ResolveInfo ri = mContext.getPackageManager()
7829                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7830                                STOCK_PM_FLAGS);
7831                CharSequence errorMsg = null;
7832                if (ri != null) {
7833                    ActivityInfo ai = ri.activityInfo;
7834                    ApplicationInfo app = ai.applicationInfo;
7835                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7836                        mTopAction = Intent.ACTION_FACTORY_TEST;
7837                        mTopData = null;
7838                        mTopComponent = new ComponentName(app.packageName,
7839                                ai.name);
7840                    } else {
7841                        errorMsg = mContext.getResources().getText(
7842                                com.android.internal.R.string.factorytest_not_system);
7843                    }
7844                } else {
7845                    errorMsg = mContext.getResources().getText(
7846                            com.android.internal.R.string.factorytest_no_action);
7847                }
7848                if (errorMsg != null) {
7849                    mTopAction = null;
7850                    mTopData = null;
7851                    mTopComponent = null;
7852                    Message msg = Message.obtain();
7853                    msg.what = SHOW_FACTORY_ERROR_MSG;
7854                    msg.getData().putCharSequence("msg", errorMsg);
7855                    mHandler.sendMessage(msg);
7856                }
7857            }
7858        }
7859
7860        retrieveSettings();
7861
7862        if (goingCallback != null) goingCallback.run();
7863
7864        synchronized (this) {
7865            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7866                try {
7867                    List apps = AppGlobals.getPackageManager().
7868                        getPersistentApplications(STOCK_PM_FLAGS);
7869                    if (apps != null) {
7870                        int N = apps.size();
7871                        int i;
7872                        for (i=0; i<N; i++) {
7873                            ApplicationInfo info
7874                                = (ApplicationInfo)apps.get(i);
7875                            if (info != null &&
7876                                    !info.packageName.equals("android")) {
7877                                addAppLocked(info, false);
7878                            }
7879                        }
7880                    }
7881                } catch (RemoteException ex) {
7882                    // pm is in same process, this will never happen.
7883                }
7884            }
7885
7886            // Start up initial activity.
7887            mBooting = true;
7888
7889            try {
7890                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7891                    Message msg = Message.obtain();
7892                    msg.what = SHOW_UID_ERROR_MSG;
7893                    mHandler.sendMessage(msg);
7894                }
7895            } catch (RemoteException e) {
7896            }
7897
7898            long ident = Binder.clearCallingIdentity();
7899            try {
7900                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
7901                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
7902                        | Intent.FLAG_RECEIVER_FOREGROUND);
7903                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
7904                broadcastIntentLocked(null, null, intent,
7905                        null, null, 0, null, null, null,
7906                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
7907            } finally {
7908                Binder.restoreCallingIdentity(ident);
7909            }
7910            mMainStack.resumeTopActivityLocked(null);
7911            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
7912        }
7913    }
7914
7915    private boolean makeAppCrashingLocked(ProcessRecord app,
7916            String shortMsg, String longMsg, String stackTrace) {
7917        app.crashing = true;
7918        app.crashingReport = generateProcessError(app,
7919                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7920        startAppProblemLocked(app);
7921        app.stopFreezingAllLocked();
7922        return handleAppCrashLocked(app);
7923    }
7924
7925    private void makeAppNotRespondingLocked(ProcessRecord app,
7926            String activity, String shortMsg, String longMsg) {
7927        app.notResponding = true;
7928        app.notRespondingReport = generateProcessError(app,
7929                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7930                activity, shortMsg, longMsg, null);
7931        startAppProblemLocked(app);
7932        app.stopFreezingAllLocked();
7933    }
7934
7935    /**
7936     * Generate a process error record, suitable for attachment to a ProcessRecord.
7937     *
7938     * @param app The ProcessRecord in which the error occurred.
7939     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7940     *                      ActivityManager.AppErrorStateInfo
7941     * @param activity The activity associated with the crash, if known.
7942     * @param shortMsg Short message describing the crash.
7943     * @param longMsg Long message describing the crash.
7944     * @param stackTrace Full crash stack trace, may be null.
7945     *
7946     * @return Returns a fully-formed AppErrorStateInfo record.
7947     */
7948    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7949            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7950        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7951
7952        report.condition = condition;
7953        report.processName = app.processName;
7954        report.pid = app.pid;
7955        report.uid = app.info.uid;
7956        report.tag = activity;
7957        report.shortMsg = shortMsg;
7958        report.longMsg = longMsg;
7959        report.stackTrace = stackTrace;
7960
7961        return report;
7962    }
7963
7964    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7965        synchronized (this) {
7966            app.crashing = false;
7967            app.crashingReport = null;
7968            app.notResponding = false;
7969            app.notRespondingReport = null;
7970            if (app.anrDialog == fromDialog) {
7971                app.anrDialog = null;
7972            }
7973            if (app.waitDialog == fromDialog) {
7974                app.waitDialog = null;
7975            }
7976            if (app.pid > 0 && app.pid != MY_PID) {
7977                handleAppCrashLocked(app);
7978                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7979                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
7980                        app.processName, app.setAdj, "user's request after error");
7981                Process.killProcessQuiet(app.pid);
7982            }
7983        }
7984    }
7985
7986    private boolean handleAppCrashLocked(ProcessRecord app) {
7987        if (mHeadless) {
7988            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7989            return false;
7990        }
7991        long now = SystemClock.uptimeMillis();
7992
7993        Long crashTime;
7994        if (!app.isolated) {
7995            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7996        } else {
7997            crashTime = null;
7998        }
7999        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
8000            // This process loses!
8001            Slog.w(TAG, "Process " + app.info.processName
8002                    + " has crashed too many times: killing!");
8003            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
8004                    app.userId, app.info.processName, app.uid);
8005            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
8006                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
8007                if (r.app == app) {
8008                    Slog.w(TAG, "  Force finishing activity "
8009                        + r.intent.getComponent().flattenToShortString());
8010                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
8011                            null, "crashed", false);
8012                }
8013            }
8014            if (!app.persistent) {
8015                // We don't want to start this process again until the user
8016                // explicitly does so...  but for persistent process, we really
8017                // need to keep it running.  If a persistent process is actually
8018                // repeatedly crashing, then badness for everyone.
8019                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
8020                        app.info.processName);
8021                if (!app.isolated) {
8022                    // XXX We don't have a way to mark isolated processes
8023                    // as bad, since they don't have a peristent identity.
8024                    mBadProcesses.put(app.info.processName, app.uid, now);
8025                    mProcessCrashTimes.remove(app.info.processName, app.uid);
8026                }
8027                app.bad = true;
8028                app.removed = true;
8029                // Don't let services in this process be restarted and potentially
8030                // annoy the user repeatedly.  Unless it is persistent, since those
8031                // processes run critical code.
8032                removeProcessLocked(app, false, false, "crash");
8033                mMainStack.resumeTopActivityLocked(null);
8034                return false;
8035            }
8036            mMainStack.resumeTopActivityLocked(null);
8037        } else {
8038            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
8039            if (r != null && r.app == app) {
8040                // If the top running activity is from this crashing
8041                // process, then terminate it to avoid getting in a loop.
8042                Slog.w(TAG, "  Force finishing activity "
8043                        + r.intent.getComponent().flattenToShortString());
8044                int index = mMainStack.indexOfActivityLocked(r);
8045                r.stack.finishActivityLocked(r, index,
8046                        Activity.RESULT_CANCELED, null, "crashed", false);
8047                // Also terminate any activities below it that aren't yet
8048                // stopped, to avoid a situation where one will get
8049                // re-start our crashing activity once it gets resumed again.
8050                index--;
8051                if (index >= 0) {
8052                    r = (ActivityRecord)mMainStack.mHistory.get(index);
8053                    if (r.state == ActivityState.RESUMED
8054                            || r.state == ActivityState.PAUSING
8055                            || r.state == ActivityState.PAUSED) {
8056                        if (!r.isHomeActivity || mHomeProcess != r.app) {
8057                            Slog.w(TAG, "  Force finishing activity "
8058                                    + r.intent.getComponent().flattenToShortString());
8059                            r.stack.finishActivityLocked(r, index,
8060                                    Activity.RESULT_CANCELED, null, "crashed", false);
8061                        }
8062                    }
8063                }
8064            }
8065        }
8066
8067        // Bump up the crash count of any services currently running in the proc.
8068        if (app.services.size() != 0) {
8069            // Any services running in the application need to be placed
8070            // back in the pending list.
8071            Iterator<ServiceRecord> it = app.services.iterator();
8072            while (it.hasNext()) {
8073                ServiceRecord sr = it.next();
8074                sr.crashCount++;
8075            }
8076        }
8077
8078        // If the crashing process is what we consider to be the "home process" and it has been
8079        // replaced by a third-party app, clear the package preferred activities from packages
8080        // with a home activity running in the process to prevent a repeatedly crashing app
8081        // from blocking the user to manually clear the list.
8082        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
8083                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
8084            Iterator it = mHomeProcess.activities.iterator();
8085            while (it.hasNext()) {
8086                ActivityRecord r = (ActivityRecord)it.next();
8087                if (r.isHomeActivity) {
8088                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
8089                    try {
8090                        ActivityThread.getPackageManager()
8091                                .clearPackagePreferredActivities(r.packageName);
8092                    } catch (RemoteException c) {
8093                        // pm is in same process, this will never happen.
8094                    }
8095                }
8096            }
8097        }
8098
8099        if (!app.isolated) {
8100            // XXX Can't keep track of crash times for isolated processes,
8101            // because they don't have a perisistent identity.
8102            mProcessCrashTimes.put(app.info.processName, app.uid, now);
8103        }
8104
8105        return true;
8106    }
8107
8108    void startAppProblemLocked(ProcessRecord app) {
8109        if (app.userId == mCurrentUserId) {
8110            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
8111                    mContext, app.info.packageName, app.info.flags);
8112        } else {
8113            // If this app is not running under the current user, then we
8114            // can't give it a report button because that would require
8115            // launching the report UI under a different user.
8116            app.errorReportReceiver = null;
8117        }
8118        skipCurrentReceiverLocked(app);
8119    }
8120
8121    void skipCurrentReceiverLocked(ProcessRecord app) {
8122        for (BroadcastQueue queue : mBroadcastQueues) {
8123            queue.skipCurrentReceiverLocked(app);
8124        }
8125    }
8126
8127    /**
8128     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8129     * The application process will exit immediately after this call returns.
8130     * @param app object of the crashing app, null for the system server
8131     * @param crashInfo describing the exception
8132     */
8133    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
8134        ProcessRecord r = findAppProcess(app, "Crash");
8135        final String processName = app == null ? "system_server"
8136                : (r == null ? "unknown" : r.processName);
8137
8138        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
8139                UserHandle.getUserId(Binder.getCallingUid()), processName,
8140                r == null ? -1 : r.info.flags,
8141                crashInfo.exceptionClassName,
8142                crashInfo.exceptionMessage,
8143                crashInfo.throwFileName,
8144                crashInfo.throwLineNumber);
8145
8146        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
8147
8148        crashApplication(r, crashInfo);
8149    }
8150
8151    public void handleApplicationStrictModeViolation(
8152            IBinder app,
8153            int violationMask,
8154            StrictMode.ViolationInfo info) {
8155        ProcessRecord r = findAppProcess(app, "StrictMode");
8156        if (r == null) {
8157            return;
8158        }
8159
8160        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
8161            Integer stackFingerprint = info.hashCode();
8162            boolean logIt = true;
8163            synchronized (mAlreadyLoggedViolatedStacks) {
8164                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
8165                    logIt = false;
8166                    // TODO: sub-sample into EventLog for these, with
8167                    // the info.durationMillis?  Then we'd get
8168                    // the relative pain numbers, without logging all
8169                    // the stack traces repeatedly.  We'd want to do
8170                    // likewise in the client code, which also does
8171                    // dup suppression, before the Binder call.
8172                } else {
8173                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
8174                        mAlreadyLoggedViolatedStacks.clear();
8175                    }
8176                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
8177                }
8178            }
8179            if (logIt) {
8180                logStrictModeViolationToDropBox(r, info);
8181            }
8182        }
8183
8184        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
8185            AppErrorResult result = new AppErrorResult();
8186            synchronized (this) {
8187                final long origId = Binder.clearCallingIdentity();
8188
8189                Message msg = Message.obtain();
8190                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
8191                HashMap<String, Object> data = new HashMap<String, Object>();
8192                data.put("result", result);
8193                data.put("app", r);
8194                data.put("violationMask", violationMask);
8195                data.put("info", info);
8196                msg.obj = data;
8197                mHandler.sendMessage(msg);
8198
8199                Binder.restoreCallingIdentity(origId);
8200            }
8201            int res = result.get();
8202            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
8203        }
8204    }
8205
8206    // Depending on the policy in effect, there could be a bunch of
8207    // these in quick succession so we try to batch these together to
8208    // minimize disk writes, number of dropbox entries, and maximize
8209    // compression, by having more fewer, larger records.
8210    private void logStrictModeViolationToDropBox(
8211            ProcessRecord process,
8212            StrictMode.ViolationInfo info) {
8213        if (info == null) {
8214            return;
8215        }
8216        final boolean isSystemApp = process == null ||
8217                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8218                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
8219        final String processName = process == null ? "unknown" : process.processName;
8220        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8221        final DropBoxManager dbox = (DropBoxManager)
8222                mContext.getSystemService(Context.DROPBOX_SERVICE);
8223
8224        // Exit early if the dropbox isn't configured to accept this report type.
8225        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8226
8227        boolean bufferWasEmpty;
8228        boolean needsFlush;
8229        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8230        synchronized (sb) {
8231            bufferWasEmpty = sb.length() == 0;
8232            appendDropBoxProcessHeaders(process, processName, sb);
8233            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8234            sb.append("System-App: ").append(isSystemApp).append("\n");
8235            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8236            if (info.violationNumThisLoop != 0) {
8237                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8238            }
8239            if (info.numAnimationsRunning != 0) {
8240                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8241            }
8242            if (info.broadcastIntentAction != null) {
8243                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8244            }
8245            if (info.durationMillis != -1) {
8246                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
8247            }
8248            if (info.numInstances != -1) {
8249                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8250            }
8251            if (info.tags != null) {
8252                for (String tag : info.tags) {
8253                    sb.append("Span-Tag: ").append(tag).append("\n");
8254                }
8255            }
8256            sb.append("\n");
8257            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8258                sb.append(info.crashInfo.stackTrace);
8259            }
8260            sb.append("\n");
8261
8262            // Only buffer up to ~64k.  Various logging bits truncate
8263            // things at 128k.
8264            needsFlush = (sb.length() > 64 * 1024);
8265        }
8266
8267        // Flush immediately if the buffer's grown too large, or this
8268        // is a non-system app.  Non-system apps are isolated with a
8269        // different tag & policy and not batched.
8270        //
8271        // Batching is useful during internal testing with
8272        // StrictMode settings turned up high.  Without batching,
8273        // thousands of separate files could be created on boot.
8274        if (!isSystemApp || needsFlush) {
8275            new Thread("Error dump: " + dropboxTag) {
8276                @Override
8277                public void run() {
8278                    String report;
8279                    synchronized (sb) {
8280                        report = sb.toString();
8281                        sb.delete(0, sb.length());
8282                        sb.trimToSize();
8283                    }
8284                    if (report.length() != 0) {
8285                        dbox.addText(dropboxTag, report);
8286                    }
8287                }
8288            }.start();
8289            return;
8290        }
8291
8292        // System app batching:
8293        if (!bufferWasEmpty) {
8294            // An existing dropbox-writing thread is outstanding, so
8295            // we don't need to start it up.  The existing thread will
8296            // catch the buffer appends we just did.
8297            return;
8298        }
8299
8300        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8301        // (After this point, we shouldn't access AMS internal data structures.)
8302        new Thread("Error dump: " + dropboxTag) {
8303            @Override
8304            public void run() {
8305                // 5 second sleep to let stacks arrive and be batched together
8306                try {
8307                    Thread.sleep(5000);  // 5 seconds
8308                } catch (InterruptedException e) {}
8309
8310                String errorReport;
8311                synchronized (mStrictModeBuffer) {
8312                    errorReport = mStrictModeBuffer.toString();
8313                    if (errorReport.length() == 0) {
8314                        return;
8315                    }
8316                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8317                    mStrictModeBuffer.trimToSize();
8318                }
8319                dbox.addText(dropboxTag, errorReport);
8320            }
8321        }.start();
8322    }
8323
8324    /**
8325     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8326     * @param app object of the crashing app, null for the system server
8327     * @param tag reported by the caller
8328     * @param crashInfo describing the context of the error
8329     * @return true if the process should exit immediately (WTF is fatal)
8330     */
8331    public boolean handleApplicationWtf(IBinder app, String tag,
8332            ApplicationErrorReport.CrashInfo crashInfo) {
8333        ProcessRecord r = findAppProcess(app, "WTF");
8334        final String processName = app == null ? "system_server"
8335                : (r == null ? "unknown" : r.processName);
8336
8337        EventLog.writeEvent(EventLogTags.AM_WTF,
8338                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
8339                processName,
8340                r == null ? -1 : r.info.flags,
8341                tag, crashInfo.exceptionMessage);
8342
8343        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8344
8345        if (r != null && r.pid != Process.myPid() &&
8346                Settings.Global.getInt(mContext.getContentResolver(),
8347                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
8348            crashApplication(r, crashInfo);
8349            return true;
8350        } else {
8351            return false;
8352        }
8353    }
8354
8355    /**
8356     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8357     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8358     */
8359    private ProcessRecord findAppProcess(IBinder app, String reason) {
8360        if (app == null) {
8361            return null;
8362        }
8363
8364        synchronized (this) {
8365            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8366                final int NA = apps.size();
8367                for (int ia=0; ia<NA; ia++) {
8368                    ProcessRecord p = apps.valueAt(ia);
8369                    if (p.thread != null && p.thread.asBinder() == app) {
8370                        return p;
8371                    }
8372                }
8373            }
8374
8375            Slog.w(TAG, "Can't find mystery application for " + reason
8376                    + " from pid=" + Binder.getCallingPid()
8377                    + " uid=" + Binder.getCallingUid() + ": " + app);
8378            return null;
8379        }
8380    }
8381
8382    /**
8383     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8384     * to append various headers to the dropbox log text.
8385     */
8386    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8387            StringBuilder sb) {
8388        // Watchdog thread ends up invoking this function (with
8389        // a null ProcessRecord) to add the stack file to dropbox.
8390        // Do not acquire a lock on this (am) in such cases, as it
8391        // could cause a potential deadlock, if and when watchdog
8392        // is invoked due to unavailability of lock on am and it
8393        // would prevent watchdog from killing system_server.
8394        if (process == null) {
8395            sb.append("Process: ").append(processName).append("\n");
8396            return;
8397        }
8398        // Note: ProcessRecord 'process' is guarded by the service
8399        // instance.  (notably process.pkgList, which could otherwise change
8400        // concurrently during execution of this method)
8401        synchronized (this) {
8402            sb.append("Process: ").append(processName).append("\n");
8403            int flags = process.info.flags;
8404            IPackageManager pm = AppGlobals.getPackageManager();
8405            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8406            for (String pkg : process.pkgList) {
8407                sb.append("Package: ").append(pkg);
8408                try {
8409                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
8410                    if (pi != null) {
8411                        sb.append(" v").append(pi.versionCode);
8412                        if (pi.versionName != null) {
8413                            sb.append(" (").append(pi.versionName).append(")");
8414                        }
8415                    }
8416                } catch (RemoteException e) {
8417                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8418                }
8419                sb.append("\n");
8420            }
8421        }
8422    }
8423
8424    private static String processClass(ProcessRecord process) {
8425        if (process == null || process.pid == MY_PID) {
8426            return "system_server";
8427        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8428            return "system_app";
8429        } else {
8430            return "data_app";
8431        }
8432    }
8433
8434    /**
8435     * Write a description of an error (crash, WTF, ANR) to the drop box.
8436     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8437     * @param process which caused the error, null means the system server
8438     * @param activity which triggered the error, null if unknown
8439     * @param parent activity related to the error, null if unknown
8440     * @param subject line related to the error, null if absent
8441     * @param report in long form describing the error, null if absent
8442     * @param logFile to include in the report, null if none
8443     * @param crashInfo giving an application stack trace, null if absent
8444     */
8445    public void addErrorToDropBox(String eventType,
8446            ProcessRecord process, String processName, ActivityRecord activity,
8447            ActivityRecord parent, String subject,
8448            final String report, final File logFile,
8449            final ApplicationErrorReport.CrashInfo crashInfo) {
8450        // NOTE -- this must never acquire the ActivityManagerService lock,
8451        // otherwise the watchdog may be prevented from resetting the system.
8452
8453        final String dropboxTag = processClass(process) + "_" + eventType;
8454        final DropBoxManager dbox = (DropBoxManager)
8455                mContext.getSystemService(Context.DROPBOX_SERVICE);
8456
8457        // Exit early if the dropbox isn't configured to accept this report type.
8458        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8459
8460        final StringBuilder sb = new StringBuilder(1024);
8461        appendDropBoxProcessHeaders(process, processName, sb);
8462        if (activity != null) {
8463            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8464        }
8465        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8466            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8467        }
8468        if (parent != null && parent != activity) {
8469            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8470        }
8471        if (subject != null) {
8472            sb.append("Subject: ").append(subject).append("\n");
8473        }
8474        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8475        if (Debug.isDebuggerConnected()) {
8476            sb.append("Debugger: Connected\n");
8477        }
8478        sb.append("\n");
8479
8480        // Do the rest in a worker thread to avoid blocking the caller on I/O
8481        // (After this point, we shouldn't access AMS internal data structures.)
8482        Thread worker = new Thread("Error dump: " + dropboxTag) {
8483            @Override
8484            public void run() {
8485                if (report != null) {
8486                    sb.append(report);
8487                }
8488                if (logFile != null) {
8489                    try {
8490                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8491                    } catch (IOException e) {
8492                        Slog.e(TAG, "Error reading " + logFile, e);
8493                    }
8494                }
8495                if (crashInfo != null && crashInfo.stackTrace != null) {
8496                    sb.append(crashInfo.stackTrace);
8497                }
8498
8499                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
8500                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
8501                if (lines > 0) {
8502                    sb.append("\n");
8503
8504                    // Merge several logcat streams, and take the last N lines
8505                    InputStreamReader input = null;
8506                    try {
8507                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8508                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8509                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8510
8511                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8512                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8513                        input = new InputStreamReader(logcat.getInputStream());
8514
8515                        int num;
8516                        char[] buf = new char[8192];
8517                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8518                    } catch (IOException e) {
8519                        Slog.e(TAG, "Error running logcat", e);
8520                    } finally {
8521                        if (input != null) try { input.close(); } catch (IOException e) {}
8522                    }
8523                }
8524
8525                dbox.addText(dropboxTag, sb.toString());
8526            }
8527        };
8528
8529        if (process == null) {
8530            // If process is null, we are being called from some internal code
8531            // and may be about to die -- run this synchronously.
8532            worker.run();
8533        } else {
8534            worker.start();
8535        }
8536    }
8537
8538    /**
8539     * Bring up the "unexpected error" dialog box for a crashing app.
8540     * Deal with edge cases (intercepts from instrumented applications,
8541     * ActivityController, error intent receivers, that sort of thing).
8542     * @param r the application crashing
8543     * @param crashInfo describing the failure
8544     */
8545    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8546        long timeMillis = System.currentTimeMillis();
8547        String shortMsg = crashInfo.exceptionClassName;
8548        String longMsg = crashInfo.exceptionMessage;
8549        String stackTrace = crashInfo.stackTrace;
8550        if (shortMsg != null && longMsg != null) {
8551            longMsg = shortMsg + ": " + longMsg;
8552        } else if (shortMsg != null) {
8553            longMsg = shortMsg;
8554        }
8555
8556        AppErrorResult result = new AppErrorResult();
8557        synchronized (this) {
8558            if (mController != null) {
8559                try {
8560                    String name = r != null ? r.processName : null;
8561                    int pid = r != null ? r.pid : Binder.getCallingPid();
8562                    if (!mController.appCrashed(name, pid,
8563                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8564                        Slog.w(TAG, "Force-killing crashed app " + name
8565                                + " at watcher's request");
8566                        Process.killProcess(pid);
8567                        return;
8568                    }
8569                } catch (RemoteException e) {
8570                    mController = null;
8571                }
8572            }
8573
8574            final long origId = Binder.clearCallingIdentity();
8575
8576            // If this process is running instrumentation, finish it.
8577            if (r != null && r.instrumentationClass != null) {
8578                Slog.w(TAG, "Error in app " + r.processName
8579                      + " running instrumentation " + r.instrumentationClass + ":");
8580                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8581                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8582                Bundle info = new Bundle();
8583                info.putString("shortMsg", shortMsg);
8584                info.putString("longMsg", longMsg);
8585                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8586                Binder.restoreCallingIdentity(origId);
8587                return;
8588            }
8589
8590            // If we can't identify the process or it's already exceeded its crash quota,
8591            // quit right away without showing a crash dialog.
8592            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8593                Binder.restoreCallingIdentity(origId);
8594                return;
8595            }
8596
8597            Message msg = Message.obtain();
8598            msg.what = SHOW_ERROR_MSG;
8599            HashMap data = new HashMap();
8600            data.put("result", result);
8601            data.put("app", r);
8602            msg.obj = data;
8603            mHandler.sendMessage(msg);
8604
8605            Binder.restoreCallingIdentity(origId);
8606        }
8607
8608        int res = result.get();
8609
8610        Intent appErrorIntent = null;
8611        synchronized (this) {
8612            if (r != null && !r.isolated) {
8613                // XXX Can't keep track of crash time for isolated processes,
8614                // since they don't have a persistent identity.
8615                mProcessCrashTimes.put(r.info.processName, r.uid,
8616                        SystemClock.uptimeMillis());
8617            }
8618            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8619                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8620            }
8621        }
8622
8623        if (appErrorIntent != null) {
8624            try {
8625                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
8626            } catch (ActivityNotFoundException e) {
8627                Slog.w(TAG, "bug report receiver dissappeared", e);
8628            }
8629        }
8630    }
8631
8632    Intent createAppErrorIntentLocked(ProcessRecord r,
8633            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8634        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8635        if (report == null) {
8636            return null;
8637        }
8638        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8639        result.setComponent(r.errorReportReceiver);
8640        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8641        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8642        return result;
8643    }
8644
8645    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8646            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8647        if (r.errorReportReceiver == null) {
8648            return null;
8649        }
8650
8651        if (!r.crashing && !r.notResponding) {
8652            return null;
8653        }
8654
8655        ApplicationErrorReport report = new ApplicationErrorReport();
8656        report.packageName = r.info.packageName;
8657        report.installerPackageName = r.errorReportReceiver.getPackageName();
8658        report.processName = r.processName;
8659        report.time = timeMillis;
8660        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8661
8662        if (r.crashing) {
8663            report.type = ApplicationErrorReport.TYPE_CRASH;
8664            report.crashInfo = crashInfo;
8665        } else if (r.notResponding) {
8666            report.type = ApplicationErrorReport.TYPE_ANR;
8667            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8668
8669            report.anrInfo.activity = r.notRespondingReport.tag;
8670            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8671            report.anrInfo.info = r.notRespondingReport.longMsg;
8672        }
8673
8674        return report;
8675    }
8676
8677    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8678        enforceNotIsolatedCaller("getProcessesInErrorState");
8679        // assume our apps are happy - lazy create the list
8680        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8681
8682        final boolean allUsers = ActivityManager.checkUidPermission(
8683                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8684                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8685        int userId = UserHandle.getUserId(Binder.getCallingUid());
8686
8687        synchronized (this) {
8688
8689            // iterate across all processes
8690            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8691                ProcessRecord app = mLruProcesses.get(i);
8692                if (!allUsers && app.userId != userId) {
8693                    continue;
8694                }
8695                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8696                    // This one's in trouble, so we'll generate a report for it
8697                    // crashes are higher priority (in case there's a crash *and* an anr)
8698                    ActivityManager.ProcessErrorStateInfo report = null;
8699                    if (app.crashing) {
8700                        report = app.crashingReport;
8701                    } else if (app.notResponding) {
8702                        report = app.notRespondingReport;
8703                    }
8704
8705                    if (report != null) {
8706                        if (errList == null) {
8707                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8708                        }
8709                        errList.add(report);
8710                    } else {
8711                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8712                                " crashing = " + app.crashing +
8713                                " notResponding = " + app.notResponding);
8714                    }
8715                }
8716            }
8717        }
8718
8719        return errList;
8720    }
8721
8722    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8723        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8724            if (currApp != null) {
8725                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8726            }
8727            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8728        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8729            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8730        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8731            if (currApp != null) {
8732                currApp.lru = 0;
8733            }
8734            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8735        } else if (adj >= ProcessList.SERVICE_ADJ) {
8736            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8737        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8738            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8739        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8740            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8741        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8742            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8743        } else {
8744            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8745        }
8746    }
8747
8748    private void fillInProcMemInfo(ProcessRecord app,
8749            ActivityManager.RunningAppProcessInfo outInfo) {
8750        outInfo.pid = app.pid;
8751        outInfo.uid = app.info.uid;
8752        if (mHeavyWeightProcess == app) {
8753            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8754        }
8755        if (app.persistent) {
8756            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8757        }
8758        if (app.hasActivities) {
8759            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8760        }
8761        outInfo.lastTrimLevel = app.trimMemoryLevel;
8762        int adj = app.curAdj;
8763        outInfo.importance = oomAdjToImportance(adj, outInfo);
8764        outInfo.importanceReasonCode = app.adjTypeCode;
8765    }
8766
8767    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8768        enforceNotIsolatedCaller("getRunningAppProcesses");
8769        // Lazy instantiation of list
8770        List<ActivityManager.RunningAppProcessInfo> runList = null;
8771        final boolean allUsers = ActivityManager.checkUidPermission(
8772                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8773                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8774        int userId = UserHandle.getUserId(Binder.getCallingUid());
8775        synchronized (this) {
8776            // Iterate across all processes
8777            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8778                ProcessRecord app = mLruProcesses.get(i);
8779                if (!allUsers && app.userId != userId) {
8780                    continue;
8781                }
8782                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8783                    // Generate process state info for running application
8784                    ActivityManager.RunningAppProcessInfo currApp =
8785                        new ActivityManager.RunningAppProcessInfo(app.processName,
8786                                app.pid, app.getPackageList());
8787                    fillInProcMemInfo(app, currApp);
8788                    if (app.adjSource instanceof ProcessRecord) {
8789                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8790                        currApp.importanceReasonImportance = oomAdjToImportance(
8791                                app.adjSourceOom, null);
8792                    } else if (app.adjSource instanceof ActivityRecord) {
8793                        ActivityRecord r = (ActivityRecord)app.adjSource;
8794                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8795                    }
8796                    if (app.adjTarget instanceof ComponentName) {
8797                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8798                    }
8799                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8800                    //        + " lru=" + currApp.lru);
8801                    if (runList == null) {
8802                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8803                    }
8804                    runList.add(currApp);
8805                }
8806            }
8807        }
8808        return runList;
8809    }
8810
8811    public List<ApplicationInfo> getRunningExternalApplications() {
8812        enforceNotIsolatedCaller("getRunningExternalApplications");
8813        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8814        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8815        if (runningApps != null && runningApps.size() > 0) {
8816            Set<String> extList = new HashSet<String>();
8817            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8818                if (app.pkgList != null) {
8819                    for (String pkg : app.pkgList) {
8820                        extList.add(pkg);
8821                    }
8822                }
8823            }
8824            IPackageManager pm = AppGlobals.getPackageManager();
8825            for (String pkg : extList) {
8826                try {
8827                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8828                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8829                        retList.add(info);
8830                    }
8831                } catch (RemoteException e) {
8832                }
8833            }
8834        }
8835        return retList;
8836    }
8837
8838    @Override
8839    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8840        enforceNotIsolatedCaller("getMyMemoryState");
8841        synchronized (this) {
8842            ProcessRecord proc;
8843            synchronized (mPidsSelfLocked) {
8844                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8845            }
8846            fillInProcMemInfo(proc, outInfo);
8847        }
8848    }
8849
8850    @Override
8851    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8852        if (checkCallingPermission(android.Manifest.permission.DUMP)
8853                != PackageManager.PERMISSION_GRANTED) {
8854            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8855                    + Binder.getCallingPid()
8856                    + ", uid=" + Binder.getCallingUid()
8857                    + " without permission "
8858                    + android.Manifest.permission.DUMP);
8859            return;
8860        }
8861
8862        boolean dumpAll = false;
8863        boolean dumpClient = false;
8864        String dumpPackage = null;
8865
8866        int opti = 0;
8867        while (opti < args.length) {
8868            String opt = args[opti];
8869            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8870                break;
8871            }
8872            opti++;
8873            if ("-a".equals(opt)) {
8874                dumpAll = true;
8875            } else if ("-c".equals(opt)) {
8876                dumpClient = true;
8877            } else if ("-h".equals(opt)) {
8878                pw.println("Activity manager dump options:");
8879                pw.println("  [-a] [-c] [-h] [cmd] ...");
8880                pw.println("  cmd may be one of:");
8881                pw.println("    a[ctivities]: activity stack state");
8882                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8883                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8884                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8885                pw.println("    o[om]: out of memory management");
8886                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8887                pw.println("    provider [COMP_SPEC]: provider client-side state");
8888                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8889                pw.println("    service [COMP_SPEC]: service client-side state");
8890                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8891                pw.println("    all: dump all activities");
8892                pw.println("    top: dump the top activity");
8893                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8894                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8895                pw.println("    a partial substring in a component name, a");
8896                pw.println("    hex object identifier.");
8897                pw.println("  -a: include all available server state.");
8898                pw.println("  -c: include client state.");
8899                return;
8900            } else {
8901                pw.println("Unknown argument: " + opt + "; use -h for help");
8902            }
8903        }
8904
8905        long origId = Binder.clearCallingIdentity();
8906        boolean more = false;
8907        // Is the caller requesting to dump a particular piece of data?
8908        if (opti < args.length) {
8909            String cmd = args[opti];
8910            opti++;
8911            if ("activities".equals(cmd) || "a".equals(cmd)) {
8912                synchronized (this) {
8913                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8914                }
8915            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8916                String[] newArgs;
8917                String name;
8918                if (opti >= args.length) {
8919                    name = null;
8920                    newArgs = EMPTY_STRING_ARRAY;
8921                } else {
8922                    name = args[opti];
8923                    opti++;
8924                    newArgs = new String[args.length - opti];
8925                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8926                            args.length - opti);
8927                }
8928                synchronized (this) {
8929                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8930                }
8931            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8932                String[] newArgs;
8933                String name;
8934                if (opti >= args.length) {
8935                    name = null;
8936                    newArgs = EMPTY_STRING_ARRAY;
8937                } else {
8938                    name = args[opti];
8939                    opti++;
8940                    newArgs = new String[args.length - opti];
8941                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8942                            args.length - opti);
8943                }
8944                synchronized (this) {
8945                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8946                }
8947            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8948                String[] newArgs;
8949                String name;
8950                if (opti >= args.length) {
8951                    name = null;
8952                    newArgs = EMPTY_STRING_ARRAY;
8953                } else {
8954                    name = args[opti];
8955                    opti++;
8956                    newArgs = new String[args.length - opti];
8957                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8958                            args.length - opti);
8959                }
8960                synchronized (this) {
8961                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8962                }
8963            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8964                synchronized (this) {
8965                    dumpOomLocked(fd, pw, args, opti, true);
8966                }
8967            } else if ("provider".equals(cmd)) {
8968                String[] newArgs;
8969                String name;
8970                if (opti >= args.length) {
8971                    name = null;
8972                    newArgs = EMPTY_STRING_ARRAY;
8973                } else {
8974                    name = args[opti];
8975                    opti++;
8976                    newArgs = new String[args.length - opti];
8977                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8978                }
8979                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8980                    pw.println("No providers match: " + name);
8981                    pw.println("Use -h for help.");
8982                }
8983            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8984                synchronized (this) {
8985                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8986                }
8987            } else if ("service".equals(cmd)) {
8988                String[] newArgs;
8989                String name;
8990                if (opti >= args.length) {
8991                    name = null;
8992                    newArgs = EMPTY_STRING_ARRAY;
8993                } else {
8994                    name = args[opti];
8995                    opti++;
8996                    newArgs = new String[args.length - opti];
8997                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8998                            args.length - opti);
8999                }
9000                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
9001                    pw.println("No services match: " + name);
9002                    pw.println("Use -h for help.");
9003                }
9004            } else if ("package".equals(cmd)) {
9005                String[] newArgs;
9006                if (opti >= args.length) {
9007                    pw.println("package: no package name specified");
9008                    pw.println("Use -h for help.");
9009                } else {
9010                    dumpPackage = args[opti];
9011                    opti++;
9012                    newArgs = new String[args.length - opti];
9013                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9014                            args.length - opti);
9015                    args = newArgs;
9016                    opti = 0;
9017                    more = true;
9018                }
9019            } else if ("services".equals(cmd) || "s".equals(cmd)) {
9020                synchronized (this) {
9021                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
9022                }
9023            } else {
9024                // Dumping a single activity?
9025                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
9026                    pw.println("Bad activity command, or no activities match: " + cmd);
9027                    pw.println("Use -h for help.");
9028                }
9029            }
9030            if (!more) {
9031                Binder.restoreCallingIdentity(origId);
9032                return;
9033            }
9034        }
9035
9036        // No piece of data specified, dump everything.
9037        synchronized (this) {
9038            boolean needSep;
9039            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9040            if (needSep) {
9041                pw.println(" ");
9042            }
9043            if (dumpAll) {
9044                pw.println("-------------------------------------------------------------------------------");
9045            }
9046            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9047            if (needSep) {
9048                pw.println(" ");
9049            }
9050            if (dumpAll) {
9051                pw.println("-------------------------------------------------------------------------------");
9052            }
9053            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9054            if (needSep) {
9055                pw.println(" ");
9056            }
9057            if (dumpAll) {
9058                pw.println("-------------------------------------------------------------------------------");
9059            }
9060            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9061            if (needSep) {
9062                pw.println(" ");
9063            }
9064            if (dumpAll) {
9065                pw.println("-------------------------------------------------------------------------------");
9066            }
9067            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9068            if (needSep) {
9069                pw.println(" ");
9070            }
9071            if (dumpAll) {
9072                pw.println("-------------------------------------------------------------------------------");
9073            }
9074            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9075        }
9076        Binder.restoreCallingIdentity(origId);
9077    }
9078
9079    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9080            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
9081        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
9082        pw.println("  Main stack:");
9083        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
9084                dumpPackage);
9085        pw.println(" ");
9086        pw.println("  Running activities (most recent first):");
9087        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
9088                dumpPackage);
9089        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
9090            pw.println(" ");
9091            pw.println("  Activities waiting for another to become visible:");
9092            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
9093                    !dumpAll, false, dumpPackage);
9094        }
9095        if (mMainStack.mStoppingActivities.size() > 0) {
9096            pw.println(" ");
9097            pw.println("  Activities waiting to stop:");
9098            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
9099                    !dumpAll, false, dumpPackage);
9100        }
9101        if (mMainStack.mGoingToSleepActivities.size() > 0) {
9102            pw.println(" ");
9103            pw.println("  Activities waiting to sleep:");
9104            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
9105                    !dumpAll, false, dumpPackage);
9106        }
9107        if (mMainStack.mFinishingActivities.size() > 0) {
9108            pw.println(" ");
9109            pw.println("  Activities waiting to finish:");
9110            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
9111                    !dumpAll, false, dumpPackage);
9112        }
9113
9114        pw.println(" ");
9115        if (mMainStack.mPausingActivity != null) {
9116            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
9117        }
9118        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
9119        pw.println("  mFocusedActivity: " + mFocusedActivity);
9120        if (dumpAll) {
9121            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
9122            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
9123            pw.println("  mDismissKeyguardOnNextActivity: "
9124                    + mMainStack.mDismissKeyguardOnNextActivity);
9125        }
9126
9127        if (mRecentTasks.size() > 0) {
9128            pw.println();
9129            pw.println("  Recent tasks:");
9130
9131            final int N = mRecentTasks.size();
9132            for (int i=0; i<N; i++) {
9133                TaskRecord tr = mRecentTasks.get(i);
9134                if (dumpPackage != null) {
9135                    if (tr.realActivity == null ||
9136                            !dumpPackage.equals(tr.realActivity)) {
9137                        continue;
9138                    }
9139                }
9140                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
9141                        pw.println(tr);
9142                if (dumpAll) {
9143                    mRecentTasks.get(i).dump(pw, "    ");
9144                }
9145            }
9146        }
9147
9148        if (dumpAll) {
9149            pw.println(" ");
9150            pw.println("  mCurTask: " + mCurTask);
9151        }
9152
9153        return true;
9154    }
9155
9156    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9157            int opti, boolean dumpAll, String dumpPackage) {
9158        boolean needSep = false;
9159        int numPers = 0;
9160
9161        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
9162
9163        if (dumpAll) {
9164            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9165                final int NA = procs.size();
9166                for (int ia=0; ia<NA; ia++) {
9167                    ProcessRecord r = procs.valueAt(ia);
9168                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9169                        continue;
9170                    }
9171                    if (!needSep) {
9172                        pw.println("  All known processes:");
9173                        needSep = true;
9174                    }
9175                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
9176                        pw.print(" UID "); pw.print(procs.keyAt(ia));
9177                        pw.print(" "); pw.println(r);
9178                    r.dump(pw, "    ");
9179                    if (r.persistent) {
9180                        numPers++;
9181                    }
9182                }
9183            }
9184        }
9185
9186        if (mIsolatedProcesses.size() > 0) {
9187            if (needSep) pw.println(" ");
9188            needSep = true;
9189            pw.println("  Isolated process list (sorted by uid):");
9190            for (int i=0; i<mIsolatedProcesses.size(); i++) {
9191                ProcessRecord r = mIsolatedProcesses.valueAt(i);
9192                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9193                    continue;
9194                }
9195                pw.println(String.format("%sIsolated #%2d: %s",
9196                        "    ", i, r.toString()));
9197            }
9198        }
9199
9200        if (mLruProcesses.size() > 0) {
9201            if (needSep) pw.println(" ");
9202            needSep = true;
9203            pw.println("  Process LRU list (sorted by oom_adj):");
9204            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9205                    "Proc", "PERS", false, dumpPackage);
9206            needSep = true;
9207        }
9208
9209        if (dumpAll) {
9210            synchronized (mPidsSelfLocked) {
9211                boolean printed = false;
9212                for (int i=0; i<mPidsSelfLocked.size(); i++) {
9213                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
9214                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9215                        continue;
9216                    }
9217                    if (!printed) {
9218                        if (needSep) pw.println(" ");
9219                        needSep = true;
9220                        pw.println("  PID mappings:");
9221                        printed = true;
9222                    }
9223                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9224                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9225                }
9226            }
9227        }
9228
9229        if (mForegroundProcesses.size() > 0) {
9230            synchronized (mPidsSelfLocked) {
9231                boolean printed = false;
9232                for (int i=0; i<mForegroundProcesses.size(); i++) {
9233                    ProcessRecord r = mPidsSelfLocked.get(
9234                            mForegroundProcesses.valueAt(i).pid);
9235                    if (dumpPackage != null && (r == null
9236                            || !dumpPackage.equals(r.info.packageName))) {
9237                        continue;
9238                    }
9239                    if (!printed) {
9240                        if (needSep) pw.println(" ");
9241                        needSep = true;
9242                        pw.println("  Foreground Processes:");
9243                        printed = true;
9244                    }
9245                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9246                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9247                }
9248            }
9249        }
9250
9251        if (mPersistentStartingProcesses.size() > 0) {
9252            if (needSep) pw.println(" ");
9253            needSep = true;
9254            pw.println("  Persisent processes that are starting:");
9255            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
9256                    "Starting Norm", "Restarting PERS", dumpPackage);
9257        }
9258
9259        if (mRemovedProcesses.size() > 0) {
9260            if (needSep) pw.println(" ");
9261            needSep = true;
9262            pw.println("  Processes that are being removed:");
9263            dumpProcessList(pw, this, mRemovedProcesses, "    ",
9264                    "Removed Norm", "Removed PERS", dumpPackage);
9265        }
9266
9267        if (mProcessesOnHold.size() > 0) {
9268            if (needSep) pw.println(" ");
9269            needSep = true;
9270            pw.println("  Processes that are on old until the system is ready:");
9271            dumpProcessList(pw, this, mProcessesOnHold, "    ",
9272                    "OnHold Norm", "OnHold PERS", dumpPackage);
9273        }
9274
9275        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
9276
9277        if (mProcessCrashTimes.getMap().size() > 0) {
9278            boolean printed = false;
9279            long now = SystemClock.uptimeMillis();
9280            for (Map.Entry<String, SparseArray<Long>> procs
9281                    : mProcessCrashTimes.getMap().entrySet()) {
9282                String pname = procs.getKey();
9283                SparseArray<Long> uids = procs.getValue();
9284                final int N = uids.size();
9285                for (int i=0; i<N; i++) {
9286                    int puid = uids.keyAt(i);
9287                    ProcessRecord r = mProcessNames.get(pname, puid);
9288                    if (dumpPackage != null && (r == null
9289                            || !dumpPackage.equals(r.info.packageName))) {
9290                        continue;
9291                    }
9292                    if (!printed) {
9293                        if (needSep) pw.println(" ");
9294                        needSep = true;
9295                        pw.println("  Time since processes crashed:");
9296                        printed = true;
9297                    }
9298                    pw.print("    Process "); pw.print(pname);
9299                            pw.print(" uid "); pw.print(puid);
9300                            pw.print(": last crashed ");
9301                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9302                            pw.println(" ago");
9303                }
9304            }
9305        }
9306
9307        if (mBadProcesses.getMap().size() > 0) {
9308            boolean printed = false;
9309            for (Map.Entry<String, SparseArray<Long>> procs
9310                    : mBadProcesses.getMap().entrySet()) {
9311                String pname = procs.getKey();
9312                SparseArray<Long> uids = procs.getValue();
9313                final int N = uids.size();
9314                for (int i=0; i<N; i++) {
9315                    int puid = uids.keyAt(i);
9316                    ProcessRecord r = mProcessNames.get(pname, puid);
9317                    if (dumpPackage != null && (r == null
9318                            || !dumpPackage.equals(r.info.packageName))) {
9319                        continue;
9320                    }
9321                    if (!printed) {
9322                        if (needSep) pw.println(" ");
9323                        needSep = true;
9324                        pw.println("  Bad processes:");
9325                    }
9326                    pw.print("    Bad process "); pw.print(pname);
9327                            pw.print(" uid "); pw.print(puid);
9328                            pw.print(": crashed at time ");
9329                            pw.println(uids.valueAt(i));
9330                }
9331            }
9332        }
9333
9334        pw.println();
9335        pw.println("  mStartedUsers:");
9336        for (int i=0; i<mStartedUsers.size(); i++) {
9337            UserStartedState uss = mStartedUsers.valueAt(i);
9338            pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
9339                    pw.print(": "); uss.dump("", pw);
9340        }
9341        pw.print("  mUserLru: [");
9342        for (int i=0; i<mUserLru.size(); i++) {
9343            if (i > 0) pw.print(", ");
9344            pw.print(mUserLru.get(i));
9345        }
9346        pw.println("]");
9347        if (dumpAll) {
9348            pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
9349        }
9350        pw.println("  mHomeProcess: " + mHomeProcess);
9351        pw.println("  mPreviousProcess: " + mPreviousProcess);
9352        if (dumpAll) {
9353            StringBuilder sb = new StringBuilder(128);
9354            sb.append("  mPreviousProcessVisibleTime: ");
9355            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9356            pw.println(sb);
9357        }
9358        if (mHeavyWeightProcess != null) {
9359            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9360        }
9361        pw.println("  mConfiguration: " + mConfiguration);
9362        if (dumpAll) {
9363            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9364            if (mCompatModePackages.getPackages().size() > 0) {
9365                boolean printed = false;
9366                for (Map.Entry<String, Integer> entry
9367                        : mCompatModePackages.getPackages().entrySet()) {
9368                    String pkg = entry.getKey();
9369                    int mode = entry.getValue();
9370                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9371                        continue;
9372                    }
9373                    if (!printed) {
9374                        pw.println("  mScreenCompatPackages:");
9375                        printed = true;
9376                    }
9377                    pw.print("    "); pw.print(pkg); pw.print(": ");
9378                            pw.print(mode); pw.println();
9379                }
9380            }
9381        }
9382        if (mSleeping || mWentToSleep || mLockScreenShown) {
9383            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9384                    + " mLockScreenShown " + mLockScreenShown);
9385        }
9386        if (mShuttingDown) {
9387            pw.println("  mShuttingDown=" + mShuttingDown);
9388        }
9389        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9390                || mOrigWaitForDebugger) {
9391            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9392                    + " mDebugTransient=" + mDebugTransient
9393                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9394        }
9395        if (mOpenGlTraceApp != null) {
9396            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9397        }
9398        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9399                || mProfileFd != null) {
9400            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9401            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9402            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9403                    + mAutoStopProfiler);
9404        }
9405        if (mAlwaysFinishActivities || mController != null) {
9406            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9407                    + " mController=" + mController);
9408        }
9409        if (dumpAll) {
9410            pw.println("  Total persistent processes: " + numPers);
9411            pw.println("  mStartRunning=" + mStartRunning
9412                    + " mProcessesReady=" + mProcessesReady
9413                    + " mSystemReady=" + mSystemReady);
9414            pw.println("  mBooting=" + mBooting
9415                    + " mBooted=" + mBooted
9416                    + " mFactoryTest=" + mFactoryTest);
9417            pw.print("  mLastPowerCheckRealtime=");
9418                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9419                    pw.println("");
9420            pw.print("  mLastPowerCheckUptime=");
9421                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9422                    pw.println("");
9423            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9424            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9425            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9426            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9427                    + " mNumHiddenProcs=" + mNumHiddenProcs
9428                    + " mNumServiceProcs=" + mNumServiceProcs
9429                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9430        }
9431
9432        return true;
9433    }
9434
9435    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9436            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9437        if (mProcessesToGc.size() > 0) {
9438            boolean printed = false;
9439            long now = SystemClock.uptimeMillis();
9440            for (int i=0; i<mProcessesToGc.size(); i++) {
9441                ProcessRecord proc = mProcessesToGc.get(i);
9442                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9443                    continue;
9444                }
9445                if (!printed) {
9446                    if (needSep) pw.println(" ");
9447                    needSep = true;
9448                    pw.println("  Processes that are waiting to GC:");
9449                    printed = true;
9450                }
9451                pw.print("    Process "); pw.println(proc);
9452                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9453                        pw.print(", last gced=");
9454                        pw.print(now-proc.lastRequestedGc);
9455                        pw.print(" ms ago, last lowMem=");
9456                        pw.print(now-proc.lastLowMemory);
9457                        pw.println(" ms ago");
9458
9459            }
9460        }
9461        return needSep;
9462    }
9463
9464    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9465            int opti, boolean dumpAll) {
9466        boolean needSep = false;
9467
9468        if (mLruProcesses.size() > 0) {
9469            if (needSep) pw.println(" ");
9470            needSep = true;
9471            pw.println("  OOM levels:");
9472            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9473            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9474            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9475            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9476            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9477            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9478            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9479            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9480            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9481            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9482            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9483            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9484            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9485
9486            if (needSep) pw.println(" ");
9487            needSep = true;
9488            pw.println("  Process OOM control:");
9489            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9490                    "Proc", "PERS", true, null);
9491            needSep = true;
9492        }
9493
9494        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9495
9496        pw.println();
9497        pw.println("  mHomeProcess: " + mHomeProcess);
9498        pw.println("  mPreviousProcess: " + mPreviousProcess);
9499        if (mHeavyWeightProcess != null) {
9500            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9501        }
9502
9503        return true;
9504    }
9505
9506    /**
9507     * There are three ways to call this:
9508     *  - no provider specified: dump all the providers
9509     *  - a flattened component name that matched an existing provider was specified as the
9510     *    first arg: dump that one provider
9511     *  - the first arg isn't the flattened component name of an existing provider:
9512     *    dump all providers whose component contains the first arg as a substring
9513     */
9514    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9515            int opti, boolean dumpAll) {
9516        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9517    }
9518
9519    static class ItemMatcher {
9520        ArrayList<ComponentName> components;
9521        ArrayList<String> strings;
9522        ArrayList<Integer> objects;
9523        boolean all;
9524
9525        ItemMatcher() {
9526            all = true;
9527        }
9528
9529        void build(String name) {
9530            ComponentName componentName = ComponentName.unflattenFromString(name);
9531            if (componentName != null) {
9532                if (components == null) {
9533                    components = new ArrayList<ComponentName>();
9534                }
9535                components.add(componentName);
9536                all = false;
9537            } else {
9538                int objectId = 0;
9539                // Not a '/' separated full component name; maybe an object ID?
9540                try {
9541                    objectId = Integer.parseInt(name, 16);
9542                    if (objects == null) {
9543                        objects = new ArrayList<Integer>();
9544                    }
9545                    objects.add(objectId);
9546                    all = false;
9547                } catch (RuntimeException e) {
9548                    // Not an integer; just do string match.
9549                    if (strings == null) {
9550                        strings = new ArrayList<String>();
9551                    }
9552                    strings.add(name);
9553                    all = false;
9554                }
9555            }
9556        }
9557
9558        int build(String[] args, int opti) {
9559            for (; opti<args.length; opti++) {
9560                String name = args[opti];
9561                if ("--".equals(name)) {
9562                    return opti+1;
9563                }
9564                build(name);
9565            }
9566            return opti;
9567        }
9568
9569        boolean match(Object object, ComponentName comp) {
9570            if (all) {
9571                return true;
9572            }
9573            if (components != null) {
9574                for (int i=0; i<components.size(); i++) {
9575                    if (components.get(i).equals(comp)) {
9576                        return true;
9577                    }
9578                }
9579            }
9580            if (objects != null) {
9581                for (int i=0; i<objects.size(); i++) {
9582                    if (System.identityHashCode(object) == objects.get(i)) {
9583                        return true;
9584                    }
9585                }
9586            }
9587            if (strings != null) {
9588                String flat = comp.flattenToString();
9589                for (int i=0; i<strings.size(); i++) {
9590                    if (flat.contains(strings.get(i))) {
9591                        return true;
9592                    }
9593                }
9594            }
9595            return false;
9596        }
9597    }
9598
9599    /**
9600     * There are three things that cmd can be:
9601     *  - a flattened component name that matches an existing activity
9602     *  - the cmd arg isn't the flattened component name of an existing activity:
9603     *    dump all activity whose component contains the cmd as a substring
9604     *  - A hex number of the ActivityRecord object instance.
9605     */
9606    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9607            int opti, boolean dumpAll) {
9608        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9609
9610        if ("all".equals(name)) {
9611            synchronized (this) {
9612                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9613                    activities.add(r1);
9614                }
9615            }
9616        } else if ("top".equals(name)) {
9617            synchronized (this) {
9618                final int N = mMainStack.mHistory.size();
9619                if (N > 0) {
9620                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9621                }
9622            }
9623        } else {
9624            ItemMatcher matcher = new ItemMatcher();
9625            matcher.build(name);
9626
9627            synchronized (this) {
9628                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9629                    if (matcher.match(r1, r1.intent.getComponent())) {
9630                        activities.add(r1);
9631                    }
9632                }
9633            }
9634        }
9635
9636        if (activities.size() <= 0) {
9637            return false;
9638        }
9639
9640        String[] newArgs = new String[args.length - opti];
9641        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9642
9643        TaskRecord lastTask = null;
9644        boolean needSep = false;
9645        for (int i=activities.size()-1; i>=0; i--) {
9646            ActivityRecord r = (ActivityRecord)activities.get(i);
9647            if (needSep) {
9648                pw.println();
9649            }
9650            needSep = true;
9651            synchronized (this) {
9652                if (lastTask != r.task) {
9653                    lastTask = r.task;
9654                    pw.print("TASK "); pw.print(lastTask.affinity);
9655                            pw.print(" id="); pw.println(lastTask.taskId);
9656                    if (dumpAll) {
9657                        lastTask.dump(pw, "  ");
9658                    }
9659                }
9660            }
9661            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9662        }
9663        return true;
9664    }
9665
9666    /**
9667     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9668     * there is a thread associated with the activity.
9669     */
9670    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9671            final ActivityRecord r, String[] args, boolean dumpAll) {
9672        String innerPrefix = prefix + "  ";
9673        synchronized (this) {
9674            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9675                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9676                    pw.print(" pid=");
9677                    if (r.app != null) pw.println(r.app.pid);
9678                    else pw.println("(not running)");
9679            if (dumpAll) {
9680                r.dump(pw, innerPrefix);
9681            }
9682        }
9683        if (r.app != null && r.app.thread != null) {
9684            // flush anything that is already in the PrintWriter since the thread is going
9685            // to write to the file descriptor directly
9686            pw.flush();
9687            try {
9688                TransferPipe tp = new TransferPipe();
9689                try {
9690                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9691                            r.appToken, innerPrefix, args);
9692                    tp.go(fd);
9693                } finally {
9694                    tp.kill();
9695                }
9696            } catch (IOException e) {
9697                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9698            } catch (RemoteException e) {
9699                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9700            }
9701        }
9702    }
9703
9704    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9705            int opti, boolean dumpAll, String dumpPackage) {
9706        boolean needSep = false;
9707        boolean onlyHistory = false;
9708
9709        if ("history".equals(dumpPackage)) {
9710            onlyHistory = true;
9711            dumpPackage = null;
9712        }
9713
9714        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9715        if (!onlyHistory && dumpAll) {
9716            if (mRegisteredReceivers.size() > 0) {
9717                boolean printed = false;
9718                Iterator it = mRegisteredReceivers.values().iterator();
9719                while (it.hasNext()) {
9720                    ReceiverList r = (ReceiverList)it.next();
9721                    if (dumpPackage != null && (r.app == null ||
9722                            !dumpPackage.equals(r.app.info.packageName))) {
9723                        continue;
9724                    }
9725                    if (!printed) {
9726                        pw.println("  Registered Receivers:");
9727                        needSep = true;
9728                        printed = true;
9729                    }
9730                    pw.print("  * "); pw.println(r);
9731                    r.dump(pw, "    ");
9732                }
9733            }
9734
9735            if (mReceiverResolver.dump(pw, needSep ?
9736                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9737                    "    ", dumpPackage, false)) {
9738                needSep = true;
9739            }
9740        }
9741
9742        for (BroadcastQueue q : mBroadcastQueues) {
9743            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9744        }
9745
9746        needSep = true;
9747
9748        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
9749            for (int user=0; user<mStickyBroadcasts.size(); user++) {
9750                if (needSep) {
9751                    pw.println();
9752                }
9753                needSep = true;
9754                pw.print("  Sticky broadcasts for user ");
9755                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
9756                StringBuilder sb = new StringBuilder(128);
9757                for (Map.Entry<String, ArrayList<Intent>> ent
9758                        : mStickyBroadcasts.valueAt(user).entrySet()) {
9759                    pw.print("  * Sticky action "); pw.print(ent.getKey());
9760                    if (dumpAll) {
9761                        pw.println(":");
9762                        ArrayList<Intent> intents = ent.getValue();
9763                        final int N = intents.size();
9764                        for (int i=0; i<N; i++) {
9765                            sb.setLength(0);
9766                            sb.append("    Intent: ");
9767                            intents.get(i).toShortString(sb, false, true, false, false);
9768                            pw.println(sb.toString());
9769                            Bundle bundle = intents.get(i).getExtras();
9770                            if (bundle != null) {
9771                                pw.print("      ");
9772                                pw.println(bundle.toString());
9773                            }
9774                        }
9775                    } else {
9776                        pw.println("");
9777                    }
9778                }
9779            }
9780        }
9781
9782        if (!onlyHistory && dumpAll) {
9783            pw.println();
9784            for (BroadcastQueue queue : mBroadcastQueues) {
9785                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9786                        + queue.mBroadcastsScheduled);
9787            }
9788            pw.println("  mHandler:");
9789            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9790            needSep = true;
9791        }
9792
9793        return needSep;
9794    }
9795
9796    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9797            int opti, boolean dumpAll, String dumpPackage) {
9798        boolean needSep = true;
9799
9800        ItemMatcher matcher = new ItemMatcher();
9801        matcher.build(args, opti);
9802
9803        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9804
9805        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9806
9807        if (mLaunchingProviders.size() > 0) {
9808            boolean printed = false;
9809            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9810                ContentProviderRecord r = mLaunchingProviders.get(i);
9811                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9812                    continue;
9813                }
9814                if (!printed) {
9815                    if (needSep) pw.println(" ");
9816                    needSep = true;
9817                    pw.println("  Launching content providers:");
9818                    printed = true;
9819                }
9820                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9821                        pw.println(r);
9822            }
9823        }
9824
9825        if (mGrantedUriPermissions.size() > 0) {
9826            if (needSep) pw.println();
9827            needSep = true;
9828            pw.println("Granted Uri Permissions:");
9829            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9830                int uid = mGrantedUriPermissions.keyAt(i);
9831                HashMap<Uri, UriPermission> perms
9832                        = mGrantedUriPermissions.valueAt(i);
9833                pw.print("  * UID "); pw.print(uid);
9834                        pw.println(" holds:");
9835                for (UriPermission perm : perms.values()) {
9836                    pw.print("    "); pw.println(perm);
9837                    if (dumpAll) {
9838                        perm.dump(pw, "      ");
9839                    }
9840                }
9841            }
9842            needSep = true;
9843        }
9844
9845        return needSep;
9846    }
9847
9848    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9849            int opti, boolean dumpAll, String dumpPackage) {
9850        boolean needSep = false;
9851
9852        if (mIntentSenderRecords.size() > 0) {
9853            boolean printed = false;
9854            Iterator<WeakReference<PendingIntentRecord>> it
9855                    = mIntentSenderRecords.values().iterator();
9856            while (it.hasNext()) {
9857                WeakReference<PendingIntentRecord> ref = it.next();
9858                PendingIntentRecord rec = ref != null ? ref.get(): null;
9859                if (dumpPackage != null && (rec == null
9860                        || !dumpPackage.equals(rec.key.packageName))) {
9861                    continue;
9862                }
9863                if (!printed) {
9864                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9865                    printed = true;
9866                }
9867                needSep = true;
9868                if (rec != null) {
9869                    pw.print("  * "); pw.println(rec);
9870                    if (dumpAll) {
9871                        rec.dump(pw, "    ");
9872                    }
9873                } else {
9874                    pw.print("  * "); pw.println(ref);
9875                }
9876            }
9877        }
9878
9879        return needSep;
9880    }
9881
9882    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9883            String prefix, String label, boolean complete, boolean brief, boolean client,
9884            String dumpPackage) {
9885        TaskRecord lastTask = null;
9886        boolean needNL = false;
9887        final String innerPrefix = prefix + "      ";
9888        final String[] args = new String[0];
9889        for (int i=list.size()-1; i>=0; i--) {
9890            final ActivityRecord r = (ActivityRecord)list.get(i);
9891            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9892                continue;
9893            }
9894            final boolean full = !brief && (complete || !r.isInHistory());
9895            if (needNL) {
9896                pw.println(" ");
9897                needNL = false;
9898            }
9899            if (lastTask != r.task) {
9900                lastTask = r.task;
9901                pw.print(prefix);
9902                pw.print(full ? "* " : "  ");
9903                pw.println(lastTask);
9904                if (full) {
9905                    lastTask.dump(pw, prefix + "  ");
9906                } else if (complete) {
9907                    // Complete + brief == give a summary.  Isn't that obvious?!?
9908                    if (lastTask.intent != null) {
9909                        pw.print(prefix); pw.print("  ");
9910                                pw.println(lastTask.intent.toInsecureStringWithClip());
9911                    }
9912                }
9913            }
9914            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9915            pw.print(" #"); pw.print(i); pw.print(": ");
9916            pw.println(r);
9917            if (full) {
9918                r.dump(pw, innerPrefix);
9919            } else if (complete) {
9920                // Complete + brief == give a summary.  Isn't that obvious?!?
9921                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9922                if (r.app != null) {
9923                    pw.print(innerPrefix); pw.println(r.app);
9924                }
9925            }
9926            if (client && r.app != null && r.app.thread != null) {
9927                // flush anything that is already in the PrintWriter since the thread is going
9928                // to write to the file descriptor directly
9929                pw.flush();
9930                try {
9931                    TransferPipe tp = new TransferPipe();
9932                    try {
9933                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9934                                r.appToken, innerPrefix, args);
9935                        // Short timeout, since blocking here can
9936                        // deadlock with the application.
9937                        tp.go(fd, 2000);
9938                    } finally {
9939                        tp.kill();
9940                    }
9941                } catch (IOException e) {
9942                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9943                } catch (RemoteException e) {
9944                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9945                }
9946                needNL = true;
9947            }
9948        }
9949    }
9950
9951    private static String buildOomTag(String prefix, String space, int val, int base) {
9952        if (val == base) {
9953            if (space == null) return prefix;
9954            return prefix + "  ";
9955        }
9956        return prefix + "+" + Integer.toString(val-base);
9957    }
9958
9959    private static final int dumpProcessList(PrintWriter pw,
9960            ActivityManagerService service, List list,
9961            String prefix, String normalLabel, String persistentLabel,
9962            String dumpPackage) {
9963        int numPers = 0;
9964        final int N = list.size()-1;
9965        for (int i=N; i>=0; i--) {
9966            ProcessRecord r = (ProcessRecord)list.get(i);
9967            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9968                continue;
9969            }
9970            pw.println(String.format("%s%s #%2d: %s",
9971                    prefix, (r.persistent ? persistentLabel : normalLabel),
9972                    i, r.toString()));
9973            if (r.persistent) {
9974                numPers++;
9975            }
9976        }
9977        return numPers;
9978    }
9979
9980    private static final boolean dumpProcessOomList(PrintWriter pw,
9981            ActivityManagerService service, List<ProcessRecord> origList,
9982            String prefix, String normalLabel, String persistentLabel,
9983            boolean inclDetails, String dumpPackage) {
9984
9985        ArrayList<Pair<ProcessRecord, Integer>> list
9986                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9987        for (int i=0; i<origList.size(); i++) {
9988            ProcessRecord r = origList.get(i);
9989            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9990                continue;
9991            }
9992            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9993        }
9994
9995        if (list.size() <= 0) {
9996            return false;
9997        }
9998
9999        Comparator<Pair<ProcessRecord, Integer>> comparator
10000                = new Comparator<Pair<ProcessRecord, Integer>>() {
10001            @Override
10002            public int compare(Pair<ProcessRecord, Integer> object1,
10003                    Pair<ProcessRecord, Integer> object2) {
10004                if (object1.first.setAdj != object2.first.setAdj) {
10005                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
10006                }
10007                if (object1.second.intValue() != object2.second.intValue()) {
10008                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
10009                }
10010                return 0;
10011            }
10012        };
10013
10014        Collections.sort(list, comparator);
10015
10016        final long curRealtime = SystemClock.elapsedRealtime();
10017        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
10018        final long curUptime = SystemClock.uptimeMillis();
10019        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
10020
10021        for (int i=list.size()-1; i>=0; i--) {
10022            ProcessRecord r = list.get(i).first;
10023            String oomAdj;
10024            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
10025                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
10026            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
10027                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
10028            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
10029                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
10030            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
10031                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
10032            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
10033                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
10034            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
10035                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
10036            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10037                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
10038            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10039                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
10040            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
10041                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
10042            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
10043                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
10044            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
10045                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
10046            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
10047                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
10048            } else {
10049                oomAdj = Integer.toString(r.setAdj);
10050            }
10051            String schedGroup;
10052            switch (r.setSchedGroup) {
10053                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
10054                    schedGroup = "B";
10055                    break;
10056                case Process.THREAD_GROUP_DEFAULT:
10057                    schedGroup = "F";
10058                    break;
10059                default:
10060                    schedGroup = Integer.toString(r.setSchedGroup);
10061                    break;
10062            }
10063            String foreground;
10064            if (r.foregroundActivities) {
10065                foreground = "A";
10066            } else if (r.foregroundServices) {
10067                foreground = "S";
10068            } else {
10069                foreground = " ";
10070            }
10071            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
10072                    prefix, (r.persistent ? persistentLabel : normalLabel),
10073                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
10074                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
10075            if (r.adjSource != null || r.adjTarget != null) {
10076                pw.print(prefix);
10077                pw.print("    ");
10078                if (r.adjTarget instanceof ComponentName) {
10079                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
10080                } else if (r.adjTarget != null) {
10081                    pw.print(r.adjTarget.toString());
10082                } else {
10083                    pw.print("{null}");
10084                }
10085                pw.print("<=");
10086                if (r.adjSource instanceof ProcessRecord) {
10087                    pw.print("Proc{");
10088                    pw.print(((ProcessRecord)r.adjSource).toShortString());
10089                    pw.println("}");
10090                } else if (r.adjSource != null) {
10091                    pw.println(r.adjSource.toString());
10092                } else {
10093                    pw.println("{null}");
10094                }
10095            }
10096            if (inclDetails) {
10097                pw.print(prefix);
10098                pw.print("    ");
10099                pw.print("oom: max="); pw.print(r.maxAdj);
10100                pw.print(" hidden="); pw.print(r.hiddenAdj);
10101                pw.print(" client="); pw.print(r.clientHiddenAdj);
10102                pw.print(" empty="); pw.print(r.emptyAdj);
10103                pw.print(" curRaw="); pw.print(r.curRawAdj);
10104                pw.print(" setRaw="); pw.print(r.setRawAdj);
10105                pw.print(" cur="); pw.print(r.curAdj);
10106                pw.print(" set="); pw.println(r.setAdj);
10107                pw.print(prefix);
10108                pw.print("    ");
10109                pw.print("keeping="); pw.print(r.keeping);
10110                pw.print(" hidden="); pw.print(r.hidden);
10111                pw.print(" empty="); pw.print(r.empty);
10112                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
10113
10114                if (!r.keeping) {
10115                    if (r.lastWakeTime != 0) {
10116                        long wtime;
10117                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10118                        synchronized (stats) {
10119                            wtime = stats.getProcessWakeTime(r.info.uid,
10120                                    r.pid, curRealtime);
10121                        }
10122                        long timeUsed = wtime - r.lastWakeTime;
10123                        pw.print(prefix);
10124                        pw.print("    ");
10125                        pw.print("keep awake over ");
10126                        TimeUtils.formatDuration(realtimeSince, pw);
10127                        pw.print(" used ");
10128                        TimeUtils.formatDuration(timeUsed, pw);
10129                        pw.print(" (");
10130                        pw.print((timeUsed*100)/realtimeSince);
10131                        pw.println("%)");
10132                    }
10133                    if (r.lastCpuTime != 0) {
10134                        long timeUsed = r.curCpuTime - r.lastCpuTime;
10135                        pw.print(prefix);
10136                        pw.print("    ");
10137                        pw.print("run cpu over ");
10138                        TimeUtils.formatDuration(uptimeSince, pw);
10139                        pw.print(" used ");
10140                        TimeUtils.formatDuration(timeUsed, pw);
10141                        pw.print(" (");
10142                        pw.print((timeUsed*100)/uptimeSince);
10143                        pw.println("%)");
10144                    }
10145                }
10146            }
10147        }
10148        return true;
10149    }
10150
10151    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
10152        ArrayList<ProcessRecord> procs;
10153        synchronized (this) {
10154            if (args != null && args.length > start
10155                    && args[start].charAt(0) != '-') {
10156                procs = new ArrayList<ProcessRecord>();
10157                int pid = -1;
10158                try {
10159                    pid = Integer.parseInt(args[start]);
10160                } catch (NumberFormatException e) {
10161
10162                }
10163                for (int i=mLruProcesses.size()-1; i>=0; i--) {
10164                    ProcessRecord proc = mLruProcesses.get(i);
10165                    if (proc.pid == pid) {
10166                        procs.add(proc);
10167                    } else if (proc.processName.equals(args[start])) {
10168                        procs.add(proc);
10169                    }
10170                }
10171                if (procs.size() <= 0) {
10172                    pw.println("No process found for: " + args[start]);
10173                    return null;
10174                }
10175            } else {
10176                procs = new ArrayList<ProcessRecord>(mLruProcesses);
10177            }
10178        }
10179        return procs;
10180    }
10181
10182    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10183            PrintWriter pw, String[] args) {
10184        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10185        if (procs == null) {
10186            return;
10187        }
10188
10189        long uptime = SystemClock.uptimeMillis();
10190        long realtime = SystemClock.elapsedRealtime();
10191        pw.println("Applications Graphics Acceleration Info:");
10192        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10193
10194        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10195            ProcessRecord r = procs.get(i);
10196            if (r.thread != null) {
10197                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10198                pw.flush();
10199                try {
10200                    TransferPipe tp = new TransferPipe();
10201                    try {
10202                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10203                        tp.go(fd);
10204                    } finally {
10205                        tp.kill();
10206                    }
10207                } catch (IOException e) {
10208                    pw.println("Failure while dumping the app: " + r);
10209                    pw.flush();
10210                } catch (RemoteException e) {
10211                    pw.println("Got a RemoteException while dumping the app " + r);
10212                    pw.flush();
10213                }
10214            }
10215        }
10216    }
10217
10218    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10219        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10220        if (procs == null) {
10221            return;
10222        }
10223
10224        pw.println("Applications Database Info:");
10225
10226        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10227            ProcessRecord r = procs.get(i);
10228            if (r.thread != null) {
10229                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10230                pw.flush();
10231                try {
10232                    TransferPipe tp = new TransferPipe();
10233                    try {
10234                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10235                        tp.go(fd);
10236                    } finally {
10237                        tp.kill();
10238                    }
10239                } catch (IOException e) {
10240                    pw.println("Failure while dumping the app: " + r);
10241                    pw.flush();
10242                } catch (RemoteException e) {
10243                    pw.println("Got a RemoteException while dumping the app " + r);
10244                    pw.flush();
10245                }
10246            }
10247        }
10248    }
10249
10250    final static class MemItem {
10251        final String label;
10252        final String shortLabel;
10253        final long pss;
10254        final int id;
10255        ArrayList<MemItem> subitems;
10256
10257        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10258            label = _label;
10259            shortLabel = _shortLabel;
10260            pss = _pss;
10261            id = _id;
10262        }
10263    }
10264
10265    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10266            boolean sort) {
10267        if (sort) {
10268            Collections.sort(items, new Comparator<MemItem>() {
10269                @Override
10270                public int compare(MemItem lhs, MemItem rhs) {
10271                    if (lhs.pss < rhs.pss) {
10272                        return 1;
10273                    } else if (lhs.pss > rhs.pss) {
10274                        return -1;
10275                    }
10276                    return 0;
10277                }
10278            });
10279        }
10280
10281        for (int i=0; i<items.size(); i++) {
10282            MemItem mi = items.get(i);
10283            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10284            if (mi.subitems != null) {
10285                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10286            }
10287        }
10288    }
10289
10290    // These are in KB.
10291    static final long[] DUMP_MEM_BUCKETS = new long[] {
10292        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10293        120*1024, 160*1024, 200*1024,
10294        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10295        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10296    };
10297
10298    static final void appendMemBucket(StringBuilder out, long memKB, String label,
10299            boolean stackLike) {
10300        int start = label.lastIndexOf('.');
10301        if (start >= 0) start++;
10302        else start = 0;
10303        int end = label.length();
10304        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10305            if (DUMP_MEM_BUCKETS[i] >= memKB) {
10306                long bucket = DUMP_MEM_BUCKETS[i]/1024;
10307                out.append(bucket);
10308                out.append(stackLike ? "MB." : "MB ");
10309                out.append(label, start, end);
10310                return;
10311            }
10312        }
10313        out.append(memKB/1024);
10314        out.append(stackLike ? "MB." : "MB ");
10315        out.append(label, start, end);
10316    }
10317
10318    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10319            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10320            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10321            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10322            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10323    };
10324    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10325            "System", "Persistent", "Foreground",
10326            "Visible", "Perceptible", "Heavy Weight",
10327            "Backup", "A Services", "Home", "Previous",
10328            "B Services", "Background"
10329    };
10330
10331    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10332            PrintWriter pw, String prefix, String[] args, boolean brief,
10333            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10334        boolean dumpAll = false;
10335        boolean oomOnly = false;
10336
10337        int opti = 0;
10338        while (opti < args.length) {
10339            String opt = args[opti];
10340            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10341                break;
10342            }
10343            opti++;
10344            if ("-a".equals(opt)) {
10345                dumpAll = true;
10346            } else if ("--oom".equals(opt)) {
10347                oomOnly = true;
10348            } else if ("-h".equals(opt)) {
10349                pw.println("meminfo dump options: [-a] [--oom] [process]");
10350                pw.println("  -a: include all available information for each process.");
10351                pw.println("  --oom: only show processes organized by oom adj.");
10352                pw.println("If [process] is specified it can be the name or ");
10353                pw.println("pid of a specific process to dump.");
10354                return;
10355            } else {
10356                pw.println("Unknown argument: " + opt + "; use -h for help");
10357            }
10358        }
10359
10360        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10361        if (procs == null) {
10362            return;
10363        }
10364
10365        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10366        long uptime = SystemClock.uptimeMillis();
10367        long realtime = SystemClock.elapsedRealtime();
10368
10369        if (procs.size() == 1 || isCheckinRequest) {
10370            dumpAll = true;
10371        }
10372
10373        if (isCheckinRequest) {
10374            // short checkin version
10375            pw.println(uptime + "," + realtime);
10376            pw.flush();
10377        } else {
10378            pw.println("Applications Memory Usage (kB):");
10379            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10380        }
10381
10382        String[] innerArgs = new String[args.length-opti];
10383        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10384
10385        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10386        long nativePss=0, dalvikPss=0, otherPss=0;
10387        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10388
10389        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10390        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10391                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10392
10393        long totalPss = 0;
10394
10395        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10396            ProcessRecord r = procs.get(i);
10397            if (r.thread != null) {
10398                if (!isCheckinRequest && dumpAll) {
10399                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10400                    pw.flush();
10401                }
10402                Debug.MemoryInfo mi = null;
10403                if (dumpAll) {
10404                    try {
10405                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10406                    } catch (RemoteException e) {
10407                        if (!isCheckinRequest) {
10408                            pw.println("Got RemoteException!");
10409                            pw.flush();
10410                        }
10411                    }
10412                } else {
10413                    mi = new Debug.MemoryInfo();
10414                    Debug.getMemoryInfo(r.pid, mi);
10415                }
10416
10417                if (!isCheckinRequest && mi != null) {
10418                    long myTotalPss = mi.getTotalPss();
10419                    totalPss += myTotalPss;
10420                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10421                            r.processName, myTotalPss, 0);
10422                    procMems.add(pssItem);
10423
10424                    nativePss += mi.nativePss;
10425                    dalvikPss += mi.dalvikPss;
10426                    otherPss += mi.otherPss;
10427                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10428                        long mem = mi.getOtherPss(j);
10429                        miscPss[j] += mem;
10430                        otherPss -= mem;
10431                    }
10432
10433                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10434                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10435                                || oomIndex == (oomPss.length-1)) {
10436                            oomPss[oomIndex] += myTotalPss;
10437                            if (oomProcs[oomIndex] == null) {
10438                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10439                            }
10440                            oomProcs[oomIndex].add(pssItem);
10441                            break;
10442                        }
10443                    }
10444                }
10445            }
10446        }
10447
10448        if (!isCheckinRequest && procs.size() > 1) {
10449            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10450
10451            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10452            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10453            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10454            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10455                String label = Debug.MemoryInfo.getOtherLabel(j);
10456                catMems.add(new MemItem(label, label, miscPss[j], j));
10457            }
10458
10459            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10460            for (int j=0; j<oomPss.length; j++) {
10461                if (oomPss[j] != 0) {
10462                    String label = DUMP_MEM_OOM_LABEL[j];
10463                    MemItem item = new MemItem(label, label, oomPss[j],
10464                            DUMP_MEM_OOM_ADJ[j]);
10465                    item.subitems = oomProcs[j];
10466                    oomMems.add(item);
10467                }
10468            }
10469
10470            if (outTag != null || outStack != null) {
10471                if (outTag != null) {
10472                    appendMemBucket(outTag, totalPss, "total", false);
10473                }
10474                if (outStack != null) {
10475                    appendMemBucket(outStack, totalPss, "total", true);
10476                }
10477                boolean firstLine = true;
10478                for (int i=0; i<oomMems.size(); i++) {
10479                    MemItem miCat = oomMems.get(i);
10480                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10481                        continue;
10482                    }
10483                    if (miCat.id < ProcessList.SERVICE_ADJ
10484                            || miCat.id == ProcessList.HOME_APP_ADJ
10485                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10486                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10487                            outTag.append(" / ");
10488                        }
10489                        if (outStack != null) {
10490                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10491                                if (firstLine) {
10492                                    outStack.append(":");
10493                                    firstLine = false;
10494                                }
10495                                outStack.append("\n\t at ");
10496                            } else {
10497                                outStack.append("$");
10498                            }
10499                        }
10500                        for (int j=0; j<miCat.subitems.size(); j++) {
10501                            MemItem mi = miCat.subitems.get(j);
10502                            if (j > 0) {
10503                                if (outTag != null) {
10504                                    outTag.append(" ");
10505                                }
10506                                if (outStack != null) {
10507                                    outStack.append("$");
10508                                }
10509                            }
10510                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10511                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10512                            }
10513                            if (outStack != null) {
10514                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10515                            }
10516                        }
10517                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10518                            outStack.append("(");
10519                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10520                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10521                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10522                                    outStack.append(":");
10523                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10524                                }
10525                            }
10526                            outStack.append(")");
10527                        }
10528                    }
10529                }
10530            }
10531
10532            if (!brief && !oomOnly) {
10533                pw.println();
10534                pw.println("Total PSS by process:");
10535                dumpMemItems(pw, "  ", procMems, true);
10536                pw.println();
10537            }
10538            pw.println("Total PSS by OOM adjustment:");
10539            dumpMemItems(pw, "  ", oomMems, false);
10540            if (!oomOnly) {
10541                PrintWriter out = categoryPw != null ? categoryPw : pw;
10542                out.println();
10543                out.println("Total PSS by category:");
10544                dumpMemItems(out, "  ", catMems, true);
10545            }
10546            pw.println();
10547            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10548            final int[] SINGLE_LONG_FORMAT = new int[] {
10549                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10550            };
10551            long[] longOut = new long[1];
10552            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10553                    SINGLE_LONG_FORMAT, null, longOut, null);
10554            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10555            longOut[0] = 0;
10556            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10557                    SINGLE_LONG_FORMAT, null, longOut, null);
10558            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10559            longOut[0] = 0;
10560            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10561                    SINGLE_LONG_FORMAT, null, longOut, null);
10562            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10563            longOut[0] = 0;
10564            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10565                    SINGLE_LONG_FORMAT, null, longOut, null);
10566            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10567            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10568                    pw.print(shared); pw.println(" kB");
10569            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10570                    pw.print(voltile); pw.println(" kB volatile");
10571        }
10572    }
10573
10574    /**
10575     * Searches array of arguments for the specified string
10576     * @param args array of argument strings
10577     * @param value value to search for
10578     * @return true if the value is contained in the array
10579     */
10580    private static boolean scanArgs(String[] args, String value) {
10581        if (args != null) {
10582            for (String arg : args) {
10583                if (value.equals(arg)) {
10584                    return true;
10585                }
10586            }
10587        }
10588        return false;
10589    }
10590
10591    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10592            ContentProviderRecord cpr, boolean always) {
10593        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10594
10595        if (!inLaunching || always) {
10596            synchronized (cpr) {
10597                cpr.launchingApp = null;
10598                cpr.notifyAll();
10599            }
10600            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10601            String names[] = cpr.info.authority.split(";");
10602            for (int j = 0; j < names.length; j++) {
10603                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10604            }
10605        }
10606
10607        for (int i=0; i<cpr.connections.size(); i++) {
10608            ContentProviderConnection conn = cpr.connections.get(i);
10609            if (conn.waiting) {
10610                // If this connection is waiting for the provider, then we don't
10611                // need to mess with its process unless we are always removing
10612                // or for some reason the provider is not currently launching.
10613                if (inLaunching && !always) {
10614                    continue;
10615                }
10616            }
10617            ProcessRecord capp = conn.client;
10618            conn.dead = true;
10619            if (conn.stableCount > 0) {
10620                if (!capp.persistent && capp.thread != null
10621                        && capp.pid != 0
10622                        && capp.pid != MY_PID) {
10623                    Slog.i(TAG, "Kill " + capp.processName
10624                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10625                            + " in dying process " + (proc != null ? proc.processName : "??"));
10626                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.userId, capp.pid,
10627                            capp.processName, capp.setAdj, "dying provider "
10628                                    + cpr.name.toShortString());
10629                    Process.killProcessQuiet(capp.pid);
10630                }
10631            } else if (capp.thread != null && conn.provider.provider != null) {
10632                try {
10633                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10634                } catch (RemoteException e) {
10635                }
10636                // In the protocol here, we don't expect the client to correctly
10637                // clean up this connection, we'll just remove it.
10638                cpr.connections.remove(i);
10639                conn.client.conProviders.remove(conn);
10640            }
10641        }
10642
10643        if (inLaunching && always) {
10644            mLaunchingProviders.remove(cpr);
10645        }
10646        return inLaunching;
10647    }
10648
10649    /**
10650     * Main code for cleaning up a process when it has gone away.  This is
10651     * called both as a result of the process dying, or directly when stopping
10652     * a process when running in single process mode.
10653     */
10654    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10655            boolean restarting, boolean allowRestart, int index) {
10656        if (index >= 0) {
10657            mLruProcesses.remove(index);
10658        }
10659
10660        mProcessesToGc.remove(app);
10661
10662        // Dismiss any open dialogs.
10663        if (app.crashDialog != null) {
10664            app.crashDialog.dismiss();
10665            app.crashDialog = null;
10666        }
10667        if (app.anrDialog != null) {
10668            app.anrDialog.dismiss();
10669            app.anrDialog = null;
10670        }
10671        if (app.waitDialog != null) {
10672            app.waitDialog.dismiss();
10673            app.waitDialog = null;
10674        }
10675
10676        app.crashing = false;
10677        app.notResponding = false;
10678
10679        app.resetPackageList();
10680        app.unlinkDeathRecipient();
10681        app.thread = null;
10682        app.forcingToForeground = null;
10683        app.foregroundServices = false;
10684        app.foregroundActivities = false;
10685        app.hasShownUi = false;
10686        app.hasAboveClient = false;
10687
10688        mServices.killServicesLocked(app, allowRestart);
10689
10690        boolean restart = false;
10691
10692        // Remove published content providers.
10693        if (!app.pubProviders.isEmpty()) {
10694            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10695            while (it.hasNext()) {
10696                ContentProviderRecord cpr = it.next();
10697
10698                final boolean always = app.bad || !allowRestart;
10699                if (removeDyingProviderLocked(app, cpr, always) || always) {
10700                    // We left the provider in the launching list, need to
10701                    // restart it.
10702                    restart = true;
10703                }
10704
10705                cpr.provider = null;
10706                cpr.proc = null;
10707            }
10708            app.pubProviders.clear();
10709        }
10710
10711        // Take care of any launching providers waiting for this process.
10712        if (checkAppInLaunchingProvidersLocked(app, false)) {
10713            restart = true;
10714        }
10715
10716        // Unregister from connected content providers.
10717        if (!app.conProviders.isEmpty()) {
10718            for (int i=0; i<app.conProviders.size(); i++) {
10719                ContentProviderConnection conn = app.conProviders.get(i);
10720                conn.provider.connections.remove(conn);
10721            }
10722            app.conProviders.clear();
10723        }
10724
10725        // At this point there may be remaining entries in mLaunchingProviders
10726        // where we were the only one waiting, so they are no longer of use.
10727        // Look for these and clean up if found.
10728        // XXX Commented out for now.  Trying to figure out a way to reproduce
10729        // the actual situation to identify what is actually going on.
10730        if (false) {
10731            for (int i=0; i<mLaunchingProviders.size(); i++) {
10732                ContentProviderRecord cpr = (ContentProviderRecord)
10733                        mLaunchingProviders.get(i);
10734                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10735                    synchronized (cpr) {
10736                        cpr.launchingApp = null;
10737                        cpr.notifyAll();
10738                    }
10739                }
10740            }
10741        }
10742
10743        skipCurrentReceiverLocked(app);
10744
10745        // Unregister any receivers.
10746        if (app.receivers.size() > 0) {
10747            Iterator<ReceiverList> it = app.receivers.iterator();
10748            while (it.hasNext()) {
10749                removeReceiverLocked(it.next());
10750            }
10751            app.receivers.clear();
10752        }
10753
10754        // If the app is undergoing backup, tell the backup manager about it
10755        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10756            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
10757                    + mBackupTarget.appInfo + " died during backup");
10758            try {
10759                IBackupManager bm = IBackupManager.Stub.asInterface(
10760                        ServiceManager.getService(Context.BACKUP_SERVICE));
10761                bm.agentDisconnected(app.info.packageName);
10762            } catch (RemoteException e) {
10763                // can't happen; backup manager is local
10764            }
10765        }
10766
10767        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10768            ProcessChangeItem item = mPendingProcessChanges.get(i);
10769            if (item.pid == app.pid) {
10770                mPendingProcessChanges.remove(i);
10771                mAvailProcessChanges.add(item);
10772            }
10773        }
10774        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10775
10776        // If the caller is restarting this app, then leave it in its
10777        // current lists and let the caller take care of it.
10778        if (restarting) {
10779            return;
10780        }
10781
10782        if (!app.persistent || app.isolated) {
10783            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
10784                    "Removing non-persistent process during cleanup: " + app);
10785            mProcessNames.remove(app.processName, app.uid);
10786            mIsolatedProcesses.remove(app.uid);
10787            if (mHeavyWeightProcess == app) {
10788                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
10789                        mHeavyWeightProcess.userId, 0));
10790                mHeavyWeightProcess = null;
10791            }
10792        } else if (!app.removed) {
10793            // This app is persistent, so we need to keep its record around.
10794            // If it is not already on the pending app list, add it there
10795            // and start a new process for it.
10796            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10797                mPersistentStartingProcesses.add(app);
10798                restart = true;
10799            }
10800        }
10801        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
10802                "Clean-up removing on hold: " + app);
10803        mProcessesOnHold.remove(app);
10804
10805        if (app == mHomeProcess) {
10806            mHomeProcess = null;
10807        }
10808        if (app == mPreviousProcess) {
10809            mPreviousProcess = null;
10810        }
10811
10812        if (restart && !app.isolated) {
10813            // We have components that still need to be running in the
10814            // process, so re-launch it.
10815            mProcessNames.put(app.processName, app.uid, app);
10816            startProcessLocked(app, "restart", app.processName);
10817        } else if (app.pid > 0 && app.pid != MY_PID) {
10818            // Goodbye!
10819            synchronized (mPidsSelfLocked) {
10820                mPidsSelfLocked.remove(app.pid);
10821                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10822            }
10823            app.setPid(0);
10824        }
10825    }
10826
10827    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10828        // Look through the content providers we are waiting to have launched,
10829        // and if any run in this process then either schedule a restart of
10830        // the process or kill the client waiting for it if this process has
10831        // gone bad.
10832        int NL = mLaunchingProviders.size();
10833        boolean restart = false;
10834        for (int i=0; i<NL; i++) {
10835            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10836            if (cpr.launchingApp == app) {
10837                if (!alwaysBad && !app.bad) {
10838                    restart = true;
10839                } else {
10840                    removeDyingProviderLocked(app, cpr, true);
10841                    // cpr should have been removed from mLaunchingProviders
10842                    NL = mLaunchingProviders.size();
10843                    i--;
10844                }
10845            }
10846        }
10847        return restart;
10848    }
10849
10850    // =========================================================
10851    // SERVICES
10852    // =========================================================
10853
10854    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10855            int flags) {
10856        enforceNotIsolatedCaller("getServices");
10857        synchronized (this) {
10858            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10859        }
10860    }
10861
10862    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10863        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10864        synchronized (this) {
10865            return mServices.getRunningServiceControlPanelLocked(name);
10866        }
10867    }
10868
10869    public ComponentName startService(IApplicationThread caller, Intent service,
10870            String resolvedType, int userId) {
10871        enforceNotIsolatedCaller("startService");
10872        // Refuse possible leaked file descriptors
10873        if (service != null && service.hasFileDescriptors() == true) {
10874            throw new IllegalArgumentException("File descriptors passed in Intent");
10875        }
10876
10877        if (DEBUG_SERVICE)
10878            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10879        synchronized(this) {
10880            final int callingPid = Binder.getCallingPid();
10881            final int callingUid = Binder.getCallingUid();
10882            checkValidCaller(callingUid, userId);
10883            final long origId = Binder.clearCallingIdentity();
10884            ComponentName res = mServices.startServiceLocked(caller, service,
10885                    resolvedType, callingPid, callingUid, userId);
10886            Binder.restoreCallingIdentity(origId);
10887            return res;
10888        }
10889    }
10890
10891    ComponentName startServiceInPackage(int uid,
10892            Intent service, String resolvedType, int userId) {
10893        synchronized(this) {
10894            if (DEBUG_SERVICE)
10895                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10896            final long origId = Binder.clearCallingIdentity();
10897            ComponentName res = mServices.startServiceLocked(null, service,
10898                    resolvedType, -1, uid, userId);
10899            Binder.restoreCallingIdentity(origId);
10900            return res;
10901        }
10902    }
10903
10904    public int stopService(IApplicationThread caller, Intent service,
10905            String resolvedType, int userId) {
10906        enforceNotIsolatedCaller("stopService");
10907        // Refuse possible leaked file descriptors
10908        if (service != null && service.hasFileDescriptors() == true) {
10909            throw new IllegalArgumentException("File descriptors passed in Intent");
10910        }
10911
10912        checkValidCaller(Binder.getCallingUid(), userId);
10913
10914        synchronized(this) {
10915            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
10916        }
10917    }
10918
10919    public IBinder peekService(Intent service, String resolvedType) {
10920        enforceNotIsolatedCaller("peekService");
10921        // Refuse possible leaked file descriptors
10922        if (service != null && service.hasFileDescriptors() == true) {
10923            throw new IllegalArgumentException("File descriptors passed in Intent");
10924        }
10925        synchronized(this) {
10926            return mServices.peekServiceLocked(service, resolvedType);
10927        }
10928    }
10929
10930    public boolean stopServiceToken(ComponentName className, IBinder token,
10931            int startId) {
10932        synchronized(this) {
10933            return mServices.stopServiceTokenLocked(className, token, startId);
10934        }
10935    }
10936
10937    public void setServiceForeground(ComponentName className, IBinder token,
10938            int id, Notification notification, boolean removeNotification) {
10939        synchronized(this) {
10940            mServices.setServiceForegroundLocked(className, token, id, notification,
10941                    removeNotification);
10942        }
10943    }
10944
10945    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
10946            boolean requireFull, String name, String callerPackage) {
10947        final int callingUserId = UserHandle.getUserId(callingUid);
10948        if (callingUserId != userId) {
10949            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10950                if ((requireFull || checkComponentPermission(
10951                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10952                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
10953                        && checkComponentPermission(
10954                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10955                                callingPid, callingUid, -1, true)
10956                                != PackageManager.PERMISSION_GRANTED) {
10957                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
10958                        // In this case, they would like to just execute as their
10959                        // owner user instead of failing.
10960                        userId = callingUserId;
10961                    } else {
10962                        StringBuilder builder = new StringBuilder(128);
10963                        builder.append("Permission Denial: ");
10964                        builder.append(name);
10965                        if (callerPackage != null) {
10966                            builder.append(" from ");
10967                            builder.append(callerPackage);
10968                        }
10969                        builder.append(" asks to run as user ");
10970                        builder.append(userId);
10971                        builder.append(" but is calling from user ");
10972                        builder.append(UserHandle.getUserId(callingUid));
10973                        builder.append("; this requires ");
10974                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
10975                        if (!requireFull) {
10976                            builder.append(" or ");
10977                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
10978                        }
10979                        String msg = builder.toString();
10980                        Slog.w(TAG, msg);
10981                        throw new SecurityException(msg);
10982                    }
10983                }
10984            }
10985            if (userId == UserHandle.USER_CURRENT
10986                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
10987                // Note that we may be accessing this outside of a lock...
10988                // shouldn't be a big deal, if this is being called outside
10989                // of a locked context there is intrinsically a race with
10990                // the value the caller will receive and someone else changing it.
10991                userId = mCurrentUserId;
10992            }
10993            if (!allowAll && userId < 0) {
10994                throw new IllegalArgumentException(
10995                        "Call does not support special user #" + userId);
10996            }
10997        }
10998        return userId;
10999    }
11000
11001    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
11002            String className, int flags) {
11003        boolean result = false;
11004        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
11005            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
11006                if (ActivityManager.checkUidPermission(
11007                        android.Manifest.permission.INTERACT_ACROSS_USERS,
11008                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
11009                    ComponentName comp = new ComponentName(aInfo.packageName, className);
11010                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
11011                            + " requests FLAG_SINGLE_USER, but app does not hold "
11012                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
11013                    Slog.w(TAG, msg);
11014                    throw new SecurityException(msg);
11015                }
11016                result = true;
11017            }
11018        } else if (componentProcessName == aInfo.packageName) {
11019            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
11020        } else if ("system".equals(componentProcessName)) {
11021            result = true;
11022        }
11023        if (DEBUG_MU) {
11024            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
11025                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
11026        }
11027        return result;
11028    }
11029
11030    public int bindService(IApplicationThread caller, IBinder token,
11031            Intent service, String resolvedType,
11032            IServiceConnection connection, int flags, int userId) {
11033        enforceNotIsolatedCaller("bindService");
11034        // Refuse possible leaked file descriptors
11035        if (service != null && service.hasFileDescriptors() == true) {
11036            throw new IllegalArgumentException("File descriptors passed in Intent");
11037        }
11038
11039        synchronized(this) {
11040            return mServices.bindServiceLocked(caller, token, service, resolvedType,
11041                    connection, flags, userId);
11042        }
11043    }
11044
11045    public boolean unbindService(IServiceConnection connection) {
11046        synchronized (this) {
11047            return mServices.unbindServiceLocked(connection);
11048        }
11049    }
11050
11051    public void publishService(IBinder token, Intent intent, IBinder service) {
11052        // Refuse possible leaked file descriptors
11053        if (intent != null && intent.hasFileDescriptors() == true) {
11054            throw new IllegalArgumentException("File descriptors passed in Intent");
11055        }
11056
11057        synchronized(this) {
11058            if (!(token instanceof ServiceRecord)) {
11059                throw new IllegalArgumentException("Invalid service token");
11060            }
11061            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
11062        }
11063    }
11064
11065    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11066        // Refuse possible leaked file descriptors
11067        if (intent != null && intent.hasFileDescriptors() == true) {
11068            throw new IllegalArgumentException("File descriptors passed in Intent");
11069        }
11070
11071        synchronized(this) {
11072            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
11073        }
11074    }
11075
11076    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
11077        synchronized(this) {
11078            if (!(token instanceof ServiceRecord)) {
11079                throw new IllegalArgumentException("Invalid service token");
11080            }
11081            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
11082        }
11083    }
11084
11085    // =========================================================
11086    // BACKUP AND RESTORE
11087    // =========================================================
11088
11089    // Cause the target app to be launched if necessary and its backup agent
11090    // instantiated.  The backup agent will invoke backupAgentCreated() on the
11091    // activity manager to announce its creation.
11092    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
11093        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
11094        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11095
11096        synchronized(this) {
11097            // !!! TODO: currently no check here that we're already bound
11098            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11099            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11100            synchronized (stats) {
11101                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11102            }
11103
11104            // Backup agent is now in use, its package can't be stopped.
11105            try {
11106                AppGlobals.getPackageManager().setPackageStoppedState(
11107                        app.packageName, false, UserHandle.getUserId(app.uid));
11108            } catch (RemoteException e) {
11109            } catch (IllegalArgumentException e) {
11110                Slog.w(TAG, "Failed trying to unstop package "
11111                        + app.packageName + ": " + e);
11112            }
11113
11114            BackupRecord r = new BackupRecord(ss, app, backupMode);
11115            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11116                    ? new ComponentName(app.packageName, app.backupAgentName)
11117                    : new ComponentName("android", "FullBackupAgent");
11118            // startProcessLocked() returns existing proc's record if it's already running
11119            ProcessRecord proc = startProcessLocked(app.processName, app,
11120                    false, 0, "backup", hostingName, false, false);
11121            if (proc == null) {
11122                Slog.e(TAG, "Unable to start backup agent process " + r);
11123                return false;
11124            }
11125
11126            r.app = proc;
11127            mBackupTarget = r;
11128            mBackupAppName = app.packageName;
11129
11130            // Try not to kill the process during backup
11131            updateOomAdjLocked(proc);
11132
11133            // If the process is already attached, schedule the creation of the backup agent now.
11134            // If it is not yet live, this will be done when it attaches to the framework.
11135            if (proc.thread != null) {
11136                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
11137                try {
11138                    proc.thread.scheduleCreateBackupAgent(app,
11139                            compatibilityInfoForPackageLocked(app), backupMode);
11140                } catch (RemoteException e) {
11141                    // Will time out on the backup manager side
11142                }
11143            } else {
11144                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
11145            }
11146            // Invariants: at this point, the target app process exists and the application
11147            // is either already running or in the process of coming up.  mBackupTarget and
11148            // mBackupAppName describe the app, so that when it binds back to the AM we
11149            // know that it's scheduled for a backup-agent operation.
11150        }
11151
11152        return true;
11153    }
11154
11155    // A backup agent has just come up
11156    public void backupAgentCreated(String agentPackageName, IBinder agent) {
11157        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
11158                + " = " + agent);
11159
11160        synchronized(this) {
11161            if (!agentPackageName.equals(mBackupAppName)) {
11162                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
11163                return;
11164            }
11165        }
11166
11167        long oldIdent = Binder.clearCallingIdentity();
11168        try {
11169            IBackupManager bm = IBackupManager.Stub.asInterface(
11170                    ServiceManager.getService(Context.BACKUP_SERVICE));
11171            bm.agentConnected(agentPackageName, agent);
11172        } catch (RemoteException e) {
11173            // can't happen; the backup manager service is local
11174        } catch (Exception e) {
11175            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11176            e.printStackTrace();
11177        } finally {
11178            Binder.restoreCallingIdentity(oldIdent);
11179        }
11180    }
11181
11182    // done with this agent
11183    public void unbindBackupAgent(ApplicationInfo appInfo) {
11184        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
11185        if (appInfo == null) {
11186            Slog.w(TAG, "unbind backup agent for null app");
11187            return;
11188        }
11189
11190        synchronized(this) {
11191            if (mBackupAppName == null) {
11192                Slog.w(TAG, "Unbinding backup agent with no active backup");
11193                return;
11194            }
11195
11196            if (!mBackupAppName.equals(appInfo.packageName)) {
11197                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11198                return;
11199            }
11200
11201            ProcessRecord proc = mBackupTarget.app;
11202            mBackupTarget = null;
11203            mBackupAppName = null;
11204
11205            // Not backing this app up any more; reset its OOM adjustment
11206            updateOomAdjLocked(proc);
11207
11208            // If the app crashed during backup, 'thread' will be null here
11209            if (proc.thread != null) {
11210                try {
11211                    proc.thread.scheduleDestroyBackupAgent(appInfo,
11212                            compatibilityInfoForPackageLocked(appInfo));
11213                } catch (Exception e) {
11214                    Slog.e(TAG, "Exception when unbinding backup agent:");
11215                    e.printStackTrace();
11216                }
11217            }
11218        }
11219    }
11220    // =========================================================
11221    // BROADCASTS
11222    // =========================================================
11223
11224    private final List getStickiesLocked(String action, IntentFilter filter,
11225            List cur, int userId) {
11226        final ContentResolver resolver = mContext.getContentResolver();
11227        HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11228        if (stickies == null) {
11229            return cur;
11230        }
11231        final ArrayList<Intent> list = stickies.get(action);
11232        if (list == null) {
11233            return cur;
11234        }
11235        int N = list.size();
11236        for (int i=0; i<N; i++) {
11237            Intent intent = list.get(i);
11238            if (filter.match(resolver, intent, true, TAG) >= 0) {
11239                if (cur == null) {
11240                    cur = new ArrayList<Intent>();
11241                }
11242                cur.add(intent);
11243            }
11244        }
11245        return cur;
11246    }
11247
11248    boolean isPendingBroadcastProcessLocked(int pid) {
11249        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
11250                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
11251    }
11252
11253    void skipPendingBroadcastLocked(int pid) {
11254            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
11255            for (BroadcastQueue queue : mBroadcastQueues) {
11256                queue.skipPendingBroadcastLocked(pid);
11257            }
11258    }
11259
11260    // The app just attached; send any pending broadcasts that it should receive
11261    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
11262        boolean didSomething = false;
11263        for (BroadcastQueue queue : mBroadcastQueues) {
11264            didSomething |= queue.sendPendingBroadcastsLocked(app);
11265        }
11266        return didSomething;
11267    }
11268
11269    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
11270            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
11271        enforceNotIsolatedCaller("registerReceiver");
11272        int callingUid;
11273        int callingPid;
11274        synchronized(this) {
11275            ProcessRecord callerApp = null;
11276            if (caller != null) {
11277                callerApp = getRecordForAppLocked(caller);
11278                if (callerApp == null) {
11279                    throw new SecurityException(
11280                            "Unable to find app for caller " + caller
11281                            + " (pid=" + Binder.getCallingPid()
11282                            + ") when registering receiver " + receiver);
11283                }
11284                if (callerApp.info.uid != Process.SYSTEM_UID &&
11285                        !callerApp.pkgList.contains(callerPackage)) {
11286                    throw new SecurityException("Given caller package " + callerPackage
11287                            + " is not running in process " + callerApp);
11288                }
11289                callingUid = callerApp.info.uid;
11290                callingPid = callerApp.pid;
11291            } else {
11292                callerPackage = null;
11293                callingUid = Binder.getCallingUid();
11294                callingPid = Binder.getCallingPid();
11295            }
11296
11297            userId = this.handleIncomingUser(callingPid, callingUid, userId,
11298                    true, true, "registerReceiver", callerPackage);
11299
11300            List allSticky = null;
11301
11302            // Look for any matching sticky broadcasts...
11303            Iterator actions = filter.actionsIterator();
11304            if (actions != null) {
11305                while (actions.hasNext()) {
11306                    String action = (String)actions.next();
11307                    allSticky = getStickiesLocked(action, filter, allSticky,
11308                            UserHandle.USER_ALL);
11309                    allSticky = getStickiesLocked(action, filter, allSticky,
11310                            UserHandle.getUserId(callingUid));
11311                }
11312            } else {
11313                allSticky = getStickiesLocked(null, filter, allSticky,
11314                        UserHandle.USER_ALL);
11315                allSticky = getStickiesLocked(null, filter, allSticky,
11316                        UserHandle.getUserId(callingUid));
11317            }
11318
11319            // The first sticky in the list is returned directly back to
11320            // the client.
11321            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11322
11323            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
11324                    + ": " + sticky);
11325
11326            if (receiver == null) {
11327                return sticky;
11328            }
11329
11330            ReceiverList rl
11331                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11332            if (rl == null) {
11333                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
11334                        userId, receiver);
11335                if (rl.app != null) {
11336                    rl.app.receivers.add(rl);
11337                } else {
11338                    try {
11339                        receiver.asBinder().linkToDeath(rl, 0);
11340                    } catch (RemoteException e) {
11341                        return sticky;
11342                    }
11343                    rl.linkedToDeath = true;
11344                }
11345                mRegisteredReceivers.put(receiver.asBinder(), rl);
11346            } else if (rl.uid != callingUid) {
11347                throw new IllegalArgumentException(
11348                        "Receiver requested to register for uid " + callingUid
11349                        + " was previously registered for uid " + rl.uid);
11350            } else if (rl.pid != callingPid) {
11351                throw new IllegalArgumentException(
11352                        "Receiver requested to register for pid " + callingPid
11353                        + " was previously registered for pid " + rl.pid);
11354            } else if (rl.userId != userId) {
11355                throw new IllegalArgumentException(
11356                        "Receiver requested to register for user " + userId
11357                        + " was previously registered for user " + rl.userId);
11358            }
11359            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
11360                    permission, callingUid, userId);
11361            rl.add(bf);
11362            if (!bf.debugCheck()) {
11363                Slog.w(TAG, "==> For Dynamic broadast");
11364            }
11365            mReceiverResolver.addFilter(bf);
11366
11367            // Enqueue broadcasts for all existing stickies that match
11368            // this filter.
11369            if (allSticky != null) {
11370                ArrayList receivers = new ArrayList();
11371                receivers.add(bf);
11372
11373                int N = allSticky.size();
11374                for (int i=0; i<N; i++) {
11375                    Intent intent = (Intent)allSticky.get(i);
11376                    BroadcastQueue queue = broadcastQueueForIntent(intent);
11377                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
11378                            null, -1, -1, null, receivers, null, 0, null, null,
11379                            false, true, true, -1);
11380                    queue.enqueueParallelBroadcastLocked(r);
11381                    queue.scheduleBroadcastsLocked();
11382                }
11383            }
11384
11385            return sticky;
11386        }
11387    }
11388
11389    public void unregisterReceiver(IIntentReceiver receiver) {
11390        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11391
11392        final long origId = Binder.clearCallingIdentity();
11393        try {
11394            boolean doTrim = false;
11395
11396            synchronized(this) {
11397                ReceiverList rl
11398                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11399                if (rl != null) {
11400                    if (rl.curBroadcast != null) {
11401                        BroadcastRecord r = rl.curBroadcast;
11402                        final boolean doNext = finishReceiverLocked(
11403                                receiver.asBinder(), r.resultCode, r.resultData,
11404                                r.resultExtras, r.resultAbort, true);
11405                        if (doNext) {
11406                            doTrim = true;
11407                            r.queue.processNextBroadcast(false);
11408                        }
11409                    }
11410
11411                    if (rl.app != null) {
11412                        rl.app.receivers.remove(rl);
11413                    }
11414                    removeReceiverLocked(rl);
11415                    if (rl.linkedToDeath) {
11416                        rl.linkedToDeath = false;
11417                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
11418                    }
11419                }
11420            }
11421
11422            // If we actually concluded any broadcasts, we might now be able
11423            // to trim the recipients' apps from our working set
11424            if (doTrim) {
11425                trimApplications();
11426                return;
11427            }
11428
11429        } finally {
11430            Binder.restoreCallingIdentity(origId);
11431        }
11432    }
11433
11434    void removeReceiverLocked(ReceiverList rl) {
11435        mRegisteredReceivers.remove(rl.receiver.asBinder());
11436        int N = rl.size();
11437        for (int i=0; i<N; i++) {
11438            mReceiverResolver.removeFilter(rl.get(i));
11439        }
11440    }
11441
11442    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
11443        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11444            ProcessRecord r = mLruProcesses.get(i);
11445            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
11446                try {
11447                    r.thread.dispatchPackageBroadcast(cmd, packages);
11448                } catch (RemoteException ex) {
11449                }
11450            }
11451        }
11452    }
11453
11454    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
11455            int[] users) {
11456        List<ResolveInfo> receivers = null;
11457        try {
11458            HashSet<ComponentName> singleUserReceivers = null;
11459            boolean scannedFirstReceivers = false;
11460            for (int user : users) {
11461                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
11462                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
11463                if (user != 0 && newReceivers != null) {
11464                    // If this is not the primary user, we need to check for
11465                    // any receivers that should be filtered out.
11466                    for (int i=0; i<newReceivers.size(); i++) {
11467                        ResolveInfo ri = newReceivers.get(i);
11468                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
11469                            newReceivers.remove(i);
11470                            i--;
11471                        }
11472                    }
11473                }
11474                if (newReceivers != null && newReceivers.size() == 0) {
11475                    newReceivers = null;
11476                }
11477                if (receivers == null) {
11478                    receivers = newReceivers;
11479                } else if (newReceivers != null) {
11480                    // We need to concatenate the additional receivers
11481                    // found with what we have do far.  This would be easy,
11482                    // but we also need to de-dup any receivers that are
11483                    // singleUser.
11484                    if (!scannedFirstReceivers) {
11485                        // Collect any single user receivers we had already retrieved.
11486                        scannedFirstReceivers = true;
11487                        for (int i=0; i<receivers.size(); i++) {
11488                            ResolveInfo ri = receivers.get(i);
11489                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11490                                ComponentName cn = new ComponentName(
11491                                        ri.activityInfo.packageName, ri.activityInfo.name);
11492                                if (singleUserReceivers == null) {
11493                                    singleUserReceivers = new HashSet<ComponentName>();
11494                                }
11495                                singleUserReceivers.add(cn);
11496                            }
11497                        }
11498                    }
11499                    // Add the new results to the existing results, tracking
11500                    // and de-dupping single user receivers.
11501                    for (int i=0; i<newReceivers.size(); i++) {
11502                        ResolveInfo ri = newReceivers.get(i);
11503                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11504                            ComponentName cn = new ComponentName(
11505                                    ri.activityInfo.packageName, ri.activityInfo.name);
11506                            if (singleUserReceivers == null) {
11507                                singleUserReceivers = new HashSet<ComponentName>();
11508                            }
11509                            if (!singleUserReceivers.contains(cn)) {
11510                                singleUserReceivers.add(cn);
11511                                receivers.add(ri);
11512                            }
11513                        } else {
11514                            receivers.add(ri);
11515                        }
11516                    }
11517                }
11518            }
11519        } catch (RemoteException ex) {
11520            // pm is in same process, this will never happen.
11521        }
11522        return receivers;
11523    }
11524
11525    private final int broadcastIntentLocked(ProcessRecord callerApp,
11526            String callerPackage, Intent intent, String resolvedType,
11527            IIntentReceiver resultTo, int resultCode, String resultData,
11528            Bundle map, String requiredPermission,
11529            boolean ordered, boolean sticky, int callingPid, int callingUid,
11530            int userId) {
11531        intent = new Intent(intent);
11532
11533        // By default broadcasts do not go to stopped apps.
11534        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11535
11536        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11537            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11538            + " ordered=" + ordered + " userid=" + userId);
11539        if ((resultTo != null) && !ordered) {
11540            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11541        }
11542
11543        userId = handleIncomingUser(callingPid, callingUid, userId,
11544                true, false, "broadcast", callerPackage);
11545
11546        // Make sure that the user who is receiving this broadcast is started.
11547        // If not, we will just skip it.
11548        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
11549            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
11550                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
11551                Slog.w(TAG, "Skipping broadcast of " + intent
11552                        + ": user " + userId + " is stopped");
11553                return ActivityManager.BROADCAST_SUCCESS;
11554            }
11555        }
11556
11557        /*
11558         * Prevent non-system code (defined here to be non-persistent
11559         * processes) from sending protected broadcasts.
11560         */
11561        int callingAppId = UserHandle.getAppId(callingUid);
11562        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
11563            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
11564            callingUid == 0) {
11565            // Always okay.
11566        } else if (callerApp == null || !callerApp.persistent) {
11567            try {
11568                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11569                        intent.getAction())) {
11570                    String msg = "Permission Denial: not allowed to send broadcast "
11571                            + intent.getAction() + " from pid="
11572                            + callingPid + ", uid=" + callingUid;
11573                    Slog.w(TAG, msg);
11574                    throw new SecurityException(msg);
11575                }
11576            } catch (RemoteException e) {
11577                Slog.w(TAG, "Remote exception", e);
11578                return ActivityManager.BROADCAST_SUCCESS;
11579            }
11580        }
11581
11582        // Handle special intents: if this broadcast is from the package
11583        // manager about a package being removed, we need to remove all of
11584        // its activities from the history stack.
11585        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11586                intent.getAction());
11587        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11588                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11589                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11590                || uidRemoved) {
11591            if (checkComponentPermission(
11592                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11593                    callingPid, callingUid, -1, true)
11594                    == PackageManager.PERMISSION_GRANTED) {
11595                if (uidRemoved) {
11596                    final Bundle intentExtras = intent.getExtras();
11597                    final int uid = intentExtras != null
11598                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11599                    if (uid >= 0) {
11600                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11601                        synchronized (bs) {
11602                            bs.removeUidStatsLocked(uid);
11603                        }
11604                    }
11605                } else {
11606                    // If resources are unavailable just force stop all
11607                    // those packages and flush the attribute cache as well.
11608                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11609                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11610                        if (list != null && (list.length > 0)) {
11611                            for (String pkg : list) {
11612                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11613                            }
11614                            sendPackageBroadcastLocked(
11615                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
11616                        }
11617                    } else {
11618                        Uri data = intent.getData();
11619                        String ssp;
11620                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11621                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11622                                forceStopPackageLocked(ssp,
11623                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11624                                        false, userId);
11625                            }
11626                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11627                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11628                                        new String[] {ssp}, userId);
11629                            }
11630                        }
11631                    }
11632                }
11633            } else {
11634                String msg = "Permission Denial: " + intent.getAction()
11635                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11636                        + ", uid=" + callingUid + ")"
11637                        + " requires "
11638                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11639                Slog.w(TAG, msg);
11640                throw new SecurityException(msg);
11641            }
11642
11643        // Special case for adding a package: by default turn on compatibility
11644        // mode.
11645        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11646            Uri data = intent.getData();
11647            String ssp;
11648            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11649                mCompatModePackages.handlePackageAddedLocked(ssp,
11650                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11651            }
11652        }
11653
11654        /*
11655         * If this is the time zone changed action, queue up a message that will reset the timezone
11656         * of all currently running processes. This message will get queued up before the broadcast
11657         * happens.
11658         */
11659        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11660            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11661        }
11662
11663        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11664            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11665        }
11666
11667        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11668            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11669            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11670        }
11671
11672        // Add to the sticky list if requested.
11673        if (sticky) {
11674            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11675                    callingPid, callingUid)
11676                    != PackageManager.PERMISSION_GRANTED) {
11677                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11678                        + callingPid + ", uid=" + callingUid
11679                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11680                Slog.w(TAG, msg);
11681                throw new SecurityException(msg);
11682            }
11683            if (requiredPermission != null) {
11684                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11685                        + " and enforce permission " + requiredPermission);
11686                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11687            }
11688            if (intent.getComponent() != null) {
11689                throw new SecurityException(
11690                        "Sticky broadcasts can't target a specific component");
11691            }
11692            // We use userId directly here, since the "all" target is maintained
11693            // as a separate set of sticky broadcasts.
11694            if (userId != UserHandle.USER_ALL) {
11695                // But first, if this is not a broadcast to all users, then
11696                // make sure it doesn't conflict with an existing broadcast to
11697                // all users.
11698                HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
11699                        UserHandle.USER_ALL);
11700                if (stickies != null) {
11701                    ArrayList<Intent> list = stickies.get(intent.getAction());
11702                    if (list != null) {
11703                        int N = list.size();
11704                        int i;
11705                        for (i=0; i<N; i++) {
11706                            if (intent.filterEquals(list.get(i))) {
11707                                throw new IllegalArgumentException(
11708                                        "Sticky broadcast " + intent + " for user "
11709                                        + userId + " conflicts with existing global broadcast");
11710                            }
11711                        }
11712                    }
11713                }
11714            }
11715            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11716            if (stickies == null) {
11717                stickies = new HashMap<String, ArrayList<Intent>>();
11718                mStickyBroadcasts.put(userId, stickies);
11719            }
11720            ArrayList<Intent> list = stickies.get(intent.getAction());
11721            if (list == null) {
11722                list = new ArrayList<Intent>();
11723                stickies.put(intent.getAction(), list);
11724            }
11725            int N = list.size();
11726            int i;
11727            for (i=0; i<N; i++) {
11728                if (intent.filterEquals(list.get(i))) {
11729                    // This sticky already exists, replace it.
11730                    list.set(i, new Intent(intent));
11731                    break;
11732                }
11733            }
11734            if (i >= N) {
11735                list.add(new Intent(intent));
11736            }
11737        }
11738
11739        int[] users;
11740        if (userId == UserHandle.USER_ALL) {
11741            // Caller wants broadcast to go to all started users.
11742            users = mStartedUserArray;
11743        } else {
11744            // Caller wants broadcast to go to one specific user.
11745            users = new int[] {userId};
11746        }
11747
11748        // Figure out who all will receive this broadcast.
11749        List receivers = null;
11750        List<BroadcastFilter> registeredReceivers = null;
11751        // Need to resolve the intent to interested receivers...
11752        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11753                 == 0) {
11754            receivers = collectReceiverComponents(intent, resolvedType, users);
11755        }
11756        if (intent.getComponent() == null) {
11757            registeredReceivers = mReceiverResolver.queryIntent(intent,
11758                    resolvedType, false, userId);
11759        }
11760
11761        final boolean replacePending =
11762                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11763
11764        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11765                + " replacePending=" + replacePending);
11766
11767        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11768        if (!ordered && NR > 0) {
11769            // If we are not serializing this broadcast, then send the
11770            // registered receivers separately so they don't wait for the
11771            // components to be launched.
11772            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11773            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11774                    callerPackage, callingPid, callingUid, requiredPermission,
11775                    registeredReceivers, resultTo, resultCode, resultData, map,
11776                    ordered, sticky, false, userId);
11777            if (DEBUG_BROADCAST) Slog.v(
11778                    TAG, "Enqueueing parallel broadcast " + r);
11779            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11780            if (!replaced) {
11781                queue.enqueueParallelBroadcastLocked(r);
11782                queue.scheduleBroadcastsLocked();
11783            }
11784            registeredReceivers = null;
11785            NR = 0;
11786        }
11787
11788        // Merge into one list.
11789        int ir = 0;
11790        if (receivers != null) {
11791            // A special case for PACKAGE_ADDED: do not allow the package
11792            // being added to see this broadcast.  This prevents them from
11793            // using this as a back door to get run as soon as they are
11794            // installed.  Maybe in the future we want to have a special install
11795            // broadcast or such for apps, but we'd like to deliberately make
11796            // this decision.
11797            String skipPackages[] = null;
11798            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11799                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11800                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11801                Uri data = intent.getData();
11802                if (data != null) {
11803                    String pkgName = data.getSchemeSpecificPart();
11804                    if (pkgName != null) {
11805                        skipPackages = new String[] { pkgName };
11806                    }
11807                }
11808            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11809                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11810            }
11811            if (skipPackages != null && (skipPackages.length > 0)) {
11812                for (String skipPackage : skipPackages) {
11813                    if (skipPackage != null) {
11814                        int NT = receivers.size();
11815                        for (int it=0; it<NT; it++) {
11816                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11817                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11818                                receivers.remove(it);
11819                                it--;
11820                                NT--;
11821                            }
11822                        }
11823                    }
11824                }
11825            }
11826
11827            int NT = receivers != null ? receivers.size() : 0;
11828            int it = 0;
11829            ResolveInfo curt = null;
11830            BroadcastFilter curr = null;
11831            while (it < NT && ir < NR) {
11832                if (curt == null) {
11833                    curt = (ResolveInfo)receivers.get(it);
11834                }
11835                if (curr == null) {
11836                    curr = registeredReceivers.get(ir);
11837                }
11838                if (curr.getPriority() >= curt.priority) {
11839                    // Insert this broadcast record into the final list.
11840                    receivers.add(it, curr);
11841                    ir++;
11842                    curr = null;
11843                    it++;
11844                    NT++;
11845                } else {
11846                    // Skip to the next ResolveInfo in the final list.
11847                    it++;
11848                    curt = null;
11849                }
11850            }
11851        }
11852        while (ir < NR) {
11853            if (receivers == null) {
11854                receivers = new ArrayList();
11855            }
11856            receivers.add(registeredReceivers.get(ir));
11857            ir++;
11858        }
11859
11860        if ((receivers != null && receivers.size() > 0)
11861                || resultTo != null) {
11862            BroadcastQueue queue = broadcastQueueForIntent(intent);
11863            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11864                    callerPackage, callingPid, callingUid, requiredPermission,
11865                    receivers, resultTo, resultCode, resultData, map, ordered,
11866                    sticky, false, userId);
11867            if (DEBUG_BROADCAST) Slog.v(
11868                    TAG, "Enqueueing ordered broadcast " + r
11869                    + ": prev had " + queue.mOrderedBroadcasts.size());
11870            if (DEBUG_BROADCAST) {
11871                int seq = r.intent.getIntExtra("seq", -1);
11872                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11873            }
11874            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11875            if (!replaced) {
11876                queue.enqueueOrderedBroadcastLocked(r);
11877                queue.scheduleBroadcastsLocked();
11878            }
11879        }
11880
11881        return ActivityManager.BROADCAST_SUCCESS;
11882    }
11883
11884    final Intent verifyBroadcastLocked(Intent intent) {
11885        // Refuse possible leaked file descriptors
11886        if (intent != null && intent.hasFileDescriptors() == true) {
11887            throw new IllegalArgumentException("File descriptors passed in Intent");
11888        }
11889
11890        int flags = intent.getFlags();
11891
11892        if (!mProcessesReady) {
11893            // if the caller really truly claims to know what they're doing, go
11894            // ahead and allow the broadcast without launching any receivers
11895            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11896                intent = new Intent(intent);
11897                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11898            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11899                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11900                        + " before boot completion");
11901                throw new IllegalStateException("Cannot broadcast before boot completed");
11902            }
11903        }
11904
11905        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11906            throw new IllegalArgumentException(
11907                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11908        }
11909
11910        return intent;
11911    }
11912
11913    public final int broadcastIntent(IApplicationThread caller,
11914            Intent intent, String resolvedType, IIntentReceiver resultTo,
11915            int resultCode, String resultData, Bundle map,
11916            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11917        enforceNotIsolatedCaller("broadcastIntent");
11918        synchronized(this) {
11919            intent = verifyBroadcastLocked(intent);
11920
11921            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11922            final int callingPid = Binder.getCallingPid();
11923            final int callingUid = Binder.getCallingUid();
11924            final long origId = Binder.clearCallingIdentity();
11925            int res = broadcastIntentLocked(callerApp,
11926                    callerApp != null ? callerApp.info.packageName : null,
11927                    intent, resolvedType, resultTo,
11928                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11929                    callingPid, callingUid, userId);
11930            Binder.restoreCallingIdentity(origId);
11931            return res;
11932        }
11933    }
11934
11935    int broadcastIntentInPackage(String packageName, int uid,
11936            Intent intent, String resolvedType, IIntentReceiver resultTo,
11937            int resultCode, String resultData, Bundle map,
11938            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11939        synchronized(this) {
11940            intent = verifyBroadcastLocked(intent);
11941
11942            final long origId = Binder.clearCallingIdentity();
11943            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11944                    resultTo, resultCode, resultData, map, requiredPermission,
11945                    serialized, sticky, -1, uid, userId);
11946            Binder.restoreCallingIdentity(origId);
11947            return res;
11948        }
11949    }
11950
11951    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11952        // Refuse possible leaked file descriptors
11953        if (intent != null && intent.hasFileDescriptors() == true) {
11954            throw new IllegalArgumentException("File descriptors passed in Intent");
11955        }
11956
11957        userId = handleIncomingUser(Binder.getCallingPid(),
11958                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
11959
11960        synchronized(this) {
11961            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11962                    != PackageManager.PERMISSION_GRANTED) {
11963                String msg = "Permission Denial: unbroadcastIntent() from pid="
11964                        + Binder.getCallingPid()
11965                        + ", uid=" + Binder.getCallingUid()
11966                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11967                Slog.w(TAG, msg);
11968                throw new SecurityException(msg);
11969            }
11970            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11971            if (stickies != null) {
11972                ArrayList<Intent> list = stickies.get(intent.getAction());
11973                if (list != null) {
11974                    int N = list.size();
11975                    int i;
11976                    for (i=0; i<N; i++) {
11977                        if (intent.filterEquals(list.get(i))) {
11978                            list.remove(i);
11979                            break;
11980                        }
11981                    }
11982                    if (list.size() <= 0) {
11983                        stickies.remove(intent.getAction());
11984                    }
11985                }
11986                if (stickies.size() <= 0) {
11987                    mStickyBroadcasts.remove(userId);
11988                }
11989            }
11990        }
11991    }
11992
11993    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11994            String resultData, Bundle resultExtras, boolean resultAbort,
11995            boolean explicit) {
11996        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11997        if (r == null) {
11998            Slog.w(TAG, "finishReceiver called but not found on queue");
11999            return false;
12000        }
12001
12002        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
12003                explicit);
12004    }
12005
12006    public void finishReceiver(IBinder who, int resultCode, String resultData,
12007            Bundle resultExtras, boolean resultAbort) {
12008        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
12009
12010        // Refuse possible leaked file descriptors
12011        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12012            throw new IllegalArgumentException("File descriptors passed in Bundle");
12013        }
12014
12015        final long origId = Binder.clearCallingIdentity();
12016        try {
12017            boolean doNext = false;
12018            BroadcastRecord r = null;
12019
12020            synchronized(this) {
12021                r = broadcastRecordForReceiverLocked(who);
12022                if (r != null) {
12023                    doNext = r.queue.finishReceiverLocked(r, resultCode,
12024                        resultData, resultExtras, resultAbort, true);
12025                }
12026            }
12027
12028            if (doNext) {
12029                r.queue.processNextBroadcast(false);
12030            }
12031            trimApplications();
12032        } finally {
12033            Binder.restoreCallingIdentity(origId);
12034        }
12035    }
12036
12037    // =========================================================
12038    // INSTRUMENTATION
12039    // =========================================================
12040
12041    public boolean startInstrumentation(ComponentName className,
12042            String profileFile, int flags, Bundle arguments,
12043            IInstrumentationWatcher watcher, int userId) {
12044        enforceNotIsolatedCaller("startInstrumentation");
12045        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
12046                userId, false, true, "startInstrumentation", null);
12047        // Refuse possible leaked file descriptors
12048        if (arguments != null && arguments.hasFileDescriptors()) {
12049            throw new IllegalArgumentException("File descriptors passed in Bundle");
12050        }
12051
12052        synchronized(this) {
12053            InstrumentationInfo ii = null;
12054            ApplicationInfo ai = null;
12055            try {
12056                ii = mContext.getPackageManager().getInstrumentationInfo(
12057                    className, STOCK_PM_FLAGS);
12058                ai = AppGlobals.getPackageManager().getApplicationInfo(
12059                        ii.targetPackage, STOCK_PM_FLAGS, userId);
12060            } catch (PackageManager.NameNotFoundException e) {
12061            } catch (RemoteException e) {
12062            }
12063            if (ii == null) {
12064                reportStartInstrumentationFailure(watcher, className,
12065                        "Unable to find instrumentation info for: " + className);
12066                return false;
12067            }
12068            if (ai == null) {
12069                reportStartInstrumentationFailure(watcher, className,
12070                        "Unable to find instrumentation target package: " + ii.targetPackage);
12071                return false;
12072            }
12073
12074            int match = mContext.getPackageManager().checkSignatures(
12075                    ii.targetPackage, ii.packageName);
12076            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12077                String msg = "Permission Denial: starting instrumentation "
12078                        + className + " from pid="
12079                        + Binder.getCallingPid()
12080                        + ", uid=" + Binder.getCallingPid()
12081                        + " not allowed because package " + ii.packageName
12082                        + " does not have a signature matching the target "
12083                        + ii.targetPackage;
12084                reportStartInstrumentationFailure(watcher, className, msg);
12085                throw new SecurityException(msg);
12086            }
12087
12088            final long origId = Binder.clearCallingIdentity();
12089            // Instrumentation can kill and relaunch even persistent processes
12090            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
12091            ProcessRecord app = addAppLocked(ai, false);
12092            app.instrumentationClass = className;
12093            app.instrumentationInfo = ai;
12094            app.instrumentationProfileFile = profileFile;
12095            app.instrumentationArguments = arguments;
12096            app.instrumentationWatcher = watcher;
12097            app.instrumentationResultClass = className;
12098            Binder.restoreCallingIdentity(origId);
12099        }
12100
12101        return true;
12102    }
12103
12104    /**
12105     * Report errors that occur while attempting to start Instrumentation.  Always writes the
12106     * error to the logs, but if somebody is watching, send the report there too.  This enables
12107     * the "am" command to report errors with more information.
12108     *
12109     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
12110     * @param cn The component name of the instrumentation.
12111     * @param report The error report.
12112     */
12113    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12114            ComponentName cn, String report) {
12115        Slog.w(TAG, report);
12116        try {
12117            if (watcher != null) {
12118                Bundle results = new Bundle();
12119                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12120                results.putString("Error", report);
12121                watcher.instrumentationStatus(cn, -1, results);
12122            }
12123        } catch (RemoteException e) {
12124            Slog.w(TAG, e);
12125        }
12126    }
12127
12128    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12129        if (app.instrumentationWatcher != null) {
12130            try {
12131                // NOTE:  IInstrumentationWatcher *must* be oneway here
12132                app.instrumentationWatcher.instrumentationFinished(
12133                    app.instrumentationClass,
12134                    resultCode,
12135                    results);
12136            } catch (RemoteException e) {
12137            }
12138        }
12139        app.instrumentationWatcher = null;
12140        app.instrumentationClass = null;
12141        app.instrumentationInfo = null;
12142        app.instrumentationProfileFile = null;
12143        app.instrumentationArguments = null;
12144
12145        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
12146    }
12147
12148    public void finishInstrumentation(IApplicationThread target,
12149            int resultCode, Bundle results) {
12150        int userId = UserHandle.getCallingUserId();
12151        // Refuse possible leaked file descriptors
12152        if (results != null && results.hasFileDescriptors()) {
12153            throw new IllegalArgumentException("File descriptors passed in Intent");
12154        }
12155
12156        synchronized(this) {
12157            ProcessRecord app = getRecordForAppLocked(target);
12158            if (app == null) {
12159                Slog.w(TAG, "finishInstrumentation: no app for " + target);
12160                return;
12161            }
12162            final long origId = Binder.clearCallingIdentity();
12163            finishInstrumentationLocked(app, resultCode, results);
12164            Binder.restoreCallingIdentity(origId);
12165        }
12166    }
12167
12168    // =========================================================
12169    // CONFIGURATION
12170    // =========================================================
12171
12172    public ConfigurationInfo getDeviceConfigurationInfo() {
12173        ConfigurationInfo config = new ConfigurationInfo();
12174        synchronized (this) {
12175            config.reqTouchScreen = mConfiguration.touchscreen;
12176            config.reqKeyboardType = mConfiguration.keyboard;
12177            config.reqNavigation = mConfiguration.navigation;
12178            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12179                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
12180                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12181            }
12182            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12183                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
12184                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12185            }
12186            config.reqGlEsVersion = GL_ES_VERSION;
12187        }
12188        return config;
12189    }
12190
12191    public Configuration getConfiguration() {
12192        Configuration ci;
12193        synchronized(this) {
12194            ci = new Configuration(mConfiguration);
12195        }
12196        return ci;
12197    }
12198
12199    public void updatePersistentConfiguration(Configuration values) {
12200        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12201                "updateConfiguration()");
12202        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12203                "updateConfiguration()");
12204        if (values == null) {
12205            throw new NullPointerException("Configuration must not be null");
12206        }
12207
12208        synchronized(this) {
12209            final long origId = Binder.clearCallingIdentity();
12210            updateConfigurationLocked(values, null, true, false);
12211            Binder.restoreCallingIdentity(origId);
12212        }
12213    }
12214
12215    public void updateConfiguration(Configuration values) {
12216        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12217                "updateConfiguration()");
12218
12219        synchronized(this) {
12220            if (values == null && mWindowManager != null) {
12221                // sentinel: fetch the current configuration from the window manager
12222                values = mWindowManager.computeNewConfiguration();
12223            }
12224
12225            if (mWindowManager != null) {
12226                mProcessList.applyDisplaySize(mWindowManager);
12227            }
12228
12229            final long origId = Binder.clearCallingIdentity();
12230            if (values != null) {
12231                Settings.System.clearConfiguration(values);
12232            }
12233            updateConfigurationLocked(values, null, false, false);
12234            Binder.restoreCallingIdentity(origId);
12235        }
12236    }
12237
12238    /**
12239     * Do either or both things: (1) change the current configuration, and (2)
12240     * make sure the given activity is running with the (now) current
12241     * configuration.  Returns true if the activity has been left running, or
12242     * false if <var>starting</var> is being destroyed to match the new
12243     * configuration.
12244     * @param persistent TODO
12245     */
12246    boolean updateConfigurationLocked(Configuration values,
12247            ActivityRecord starting, boolean persistent, boolean initLocale) {
12248        // do nothing if we are headless
12249        if (mHeadless) return true;
12250
12251        int changes = 0;
12252
12253        boolean kept = true;
12254
12255        if (values != null) {
12256            Configuration newConfig = new Configuration(mConfiguration);
12257            changes = newConfig.updateFrom(values);
12258            if (changes != 0) {
12259                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12260                    Slog.i(TAG, "Updating configuration to: " + values);
12261                }
12262
12263                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
12264
12265                if (values.locale != null && !initLocale) {
12266                    saveLocaleLocked(values.locale,
12267                                     !values.locale.equals(mConfiguration.locale),
12268                                     values.userSetLocale);
12269                }
12270
12271                mConfigurationSeq++;
12272                if (mConfigurationSeq <= 0) {
12273                    mConfigurationSeq = 1;
12274                }
12275                newConfig.seq = mConfigurationSeq;
12276                mConfiguration = newConfig;
12277                Slog.i(TAG, "Config changed: " + newConfig);
12278
12279                final Configuration configCopy = new Configuration(mConfiguration);
12280
12281                // TODO: If our config changes, should we auto dismiss any currently
12282                // showing dialogs?
12283                mShowDialogs = shouldShowDialogs(newConfig);
12284
12285                AttributeCache ac = AttributeCache.instance();
12286                if (ac != null) {
12287                    ac.updateConfiguration(configCopy);
12288                }
12289
12290                // Make sure all resources in our process are updated
12291                // right now, so that anyone who is going to retrieve
12292                // resource values after we return will be sure to get
12293                // the new ones.  This is especially important during
12294                // boot, where the first config change needs to guarantee
12295                // all resources have that config before following boot
12296                // code is executed.
12297                mSystemThread.applyConfigurationToResources(configCopy);
12298
12299                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
12300                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12301                    msg.obj = new Configuration(configCopy);
12302                    mHandler.sendMessage(msg);
12303                }
12304
12305                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12306                    ProcessRecord app = mLruProcesses.get(i);
12307                    try {
12308                        if (app.thread != null) {
12309                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
12310                                    + app.processName + " new config " + mConfiguration);
12311                            app.thread.scheduleConfigurationChanged(configCopy);
12312                        }
12313                    } catch (Exception e) {
12314                    }
12315                }
12316                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12317                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12318                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
12319                        | Intent.FLAG_RECEIVER_FOREGROUND);
12320                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12321                        null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12322                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12323                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
12324                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12325                    broadcastIntentLocked(null, null, intent,
12326                            null, null, 0, null, null,
12327                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12328                }
12329            }
12330        }
12331
12332        if (changes != 0 && starting == null) {
12333            // If the configuration changed, and the caller is not already
12334            // in the process of starting an activity, then find the top
12335            // activity to check if its configuration needs to change.
12336            starting = mMainStack.topRunningActivityLocked(null);
12337        }
12338
12339        if (starting != null) {
12340            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
12341            // And we need to make sure at this point that all other activities
12342            // are made visible with the correct configuration.
12343            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
12344        }
12345
12346        if (values != null && mWindowManager != null) {
12347            mWindowManager.setNewConfiguration(mConfiguration);
12348        }
12349
12350        return kept;
12351    }
12352
12353    /**
12354     * Decide based on the configuration whether we should shouw the ANR,
12355     * crash, etc dialogs.  The idea is that if there is no affordnace to
12356     * press the on-screen buttons, we shouldn't show the dialog.
12357     *
12358     * A thought: SystemUI might also want to get told about this, the Power
12359     * dialog / global actions also might want different behaviors.
12360     */
12361    private static final boolean shouldShowDialogs(Configuration config) {
12362        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
12363                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
12364    }
12365
12366    /**
12367     * Save the locale.  You must be inside a synchronized (this) block.
12368     */
12369    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12370        if(isDiff) {
12371            SystemProperties.set("user.language", l.getLanguage());
12372            SystemProperties.set("user.region", l.getCountry());
12373        }
12374
12375        if(isPersist) {
12376            SystemProperties.set("persist.sys.language", l.getLanguage());
12377            SystemProperties.set("persist.sys.country", l.getCountry());
12378            SystemProperties.set("persist.sys.localevar", l.getVariant());
12379        }
12380    }
12381
12382    @Override
12383    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
12384        ActivityRecord srec = ActivityRecord.forToken(token);
12385        return srec != null && srec.task.affinity != null &&
12386                srec.task.affinity.equals(destAffinity);
12387    }
12388
12389    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
12390            Intent resultData) {
12391        ComponentName dest = destIntent.getComponent();
12392
12393        synchronized (this) {
12394            ActivityRecord srec = ActivityRecord.forToken(token);
12395            if (srec == null) {
12396                return false;
12397            }
12398            ArrayList<ActivityRecord> history = srec.stack.mHistory;
12399            final int start = history.indexOf(srec);
12400            if (start < 0) {
12401                // Current activity is not in history stack; do nothing.
12402                return false;
12403            }
12404            int finishTo = start - 1;
12405            ActivityRecord parent = null;
12406            boolean foundParentInTask = false;
12407            if (dest != null) {
12408                TaskRecord tr = srec.task;
12409                for (int i = start - 1; i >= 0; i--) {
12410                    ActivityRecord r = history.get(i);
12411                    if (tr != r.task) {
12412                        // Couldn't find parent in the same task; stop at the one above this.
12413                        // (Root of current task; in-app "home" behavior)
12414                        // Always at least finish the current activity.
12415                        finishTo = Math.min(start - 1, i + 1);
12416                        parent = history.get(finishTo);
12417                        break;
12418                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
12419                            r.info.name.equals(dest.getClassName())) {
12420                        finishTo = i;
12421                        parent = r;
12422                        foundParentInTask = true;
12423                        break;
12424                    }
12425                }
12426            }
12427
12428            if (mController != null) {
12429                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
12430                if (next != null) {
12431                    // ask watcher if this is allowed
12432                    boolean resumeOK = true;
12433                    try {
12434                        resumeOK = mController.activityResuming(next.packageName);
12435                    } catch (RemoteException e) {
12436                        mController = null;
12437                    }
12438
12439                    if (!resumeOK) {
12440                        return false;
12441                    }
12442                }
12443            }
12444            final long origId = Binder.clearCallingIdentity();
12445            for (int i = start; i > finishTo; i--) {
12446                ActivityRecord r = history.get(i);
12447                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
12448                        "navigate-up", true);
12449                // Only return the supplied result for the first activity finished
12450                resultCode = Activity.RESULT_CANCELED;
12451                resultData = null;
12452            }
12453
12454            if (parent != null && foundParentInTask) {
12455                final int parentLaunchMode = parent.info.launchMode;
12456                final int destIntentFlags = destIntent.getFlags();
12457                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
12458                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
12459                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
12460                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
12461                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
12462                } else {
12463                    try {
12464                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
12465                                destIntent.getComponent(), 0, srec.userId);
12466                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
12467                                null, aInfo, parent.appToken, null,
12468                                0, -1, parent.launchedFromUid, 0, null, true, null);
12469                        foundParentInTask = res == ActivityManager.START_SUCCESS;
12470                    } catch (RemoteException e) {
12471                        foundParentInTask = false;
12472                    }
12473                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
12474                            resultData, "navigate-up", true);
12475                }
12476            }
12477            Binder.restoreCallingIdentity(origId);
12478            return foundParentInTask;
12479        }
12480    }
12481
12482    public int getLaunchedFromUid(IBinder activityToken) {
12483        ActivityRecord srec = ActivityRecord.forToken(activityToken);
12484        if (srec == null) {
12485            return -1;
12486        }
12487        return srec.launchedFromUid;
12488    }
12489
12490    // =========================================================
12491    // LIFETIME MANAGEMENT
12492    // =========================================================
12493
12494    // Returns which broadcast queue the app is the current [or imminent] receiver
12495    // on, or 'null' if the app is not an active broadcast recipient.
12496    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12497        BroadcastRecord r = app.curReceiver;
12498        if (r != null) {
12499            return r.queue;
12500        }
12501
12502        // It's not the current receiver, but it might be starting up to become one
12503        synchronized (this) {
12504            for (BroadcastQueue queue : mBroadcastQueues) {
12505                r = queue.mPendingBroadcast;
12506                if (r != null && r.curApp == app) {
12507                    // found it; report which queue it's in
12508                    return queue;
12509                }
12510            }
12511        }
12512
12513        return null;
12514    }
12515
12516    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj,
12517            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12518        if (mAdjSeq == app.adjSeq) {
12519            // This adjustment has already been computed.  If we are calling
12520            // from the top, we may have already computed our adjustment with
12521            // an earlier hidden adjustment that isn't really for us... if
12522            // so, use the new hidden adjustment.
12523            if (!recursed && app.hidden) {
12524                if (app.hasActivities) {
12525                    app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
12526                } else if (app.hasClientActivities) {
12527                    app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientHiddenAdj;
12528                } else {
12529                    app.curAdj = app.curRawAdj = app.nonStoppingAdj = emptyAdj;
12530                }
12531            }
12532            return app.curRawAdj;
12533        }
12534
12535        if (app.thread == null) {
12536            app.adjSeq = mAdjSeq;
12537            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12538            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12539        }
12540
12541        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12542        app.adjSource = null;
12543        app.adjTarget = null;
12544        app.empty = false;
12545        app.hidden = false;
12546        app.hasClientActivities = false;
12547
12548        final int activitiesSize = app.activities.size();
12549
12550        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12551            // The max adjustment doesn't allow this app to be anything
12552            // below foreground, so it is not worth doing work for it.
12553            app.adjType = "fixed";
12554            app.adjSeq = mAdjSeq;
12555            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12556            app.hasActivities = false;
12557            app.foregroundActivities = false;
12558            app.keeping = true;
12559            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12560            // System process can do UI, and when they do we want to have
12561            // them trim their memory after the user leaves the UI.  To
12562            // facilitate this, here we need to determine whether or not it
12563            // is currently showing UI.
12564            app.systemNoUi = true;
12565            if (app == TOP_APP) {
12566                app.systemNoUi = false;
12567                app.hasActivities = true;
12568            } else if (activitiesSize > 0) {
12569                for (int j = 0; j < activitiesSize; j++) {
12570                    final ActivityRecord r = app.activities.get(j);
12571                    if (r.visible) {
12572                        app.systemNoUi = false;
12573                    }
12574                    if (r.app == app) {
12575                        app.hasActivities = true;
12576                    }
12577                }
12578            }
12579            return (app.curAdj=app.maxAdj);
12580        }
12581
12582        app.keeping = false;
12583        app.systemNoUi = false;
12584        app.hasActivities = false;
12585
12586        // Determine the importance of the process, starting with most
12587        // important to least, and assign an appropriate OOM adjustment.
12588        int adj;
12589        int schedGroup;
12590        boolean foregroundActivities = false;
12591        boolean interesting = false;
12592        BroadcastQueue queue;
12593        if (app == TOP_APP) {
12594            // The last app on the list is the foreground app.
12595            adj = ProcessList.FOREGROUND_APP_ADJ;
12596            schedGroup = Process.THREAD_GROUP_DEFAULT;
12597            app.adjType = "top-activity";
12598            foregroundActivities = true;
12599            interesting = true;
12600            app.hasActivities = true;
12601        } else if (app.instrumentationClass != null) {
12602            // Don't want to kill running instrumentation.
12603            adj = ProcessList.FOREGROUND_APP_ADJ;
12604            schedGroup = Process.THREAD_GROUP_DEFAULT;
12605            app.adjType = "instrumentation";
12606            interesting = true;
12607        } else if ((queue = isReceivingBroadcast(app)) != null) {
12608            // An app that is currently receiving a broadcast also
12609            // counts as being in the foreground for OOM killer purposes.
12610            // It's placed in a sched group based on the nature of the
12611            // broadcast as reflected by which queue it's active in.
12612            adj = ProcessList.FOREGROUND_APP_ADJ;
12613            schedGroup = (queue == mFgBroadcastQueue)
12614                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12615            app.adjType = "broadcast";
12616        } else if (app.executingServices.size() > 0) {
12617            // An app that is currently executing a service callback also
12618            // counts as being in the foreground.
12619            adj = ProcessList.FOREGROUND_APP_ADJ;
12620            schedGroup = Process.THREAD_GROUP_DEFAULT;
12621            app.adjType = "exec-service";
12622        } else {
12623            // Assume process is hidden (has activities); we will correct
12624            // later if this is not the case.
12625            adj = hiddenAdj;
12626            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12627            app.hidden = true;
12628            app.adjType = "bg-act";
12629        }
12630
12631        boolean hasStoppingActivities = false;
12632
12633        // Examine all activities if not already foreground.
12634        if (!foregroundActivities && activitiesSize > 0) {
12635            for (int j = 0; j < activitiesSize; j++) {
12636                final ActivityRecord r = app.activities.get(j);
12637                if (r.visible) {
12638                    // App has a visible activity; only upgrade adjustment.
12639                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12640                        adj = ProcessList.VISIBLE_APP_ADJ;
12641                        app.adjType = "visible";
12642                    }
12643                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12644                    app.hidden = false;
12645                    app.hasActivities = true;
12646                    foregroundActivities = true;
12647                    break;
12648                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12649                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12650                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12651                        app.adjType = "pausing";
12652                    }
12653                    app.hidden = false;
12654                    foregroundActivities = true;
12655                } else if (r.state == ActivityState.STOPPING) {
12656                    // We will apply the actual adjustment later, because
12657                    // we want to allow this process to immediately go through
12658                    // any memory trimming that is in effect.
12659                    app.hidden = false;
12660                    foregroundActivities = true;
12661                    hasStoppingActivities = true;
12662                }
12663                if (r.app == app) {
12664                    app.hasActivities = true;
12665                }
12666            }
12667        }
12668
12669        if (adj == hiddenAdj && !app.hasActivities) {
12670            if (app.hasClientActivities) {
12671                adj = clientHiddenAdj;
12672                app.adjType = "bg-client-act";
12673            } else {
12674                // Whoops, this process is completely empty as far as we know
12675                // at this point.
12676                adj = emptyAdj;
12677                app.empty = true;
12678                app.adjType = "bg-empty";
12679            }
12680        }
12681
12682        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12683            if (app.foregroundServices) {
12684                // The user is aware of this app, so make it visible.
12685                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12686                app.hidden = false;
12687                app.adjType = "fg-service";
12688                schedGroup = Process.THREAD_GROUP_DEFAULT;
12689            } else if (app.forcingToForeground != null) {
12690                // The user is aware of this app, so make it visible.
12691                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12692                app.hidden = false;
12693                app.adjType = "force-fg";
12694                app.adjSource = app.forcingToForeground;
12695                schedGroup = Process.THREAD_GROUP_DEFAULT;
12696            }
12697        }
12698
12699        if (app.foregroundServices) {
12700            interesting = true;
12701        }
12702
12703        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12704            // We don't want to kill the current heavy-weight process.
12705            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12706            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12707            app.hidden = false;
12708            app.adjType = "heavy";
12709        }
12710
12711        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12712            // This process is hosting what we currently consider to be the
12713            // home app, so we don't want to let it go into the background.
12714            adj = ProcessList.HOME_APP_ADJ;
12715            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12716            app.hidden = false;
12717            app.adjType = "home";
12718        }
12719
12720        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12721                && app.activities.size() > 0) {
12722            // This was the previous process that showed UI to the user.
12723            // We want to try to keep it around more aggressively, to give
12724            // a good experience around switching between two apps.
12725            adj = ProcessList.PREVIOUS_APP_ADJ;
12726            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12727            app.hidden = false;
12728            app.adjType = "previous";
12729        }
12730
12731        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12732                + " reason=" + app.adjType);
12733
12734        // By default, we use the computed adjustment.  It may be changed if
12735        // there are applications dependent on our services or providers, but
12736        // this gives us a baseline and makes sure we don't get into an
12737        // infinite recursion.
12738        app.adjSeq = mAdjSeq;
12739        app.curRawAdj = app.nonStoppingAdj = adj;
12740
12741        if (mBackupTarget != null && app == mBackupTarget.app) {
12742            // If possible we want to avoid killing apps while they're being backed up
12743            if (adj > ProcessList.BACKUP_APP_ADJ) {
12744                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12745                adj = ProcessList.BACKUP_APP_ADJ;
12746                app.adjType = "backup";
12747                app.hidden = false;
12748            }
12749        }
12750
12751        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12752                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12753            final long now = SystemClock.uptimeMillis();
12754            // This process is more important if the top activity is
12755            // bound to the service.
12756            Iterator<ServiceRecord> jt = app.services.iterator();
12757            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12758                ServiceRecord s = jt.next();
12759                if (s.startRequested) {
12760                    if (app.hasShownUi && app != mHomeProcess) {
12761                        // If this process has shown some UI, let it immediately
12762                        // go to the LRU list because it may be pretty heavy with
12763                        // UI stuff.  We'll tag it with a label just to help
12764                        // debug and understand what is going on.
12765                        if (adj > ProcessList.SERVICE_ADJ) {
12766                            app.adjType = "started-bg-ui-services";
12767                        }
12768                    } else {
12769                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12770                            // This service has seen some activity within
12771                            // recent memory, so we will keep its process ahead
12772                            // of the background processes.
12773                            if (adj > ProcessList.SERVICE_ADJ) {
12774                                adj = ProcessList.SERVICE_ADJ;
12775                                app.adjType = "started-services";
12776                                app.hidden = false;
12777                            }
12778                        }
12779                        // If we have let the service slide into the background
12780                        // state, still have some text describing what it is doing
12781                        // even though the service no longer has an impact.
12782                        if (adj > ProcessList.SERVICE_ADJ) {
12783                            app.adjType = "started-bg-services";
12784                        }
12785                    }
12786                    // Don't kill this process because it is doing work; it
12787                    // has said it is doing work.
12788                    app.keeping = true;
12789                }
12790                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12791                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12792                    Iterator<ArrayList<ConnectionRecord>> kt
12793                            = s.connections.values().iterator();
12794                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12795                        ArrayList<ConnectionRecord> clist = kt.next();
12796                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12797                            // XXX should compute this based on the max of
12798                            // all connected clients.
12799                            ConnectionRecord cr = clist.get(i);
12800                            if (cr.binding.client == app) {
12801                                // Binding to ourself is not interesting.
12802                                continue;
12803                            }
12804                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12805                                ProcessRecord client = cr.binding.client;
12806                                int clientAdj = adj;
12807                                int myHiddenAdj = hiddenAdj;
12808                                if (myHiddenAdj > client.hiddenAdj) {
12809                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12810                                        myHiddenAdj = client.hiddenAdj;
12811                                    } else {
12812                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12813                                    }
12814                                }
12815                                int myClientHiddenAdj = clientHiddenAdj;
12816                                if (myClientHiddenAdj > client.clientHiddenAdj) {
12817                                    if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12818                                        myClientHiddenAdj = client.clientHiddenAdj;
12819                                    } else {
12820                                        myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12821                                    }
12822                                }
12823                                int myEmptyAdj = emptyAdj;
12824                                if (myEmptyAdj > client.emptyAdj) {
12825                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12826                                        myEmptyAdj = client.emptyAdj;
12827                                    } else {
12828                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12829                                    }
12830                                }
12831                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12832                                        myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
12833                                String adjType = null;
12834                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12835                                    // Not doing bind OOM management, so treat
12836                                    // this guy more like a started service.
12837                                    if (app.hasShownUi && app != mHomeProcess) {
12838                                        // If this process has shown some UI, let it immediately
12839                                        // go to the LRU list because it may be pretty heavy with
12840                                        // UI stuff.  We'll tag it with a label just to help
12841                                        // debug and understand what is going on.
12842                                        if (adj > clientAdj) {
12843                                            adjType = "bound-bg-ui-services";
12844                                        }
12845                                        app.hidden = false;
12846                                        clientAdj = adj;
12847                                    } else {
12848                                        if (now >= (s.lastActivity
12849                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12850                                            // This service has not seen activity within
12851                                            // recent memory, so allow it to drop to the
12852                                            // LRU list if there is no other reason to keep
12853                                            // it around.  We'll also tag it with a label just
12854                                            // to help debug and undertand what is going on.
12855                                            if (adj > clientAdj) {
12856                                                adjType = "bound-bg-services";
12857                                            }
12858                                            clientAdj = adj;
12859                                        }
12860                                    }
12861                                } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
12862                                    if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) {
12863                                        // If this connection is keeping the service
12864                                        // created, then we want to try to better follow
12865                                        // its memory management semantics for activities.
12866                                        // That is, if it is sitting in the background
12867                                        // LRU list as a hidden process (with activities),
12868                                        // we don't want the service it is connected to
12869                                        // to go into the empty LRU and quickly get killed,
12870                                        // because I'll we'll do is just end up restarting
12871                                        // the service.
12872                                        app.hasClientActivities |= client.hasActivities;
12873                                    }
12874                                }
12875                                if (adj > clientAdj) {
12876                                    // If this process has recently shown UI, and
12877                                    // the process that is binding to it is less
12878                                    // important than being visible, then we don't
12879                                    // care about the binding as much as we care
12880                                    // about letting this process get into the LRU
12881                                    // list to be killed and restarted if needed for
12882                                    // memory.
12883                                    if (app.hasShownUi && app != mHomeProcess
12884                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12885                                        adjType = "bound-bg-ui-services";
12886                                    } else {
12887                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12888                                                |Context.BIND_IMPORTANT)) != 0) {
12889                                            adj = clientAdj;
12890                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12891                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12892                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12893                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12894                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12895                                            adj = clientAdj;
12896                                        } else {
12897                                            app.pendingUiClean = true;
12898                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12899                                                adj = ProcessList.VISIBLE_APP_ADJ;
12900                                            }
12901                                        }
12902                                        if (!client.hidden) {
12903                                            app.hidden = false;
12904                                        }
12905                                        if (client.keeping) {
12906                                            app.keeping = true;
12907                                        }
12908                                        adjType = "service";
12909                                    }
12910                                }
12911                                if (adjType != null) {
12912                                    app.adjType = adjType;
12913                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12914                                            .REASON_SERVICE_IN_USE;
12915                                    app.adjSource = cr.binding.client;
12916                                    app.adjSourceOom = clientAdj;
12917                                    app.adjTarget = s.name;
12918                                }
12919                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12920                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12921                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12922                                    }
12923                                }
12924                            }
12925                            final ActivityRecord a = cr.activity;
12926                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12927                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12928                                        (a.visible || a.state == ActivityState.RESUMED
12929                                         || a.state == ActivityState.PAUSING)) {
12930                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12931                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12932                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12933                                    }
12934                                    app.hidden = false;
12935                                    app.adjType = "service";
12936                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12937                                            .REASON_SERVICE_IN_USE;
12938                                    app.adjSource = a;
12939                                    app.adjSourceOom = adj;
12940                                    app.adjTarget = s.name;
12941                                }
12942                            }
12943                        }
12944                    }
12945                }
12946            }
12947
12948            // Finally, if this process has active services running in it, we
12949            // would like to avoid killing it unless it would prevent the current
12950            // application from running.  By default we put the process in
12951            // with the rest of the background processes; as we scan through
12952            // its services we may bump it up from there.
12953            if (adj > hiddenAdj) {
12954                adj = hiddenAdj;
12955                app.hidden = false;
12956                app.adjType = "bg-services";
12957            }
12958        }
12959
12960        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12961                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12962            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12963            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12964                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12965                ContentProviderRecord cpr = jt.next();
12966                for (int i = cpr.connections.size()-1;
12967                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12968                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12969                        i--) {
12970                    ContentProviderConnection conn = cpr.connections.get(i);
12971                    ProcessRecord client = conn.client;
12972                    if (client == app) {
12973                        // Being our own client is not interesting.
12974                        continue;
12975                    }
12976                    int myHiddenAdj = hiddenAdj;
12977                    if (myHiddenAdj > client.hiddenAdj) {
12978                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12979                            myHiddenAdj = client.hiddenAdj;
12980                        } else {
12981                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12982                        }
12983                    }
12984                    int myClientHiddenAdj = clientHiddenAdj;
12985                    if (myClientHiddenAdj > client.clientHiddenAdj) {
12986                        if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) {
12987                            myClientHiddenAdj = client.clientHiddenAdj;
12988                        } else {
12989                            myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12990                        }
12991                    }
12992                    int myEmptyAdj = emptyAdj;
12993                    if (myEmptyAdj > client.emptyAdj) {
12994                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
12995                            myEmptyAdj = client.emptyAdj;
12996                        } else {
12997                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
12998                        }
12999                    }
13000                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
13001                            myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
13002                    if (adj > clientAdj) {
13003                        if (app.hasShownUi && app != mHomeProcess
13004                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13005                            app.adjType = "bg-ui-provider";
13006                        } else {
13007                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13008                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
13009                            app.adjType = "provider";
13010                        }
13011                        if (!client.hidden) {
13012                            app.hidden = false;
13013                        }
13014                        if (client.keeping) {
13015                            app.keeping = true;
13016                        }
13017                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13018                                .REASON_PROVIDER_IN_USE;
13019                        app.adjSource = client;
13020                        app.adjSourceOom = clientAdj;
13021                        app.adjTarget = cpr.name;
13022                    }
13023                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13024                        schedGroup = Process.THREAD_GROUP_DEFAULT;
13025                    }
13026                }
13027                // If the provider has external (non-framework) process
13028                // dependencies, ensure that its adjustment is at least
13029                // FOREGROUND_APP_ADJ.
13030                if (cpr.hasExternalProcessHandles()) {
13031                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13032                        adj = ProcessList.FOREGROUND_APP_ADJ;
13033                        schedGroup = Process.THREAD_GROUP_DEFAULT;
13034                        app.hidden = false;
13035                        app.keeping = true;
13036                        app.adjType = "provider";
13037                        app.adjTarget = cpr.name;
13038                    }
13039                }
13040            }
13041        }
13042
13043        if (adj == ProcessList.SERVICE_ADJ) {
13044            if (doingAll) {
13045                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
13046                mNewNumServiceProcs++;
13047            }
13048            if (app.serviceb) {
13049                adj = ProcessList.SERVICE_B_ADJ;
13050            }
13051        } else {
13052            app.serviceb = false;
13053        }
13054
13055        app.nonStoppingAdj = adj;
13056
13057        if (hasStoppingActivities) {
13058            // Only upgrade adjustment.
13059            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13060                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13061                app.adjType = "stopping";
13062            }
13063        }
13064
13065        app.curRawAdj = adj;
13066
13067        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
13068        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13069        if (adj > app.maxAdj) {
13070            adj = app.maxAdj;
13071            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
13072                schedGroup = Process.THREAD_GROUP_DEFAULT;
13073            }
13074        }
13075        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13076            app.keeping = true;
13077        }
13078
13079        if (app.hasAboveClient) {
13080            // If this process has bound to any services with BIND_ABOVE_CLIENT,
13081            // then we need to drop its adjustment to be lower than the service's
13082            // in order to honor the request.  We want to drop it by one adjustment
13083            // level...  but there is special meaning applied to various levels so
13084            // we will skip some of them.
13085            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
13086                // System process will not get dropped, ever
13087            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13088                adj = ProcessList.VISIBLE_APP_ADJ;
13089            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13090                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13091            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13092                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13093            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
13094                adj++;
13095            }
13096        }
13097
13098        int importance = app.memImportance;
13099        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
13100            app.curAdj = adj;
13101            app.curSchedGroup = schedGroup;
13102            if (!interesting) {
13103                // For this reporting, if there is not something explicitly
13104                // interesting in this process then we will push it to the
13105                // background importance.
13106                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13107            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13108                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13109            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
13110                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13111            } else if (adj >= ProcessList.HOME_APP_ADJ) {
13112                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13113            } else if (adj >= ProcessList.SERVICE_ADJ) {
13114                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13115            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13116                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
13117            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
13118                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
13119            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
13120                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
13121            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
13122                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
13123            } else {
13124                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
13125            }
13126        }
13127
13128        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
13129        if (foregroundActivities != app.foregroundActivities) {
13130            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
13131        }
13132        if (changes != 0) {
13133            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
13134            app.memImportance = importance;
13135            app.foregroundActivities = foregroundActivities;
13136            int i = mPendingProcessChanges.size()-1;
13137            ProcessChangeItem item = null;
13138            while (i >= 0) {
13139                item = mPendingProcessChanges.get(i);
13140                if (item.pid == app.pid) {
13141                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
13142                    break;
13143                }
13144                i--;
13145            }
13146            if (i < 0) {
13147                // No existing item in pending changes; need a new one.
13148                final int NA = mAvailProcessChanges.size();
13149                if (NA > 0) {
13150                    item = mAvailProcessChanges.remove(NA-1);
13151                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
13152                } else {
13153                    item = new ProcessChangeItem();
13154                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
13155                }
13156                item.changes = 0;
13157                item.pid = app.pid;
13158                item.uid = app.info.uid;
13159                if (mPendingProcessChanges.size() == 0) {
13160                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
13161                            "*** Enqueueing dispatch processes changed!");
13162                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
13163                }
13164                mPendingProcessChanges.add(item);
13165            }
13166            item.changes |= changes;
13167            item.importance = importance;
13168            item.foregroundActivities = foregroundActivities;
13169            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
13170                    + Integer.toHexString(System.identityHashCode(item))
13171                    + " " + app.toShortString() + ": changes=" + item.changes
13172                    + " importance=" + item.importance
13173                    + " foreground=" + item.foregroundActivities
13174                    + " type=" + app.adjType + " source=" + app.adjSource
13175                    + " target=" + app.adjTarget);
13176        }
13177
13178        return app.curRawAdj;
13179    }
13180
13181    /**
13182     * Ask a given process to GC right now.
13183     */
13184    final void performAppGcLocked(ProcessRecord app) {
13185        try {
13186            app.lastRequestedGc = SystemClock.uptimeMillis();
13187            if (app.thread != null) {
13188                if (app.reportLowMemory) {
13189                    app.reportLowMemory = false;
13190                    app.thread.scheduleLowMemory();
13191                } else {
13192                    app.thread.processInBackground();
13193                }
13194            }
13195        } catch (Exception e) {
13196            // whatever.
13197        }
13198    }
13199
13200    /**
13201     * Returns true if things are idle enough to perform GCs.
13202     */
13203    private final boolean canGcNowLocked() {
13204        boolean processingBroadcasts = false;
13205        for (BroadcastQueue q : mBroadcastQueues) {
13206            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
13207                processingBroadcasts = true;
13208            }
13209        }
13210        return !processingBroadcasts
13211                && (mSleeping || (mMainStack.mResumedActivity != null &&
13212                        mMainStack.mResumedActivity.idle));
13213    }
13214
13215    /**
13216     * Perform GCs on all processes that are waiting for it, but only
13217     * if things are idle.
13218     */
13219    final void performAppGcsLocked() {
13220        final int N = mProcessesToGc.size();
13221        if (N <= 0) {
13222            return;
13223        }
13224        if (canGcNowLocked()) {
13225            while (mProcessesToGc.size() > 0) {
13226                ProcessRecord proc = mProcessesToGc.remove(0);
13227                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
13228                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13229                            <= SystemClock.uptimeMillis()) {
13230                        // To avoid spamming the system, we will GC processes one
13231                        // at a time, waiting a few seconds between each.
13232                        performAppGcLocked(proc);
13233                        scheduleAppGcsLocked();
13234                        return;
13235                    } else {
13236                        // It hasn't been long enough since we last GCed this
13237                        // process...  put it in the list to wait for its time.
13238                        addProcessToGcListLocked(proc);
13239                        break;
13240                    }
13241                }
13242            }
13243
13244            scheduleAppGcsLocked();
13245        }
13246    }
13247
13248    /**
13249     * If all looks good, perform GCs on all processes waiting for them.
13250     */
13251    final void performAppGcsIfAppropriateLocked() {
13252        if (canGcNowLocked()) {
13253            performAppGcsLocked();
13254            return;
13255        }
13256        // Still not idle, wait some more.
13257        scheduleAppGcsLocked();
13258    }
13259
13260    /**
13261     * Schedule the execution of all pending app GCs.
13262     */
13263    final void scheduleAppGcsLocked() {
13264        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
13265
13266        if (mProcessesToGc.size() > 0) {
13267            // Schedule a GC for the time to the next process.
13268            ProcessRecord proc = mProcessesToGc.get(0);
13269            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13270
13271            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
13272            long now = SystemClock.uptimeMillis();
13273            if (when < (now+GC_TIMEOUT)) {
13274                when = now + GC_TIMEOUT;
13275            }
13276            mHandler.sendMessageAtTime(msg, when);
13277        }
13278    }
13279
13280    /**
13281     * Add a process to the array of processes waiting to be GCed.  Keeps the
13282     * list in sorted order by the last GC time.  The process can't already be
13283     * on the list.
13284     */
13285    final void addProcessToGcListLocked(ProcessRecord proc) {
13286        boolean added = false;
13287        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13288            if (mProcessesToGc.get(i).lastRequestedGc <
13289                    proc.lastRequestedGc) {
13290                added = true;
13291                mProcessesToGc.add(i+1, proc);
13292                break;
13293            }
13294        }
13295        if (!added) {
13296            mProcessesToGc.add(0, proc);
13297        }
13298    }
13299
13300    /**
13301     * Set up to ask a process to GC itself.  This will either do it
13302     * immediately, or put it on the list of processes to gc the next
13303     * time things are idle.
13304     */
13305    final void scheduleAppGcLocked(ProcessRecord app) {
13306        long now = SystemClock.uptimeMillis();
13307        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13308            return;
13309        }
13310        if (!mProcessesToGc.contains(app)) {
13311            addProcessToGcListLocked(app);
13312            scheduleAppGcsLocked();
13313        }
13314    }
13315
13316    final void checkExcessivePowerUsageLocked(boolean doKills) {
13317        updateCpuStatsNow();
13318
13319        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13320        boolean doWakeKills = doKills;
13321        boolean doCpuKills = doKills;
13322        if (mLastPowerCheckRealtime == 0) {
13323            doWakeKills = false;
13324        }
13325        if (mLastPowerCheckUptime == 0) {
13326            doCpuKills = false;
13327        }
13328        if (stats.isScreenOn()) {
13329            doWakeKills = false;
13330        }
13331        final long curRealtime = SystemClock.elapsedRealtime();
13332        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13333        final long curUptime = SystemClock.uptimeMillis();
13334        final long uptimeSince = curUptime - mLastPowerCheckUptime;
13335        mLastPowerCheckRealtime = curRealtime;
13336        mLastPowerCheckUptime = curUptime;
13337        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13338            doWakeKills = false;
13339        }
13340        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13341            doCpuKills = false;
13342        }
13343        int i = mLruProcesses.size();
13344        while (i > 0) {
13345            i--;
13346            ProcessRecord app = mLruProcesses.get(i);
13347            if (!app.keeping) {
13348                long wtime;
13349                synchronized (stats) {
13350                    wtime = stats.getProcessWakeTime(app.info.uid,
13351                            app.pid, curRealtime);
13352                }
13353                long wtimeUsed = wtime - app.lastWakeTime;
13354                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13355                if (DEBUG_POWER) {
13356                    StringBuilder sb = new StringBuilder(128);
13357                    sb.append("Wake for ");
13358                    app.toShortString(sb);
13359                    sb.append(": over ");
13360                    TimeUtils.formatDuration(realtimeSince, sb);
13361                    sb.append(" used ");
13362                    TimeUtils.formatDuration(wtimeUsed, sb);
13363                    sb.append(" (");
13364                    sb.append((wtimeUsed*100)/realtimeSince);
13365                    sb.append("%)");
13366                    Slog.i(TAG, sb.toString());
13367                    sb.setLength(0);
13368                    sb.append("CPU for ");
13369                    app.toShortString(sb);
13370                    sb.append(": over ");
13371                    TimeUtils.formatDuration(uptimeSince, sb);
13372                    sb.append(" used ");
13373                    TimeUtils.formatDuration(cputimeUsed, sb);
13374                    sb.append(" (");
13375                    sb.append((cputimeUsed*100)/uptimeSince);
13376                    sb.append("%)");
13377                    Slog.i(TAG, sb.toString());
13378                }
13379                // If a process has held a wake lock for more
13380                // than 50% of the time during this period,
13381                // that sounds bad.  Kill!
13382                if (doWakeKills && realtimeSince > 0
13383                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
13384                    synchronized (stats) {
13385                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13386                                realtimeSince, wtimeUsed);
13387                    }
13388                    Slog.w(TAG, "Excessive wake lock in " + app.processName
13389                            + " (pid " + app.pid + "): held " + wtimeUsed
13390                            + " during " + realtimeSince);
13391                    EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13392                            app.processName, app.setAdj, "excessive wake lock");
13393                    Process.killProcessQuiet(app.pid);
13394                } else if (doCpuKills && uptimeSince > 0
13395                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
13396                    synchronized (stats) {
13397                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13398                                uptimeSince, cputimeUsed);
13399                    }
13400                    Slog.w(TAG, "Excessive CPU in " + app.processName
13401                            + " (pid " + app.pid + "): used " + cputimeUsed
13402                            + " during " + uptimeSince);
13403                    EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13404                            app.processName, app.setAdj, "excessive cpu");
13405                    Process.killProcessQuiet(app.pid);
13406                } else {
13407                    app.lastWakeTime = wtime;
13408                    app.lastCpuTime = app.curCpuTime;
13409                }
13410            }
13411        }
13412    }
13413
13414    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
13415            int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
13416        app.hiddenAdj = hiddenAdj;
13417        app.clientHiddenAdj = clientHiddenAdj;
13418        app.emptyAdj = emptyAdj;
13419
13420        if (app.thread == null) {
13421            return false;
13422        }
13423
13424        final boolean wasKeeping = app.keeping;
13425
13426        boolean success = true;
13427
13428        computeOomAdjLocked(app, hiddenAdj, clientHiddenAdj, emptyAdj, TOP_APP, false, doingAll);
13429
13430        if (app.curRawAdj != app.setRawAdj) {
13431            if (wasKeeping && !app.keeping) {
13432                // This app is no longer something we want to keep.  Note
13433                // its current wake lock time to later know to kill it if
13434                // it is not behaving well.
13435                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13436                synchronized (stats) {
13437                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13438                            app.pid, SystemClock.elapsedRealtime());
13439                }
13440                app.lastCpuTime = app.curCpuTime;
13441            }
13442
13443            app.setRawAdj = app.curRawAdj;
13444        }
13445
13446        if (app.curAdj != app.setAdj) {
13447            if (Process.setOomAdj(app.pid, app.curAdj)) {
13448                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13449                    TAG, "Set " + app.pid + " " + app.processName +
13450                    " adj " + app.curAdj + ": " + app.adjType);
13451                app.setAdj = app.curAdj;
13452            } else {
13453                success = false;
13454                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
13455            }
13456        }
13457        if (app.setSchedGroup != app.curSchedGroup) {
13458            app.setSchedGroup = app.curSchedGroup;
13459            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13460                    "Setting process group of " + app.processName
13461                    + " to " + app.curSchedGroup);
13462            if (app.waitingToKill != null &&
13463                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13464                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13465                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13466                        app.processName, app.setAdj, app.waitingToKill);
13467                app.killedBackground = true;
13468                Process.killProcessQuiet(app.pid);
13469                success = false;
13470            } else {
13471                if (true) {
13472                    long oldId = Binder.clearCallingIdentity();
13473                    try {
13474                        Process.setProcessGroup(app.pid, app.curSchedGroup);
13475                    } catch (Exception e) {
13476                        Slog.w(TAG, "Failed setting process group of " + app.pid
13477                                + " to " + app.curSchedGroup);
13478                        e.printStackTrace();
13479                    } finally {
13480                        Binder.restoreCallingIdentity(oldId);
13481                    }
13482                } else {
13483                    if (app.thread != null) {
13484                        try {
13485                            app.thread.setSchedulingGroup(app.curSchedGroup);
13486                        } catch (RemoteException e) {
13487                        }
13488                    }
13489                }
13490            }
13491        }
13492        return success;
13493    }
13494
13495    private final ActivityRecord resumedAppLocked() {
13496        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
13497        if (resumedActivity == null || resumedActivity.app == null) {
13498            resumedActivity = mMainStack.mPausingActivity;
13499            if (resumedActivity == null || resumedActivity.app == null) {
13500                resumedActivity = mMainStack.topRunningActivityLocked(null);
13501            }
13502        }
13503        return resumedActivity;
13504    }
13505
13506    final boolean updateOomAdjLocked(ProcessRecord app) {
13507        final ActivityRecord TOP_ACT = resumedAppLocked();
13508        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13509        int curAdj = app.curAdj;
13510        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13511            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13512
13513        mAdjSeq++;
13514
13515        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.clientHiddenAdj,
13516                app.emptyAdj, TOP_APP, false);
13517        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13518            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13519        if (nowHidden != wasHidden) {
13520            // Changed to/from hidden state, so apps after it in the LRU
13521            // list may also be changed.
13522            updateOomAdjLocked();
13523        }
13524        return success;
13525    }
13526
13527    final void updateOomAdjLocked() {
13528        final ActivityRecord TOP_ACT = resumedAppLocked();
13529        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13530        final long oldTime = SystemClock.uptimeMillis() - ProcessList.MAX_EMPTY_TIME;
13531
13532        if (false) {
13533            RuntimeException e = new RuntimeException();
13534            e.fillInStackTrace();
13535            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13536        }
13537
13538        mAdjSeq++;
13539        mNewNumServiceProcs = 0;
13540
13541        final int emptyProcessLimit;
13542        final int hiddenProcessLimit;
13543        if (mProcessLimit <= 0) {
13544            emptyProcessLimit = hiddenProcessLimit = 0;
13545        } else if (mProcessLimit == 1) {
13546            emptyProcessLimit = 1;
13547            hiddenProcessLimit = 0;
13548        } else {
13549            emptyProcessLimit = (mProcessLimit*2)/3;
13550            hiddenProcessLimit = mProcessLimit - emptyProcessLimit;
13551        }
13552
13553        // Let's determine how many processes we have running vs.
13554        // how many slots we have for background processes; we may want
13555        // to put multiple processes in a slot of there are enough of
13556        // them.
13557        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13558                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13559        int numEmptyProcs = mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs;
13560        if (numEmptyProcs > hiddenProcessLimit) {
13561            // If there are more empty processes than our limit on hidden
13562            // processes, then use the hidden process limit for the factor.
13563            // This ensures that the really old empty processes get pushed
13564            // down to the bottom, so if we are running low on memory we will
13565            // have a better chance at keeping around more hidden processes
13566            // instead of a gazillion empty processes.
13567            numEmptyProcs = hiddenProcessLimit;
13568        }
13569        int emptyFactor = numEmptyProcs/numSlots;
13570        if (emptyFactor < 1) emptyFactor = 1;
13571        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13572        if (hiddenFactor < 1) hiddenFactor = 1;
13573        int stepHidden = 0;
13574        int stepEmpty = 0;
13575        int numHidden = 0;
13576        int numEmpty = 0;
13577        int numTrimming = 0;
13578
13579        mNumNonHiddenProcs = 0;
13580        mNumHiddenProcs = 0;
13581
13582        // First update the OOM adjustment for each of the
13583        // application processes based on their current state.
13584        int i = mLruProcesses.size();
13585        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13586        int nextHiddenAdj = curHiddenAdj+1;
13587        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13588        int nextEmptyAdj = curEmptyAdj+2;
13589        int curClientHiddenAdj = curEmptyAdj;
13590        while (i > 0) {
13591            i--;
13592            ProcessRecord app = mLruProcesses.get(i);
13593            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13594            updateOomAdjLocked(app, curHiddenAdj, curClientHiddenAdj, curEmptyAdj, TOP_APP, true);
13595            if (!app.killedBackground) {
13596                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13597                    // This process was assigned as a hidden process...  step the
13598                    // hidden level.
13599                    mNumHiddenProcs++;
13600                    if (curHiddenAdj != nextHiddenAdj) {
13601                        stepHidden++;
13602                        if (stepHidden >= hiddenFactor) {
13603                            stepHidden = 0;
13604                            curHiddenAdj = nextHiddenAdj;
13605                            nextHiddenAdj += 2;
13606                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13607                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13608                            }
13609                            if (curClientHiddenAdj <= curHiddenAdj) {
13610                                curClientHiddenAdj = curHiddenAdj + 1;
13611                                if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13612                                    curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13613                                }
13614                            }
13615                        }
13616                    }
13617                    numHidden++;
13618                    if (numHidden > hiddenProcessLimit) {
13619                        Slog.i(TAG, "No longer want " + app.processName
13620                                + " (pid " + app.pid + "): hidden #" + numHidden);
13621                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13622                                app.processName, app.setAdj, "too many background");
13623                        app.killedBackground = true;
13624                        Process.killProcessQuiet(app.pid);
13625                    }
13626                } else if (app.curRawAdj == curHiddenAdj && app.hasClientActivities) {
13627                    // This process has a client that has activities.  We will have
13628                    // given it the current hidden adj; here we will just leave it
13629                    // without stepping the hidden adj.
13630                    curClientHiddenAdj++;
13631                    if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13632                        curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13633                    }
13634                } else {
13635                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13636                        // This process was assigned as an empty process...  step the
13637                        // empty level.
13638                        if (curEmptyAdj != nextEmptyAdj) {
13639                            stepEmpty++;
13640                            if (stepEmpty >= emptyFactor) {
13641                                stepEmpty = 0;
13642                                curEmptyAdj = nextEmptyAdj;
13643                                nextEmptyAdj += 2;
13644                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13645                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13646                                }
13647                            }
13648                        }
13649                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13650                        mNumNonHiddenProcs++;
13651                    }
13652                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13653                            && !app.hasClientActivities) {
13654                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
13655                                && app.lastActivityTime < oldTime) {
13656                            Slog.i(TAG, "No longer want " + app.processName
13657                                    + " (pid " + app.pid + "): empty for "
13658                                    + ((oldTime+ProcessList.MAX_EMPTY_TIME-app.lastActivityTime)
13659                                            / 1000) + "s");
13660                            EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13661                                    app.processName, app.setAdj, "old background process");
13662                            app.killedBackground = true;
13663                            Process.killProcessQuiet(app.pid);
13664                        } else {
13665                            numEmpty++;
13666                            if (numEmpty > emptyProcessLimit) {
13667                                Slog.i(TAG, "No longer want " + app.processName
13668                                        + " (pid " + app.pid + "): empty #" + numEmpty);
13669                                EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13670                                        app.processName, app.setAdj, "too many background");
13671                                app.killedBackground = true;
13672                                Process.killProcessQuiet(app.pid);
13673                            }
13674                        }
13675                    }
13676                }
13677                if (app.isolated && app.services.size() <= 0) {
13678                    // If this is an isolated process, and there are no
13679                    // services running in it, then the process is no longer
13680                    // needed.  We agressively kill these because we can by
13681                    // definition not re-use the same process again, and it is
13682                    // good to avoid having whatever code was running in them
13683                    // left sitting around after no longer needed.
13684                    Slog.i(TAG, "Isolated process " + app.processName
13685                            + " (pid " + app.pid + ") no longer needed");
13686                    EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13687                            app.processName, app.setAdj, "isolated not needed");
13688                    app.killedBackground = true;
13689                    Process.killProcessQuiet(app.pid);
13690                }
13691                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13692                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13693                        && !app.killedBackground) {
13694                    numTrimming++;
13695                }
13696            }
13697        }
13698
13699        mNumServiceProcs = mNewNumServiceProcs;
13700
13701        // Now determine the memory trimming level of background processes.
13702        // Unfortunately we need to start at the back of the list to do this
13703        // properly.  We only do this if the number of background apps we
13704        // are managing to keep around is less than half the maximum we desire;
13705        // if we are keeping a good number around, we'll let them use whatever
13706        // memory they want.
13707        if (numHidden <= ProcessList.TRIM_HIDDEN_APPS
13708                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
13709            final int numHiddenAndEmpty = numHidden + numEmpty;
13710            final int N = mLruProcesses.size();
13711            int factor = numTrimming/3;
13712            int minFactor = 2;
13713            if (mHomeProcess != null) minFactor++;
13714            if (mPreviousProcess != null) minFactor++;
13715            if (factor < minFactor) factor = minFactor;
13716            int step = 0;
13717            int fgTrimLevel;
13718            if (numHiddenAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
13719                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13720            } else if (numHiddenAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
13721                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13722            } else {
13723                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13724            }
13725            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13726            for (i=0; i<N; i++) {
13727                ProcessRecord app = mLruProcesses.get(i);
13728                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13729                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13730                        && !app.killedBackground) {
13731                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13732                        try {
13733                            app.thread.scheduleTrimMemory(curLevel);
13734                        } catch (RemoteException e) {
13735                        }
13736                        if (false) {
13737                            // For now we won't do this; our memory trimming seems
13738                            // to be good enough at this point that destroying
13739                            // activities causes more harm than good.
13740                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13741                                    && app != mHomeProcess && app != mPreviousProcess) {
13742                                // Need to do this on its own message because the stack may not
13743                                // be in a consistent state at this point.
13744                                // For these apps we will also finish their activities
13745                                // to help them free memory.
13746                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13747                            }
13748                        }
13749                    }
13750                    app.trimMemoryLevel = curLevel;
13751                    step++;
13752                    if (step >= factor) {
13753                        step = 0;
13754                        switch (curLevel) {
13755                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13756                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13757                                break;
13758                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13759                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13760                                break;
13761                        }
13762                    }
13763                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13764                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13765                            && app.thread != null) {
13766                        try {
13767                            app.thread.scheduleTrimMemory(
13768                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13769                        } catch (RemoteException e) {
13770                        }
13771                    }
13772                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13773                } else {
13774                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13775                            && app.pendingUiClean) {
13776                        // If this application is now in the background and it
13777                        // had done UI, then give it the special trim level to
13778                        // have it free UI resources.
13779                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13780                        if (app.trimMemoryLevel < level && app.thread != null) {
13781                            try {
13782                                app.thread.scheduleTrimMemory(level);
13783                            } catch (RemoteException e) {
13784                            }
13785                        }
13786                        app.pendingUiClean = false;
13787                    }
13788                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13789                        try {
13790                            app.thread.scheduleTrimMemory(fgTrimLevel);
13791                        } catch (RemoteException e) {
13792                        }
13793                    }
13794                    app.trimMemoryLevel = fgTrimLevel;
13795                }
13796            }
13797        } else {
13798            final int N = mLruProcesses.size();
13799            for (i=0; i<N; i++) {
13800                ProcessRecord app = mLruProcesses.get(i);
13801                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13802                        && app.pendingUiClean) {
13803                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13804                            && app.thread != null) {
13805                        try {
13806                            app.thread.scheduleTrimMemory(
13807                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13808                        } catch (RemoteException e) {
13809                        }
13810                    }
13811                    app.pendingUiClean = false;
13812                }
13813                app.trimMemoryLevel = 0;
13814            }
13815        }
13816
13817        if (mAlwaysFinishActivities) {
13818            // Need to do this on its own message because the stack may not
13819            // be in a consistent state at this point.
13820            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13821        }
13822    }
13823
13824    final void trimApplications() {
13825        synchronized (this) {
13826            int i;
13827
13828            // First remove any unused application processes whose package
13829            // has been removed.
13830            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13831                final ProcessRecord app = mRemovedProcesses.get(i);
13832                if (app.activities.size() == 0
13833                        && app.curReceiver == null && app.services.size() == 0) {
13834                    Slog.i(
13835                        TAG, "Exiting empty application process "
13836                        + app.processName + " ("
13837                        + (app.thread != null ? app.thread.asBinder() : null)
13838                        + ")\n");
13839                    if (app.pid > 0 && app.pid != MY_PID) {
13840                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13841                                app.processName, app.setAdj, "empty");
13842                        Process.killProcessQuiet(app.pid);
13843                    } else {
13844                        try {
13845                            app.thread.scheduleExit();
13846                        } catch (Exception e) {
13847                            // Ignore exceptions.
13848                        }
13849                    }
13850                    cleanUpApplicationRecordLocked(app, false, true, -1);
13851                    mRemovedProcesses.remove(i);
13852
13853                    if (app.persistent) {
13854                        if (app.persistent) {
13855                            addAppLocked(app.info, false);
13856                        }
13857                    }
13858                }
13859            }
13860
13861            // Now update the oom adj for all processes.
13862            updateOomAdjLocked();
13863        }
13864    }
13865
13866    /** This method sends the specified signal to each of the persistent apps */
13867    public void signalPersistentProcesses(int sig) throws RemoteException {
13868        if (sig != Process.SIGNAL_USR1) {
13869            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13870        }
13871
13872        synchronized (this) {
13873            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13874                    != PackageManager.PERMISSION_GRANTED) {
13875                throw new SecurityException("Requires permission "
13876                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13877            }
13878
13879            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13880                ProcessRecord r = mLruProcesses.get(i);
13881                if (r.thread != null && r.persistent) {
13882                    Process.sendSignal(r.pid, sig);
13883                }
13884            }
13885        }
13886    }
13887
13888    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13889        if (proc == null || proc == mProfileProc) {
13890            proc = mProfileProc;
13891            path = mProfileFile;
13892            profileType = mProfileType;
13893            clearProfilerLocked();
13894        }
13895        if (proc == null) {
13896            return;
13897        }
13898        try {
13899            proc.thread.profilerControl(false, path, null, profileType);
13900        } catch (RemoteException e) {
13901            throw new IllegalStateException("Process disappeared");
13902        }
13903    }
13904
13905    private void clearProfilerLocked() {
13906        if (mProfileFd != null) {
13907            try {
13908                mProfileFd.close();
13909            } catch (IOException e) {
13910            }
13911        }
13912        mProfileApp = null;
13913        mProfileProc = null;
13914        mProfileFile = null;
13915        mProfileType = 0;
13916        mAutoStopProfiler = false;
13917    }
13918
13919    public boolean profileControl(String process, int userId, boolean start,
13920            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13921
13922        try {
13923            synchronized (this) {
13924                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13925                // its own permission.
13926                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13927                        != PackageManager.PERMISSION_GRANTED) {
13928                    throw new SecurityException("Requires permission "
13929                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13930                }
13931
13932                if (start && fd == null) {
13933                    throw new IllegalArgumentException("null fd");
13934                }
13935
13936                ProcessRecord proc = null;
13937                if (process != null) {
13938                    proc = findProcessLocked(process, userId, "profileControl");
13939                }
13940
13941                if (start && (proc == null || proc.thread == null)) {
13942                    throw new IllegalArgumentException("Unknown process: " + process);
13943                }
13944
13945                if (start) {
13946                    stopProfilerLocked(null, null, 0);
13947                    setProfileApp(proc.info, proc.processName, path, fd, false);
13948                    mProfileProc = proc;
13949                    mProfileType = profileType;
13950                    try {
13951                        fd = fd.dup();
13952                    } catch (IOException e) {
13953                        fd = null;
13954                    }
13955                    proc.thread.profilerControl(start, path, fd, profileType);
13956                    fd = null;
13957                    mProfileFd = null;
13958                } else {
13959                    stopProfilerLocked(proc, path, profileType);
13960                    if (fd != null) {
13961                        try {
13962                            fd.close();
13963                        } catch (IOException e) {
13964                        }
13965                    }
13966                }
13967
13968                return true;
13969            }
13970        } catch (RemoteException e) {
13971            throw new IllegalStateException("Process disappeared");
13972        } finally {
13973            if (fd != null) {
13974                try {
13975                    fd.close();
13976                } catch (IOException e) {
13977                }
13978            }
13979        }
13980    }
13981
13982    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
13983        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13984                userId, true, true, callName, null);
13985        ProcessRecord proc = null;
13986        try {
13987            int pid = Integer.parseInt(process);
13988            synchronized (mPidsSelfLocked) {
13989                proc = mPidsSelfLocked.get(pid);
13990            }
13991        } catch (NumberFormatException e) {
13992        }
13993
13994        if (proc == null) {
13995            HashMap<String, SparseArray<ProcessRecord>> all
13996                    = mProcessNames.getMap();
13997            SparseArray<ProcessRecord> procs = all.get(process);
13998            if (procs != null && procs.size() > 0) {
13999                proc = procs.valueAt(0);
14000                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
14001                    for (int i=1; i<procs.size(); i++) {
14002                        ProcessRecord thisProc = procs.valueAt(i);
14003                        if (thisProc.userId == userId) {
14004                            proc = thisProc;
14005                            break;
14006                        }
14007                    }
14008                }
14009            }
14010        }
14011
14012        return proc;
14013    }
14014
14015    public boolean dumpHeap(String process, int userId, boolean managed,
14016            String path, ParcelFileDescriptor fd) throws RemoteException {
14017
14018        try {
14019            synchronized (this) {
14020                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14021                // its own permission (same as profileControl).
14022                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14023                        != PackageManager.PERMISSION_GRANTED) {
14024                    throw new SecurityException("Requires permission "
14025                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14026                }
14027
14028                if (fd == null) {
14029                    throw new IllegalArgumentException("null fd");
14030                }
14031
14032                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
14033                if (proc == null || proc.thread == null) {
14034                    throw new IllegalArgumentException("Unknown process: " + process);
14035                }
14036
14037                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14038                if (!isDebuggable) {
14039                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14040                        throw new SecurityException("Process not debuggable: " + proc);
14041                    }
14042                }
14043
14044                proc.thread.dumpHeap(managed, path, fd);
14045                fd = null;
14046                return true;
14047            }
14048        } catch (RemoteException e) {
14049            throw new IllegalStateException("Process disappeared");
14050        } finally {
14051            if (fd != null) {
14052                try {
14053                    fd.close();
14054                } catch (IOException e) {
14055                }
14056            }
14057        }
14058    }
14059
14060    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14061    public void monitor() {
14062        synchronized (this) { }
14063    }
14064
14065    void onCoreSettingsChange(Bundle settings) {
14066        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14067            ProcessRecord processRecord = mLruProcesses.get(i);
14068            try {
14069                if (processRecord.thread != null) {
14070                    processRecord.thread.setCoreSettings(settings);
14071                }
14072            } catch (RemoteException re) {
14073                /* ignore */
14074            }
14075        }
14076    }
14077
14078    // Multi-user methods
14079
14080    @Override
14081    public boolean switchUser(int userId) {
14082        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14083                != PackageManager.PERMISSION_GRANTED) {
14084            String msg = "Permission Denial: switchUser() from pid="
14085                    + Binder.getCallingPid()
14086                    + ", uid=" + Binder.getCallingUid()
14087                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14088            Slog.w(TAG, msg);
14089            throw new SecurityException(msg);
14090        }
14091
14092        final long ident = Binder.clearCallingIdentity();
14093        try {
14094            synchronized (this) {
14095                final int oldUserId = mCurrentUserId;
14096                if (oldUserId == userId) {
14097                    return true;
14098                }
14099
14100                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
14101                if (userInfo == null) {
14102                    Slog.w(TAG, "No user info for user #" + userId);
14103                    return false;
14104                }
14105
14106                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
14107                        R.anim.screen_user_enter);
14108
14109                // If the user we are switching to is not currently started, then
14110                // we need to start it now.
14111                if (mStartedUsers.get(userId) == null) {
14112                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
14113                    updateStartedUserArrayLocked();
14114                }
14115
14116                mCurrentUserId = userId;
14117                mCurrentUserArray = new int[] { userId };
14118                final Integer userIdInt = Integer.valueOf(userId);
14119                mUserLru.remove(userIdInt);
14120                mUserLru.add(userIdInt);
14121
14122                mWindowManager.setCurrentUser(userId);
14123
14124                // Once the internal notion of the active user has switched, we lock the device
14125                // with the option to show the user switcher on the keyguard.
14126                mWindowManager.lockNow(LockPatternUtils.USER_SWITCH_LOCK_OPTIONS);
14127
14128                final UserStartedState uss = mStartedUsers.get(userId);
14129
14130                // Make sure user is in the started state.  If it is currently
14131                // stopping, we need to knock that off.
14132                if (uss.mState == UserStartedState.STATE_STOPPING) {
14133                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
14134                    // so we can just fairly silently bring the user back from
14135                    // the almost-dead.
14136                    uss.mState = UserStartedState.STATE_RUNNING;
14137                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
14138                    // This means ACTION_SHUTDOWN has been sent, so we will
14139                    // need to treat this as a new boot of the user.
14140                    uss.mState = UserStartedState.STATE_BOOTING;
14141                }
14142
14143                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
14144                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14145                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
14146                        oldUserId, userId, uss));
14147                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
14148                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
14149                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14150                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14151                        | Intent.FLAG_RECEIVER_FOREGROUND);
14152                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14153                broadcastIntentLocked(null, null, intent,
14154                        null, null, 0, null, null, null,
14155                        false, false, MY_PID, Process.SYSTEM_UID, userId);
14156
14157                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
14158                    if (userId != 0) {
14159                        intent = new Intent(Intent.ACTION_USER_INITIALIZE);
14160                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14161                        broadcastIntentLocked(null, null, intent, null,
14162                                new IIntentReceiver.Stub() {
14163                                    public void performReceive(Intent intent, int resultCode,
14164                                            String data, Bundle extras, boolean ordered,
14165                                            boolean sticky, int sendingUser) {
14166                                        userInitialized(uss);
14167                                    }
14168                                }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
14169                                userId);
14170                        uss.initializing = true;
14171                    } else {
14172                        getUserManagerLocked().makeInitialized(userInfo.id);
14173                    }
14174                }
14175
14176                boolean haveActivities = mMainStack.switchUserLocked(userId, uss);
14177                if (!haveActivities) {
14178                    startHomeActivityLocked(userId);
14179                }
14180
14181                getUserManagerLocked().userForeground(userId);
14182                sendUserSwitchBroadcastsLocked(oldUserId, userId);
14183            }
14184        } finally {
14185            Binder.restoreCallingIdentity(ident);
14186        }
14187
14188        return true;
14189    }
14190
14191    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
14192        long ident = Binder.clearCallingIdentity();
14193        try {
14194            Intent intent;
14195            if (oldUserId >= 0) {
14196                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
14197                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14198                        | Intent.FLAG_RECEIVER_FOREGROUND);
14199                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
14200                broadcastIntentLocked(null, null, intent,
14201                        null, null, 0, null, null, null,
14202                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
14203            }
14204            if (newUserId >= 0) {
14205                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
14206                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14207                        | Intent.FLAG_RECEIVER_FOREGROUND);
14208                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14209                broadcastIntentLocked(null, null, intent,
14210                        null, null, 0, null, null, null,
14211                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
14212                intent = new Intent(Intent.ACTION_USER_SWITCHED);
14213                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14214                        | Intent.FLAG_RECEIVER_FOREGROUND);
14215                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14216                broadcastIntentLocked(null, null, intent,
14217                        null, null, 0, null, null,
14218                        android.Manifest.permission.MANAGE_USERS,
14219                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14220                intent = new Intent(Intent.ACTION_USER_STARTING);
14221                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14222                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14223                broadcastIntentLocked(null, null, intent,
14224                        null, new IIntentReceiver.Stub() {
14225                            @Override
14226                            public void performReceive(Intent intent, int resultCode, String data,
14227                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14228                                    throws RemoteException {
14229                            }
14230                        }, 0, null, null,
14231                        android.Manifest.permission.INTERACT_ACROSS_USERS,
14232                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14233            }
14234        } finally {
14235            Binder.restoreCallingIdentity(ident);
14236        }
14237    }
14238
14239    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
14240            final int newUserId) {
14241        final int N = mUserSwitchObservers.beginBroadcast();
14242        if (N > 0) {
14243            final IRemoteCallback callback = new IRemoteCallback.Stub() {
14244                int mCount = 0;
14245                @Override
14246                public void sendResult(Bundle data) throws RemoteException {
14247                    synchronized (ActivityManagerService.this) {
14248                        if (mCurUserSwitchCallback == this) {
14249                            mCount++;
14250                            if (mCount == N) {
14251                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14252                            }
14253                        }
14254                    }
14255                }
14256            };
14257            synchronized (this) {
14258                uss.switching = true;
14259                mCurUserSwitchCallback = callback;
14260            }
14261            for (int i=0; i<N; i++) {
14262                try {
14263                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
14264                            newUserId, callback);
14265                } catch (RemoteException e) {
14266                }
14267            }
14268        } else {
14269            synchronized (this) {
14270                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14271            }
14272        }
14273        mUserSwitchObservers.finishBroadcast();
14274    }
14275
14276    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14277        synchronized (this) {
14278            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
14279            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14280        }
14281    }
14282
14283    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
14284        mCurUserSwitchCallback = null;
14285        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14286        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
14287                oldUserId, newUserId, uss));
14288    }
14289
14290    void userInitialized(UserStartedState uss) {
14291        synchronized (ActivityManagerService.this) {
14292            getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
14293            uss.initializing = false;
14294            completeSwitchAndInitalizeLocked(uss);
14295        }
14296    }
14297
14298    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14299        final int N = mUserSwitchObservers.beginBroadcast();
14300        for (int i=0; i<N; i++) {
14301            try {
14302                mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
14303            } catch (RemoteException e) {
14304            }
14305        }
14306        mUserSwitchObservers.finishBroadcast();
14307        synchronized (this) {
14308            uss.switching = false;
14309            completeSwitchAndInitalizeLocked(uss);
14310        }
14311    }
14312
14313    void completeSwitchAndInitalizeLocked(UserStartedState uss) {
14314        if (!uss.switching && !uss.initializing) {
14315            mWindowManager.stopFreezingScreen();
14316        }
14317    }
14318
14319    void finishUserSwitch(UserStartedState uss) {
14320        synchronized (this) {
14321            if ((uss.mState == UserStartedState.STATE_BOOTING
14322                    || uss.mState == UserStartedState.STATE_SHUTDOWN)
14323                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
14324                uss.mState = UserStartedState.STATE_RUNNING;
14325                final int userId = uss.mHandle.getIdentifier();
14326                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
14327                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14328                broadcastIntentLocked(null, null, intent,
14329                        null, null, 0, null, null,
14330                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
14331                        false, false, MY_PID, Process.SYSTEM_UID, userId);
14332            }
14333            int num = mUserLru.size();
14334            int i = 0;
14335            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
14336                Integer oldUserId = mUserLru.get(i);
14337                UserStartedState oldUss = mStartedUsers.get(oldUserId);
14338                if (oldUss == null) {
14339                    // Shouldn't happen, but be sane if it does.
14340                    mUserLru.remove(i);
14341                    num--;
14342                    continue;
14343                }
14344                if (oldUss.mState == UserStartedState.STATE_STOPPING
14345                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
14346                    // This user is already stopping, doesn't count.
14347                    num--;
14348                    i++;
14349                    continue;
14350                }
14351                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
14352                    // Owner and current can't be stopped, but count as running.
14353                    i++;
14354                    continue;
14355                }
14356                // This is a user to be stopped.
14357                stopUserLocked(oldUserId, null);
14358                num--;
14359                i++;
14360            }
14361        }
14362    }
14363
14364    @Override
14365    public int stopUser(final int userId, final IStopUserCallback callback) {
14366        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14367                != PackageManager.PERMISSION_GRANTED) {
14368            String msg = "Permission Denial: switchUser() from pid="
14369                    + Binder.getCallingPid()
14370                    + ", uid=" + Binder.getCallingUid()
14371                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14372            Slog.w(TAG, msg);
14373            throw new SecurityException(msg);
14374        }
14375        if (userId <= 0) {
14376            throw new IllegalArgumentException("Can't stop primary user " + userId);
14377        }
14378        synchronized (this) {
14379            return stopUserLocked(userId, callback);
14380        }
14381    }
14382
14383    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
14384        if (mCurrentUserId == userId) {
14385            return ActivityManager.USER_OP_IS_CURRENT;
14386        }
14387
14388        final UserStartedState uss = mStartedUsers.get(userId);
14389        if (uss == null) {
14390            // User is not started, nothing to do...  but we do need to
14391            // callback if requested.
14392            if (callback != null) {
14393                mHandler.post(new Runnable() {
14394                    @Override
14395                    public void run() {
14396                        try {
14397                            callback.userStopped(userId);
14398                        } catch (RemoteException e) {
14399                        }
14400                    }
14401                });
14402            }
14403            return ActivityManager.USER_OP_SUCCESS;
14404        }
14405
14406        if (callback != null) {
14407            uss.mStopCallbacks.add(callback);
14408        }
14409
14410        if (uss.mState != UserStartedState.STATE_STOPPING
14411                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14412            uss.mState = UserStartedState.STATE_STOPPING;
14413
14414            long ident = Binder.clearCallingIdentity();
14415            try {
14416                // We are going to broadcast ACTION_USER_STOPPING and then
14417                // once that is down send a final ACTION_SHUTDOWN and then
14418                // stop the user.
14419                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
14420                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14421                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14422                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
14423                // This is the result receiver for the final shutdown broadcast.
14424                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
14425                    @Override
14426                    public void performReceive(Intent intent, int resultCode, String data,
14427                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14428                        finishUserStop(uss);
14429                    }
14430                };
14431                // This is the result receiver for the initial stopping broadcast.
14432                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
14433                    @Override
14434                    public void performReceive(Intent intent, int resultCode, String data,
14435                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14436                        // On to the next.
14437                        synchronized (ActivityManagerService.this) {
14438                            if (uss.mState != UserStartedState.STATE_STOPPING) {
14439                                // Whoops, we are being started back up.  Abort, abort!
14440                                return;
14441                            }
14442                            uss.mState = UserStartedState.STATE_SHUTDOWN;
14443                        }
14444                        broadcastIntentLocked(null, null, shutdownIntent,
14445                                null, shutdownReceiver, 0, null, null, null,
14446                                true, false, MY_PID, Process.SYSTEM_UID, userId);
14447                    }
14448                };
14449                // Kick things off.
14450                broadcastIntentLocked(null, null, stoppingIntent,
14451                        null, stoppingReceiver, 0, null, null,
14452                        android.Manifest.permission.INTERACT_ACROSS_USERS,
14453                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14454            } finally {
14455                Binder.restoreCallingIdentity(ident);
14456            }
14457        }
14458
14459        return ActivityManager.USER_OP_SUCCESS;
14460    }
14461
14462    void finishUserStop(UserStartedState uss) {
14463        final int userId = uss.mHandle.getIdentifier();
14464        boolean stopped;
14465        ArrayList<IStopUserCallback> callbacks;
14466        synchronized (this) {
14467            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
14468            if (mStartedUsers.get(userId) != uss) {
14469                stopped = false;
14470            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
14471                stopped = false;
14472            } else {
14473                stopped = true;
14474                // User can no longer run.
14475                mStartedUsers.remove(userId);
14476                mUserLru.remove(Integer.valueOf(userId));
14477                updateStartedUserArrayLocked();
14478
14479                // Clean up all state and processes associated with the user.
14480                // Kill all the processes for the user.
14481                forceStopUserLocked(userId);
14482            }
14483        }
14484
14485        for (int i=0; i<callbacks.size(); i++) {
14486            try {
14487                if (stopped) callbacks.get(i).userStopped(userId);
14488                else callbacks.get(i).userStopAborted(userId);
14489            } catch (RemoteException e) {
14490            }
14491        }
14492    }
14493
14494    @Override
14495    public UserInfo getCurrentUser() {
14496        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14497                != PackageManager.PERMISSION_GRANTED) && (
14498                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14499                != PackageManager.PERMISSION_GRANTED)) {
14500            String msg = "Permission Denial: getCurrentUser() from pid="
14501                    + Binder.getCallingPid()
14502                    + ", uid=" + Binder.getCallingUid()
14503                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14504            Slog.w(TAG, msg);
14505            throw new SecurityException(msg);
14506        }
14507        synchronized (this) {
14508            return getUserManagerLocked().getUserInfo(mCurrentUserId);
14509        }
14510    }
14511
14512    int getCurrentUserIdLocked() {
14513        return mCurrentUserId;
14514    }
14515
14516    @Override
14517    public boolean isUserRunning(int userId) {
14518        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14519                != PackageManager.PERMISSION_GRANTED) {
14520            String msg = "Permission Denial: isUserRunning() from pid="
14521                    + Binder.getCallingPid()
14522                    + ", uid=" + Binder.getCallingUid()
14523                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14524            Slog.w(TAG, msg);
14525            throw new SecurityException(msg);
14526        }
14527        synchronized (this) {
14528            return isUserRunningLocked(userId);
14529        }
14530    }
14531
14532    boolean isUserRunningLocked(int userId) {
14533        UserStartedState state = mStartedUsers.get(userId);
14534        return state != null && state.mState != UserStartedState.STATE_STOPPING
14535                && state.mState != UserStartedState.STATE_SHUTDOWN;
14536    }
14537
14538    @Override
14539    public int[] getRunningUserIds() {
14540        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14541                != PackageManager.PERMISSION_GRANTED) {
14542            String msg = "Permission Denial: isUserRunning() from pid="
14543                    + Binder.getCallingPid()
14544                    + ", uid=" + Binder.getCallingUid()
14545                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14546            Slog.w(TAG, msg);
14547            throw new SecurityException(msg);
14548        }
14549        synchronized (this) {
14550            return mStartedUserArray;
14551        }
14552    }
14553
14554    private void updateStartedUserArrayLocked() {
14555        mStartedUserArray = new int[mStartedUsers.size()];
14556        for (int i=0; i<mStartedUsers.size();  i++) {
14557            mStartedUserArray[i] = mStartedUsers.keyAt(i);
14558        }
14559    }
14560
14561    @Override
14562    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
14563        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14564                != PackageManager.PERMISSION_GRANTED) {
14565            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
14566                    + Binder.getCallingPid()
14567                    + ", uid=" + Binder.getCallingUid()
14568                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14569            Slog.w(TAG, msg);
14570            throw new SecurityException(msg);
14571        }
14572
14573        mUserSwitchObservers.register(observer);
14574    }
14575
14576    @Override
14577    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
14578        mUserSwitchObservers.unregister(observer);
14579    }
14580
14581    private boolean userExists(int userId) {
14582        if (userId == 0) {
14583            return true;
14584        }
14585        UserManagerService ums = getUserManagerLocked();
14586        return ums != null ? (ums.getUserInfo(userId) != null) : false;
14587    }
14588
14589    int[] getUsersLocked() {
14590        UserManagerService ums = getUserManagerLocked();
14591        return ums != null ? ums.getUserIds() : new int[] { 0 };
14592    }
14593
14594    UserManagerService getUserManagerLocked() {
14595        if (mUserManager == null) {
14596            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
14597            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
14598        }
14599        return mUserManager;
14600    }
14601
14602    private void checkValidCaller(int uid, int userId) {
14603        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
14604
14605        throw new SecurityException("Caller uid=" + uid
14606                + " is not privileged to communicate with user=" + userId);
14607    }
14608
14609    private int applyUserId(int uid, int userId) {
14610        return UserHandle.getUid(userId, uid);
14611    }
14612
14613    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
14614        if (info == null) return null;
14615        ApplicationInfo newInfo = new ApplicationInfo(info);
14616        newInfo.uid = applyUserId(info.uid, userId);
14617        newInfo.dataDir = USER_DATA_DIR + userId + "/"
14618                + info.packageName;
14619        return newInfo;
14620    }
14621
14622    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
14623        if (aInfo == null
14624                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
14625            return aInfo;
14626        }
14627
14628        ActivityInfo info = new ActivityInfo(aInfo);
14629        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
14630        return info;
14631    }
14632}
14633