ActivityManagerService.java revision 15491c6a728131e322c45bc440500a8a78e4a410
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20
21import com.android.internal.R;
22import com.android.internal.os.BatteryStatsImpl;
23import com.android.internal.os.ProcessStats;
24import com.android.server.AttributeCache;
25import com.android.server.IntentResolver;
26import com.android.server.ProcessMap;
27import com.android.server.SystemServer;
28import com.android.server.Watchdog;
29import com.android.server.am.ActivityStack.ActivityState;
30import com.android.server.pm.UserManagerService;
31import com.android.server.wm.WindowManagerService;
32
33import dalvik.system.Zygote;
34
35import android.app.Activity;
36import android.app.ActivityManager;
37import android.app.ActivityManagerNative;
38import android.app.ActivityOptions;
39import android.app.ActivityThread;
40import android.app.AlertDialog;
41import android.app.AppGlobals;
42import android.app.ApplicationErrorReport;
43import android.app.Dialog;
44import android.app.IActivityController;
45import android.app.IApplicationThread;
46import android.app.IInstrumentationWatcher;
47import android.app.INotificationManager;
48import android.app.IProcessObserver;
49import android.app.IServiceConnection;
50import android.app.IStopUserCallback;
51import android.app.IThumbnailReceiver;
52import android.app.IUserSwitchObserver;
53import android.app.Instrumentation;
54import android.app.Notification;
55import android.app.NotificationManager;
56import android.app.PendingIntent;
57import android.app.backup.IBackupManager;
58import android.content.ActivityNotFoundException;
59import android.content.BroadcastReceiver;
60import android.content.ClipData;
61import android.content.ComponentCallbacks2;
62import android.content.ComponentName;
63import android.content.ContentProvider;
64import android.content.ContentResolver;
65import android.content.Context;
66import android.content.DialogInterface;
67import android.content.IContentProvider;
68import android.content.IIntentReceiver;
69import android.content.IIntentSender;
70import android.content.Intent;
71import android.content.IntentFilter;
72import android.content.IntentSender;
73import android.content.pm.ActivityInfo;
74import android.content.pm.ApplicationInfo;
75import android.content.pm.ConfigurationInfo;
76import android.content.pm.IPackageDataObserver;
77import android.content.pm.IPackageManager;
78import android.content.pm.InstrumentationInfo;
79import android.content.pm.PackageInfo;
80import android.content.pm.PackageManager;
81import android.content.pm.UserInfo;
82import android.content.pm.PackageManager.NameNotFoundException;
83import android.content.pm.PathPermission;
84import android.content.pm.ProviderInfo;
85import android.content.pm.ResolveInfo;
86import android.content.pm.ServiceInfo;
87import android.content.res.CompatibilityInfo;
88import android.content.res.Configuration;
89import android.graphics.Bitmap;
90import android.net.Proxy;
91import android.net.ProxyProperties;
92import android.net.Uri;
93import android.os.Binder;
94import android.os.Build;
95import android.os.Bundle;
96import android.os.Debug;
97import android.os.DropBoxManager;
98import android.os.Environment;
99import android.os.FileObserver;
100import android.os.FileUtils;
101import android.os.Handler;
102import android.os.IBinder;
103import android.os.IPermissionController;
104import android.os.IRemoteCallback;
105import android.os.IUserManager;
106import android.os.Looper;
107import android.os.Message;
108import android.os.Parcel;
109import android.os.ParcelFileDescriptor;
110import android.os.Process;
111import android.os.RemoteCallbackList;
112import android.os.RemoteException;
113import android.os.SELinux;
114import android.os.ServiceManager;
115import android.os.StrictMode;
116import android.os.SystemClock;
117import android.os.SystemProperties;
118import android.os.UserHandle;
119import android.provider.Settings;
120import android.text.format.Time;
121import android.util.EventLog;
122import android.util.Log;
123import android.util.Pair;
124import android.util.PrintWriterPrinter;
125import android.util.Slog;
126import android.util.SparseArray;
127import android.util.TimeUtils;
128import android.view.Gravity;
129import android.view.LayoutInflater;
130import android.view.View;
131import android.view.WindowManager;
132import android.view.WindowManagerPolicy;
133
134import java.io.BufferedInputStream;
135import java.io.BufferedOutputStream;
136import java.io.BufferedReader;
137import java.io.DataInputStream;
138import java.io.DataOutputStream;
139import java.io.File;
140import java.io.FileDescriptor;
141import java.io.FileInputStream;
142import java.io.FileNotFoundException;
143import java.io.FileOutputStream;
144import java.io.IOException;
145import java.io.InputStreamReader;
146import java.io.PrintWriter;
147import java.io.StringWriter;
148import java.lang.ref.WeakReference;
149import java.util.ArrayList;
150import java.util.Collections;
151import java.util.Comparator;
152import java.util.HashMap;
153import java.util.HashSet;
154import java.util.Iterator;
155import java.util.List;
156import java.util.Locale;
157import java.util.Map;
158import java.util.Set;
159import java.util.concurrent.atomic.AtomicBoolean;
160import java.util.concurrent.atomic.AtomicLong;
161
162public final class ActivityManagerService extends ActivityManagerNative
163        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
164    private static final String USER_DATA_DIR = "/data/user/";
165    static final String TAG = "ActivityManager";
166    static final String TAG_MU = "ActivityManagerServiceMU";
167    static final boolean DEBUG = false;
168    static final boolean localLOGV = DEBUG;
169    static final boolean DEBUG_SWITCH = localLOGV || false;
170    static final boolean DEBUG_TASKS = localLOGV || false;
171    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
172    static final boolean DEBUG_PAUSE = localLOGV || false;
173    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
174    static final boolean DEBUG_TRANSITION = localLOGV || false;
175    static final boolean DEBUG_BROADCAST = localLOGV || false;
176    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
177    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
178    static final boolean DEBUG_SERVICE = localLOGV || false;
179    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
180    static final boolean DEBUG_VISBILITY = localLOGV || false;
181    static final boolean DEBUG_PROCESSES = localLOGV || false;
182    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
183    static final boolean DEBUG_PROVIDER = localLOGV || false;
184    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
185    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
186    static final boolean DEBUG_RESULTS = localLOGV || false;
187    static final boolean DEBUG_BACKUP = localLOGV || false;
188    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
189    static final boolean DEBUG_POWER = localLOGV || false;
190    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
191    static final boolean DEBUG_MU = localLOGV || false;
192    static final boolean VALIDATE_TOKENS = false;
193    static final boolean SHOW_ACTIVITY_START_TIME = true;
194
195    // Control over CPU and battery monitoring.
196    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
197    static final boolean MONITOR_CPU_USAGE = true;
198    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
199    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
200    static final boolean MONITOR_THREAD_CPU_USAGE = false;
201
202    // The flags that are set for all calls we make to the package manager.
203    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
204
205    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
206
207    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
208
209    // Maximum number of recent tasks that we can remember.
210    static final int MAX_RECENT_TASKS = 20;
211
212    // Amount of time after a call to stopAppSwitches() during which we will
213    // prevent further untrusted switches from happening.
214    static final long APP_SWITCH_DELAY_TIME = 5*1000;
215
216    // How long we wait for a launched process to attach to the activity manager
217    // before we decide it's never going to come up for real.
218    static final int PROC_START_TIMEOUT = 10*1000;
219
220    // How long we wait for a launched process to attach to the activity manager
221    // before we decide it's never going to come up for real, when the process was
222    // started with a wrapper for instrumentation (such as Valgrind) because it
223    // could take much longer than usual.
224    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
225
226    // How long to wait after going idle before forcing apps to GC.
227    static final int GC_TIMEOUT = 5*1000;
228
229    // The minimum amount of time between successive GC requests for a process.
230    static final int GC_MIN_INTERVAL = 60*1000;
231
232    // The rate at which we check for apps using excessive power -- 15 mins.
233    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
234
235    // The minimum sample duration we will allow before deciding we have
236    // enough data on wake locks to start killing things.
237    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
238
239    // The minimum sample duration we will allow before deciding we have
240    // enough data on CPU usage to start killing things.
241    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
242
243    // How long we allow a receiver to run before giving up on it.
244    static final int BROADCAST_FG_TIMEOUT = 10*1000;
245    static final int BROADCAST_BG_TIMEOUT = 60*1000;
246
247    // How long we wait until we timeout on key dispatching.
248    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
249
250    // How long we wait until we timeout on key dispatching during instrumentation.
251    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
252
253    // Amount of time we wait for observers to handle a user switch before
254    // giving up on them and unfreezing the screen.
255    static final int USER_SWITCH_TIMEOUT = 2*1000;
256
257    static final int MY_PID = Process.myPid();
258
259    static final String[] EMPTY_STRING_ARRAY = new String[0];
260
261    public ActivityStack mMainStack;
262
263    private final boolean mHeadless;
264
265    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
266    // default actuion automatically.  Important for devices without direct input
267    // devices.
268    private boolean mShowDialogs = true;
269
270    /**
271     * Description of a request to start a new activity, which has been held
272     * due to app switches being disabled.
273     */
274    static class PendingActivityLaunch {
275        ActivityRecord r;
276        ActivityRecord sourceRecord;
277        int startFlags;
278    }
279
280    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
281            = new ArrayList<PendingActivityLaunch>();
282
283
284    BroadcastQueue mFgBroadcastQueue;
285    BroadcastQueue mBgBroadcastQueue;
286    // Convenient for easy iteration over the queues. Foreground is first
287    // so that dispatch of foreground broadcasts gets precedence.
288    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
289
290    BroadcastQueue broadcastQueueForIntent(Intent intent) {
291        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
292        if (DEBUG_BACKGROUND_BROADCAST) {
293            Slog.i(TAG, "Broadcast intent " + intent + " on "
294                    + (isFg ? "foreground" : "background")
295                    + " queue");
296        }
297        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
298    }
299
300    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
301        for (BroadcastQueue queue : mBroadcastQueues) {
302            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
303            if (r != null) {
304                return r;
305            }
306        }
307        return null;
308    }
309
310    /**
311     * Activity we have told the window manager to have key focus.
312     */
313    ActivityRecord mFocusedActivity = null;
314    /**
315     * List of intents that were used to start the most recent tasks.
316     */
317    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
318
319    /**
320     * Process management.
321     */
322    final ProcessList mProcessList = new ProcessList();
323
324    /**
325     * All of the applications we currently have running organized by name.
326     * The keys are strings of the application package name (as
327     * returned by the package manager), and the keys are ApplicationRecord
328     * objects.
329     */
330    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
331
332    /**
333     * The currently running isolated processes.
334     */
335    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
336
337    /**
338     * Counter for assigning isolated process uids, to avoid frequently reusing the
339     * same ones.
340     */
341    int mNextIsolatedProcessUid = 0;
342
343    /**
344     * The currently running heavy-weight process, if any.
345     */
346    ProcessRecord mHeavyWeightProcess = null;
347
348    /**
349     * The last time that various processes have crashed.
350     */
351    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
352
353    /**
354     * Set of applications that we consider to be bad, and will reject
355     * incoming broadcasts from (which the user has no control over).
356     * Processes are added to this set when they have crashed twice within
357     * a minimum amount of time; they are removed from it when they are
358     * later restarted (hopefully due to some user action).  The value is the
359     * time it was added to the list.
360     */
361    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
362
363    /**
364     * All of the processes we currently have running organized by pid.
365     * The keys are the pid running the application.
366     *
367     * <p>NOTE: This object is protected by its own lock, NOT the global
368     * activity manager lock!
369     */
370    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
371
372    /**
373     * All of the processes that have been forced to be foreground.  The key
374     * is the pid of the caller who requested it (we hold a death
375     * link on it).
376     */
377    abstract class ForegroundToken implements IBinder.DeathRecipient {
378        int pid;
379        IBinder token;
380    }
381    final SparseArray<ForegroundToken> mForegroundProcesses
382            = new SparseArray<ForegroundToken>();
383
384    /**
385     * List of records for processes that someone had tried to start before the
386     * system was ready.  We don't start them at that point, but ensure they
387     * are started by the time booting is complete.
388     */
389    final ArrayList<ProcessRecord> mProcessesOnHold
390            = new ArrayList<ProcessRecord>();
391
392    /**
393     * List of persistent applications that are in the process
394     * of being started.
395     */
396    final ArrayList<ProcessRecord> mPersistentStartingProcesses
397            = new ArrayList<ProcessRecord>();
398
399    /**
400     * Processes that are being forcibly torn down.
401     */
402    final ArrayList<ProcessRecord> mRemovedProcesses
403            = new ArrayList<ProcessRecord>();
404
405    /**
406     * List of running applications, sorted by recent usage.
407     * The first entry in the list is the least recently used.
408     * It contains ApplicationRecord objects.  This list does NOT include
409     * any persistent application records (since we never want to exit them).
410     */
411    final ArrayList<ProcessRecord> mLruProcesses
412            = new ArrayList<ProcessRecord>();
413
414    /**
415     * List of processes that should gc as soon as things are idle.
416     */
417    final ArrayList<ProcessRecord> mProcessesToGc
418            = new ArrayList<ProcessRecord>();
419
420    /**
421     * This is the process holding what we currently consider to be
422     * the "home" activity.
423     */
424    ProcessRecord mHomeProcess;
425
426    /**
427     * This is the process holding the activity the user last visited that
428     * is in a different process from the one they are currently in.
429     */
430    ProcessRecord mPreviousProcess;
431
432    /**
433     * The time at which the previous process was last visible.
434     */
435    long mPreviousProcessVisibleTime;
436
437    /**
438     * Which uses have been started, so are allowed to run code.
439     */
440    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
441
442    /**
443     * LRU list of history of current users.  Most recently current is at the end.
444     */
445    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
446
447    /**
448     * Registered observers of the user switching mechanics.
449     */
450    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
451            = new RemoteCallbackList<IUserSwitchObserver>();
452
453    /**
454     * Currently active user switch.
455     */
456    Object mCurUserSwitchCallback;
457
458    /**
459     * Packages that the user has asked to have run in screen size
460     * compatibility mode instead of filling the screen.
461     */
462    final CompatModePackages mCompatModePackages;
463
464    /**
465     * Set of PendingResultRecord objects that are currently active.
466     */
467    final HashSet mPendingResultRecords = new HashSet();
468
469    /**
470     * Set of IntentSenderRecord objects that are currently active.
471     */
472    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
473            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
474
475    /**
476     * Fingerprints (hashCode()) of stack traces that we've
477     * already logged DropBox entries for.  Guarded by itself.  If
478     * something (rogue user app) forces this over
479     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
480     */
481    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
482    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
483
484    /**
485     * Strict Mode background batched logging state.
486     *
487     * The string buffer is guarded by itself, and its lock is also
488     * used to determine if another batched write is already
489     * in-flight.
490     */
491    private final StringBuilder mStrictModeBuffer = new StringBuilder();
492
493    /**
494     * Keeps track of all IIntentReceivers that have been registered for
495     * broadcasts.  Hash keys are the receiver IBinder, hash value is
496     * a ReceiverList.
497     */
498    final HashMap mRegisteredReceivers = new HashMap();
499
500    /**
501     * Resolver for broadcast intents to registered receivers.
502     * Holds BroadcastFilter (subclass of IntentFilter).
503     */
504    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
505            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
506        @Override
507        protected boolean allowFilterResult(
508                BroadcastFilter filter, List<BroadcastFilter> dest) {
509            IBinder target = filter.receiverList.receiver.asBinder();
510            for (int i=dest.size()-1; i>=0; i--) {
511                if (dest.get(i).receiverList.receiver.asBinder() == target) {
512                    return false;
513                }
514            }
515            return true;
516        }
517
518        @Override
519        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
520            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
521                    || userId == filter.owningUserId) {
522                return super.newResult(filter, match, userId);
523            }
524            return null;
525        }
526
527        @Override
528        protected BroadcastFilter[] newArray(int size) {
529            return new BroadcastFilter[size];
530        }
531
532        @Override
533        protected String packageForFilter(BroadcastFilter filter) {
534            return filter.packageName;
535        }
536    };
537
538    /**
539     * State of all active sticky broadcasts per user.  Keys are the action of the
540     * sticky Intent, values are an ArrayList of all broadcasted intents with
541     * that action (which should usually be one).  The SparseArray is keyed
542     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
543     * for stickies that are sent to all users.
544     */
545    final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts =
546            new SparseArray<HashMap<String, ArrayList<Intent>>>();
547
548    final ActiveServices mServices;
549
550    /**
551     * Backup/restore process management
552     */
553    String mBackupAppName = null;
554    BackupRecord mBackupTarget = null;
555
556    /**
557     * List of PendingThumbnailsRecord objects of clients who are still
558     * waiting to receive all of the thumbnails for a task.
559     */
560    final ArrayList mPendingThumbnails = new ArrayList();
561
562    /**
563     * List of HistoryRecord objects that have been finished and must
564     * still report back to a pending thumbnail receiver.
565     */
566    final ArrayList mCancelledThumbnails = new ArrayList();
567
568    final ProviderMap mProviderMap;
569
570    /**
571     * List of content providers who have clients waiting for them.  The
572     * application is currently being launched and the provider will be
573     * removed from this list once it is published.
574     */
575    final ArrayList<ContentProviderRecord> mLaunchingProviders
576            = new ArrayList<ContentProviderRecord>();
577
578    /**
579     * Global set of specific Uri permissions that have been granted.
580     */
581    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
582            = new SparseArray<HashMap<Uri, UriPermission>>();
583
584    CoreSettingsObserver mCoreSettingsObserver;
585
586    /**
587     * Thread-local storage used to carry caller permissions over through
588     * indirect content-provider access.
589     * @see #ActivityManagerService.openContentUri()
590     */
591    private class Identity {
592        public int pid;
593        public int uid;
594
595        Identity(int _pid, int _uid) {
596            pid = _pid;
597            uid = _uid;
598        }
599    }
600
601    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
602
603    /**
604     * All information we have collected about the runtime performance of
605     * any user id that can impact battery performance.
606     */
607    final BatteryStatsService mBatteryStatsService;
608
609    /**
610     * information about component usage
611     */
612    final UsageStatsService mUsageStatsService;
613
614    /**
615     * Current configuration information.  HistoryRecord objects are given
616     * a reference to this object to indicate which configuration they are
617     * currently running in, so this object must be kept immutable.
618     */
619    Configuration mConfiguration = new Configuration();
620
621    /**
622     * Current sequencing integer of the configuration, for skipping old
623     * configurations.
624     */
625    int mConfigurationSeq = 0;
626
627    /**
628     * Hardware-reported OpenGLES version.
629     */
630    final int GL_ES_VERSION;
631
632    /**
633     * List of initialization arguments to pass to all processes when binding applications to them.
634     * For example, references to the commonly used services.
635     */
636    HashMap<String, IBinder> mAppBindArgs;
637
638    /**
639     * Temporary to avoid allocations.  Protected by main lock.
640     */
641    final StringBuilder mStringBuilder = new StringBuilder(256);
642
643    /**
644     * Used to control how we initialize the service.
645     */
646    boolean mStartRunning = false;
647    ComponentName mTopComponent;
648    String mTopAction;
649    String mTopData;
650    boolean mProcessesReady = false;
651    boolean mSystemReady = false;
652    boolean mBooting = false;
653    boolean mWaitingUpdate = false;
654    boolean mDidUpdate = false;
655    boolean mOnBattery = false;
656    boolean mLaunchWarningShown = false;
657
658    Context mContext;
659
660    int mFactoryTest;
661
662    boolean mCheckedForSetup;
663
664    /**
665     * The time at which we will allow normal application switches again,
666     * after a call to {@link #stopAppSwitches()}.
667     */
668    long mAppSwitchesAllowedTime;
669
670    /**
671     * This is set to true after the first switch after mAppSwitchesAllowedTime
672     * is set; any switches after that will clear the time.
673     */
674    boolean mDidAppSwitch;
675
676    /**
677     * Last time (in realtime) at which we checked for power usage.
678     */
679    long mLastPowerCheckRealtime;
680
681    /**
682     * Last time (in uptime) at which we checked for power usage.
683     */
684    long mLastPowerCheckUptime;
685
686    /**
687     * Set while we are wanting to sleep, to prevent any
688     * activities from being started/resumed.
689     */
690    boolean mSleeping = false;
691
692    /**
693     * State of external calls telling us if the device is asleep.
694     */
695    boolean mWentToSleep = false;
696
697    /**
698     * State of external call telling us if the lock screen is shown.
699     */
700    boolean mLockScreenShown = false;
701
702    /**
703     * Set if we are shutting down the system, similar to sleeping.
704     */
705    boolean mShuttingDown = false;
706
707    /**
708     * Task identifier that activities are currently being started
709     * in.  Incremented each time a new task is created.
710     * todo: Replace this with a TokenSpace class that generates non-repeating
711     * integers that won't wrap.
712     */
713    int mCurTask = 1;
714
715    /**
716     * Current sequence id for oom_adj computation traversal.
717     */
718    int mAdjSeq = 0;
719
720    /**
721     * Current sequence id for process LRU updating.
722     */
723    int mLruSeq = 0;
724
725    /**
726     * Keep track of the non-hidden/empty process we last found, to help
727     * determine how to distribute hidden/empty processes next time.
728     */
729    int mNumNonHiddenProcs = 0;
730
731    /**
732     * Keep track of the number of hidden procs, to balance oom adj
733     * distribution between those and empty procs.
734     */
735    int mNumHiddenProcs = 0;
736
737    /**
738     * Keep track of the number of service processes we last found, to
739     * determine on the next iteration which should be B services.
740     */
741    int mNumServiceProcs = 0;
742    int mNewNumServiceProcs = 0;
743
744    /**
745     * System monitoring: number of processes that died since the last
746     * N procs were started.
747     */
748    int[] mProcDeaths = new int[20];
749
750    /**
751     * This is set if we had to do a delayed dexopt of an app before launching
752     * it, to increasing the ANR timeouts in that case.
753     */
754    boolean mDidDexOpt;
755
756    String mDebugApp = null;
757    boolean mWaitForDebugger = false;
758    boolean mDebugTransient = false;
759    String mOrigDebugApp = null;
760    boolean mOrigWaitForDebugger = false;
761    boolean mAlwaysFinishActivities = false;
762    IActivityController mController = null;
763    String mProfileApp = null;
764    ProcessRecord mProfileProc = null;
765    String mProfileFile;
766    ParcelFileDescriptor mProfileFd;
767    int mProfileType = 0;
768    boolean mAutoStopProfiler = false;
769    String mOpenGlTraceApp = null;
770
771    static class ProcessChangeItem {
772        static final int CHANGE_ACTIVITIES = 1<<0;
773        static final int CHANGE_IMPORTANCE= 1<<1;
774        int changes;
775        int uid;
776        int pid;
777        int importance;
778        boolean foregroundActivities;
779    }
780
781    final RemoteCallbackList<IProcessObserver> mProcessObservers
782            = new RemoteCallbackList<IProcessObserver>();
783    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
784
785    final ArrayList<ProcessChangeItem> mPendingProcessChanges
786            = new ArrayList<ProcessChangeItem>();
787    final ArrayList<ProcessChangeItem> mAvailProcessChanges
788            = new ArrayList<ProcessChangeItem>();
789
790    /**
791     * Callback of last caller to {@link #requestPss}.
792     */
793    Runnable mRequestPssCallback;
794
795    /**
796     * Remaining processes for which we are waiting results from the last
797     * call to {@link #requestPss}.
798     */
799    final ArrayList<ProcessRecord> mRequestPssList
800            = new ArrayList<ProcessRecord>();
801
802    /**
803     * Runtime statistics collection thread.  This object's lock is used to
804     * protect all related state.
805     */
806    final Thread mProcessStatsThread;
807
808    /**
809     * Used to collect process stats when showing not responding dialog.
810     * Protected by mProcessStatsThread.
811     */
812    final ProcessStats mProcessStats = new ProcessStats(
813            MONITOR_THREAD_CPU_USAGE);
814    final AtomicLong mLastCpuTime = new AtomicLong(0);
815    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
816
817    long mLastWriteTime = 0;
818
819    /**
820     * Set to true after the system has finished booting.
821     */
822    boolean mBooted = false;
823
824    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
825    int mProcessLimitOverride = -1;
826
827    WindowManagerService mWindowManager;
828
829    static ActivityManagerService mSelf;
830    static ActivityThread mSystemThread;
831
832    private int mCurrentUserId;
833    private UserManagerService mUserManager;
834
835    private final class AppDeathRecipient implements IBinder.DeathRecipient {
836        final ProcessRecord mApp;
837        final int mPid;
838        final IApplicationThread mAppThread;
839
840        AppDeathRecipient(ProcessRecord app, int pid,
841                IApplicationThread thread) {
842            if (localLOGV) Slog.v(
843                TAG, "New death recipient " + this
844                + " for thread " + thread.asBinder());
845            mApp = app;
846            mPid = pid;
847            mAppThread = thread;
848        }
849
850        public void binderDied() {
851            if (localLOGV) Slog.v(
852                TAG, "Death received in " + this
853                + " for thread " + mAppThread.asBinder());
854            synchronized(ActivityManagerService.this) {
855                appDiedLocked(mApp, mPid, mAppThread);
856            }
857        }
858    }
859
860    static final int SHOW_ERROR_MSG = 1;
861    static final int SHOW_NOT_RESPONDING_MSG = 2;
862    static final int SHOW_FACTORY_ERROR_MSG = 3;
863    static final int UPDATE_CONFIGURATION_MSG = 4;
864    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
865    static final int WAIT_FOR_DEBUGGER_MSG = 6;
866    static final int SERVICE_TIMEOUT_MSG = 12;
867    static final int UPDATE_TIME_ZONE = 13;
868    static final int SHOW_UID_ERROR_MSG = 14;
869    static final int IM_FEELING_LUCKY_MSG = 15;
870    static final int PROC_START_TIMEOUT_MSG = 20;
871    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
872    static final int KILL_APPLICATION_MSG = 22;
873    static final int FINALIZE_PENDING_INTENT_MSG = 23;
874    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
875    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
876    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
877    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
878    static final int CLEAR_DNS_CACHE = 28;
879    static final int UPDATE_HTTP_PROXY = 29;
880    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
881    static final int DISPATCH_PROCESSES_CHANGED = 31;
882    static final int DISPATCH_PROCESS_DIED = 32;
883    static final int REPORT_MEM_USAGE = 33;
884    static final int REPORT_USER_SWITCH_MSG = 34;
885    static final int CONTINUE_USER_SWITCH_MSG = 35;
886    static final int USER_SWITCH_TIMEOUT_MSG = 36;
887
888    static final int FIRST_ACTIVITY_STACK_MSG = 100;
889    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
890    static final int FIRST_COMPAT_MODE_MSG = 300;
891
892    AlertDialog mUidAlert;
893    CompatModeDialog mCompatModeDialog;
894    long mLastMemUsageReportTime = 0;
895
896    final Handler mHandler = new Handler() {
897        //public Handler() {
898        //    if (localLOGV) Slog.v(TAG, "Handler started!");
899        //}
900
901        public void handleMessage(Message msg) {
902            switch (msg.what) {
903            case SHOW_ERROR_MSG: {
904                HashMap data = (HashMap) msg.obj;
905                synchronized (ActivityManagerService.this) {
906                    ProcessRecord proc = (ProcessRecord)data.get("app");
907                    if (proc != null && proc.crashDialog != null) {
908                        Slog.e(TAG, "App already has crash dialog: " + proc);
909                        return;
910                    }
911                    AppErrorResult res = (AppErrorResult) data.get("result");
912                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
913                        Dialog d = new AppErrorDialog(mContext, res, proc);
914                        d.show();
915                        proc.crashDialog = d;
916                    } else {
917                        // The device is asleep, so just pretend that the user
918                        // saw a crash dialog and hit "force quit".
919                        res.set(0);
920                    }
921                }
922
923                ensureBootCompleted();
924            } break;
925            case SHOW_NOT_RESPONDING_MSG: {
926                synchronized (ActivityManagerService.this) {
927                    HashMap data = (HashMap) msg.obj;
928                    ProcessRecord proc = (ProcessRecord)data.get("app");
929                    if (proc != null && proc.anrDialog != null) {
930                        Slog.e(TAG, "App already has anr dialog: " + proc);
931                        return;
932                    }
933
934                    Intent intent = new Intent("android.intent.action.ANR");
935                    if (!mProcessesReady) {
936                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
937                                | Intent.FLAG_RECEIVER_FOREGROUND);
938                    }
939                    broadcastIntentLocked(null, null, intent,
940                            null, null, 0, null, null, null,
941                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
942
943                    if (mShowDialogs) {
944                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
945                                mContext, proc, (ActivityRecord)data.get("activity"));
946                        d.show();
947                        proc.anrDialog = d;
948                    } else {
949                        // Just kill the app if there is no dialog to be shown.
950                        killAppAtUsersRequest(proc, null);
951                    }
952                }
953
954                ensureBootCompleted();
955            } break;
956            case SHOW_STRICT_MODE_VIOLATION_MSG: {
957                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
958                synchronized (ActivityManagerService.this) {
959                    ProcessRecord proc = (ProcessRecord) data.get("app");
960                    if (proc == null) {
961                        Slog.e(TAG, "App not found when showing strict mode dialog.");
962                        break;
963                    }
964                    if (proc.crashDialog != null) {
965                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
966                        return;
967                    }
968                    AppErrorResult res = (AppErrorResult) data.get("result");
969                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
970                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
971                        d.show();
972                        proc.crashDialog = d;
973                    } else {
974                        // The device is asleep, so just pretend that the user
975                        // saw a crash dialog and hit "force quit".
976                        res.set(0);
977                    }
978                }
979                ensureBootCompleted();
980            } break;
981            case SHOW_FACTORY_ERROR_MSG: {
982                Dialog d = new FactoryErrorDialog(
983                    mContext, msg.getData().getCharSequence("msg"));
984                d.show();
985                ensureBootCompleted();
986            } break;
987            case UPDATE_CONFIGURATION_MSG: {
988                final ContentResolver resolver = mContext.getContentResolver();
989                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
990            } break;
991            case GC_BACKGROUND_PROCESSES_MSG: {
992                synchronized (ActivityManagerService.this) {
993                    performAppGcsIfAppropriateLocked();
994                }
995            } break;
996            case WAIT_FOR_DEBUGGER_MSG: {
997                synchronized (ActivityManagerService.this) {
998                    ProcessRecord app = (ProcessRecord)msg.obj;
999                    if (msg.arg1 != 0) {
1000                        if (!app.waitedForDebugger) {
1001                            Dialog d = new AppWaitingForDebuggerDialog(
1002                                    ActivityManagerService.this,
1003                                    mContext, app);
1004                            app.waitDialog = d;
1005                            app.waitedForDebugger = true;
1006                            d.show();
1007                        }
1008                    } else {
1009                        if (app.waitDialog != null) {
1010                            app.waitDialog.dismiss();
1011                            app.waitDialog = null;
1012                        }
1013                    }
1014                }
1015            } break;
1016            case SERVICE_TIMEOUT_MSG: {
1017                if (mDidDexOpt) {
1018                    mDidDexOpt = false;
1019                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1020                    nmsg.obj = msg.obj;
1021                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1022                    return;
1023                }
1024                mServices.serviceTimeout((ProcessRecord)msg.obj);
1025            } break;
1026            case UPDATE_TIME_ZONE: {
1027                synchronized (ActivityManagerService.this) {
1028                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1029                        ProcessRecord r = mLruProcesses.get(i);
1030                        if (r.thread != null) {
1031                            try {
1032                                r.thread.updateTimeZone();
1033                            } catch (RemoteException ex) {
1034                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1035                            }
1036                        }
1037                    }
1038                }
1039            } break;
1040            case CLEAR_DNS_CACHE: {
1041                synchronized (ActivityManagerService.this) {
1042                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1043                        ProcessRecord r = mLruProcesses.get(i);
1044                        if (r.thread != null) {
1045                            try {
1046                                r.thread.clearDnsCache();
1047                            } catch (RemoteException ex) {
1048                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1049                            }
1050                        }
1051                    }
1052                }
1053            } break;
1054            case UPDATE_HTTP_PROXY: {
1055                ProxyProperties proxy = (ProxyProperties)msg.obj;
1056                String host = "";
1057                String port = "";
1058                String exclList = "";
1059                if (proxy != null) {
1060                    host = proxy.getHost();
1061                    port = Integer.toString(proxy.getPort());
1062                    exclList = proxy.getExclusionList();
1063                }
1064                synchronized (ActivityManagerService.this) {
1065                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1066                        ProcessRecord r = mLruProcesses.get(i);
1067                        if (r.thread != null) {
1068                            try {
1069                                r.thread.setHttpProxy(host, port, exclList);
1070                            } catch (RemoteException ex) {
1071                                Slog.w(TAG, "Failed to update http proxy for: " +
1072                                        r.info.processName);
1073                            }
1074                        }
1075                    }
1076                }
1077            } break;
1078            case SHOW_UID_ERROR_MSG: {
1079                String title = "System UIDs Inconsistent";
1080                String text = "UIDs on the system are inconsistent, you need to wipe your"
1081                        + " data partition or your device will be unstable.";
1082                Log.e(TAG, title + ": " + text);
1083                if (mShowDialogs) {
1084                    // XXX This is a temporary dialog, no need to localize.
1085                    AlertDialog d = new BaseErrorDialog(mContext);
1086                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1087                    d.setCancelable(false);
1088                    d.setTitle(title);
1089                    d.setMessage(text);
1090                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1091                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1092                    mUidAlert = d;
1093                    d.show();
1094                }
1095            } break;
1096            case IM_FEELING_LUCKY_MSG: {
1097                if (mUidAlert != null) {
1098                    mUidAlert.dismiss();
1099                    mUidAlert = null;
1100                }
1101            } break;
1102            case PROC_START_TIMEOUT_MSG: {
1103                if (mDidDexOpt) {
1104                    mDidDexOpt = false;
1105                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1106                    nmsg.obj = msg.obj;
1107                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1108                    return;
1109                }
1110                ProcessRecord app = (ProcessRecord)msg.obj;
1111                synchronized (ActivityManagerService.this) {
1112                    processStartTimedOutLocked(app);
1113                }
1114            } break;
1115            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1116                synchronized (ActivityManagerService.this) {
1117                    doPendingActivityLaunchesLocked(true);
1118                }
1119            } break;
1120            case KILL_APPLICATION_MSG: {
1121                synchronized (ActivityManagerService.this) {
1122                    int appid = msg.arg1;
1123                    boolean restart = (msg.arg2 == 1);
1124                    String pkg = (String) msg.obj;
1125                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1126                            UserHandle.USER_ALL);
1127                }
1128            } break;
1129            case FINALIZE_PENDING_INTENT_MSG: {
1130                ((PendingIntentRecord)msg.obj).completeFinalize();
1131            } break;
1132            case POST_HEAVY_NOTIFICATION_MSG: {
1133                INotificationManager inm = NotificationManager.getService();
1134                if (inm == null) {
1135                    return;
1136                }
1137
1138                ActivityRecord root = (ActivityRecord)msg.obj;
1139                ProcessRecord process = root.app;
1140                if (process == null) {
1141                    return;
1142                }
1143
1144                try {
1145                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1146                    String text = mContext.getString(R.string.heavy_weight_notification,
1147                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1148                    Notification notification = new Notification();
1149                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1150                    notification.when = 0;
1151                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1152                    notification.tickerText = text;
1153                    notification.defaults = 0; // please be quiet
1154                    notification.sound = null;
1155                    notification.vibrate = null;
1156                    notification.setLatestEventInfo(context, text,
1157                            mContext.getText(R.string.heavy_weight_notification_detail),
1158                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1159                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1160                                    new UserHandle(root.userId)));
1161
1162                    try {
1163                        int[] outId = new int[1];
1164                        inm.enqueueNotificationWithTag("android", null,
1165                                R.string.heavy_weight_notification,
1166                                notification, outId, root.userId);
1167                    } catch (RuntimeException e) {
1168                        Slog.w(ActivityManagerService.TAG,
1169                                "Error showing notification for heavy-weight app", e);
1170                    } catch (RemoteException e) {
1171                    }
1172                } catch (NameNotFoundException e) {
1173                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1174                }
1175            } break;
1176            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1177                INotificationManager inm = NotificationManager.getService();
1178                if (inm == null) {
1179                    return;
1180                }
1181                try {
1182                    inm.cancelNotificationWithTag("android", null,
1183                            R.string.heavy_weight_notification,  msg.arg1);
1184                } catch (RuntimeException e) {
1185                    Slog.w(ActivityManagerService.TAG,
1186                            "Error canceling notification for service", e);
1187                } catch (RemoteException e) {
1188                }
1189            } break;
1190            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1191                synchronized (ActivityManagerService.this) {
1192                    checkExcessivePowerUsageLocked(true);
1193                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1194                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1195                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1196                }
1197            } break;
1198            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1199                synchronized (ActivityManagerService.this) {
1200                    ActivityRecord ar = (ActivityRecord)msg.obj;
1201                    if (mCompatModeDialog != null) {
1202                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1203                                ar.info.applicationInfo.packageName)) {
1204                            return;
1205                        }
1206                        mCompatModeDialog.dismiss();
1207                        mCompatModeDialog = null;
1208                    }
1209                    if (ar != null && false) {
1210                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1211                                ar.packageName)) {
1212                            int mode = mCompatModePackages.computeCompatModeLocked(
1213                                    ar.info.applicationInfo);
1214                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1215                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1216                                mCompatModeDialog = new CompatModeDialog(
1217                                        ActivityManagerService.this, mContext,
1218                                        ar.info.applicationInfo);
1219                                mCompatModeDialog.show();
1220                            }
1221                        }
1222                    }
1223                }
1224                break;
1225            }
1226            case DISPATCH_PROCESSES_CHANGED: {
1227                dispatchProcessesChanged();
1228                break;
1229            }
1230            case DISPATCH_PROCESS_DIED: {
1231                final int pid = msg.arg1;
1232                final int uid = msg.arg2;
1233                dispatchProcessDied(pid, uid);
1234                break;
1235            }
1236            case REPORT_MEM_USAGE: {
1237                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1238                if (!isDebuggable) {
1239                    return;
1240                }
1241                synchronized (ActivityManagerService.this) {
1242                    long now = SystemClock.uptimeMillis();
1243                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1244                        // Don't report more than every 5 minutes to somewhat
1245                        // avoid spamming.
1246                        return;
1247                    }
1248                    mLastMemUsageReportTime = now;
1249                }
1250                Thread thread = new Thread() {
1251                    @Override public void run() {
1252                        StringBuilder dropBuilder = new StringBuilder(1024);
1253                        StringBuilder logBuilder = new StringBuilder(1024);
1254                        StringWriter oomSw = new StringWriter();
1255                        PrintWriter oomPw = new PrintWriter(oomSw);
1256                        StringWriter catSw = new StringWriter();
1257                        PrintWriter catPw = new PrintWriter(catSw);
1258                        String[] emptyArgs = new String[] { };
1259                        StringBuilder tag = new StringBuilder(128);
1260                        StringBuilder stack = new StringBuilder(128);
1261                        tag.append("Low on memory -- ");
1262                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1263                                tag, stack);
1264                        dropBuilder.append(stack);
1265                        dropBuilder.append('\n');
1266                        dropBuilder.append('\n');
1267                        String oomString = oomSw.toString();
1268                        dropBuilder.append(oomString);
1269                        dropBuilder.append('\n');
1270                        logBuilder.append(oomString);
1271                        try {
1272                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1273                                    "procrank", });
1274                            final InputStreamReader converter = new InputStreamReader(
1275                                    proc.getInputStream());
1276                            BufferedReader in = new BufferedReader(converter);
1277                            String line;
1278                            while (true) {
1279                                line = in.readLine();
1280                                if (line == null) {
1281                                    break;
1282                                }
1283                                if (line.length() > 0) {
1284                                    logBuilder.append(line);
1285                                    logBuilder.append('\n');
1286                                }
1287                                dropBuilder.append(line);
1288                                dropBuilder.append('\n');
1289                            }
1290                            converter.close();
1291                        } catch (IOException e) {
1292                        }
1293                        synchronized (ActivityManagerService.this) {
1294                            catPw.println();
1295                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1296                            catPw.println();
1297                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1298                                    false, false, null);
1299                            catPw.println();
1300                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1301                        }
1302                        dropBuilder.append(catSw.toString());
1303                        addErrorToDropBox("lowmem", null, "system_server", null,
1304                                null, tag.toString(), dropBuilder.toString(), null, null);
1305                        Slog.i(TAG, logBuilder.toString());
1306                        synchronized (ActivityManagerService.this) {
1307                            long now = SystemClock.uptimeMillis();
1308                            if (mLastMemUsageReportTime < now) {
1309                                mLastMemUsageReportTime = now;
1310                            }
1311                        }
1312                    }
1313                };
1314                thread.start();
1315                break;
1316            }
1317            case REPORT_USER_SWITCH_MSG: {
1318                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1319                break;
1320            }
1321            case CONTINUE_USER_SWITCH_MSG: {
1322                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1323                break;
1324            }
1325            case USER_SWITCH_TIMEOUT_MSG: {
1326                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1327                break;
1328            }
1329            }
1330        }
1331    };
1332
1333    public static void setSystemProcess() {
1334        try {
1335            ActivityManagerService m = mSelf;
1336
1337            ServiceManager.addService("activity", m, true);
1338            ServiceManager.addService("meminfo", new MemBinder(m));
1339            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1340            ServiceManager.addService("dbinfo", new DbBinder(m));
1341            if (MONITOR_CPU_USAGE) {
1342                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1343            }
1344            ServiceManager.addService("permission", new PermissionController(m));
1345
1346            ApplicationInfo info =
1347                mSelf.mContext.getPackageManager().getApplicationInfo(
1348                            "android", STOCK_PM_FLAGS);
1349            mSystemThread.installSystemApplicationInfo(info);
1350
1351            synchronized (mSelf) {
1352                ProcessRecord app = mSelf.newProcessRecordLocked(
1353                        mSystemThread.getApplicationThread(), info,
1354                        info.processName, false);
1355                app.persistent = true;
1356                app.pid = MY_PID;
1357                app.maxAdj = ProcessList.SYSTEM_ADJ;
1358                mSelf.mProcessNames.put(app.processName, app.uid, app);
1359                synchronized (mSelf.mPidsSelfLocked) {
1360                    mSelf.mPidsSelfLocked.put(app.pid, app);
1361                }
1362                mSelf.updateLruProcessLocked(app, true, true);
1363            }
1364        } catch (PackageManager.NameNotFoundException e) {
1365            throw new RuntimeException(
1366                    "Unable to find android system package", e);
1367        }
1368    }
1369
1370    public void setWindowManager(WindowManagerService wm) {
1371        mWindowManager = wm;
1372    }
1373
1374    public static final Context main(int factoryTest) {
1375        AThread thr = new AThread();
1376        thr.start();
1377
1378        synchronized (thr) {
1379            while (thr.mService == null) {
1380                try {
1381                    thr.wait();
1382                } catch (InterruptedException e) {
1383                }
1384            }
1385        }
1386
1387        ActivityManagerService m = thr.mService;
1388        mSelf = m;
1389        ActivityThread at = ActivityThread.systemMain();
1390        mSystemThread = at;
1391        Context context = at.getSystemContext();
1392        context.setTheme(android.R.style.Theme_Holo);
1393        m.mContext = context;
1394        m.mFactoryTest = factoryTest;
1395        m.mMainStack = new ActivityStack(m, context, true);
1396
1397        m.mBatteryStatsService.publish(context);
1398        m.mUsageStatsService.publish(context);
1399
1400        synchronized (thr) {
1401            thr.mReady = true;
1402            thr.notifyAll();
1403        }
1404
1405        m.startRunning(null, null, null, null);
1406
1407        return context;
1408    }
1409
1410    public static ActivityManagerService self() {
1411        return mSelf;
1412    }
1413
1414    static class AThread extends Thread {
1415        ActivityManagerService mService;
1416        boolean mReady = false;
1417
1418        public AThread() {
1419            super("ActivityManager");
1420        }
1421
1422        public void run() {
1423            Looper.prepare();
1424
1425            android.os.Process.setThreadPriority(
1426                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1427            android.os.Process.setCanSelfBackground(false);
1428
1429            ActivityManagerService m = new ActivityManagerService();
1430
1431            synchronized (this) {
1432                mService = m;
1433                notifyAll();
1434            }
1435
1436            synchronized (this) {
1437                while (!mReady) {
1438                    try {
1439                        wait();
1440                    } catch (InterruptedException e) {
1441                    }
1442                }
1443            }
1444
1445            // For debug builds, log event loop stalls to dropbox for analysis.
1446            if (StrictMode.conditionallyEnableDebugLogging()) {
1447                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1448            }
1449
1450            Looper.loop();
1451        }
1452    }
1453
1454    static class MemBinder extends Binder {
1455        ActivityManagerService mActivityManagerService;
1456        MemBinder(ActivityManagerService activityManagerService) {
1457            mActivityManagerService = activityManagerService;
1458        }
1459
1460        @Override
1461        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1462            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1463                    != PackageManager.PERMISSION_GRANTED) {
1464                pw.println("Permission Denial: can't dump meminfo from from pid="
1465                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1466                        + " without permission " + android.Manifest.permission.DUMP);
1467                return;
1468            }
1469
1470            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1471                    false, null, null, null);
1472        }
1473    }
1474
1475    static class GraphicsBinder extends Binder {
1476        ActivityManagerService mActivityManagerService;
1477        GraphicsBinder(ActivityManagerService activityManagerService) {
1478            mActivityManagerService = activityManagerService;
1479        }
1480
1481        @Override
1482        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1483            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1484                    != PackageManager.PERMISSION_GRANTED) {
1485                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1486                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1487                        + " without permission " + android.Manifest.permission.DUMP);
1488                return;
1489            }
1490
1491            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1492        }
1493    }
1494
1495    static class DbBinder extends Binder {
1496        ActivityManagerService mActivityManagerService;
1497        DbBinder(ActivityManagerService activityManagerService) {
1498            mActivityManagerService = activityManagerService;
1499        }
1500
1501        @Override
1502        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1503            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1504                    != PackageManager.PERMISSION_GRANTED) {
1505                pw.println("Permission Denial: can't dump dbinfo from from pid="
1506                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1507                        + " without permission " + android.Manifest.permission.DUMP);
1508                return;
1509            }
1510
1511            mActivityManagerService.dumpDbInfo(fd, pw, args);
1512        }
1513    }
1514
1515    static class CpuBinder extends Binder {
1516        ActivityManagerService mActivityManagerService;
1517        CpuBinder(ActivityManagerService activityManagerService) {
1518            mActivityManagerService = activityManagerService;
1519        }
1520
1521        @Override
1522        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1523            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1524                    != PackageManager.PERMISSION_GRANTED) {
1525                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1526                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1527                        + " without permission " + android.Manifest.permission.DUMP);
1528                return;
1529            }
1530
1531            synchronized (mActivityManagerService.mProcessStatsThread) {
1532                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1533                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1534                        SystemClock.uptimeMillis()));
1535            }
1536        }
1537    }
1538
1539    private ActivityManagerService() {
1540        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1541
1542        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1543        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1544        mBroadcastQueues[0] = mFgBroadcastQueue;
1545        mBroadcastQueues[1] = mBgBroadcastQueue;
1546
1547        mServices = new ActiveServices(this);
1548        mProviderMap = new ProviderMap(this);
1549
1550        File dataDir = Environment.getDataDirectory();
1551        File systemDir = new File(dataDir, "system");
1552        systemDir.mkdirs();
1553        mBatteryStatsService = new BatteryStatsService(new File(
1554                systemDir, "batterystats.bin").toString());
1555        mBatteryStatsService.getActiveStatistics().readLocked();
1556        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1557        mOnBattery = DEBUG_POWER ? true
1558                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1559        mBatteryStatsService.getActiveStatistics().setCallback(this);
1560
1561        mUsageStatsService = new UsageStatsService(new File(
1562                systemDir, "usagestats").toString());
1563        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1564
1565        // User 0 is the first and only user that runs at boot.
1566        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1567        mUserLru.add(Integer.valueOf(0));
1568
1569        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1570            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1571
1572        mConfiguration.setToDefaults();
1573        mConfiguration.setLocale(Locale.getDefault());
1574
1575        mConfigurationSeq = mConfiguration.seq = 1;
1576        mProcessStats.init();
1577
1578        mCompatModePackages = new CompatModePackages(this, systemDir);
1579
1580        // Add ourself to the Watchdog monitors.
1581        Watchdog.getInstance().addMonitor(this);
1582
1583        mProcessStatsThread = new Thread("ProcessStats") {
1584            public void run() {
1585                while (true) {
1586                    try {
1587                        try {
1588                            synchronized(this) {
1589                                final long now = SystemClock.uptimeMillis();
1590                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1591                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1592                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1593                                //        + ", write delay=" + nextWriteDelay);
1594                                if (nextWriteDelay < nextCpuDelay) {
1595                                    nextCpuDelay = nextWriteDelay;
1596                                }
1597                                if (nextCpuDelay > 0) {
1598                                    mProcessStatsMutexFree.set(true);
1599                                    this.wait(nextCpuDelay);
1600                                }
1601                            }
1602                        } catch (InterruptedException e) {
1603                        }
1604                        updateCpuStatsNow();
1605                    } catch (Exception e) {
1606                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1607                    }
1608                }
1609            }
1610        };
1611        mProcessStatsThread.start();
1612    }
1613
1614    @Override
1615    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1616            throws RemoteException {
1617        if (code == SYSPROPS_TRANSACTION) {
1618            // We need to tell all apps about the system property change.
1619            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1620            synchronized(this) {
1621                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1622                    final int NA = apps.size();
1623                    for (int ia=0; ia<NA; ia++) {
1624                        ProcessRecord app = apps.valueAt(ia);
1625                        if (app.thread != null) {
1626                            procs.add(app.thread.asBinder());
1627                        }
1628                    }
1629                }
1630            }
1631
1632            int N = procs.size();
1633            for (int i=0; i<N; i++) {
1634                Parcel data2 = Parcel.obtain();
1635                try {
1636                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1637                } catch (RemoteException e) {
1638                }
1639                data2.recycle();
1640            }
1641        }
1642        try {
1643            return super.onTransact(code, data, reply, flags);
1644        } catch (RuntimeException e) {
1645            // The activity manager only throws security exceptions, so let's
1646            // log all others.
1647            if (!(e instanceof SecurityException)) {
1648                Slog.e(TAG, "Activity Manager Crash", e);
1649            }
1650            throw e;
1651        }
1652    }
1653
1654    void updateCpuStats() {
1655        final long now = SystemClock.uptimeMillis();
1656        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1657            return;
1658        }
1659        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1660            synchronized (mProcessStatsThread) {
1661                mProcessStatsThread.notify();
1662            }
1663        }
1664    }
1665
1666    void updateCpuStatsNow() {
1667        synchronized (mProcessStatsThread) {
1668            mProcessStatsMutexFree.set(false);
1669            final long now = SystemClock.uptimeMillis();
1670            boolean haveNewCpuStats = false;
1671
1672            if (MONITOR_CPU_USAGE &&
1673                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1674                mLastCpuTime.set(now);
1675                haveNewCpuStats = true;
1676                mProcessStats.update();
1677                //Slog.i(TAG, mProcessStats.printCurrentState());
1678                //Slog.i(TAG, "Total CPU usage: "
1679                //        + mProcessStats.getTotalCpuPercent() + "%");
1680
1681                // Slog the cpu usage if the property is set.
1682                if ("true".equals(SystemProperties.get("events.cpu"))) {
1683                    int user = mProcessStats.getLastUserTime();
1684                    int system = mProcessStats.getLastSystemTime();
1685                    int iowait = mProcessStats.getLastIoWaitTime();
1686                    int irq = mProcessStats.getLastIrqTime();
1687                    int softIrq = mProcessStats.getLastSoftIrqTime();
1688                    int idle = mProcessStats.getLastIdleTime();
1689
1690                    int total = user + system + iowait + irq + softIrq + idle;
1691                    if (total == 0) total = 1;
1692
1693                    EventLog.writeEvent(EventLogTags.CPU,
1694                            ((user+system+iowait+irq+softIrq) * 100) / total,
1695                            (user * 100) / total,
1696                            (system * 100) / total,
1697                            (iowait * 100) / total,
1698                            (irq * 100) / total,
1699                            (softIrq * 100) / total);
1700                }
1701            }
1702
1703            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1704            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1705            synchronized(bstats) {
1706                synchronized(mPidsSelfLocked) {
1707                    if (haveNewCpuStats) {
1708                        if (mOnBattery) {
1709                            int perc = bstats.startAddingCpuLocked();
1710                            int totalUTime = 0;
1711                            int totalSTime = 0;
1712                            final int N = mProcessStats.countStats();
1713                            for (int i=0; i<N; i++) {
1714                                ProcessStats.Stats st = mProcessStats.getStats(i);
1715                                if (!st.working) {
1716                                    continue;
1717                                }
1718                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1719                                int otherUTime = (st.rel_utime*perc)/100;
1720                                int otherSTime = (st.rel_stime*perc)/100;
1721                                totalUTime += otherUTime;
1722                                totalSTime += otherSTime;
1723                                if (pr != null) {
1724                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1725                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1726                                            st.rel_stime-otherSTime);
1727                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1728                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1729                                } else {
1730                                    BatteryStatsImpl.Uid.Proc ps =
1731                                            bstats.getProcessStatsLocked(st.name, st.pid);
1732                                    if (ps != null) {
1733                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1734                                                st.rel_stime-otherSTime);
1735                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1736                                    }
1737                                }
1738                            }
1739                            bstats.finishAddingCpuLocked(perc, totalUTime,
1740                                    totalSTime, cpuSpeedTimes);
1741                        }
1742                    }
1743                }
1744
1745                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1746                    mLastWriteTime = now;
1747                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1748                }
1749            }
1750        }
1751    }
1752
1753    @Override
1754    public void batteryNeedsCpuUpdate() {
1755        updateCpuStatsNow();
1756    }
1757
1758    @Override
1759    public void batteryPowerChanged(boolean onBattery) {
1760        // When plugging in, update the CPU stats first before changing
1761        // the plug state.
1762        updateCpuStatsNow();
1763        synchronized (this) {
1764            synchronized(mPidsSelfLocked) {
1765                mOnBattery = DEBUG_POWER ? true : onBattery;
1766            }
1767        }
1768    }
1769
1770    /**
1771     * Initialize the application bind args. These are passed to each
1772     * process when the bindApplication() IPC is sent to the process. They're
1773     * lazily setup to make sure the services are running when they're asked for.
1774     */
1775    private HashMap<String, IBinder> getCommonServicesLocked() {
1776        if (mAppBindArgs == null) {
1777            mAppBindArgs = new HashMap<String, IBinder>();
1778
1779            // Setup the application init args
1780            mAppBindArgs.put("package", ServiceManager.getService("package"));
1781            mAppBindArgs.put("window", ServiceManager.getService("window"));
1782            mAppBindArgs.put(Context.ALARM_SERVICE,
1783                    ServiceManager.getService(Context.ALARM_SERVICE));
1784        }
1785        return mAppBindArgs;
1786    }
1787
1788    final void setFocusedActivityLocked(ActivityRecord r) {
1789        if (mFocusedActivity != r) {
1790            mFocusedActivity = r;
1791            if (r != null) {
1792                mWindowManager.setFocusedApp(r.appToken, true);
1793            }
1794        }
1795    }
1796
1797    private final void updateLruProcessInternalLocked(ProcessRecord app,
1798            boolean updateActivityTime, int bestPos) {
1799        // put it on the LRU to keep track of when it should be exited.
1800        int lrui = mLruProcesses.indexOf(app);
1801        if (lrui >= 0) mLruProcesses.remove(lrui);
1802
1803        int i = mLruProcesses.size()-1;
1804        int skipTop = 0;
1805
1806        app.lruSeq = mLruSeq;
1807
1808        // compute the new weight for this process.
1809        if (updateActivityTime) {
1810            app.lastActivityTime = SystemClock.uptimeMillis();
1811        }
1812        if (app.activities.size() > 0) {
1813            // If this process has activities, we more strongly want to keep
1814            // it around.
1815            app.lruWeight = app.lastActivityTime;
1816        } else if (app.pubProviders.size() > 0) {
1817            // If this process contains content providers, we want to keep
1818            // it a little more strongly.
1819            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1820            // Also don't let it kick out the first few "real" hidden processes.
1821            skipTop = ProcessList.MIN_HIDDEN_APPS;
1822        } else {
1823            // If this process doesn't have activities, we less strongly
1824            // want to keep it around, and generally want to avoid getting
1825            // in front of any very recently used activities.
1826            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1827            // Also don't let it kick out the first few "real" hidden processes.
1828            skipTop = ProcessList.MIN_HIDDEN_APPS;
1829        }
1830
1831        while (i >= 0) {
1832            ProcessRecord p = mLruProcesses.get(i);
1833            // If this app shouldn't be in front of the first N background
1834            // apps, then skip over that many that are currently hidden.
1835            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1836                skipTop--;
1837            }
1838            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1839                mLruProcesses.add(i+1, app);
1840                break;
1841            }
1842            i--;
1843        }
1844        if (i < 0) {
1845            mLruProcesses.add(0, app);
1846        }
1847
1848        // If the app is currently using a content provider or service,
1849        // bump those processes as well.
1850        if (app.connections.size() > 0) {
1851            for (ConnectionRecord cr : app.connections) {
1852                if (cr.binding != null && cr.binding.service != null
1853                        && cr.binding.service.app != null
1854                        && cr.binding.service.app.lruSeq != mLruSeq) {
1855                    updateLruProcessInternalLocked(cr.binding.service.app,
1856                            updateActivityTime, i+1);
1857                }
1858            }
1859        }
1860        for (int j=app.conProviders.size()-1; j>=0; j--) {
1861            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1862            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1863                updateLruProcessInternalLocked(cpr.proc,
1864                        updateActivityTime, i+1);
1865            }
1866        }
1867    }
1868
1869    final void updateLruProcessLocked(ProcessRecord app,
1870            boolean oomAdj, boolean updateActivityTime) {
1871        mLruSeq++;
1872        updateLruProcessInternalLocked(app, updateActivityTime, 0);
1873
1874        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1875        if (oomAdj) {
1876            updateOomAdjLocked();
1877        }
1878    }
1879
1880    final ProcessRecord getProcessRecordLocked(
1881            String processName, int uid) {
1882        if (uid == Process.SYSTEM_UID) {
1883            // The system gets to run in any process.  If there are multiple
1884            // processes with the same uid, just pick the first (this
1885            // should never happen).
1886            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1887                    processName);
1888            if (procs == null) return null;
1889            final int N = procs.size();
1890            for (int i = 0; i < N; i++) {
1891                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1892            }
1893        }
1894        ProcessRecord proc = mProcessNames.get(processName, uid);
1895        return proc;
1896    }
1897
1898    void ensurePackageDexOpt(String packageName) {
1899        IPackageManager pm = AppGlobals.getPackageManager();
1900        try {
1901            if (pm.performDexOpt(packageName)) {
1902                mDidDexOpt = true;
1903            }
1904        } catch (RemoteException e) {
1905        }
1906    }
1907
1908    boolean isNextTransitionForward() {
1909        int transit = mWindowManager.getPendingAppTransition();
1910        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1911                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1912                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1913    }
1914
1915    final ProcessRecord startProcessLocked(String processName,
1916            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1917            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1918            boolean isolated) {
1919        ProcessRecord app;
1920        if (!isolated) {
1921            app = getProcessRecordLocked(processName, info.uid);
1922        } else {
1923            // If this is an isolated process, it can't re-use an existing process.
1924            app = null;
1925        }
1926        // We don't have to do anything more if:
1927        // (1) There is an existing application record; and
1928        // (2) The caller doesn't think it is dead, OR there is no thread
1929        //     object attached to it so we know it couldn't have crashed; and
1930        // (3) There is a pid assigned to it, so it is either starting or
1931        //     already running.
1932        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1933                + " app=" + app + " knownToBeDead=" + knownToBeDead
1934                + " thread=" + (app != null ? app.thread : null)
1935                + " pid=" + (app != null ? app.pid : -1));
1936        if (app != null && app.pid > 0) {
1937            if (!knownToBeDead || app.thread == null) {
1938                // We already have the app running, or are waiting for it to
1939                // come up (we have a pid but not yet its thread), so keep it.
1940                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1941                // If this is a new package in the process, add the package to the list
1942                app.addPackage(info.packageName);
1943                return app;
1944            } else {
1945                // An application record is attached to a previous process,
1946                // clean it up now.
1947                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1948                handleAppDiedLocked(app, true, true);
1949            }
1950        }
1951
1952        String hostingNameStr = hostingName != null
1953                ? hostingName.flattenToShortString() : null;
1954
1955        if (!isolated) {
1956            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1957                // If we are in the background, then check to see if this process
1958                // is bad.  If so, we will just silently fail.
1959                if (mBadProcesses.get(info.processName, info.uid) != null) {
1960                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1961                            + "/" + info.processName);
1962                    return null;
1963                }
1964            } else {
1965                // When the user is explicitly starting a process, then clear its
1966                // crash count so that we won't make it bad until they see at
1967                // least one crash dialog again, and make the process good again
1968                // if it had been bad.
1969                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1970                        + "/" + info.processName);
1971                mProcessCrashTimes.remove(info.processName, info.uid);
1972                if (mBadProcesses.get(info.processName, info.uid) != null) {
1973                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1974                            info.processName);
1975                    mBadProcesses.remove(info.processName, info.uid);
1976                    if (app != null) {
1977                        app.bad = false;
1978                    }
1979                }
1980            }
1981        }
1982
1983        if (app == null) {
1984            app = newProcessRecordLocked(null, info, processName, isolated);
1985            if (app == null) {
1986                Slog.w(TAG, "Failed making new process record for "
1987                        + processName + "/" + info.uid + " isolated=" + isolated);
1988                return null;
1989            }
1990            mProcessNames.put(processName, app.uid, app);
1991            if (isolated) {
1992                mIsolatedProcesses.put(app.uid, app);
1993            }
1994        } else {
1995            // If this is a new package in the process, add the package to the list
1996            app.addPackage(info.packageName);
1997        }
1998
1999        // If the system is not ready yet, then hold off on starting this
2000        // process until it is.
2001        if (!mProcessesReady
2002                && !isAllowedWhileBooting(info)
2003                && !allowWhileBooting) {
2004            if (!mProcessesOnHold.contains(app)) {
2005                mProcessesOnHold.add(app);
2006            }
2007            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2008            return app;
2009        }
2010
2011        startProcessLocked(app, hostingType, hostingNameStr);
2012        return (app.pid != 0) ? app : null;
2013    }
2014
2015    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2016        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2017    }
2018
2019    private final void startProcessLocked(ProcessRecord app,
2020            String hostingType, String hostingNameStr) {
2021        if (app.pid > 0 && app.pid != MY_PID) {
2022            synchronized (mPidsSelfLocked) {
2023                mPidsSelfLocked.remove(app.pid);
2024                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2025            }
2026            app.setPid(0);
2027        }
2028
2029        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2030                "startProcessLocked removing on hold: " + app);
2031        mProcessesOnHold.remove(app);
2032
2033        updateCpuStats();
2034
2035        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
2036        mProcDeaths[0] = 0;
2037
2038        try {
2039            int uid = app.uid;
2040
2041            int[] gids = null;
2042            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2043            if (!app.isolated) {
2044                int[] permGids = null;
2045                try {
2046                    final PackageManager pm = mContext.getPackageManager();
2047                    permGids = pm.getPackageGids(app.info.packageName);
2048
2049                    if (Environment.isExternalStorageEmulated()) {
2050                        if (pm.checkPermission(
2051                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2052                                app.info.packageName) == PERMISSION_GRANTED) {
2053                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2054                        } else {
2055                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2056                        }
2057                    }
2058                } catch (PackageManager.NameNotFoundException e) {
2059                    Slog.w(TAG, "Unable to retrieve gids", e);
2060                }
2061
2062                /*
2063                 * Add shared application GID so applications can share some
2064                 * resources like shared libraries
2065                 */
2066                if (permGids == null) {
2067                    gids = new int[1];
2068                } else {
2069                    gids = new int[permGids.length + 1];
2070                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2071                }
2072                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2073            }
2074            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2075                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2076                        && mTopComponent != null
2077                        && app.processName.equals(mTopComponent.getPackageName())) {
2078                    uid = 0;
2079                }
2080                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2081                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2082                    uid = 0;
2083                }
2084            }
2085            int debugFlags = 0;
2086            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2087                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2088                // Also turn on CheckJNI for debuggable apps. It's quite
2089                // awkward to turn on otherwise.
2090                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2091            }
2092            // Run the app in safe mode if its manifest requests so or the
2093            // system is booted in safe mode.
2094            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2095                Zygote.systemInSafeMode == true) {
2096                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2097            }
2098            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2099                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2100            }
2101            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2102                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2103            }
2104            if ("1".equals(SystemProperties.get("debug.assert"))) {
2105                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2106            }
2107
2108            // Start the process.  It will either succeed and return a result containing
2109            // the PID of the new process, or else throw a RuntimeException.
2110            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2111                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2112                    app.info.targetSdkVersion, null, null);
2113
2114            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2115            synchronized (bs) {
2116                if (bs.isOnBattery()) {
2117                    app.batteryStats.incStartsLocked();
2118                }
2119            }
2120
2121            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
2122                    app.processName, hostingType,
2123                    hostingNameStr != null ? hostingNameStr : "");
2124
2125            if (app.persistent) {
2126                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2127            }
2128
2129            StringBuilder buf = mStringBuilder;
2130            buf.setLength(0);
2131            buf.append("Start proc ");
2132            buf.append(app.processName);
2133            buf.append(" for ");
2134            buf.append(hostingType);
2135            if (hostingNameStr != null) {
2136                buf.append(" ");
2137                buf.append(hostingNameStr);
2138            }
2139            buf.append(": pid=");
2140            buf.append(startResult.pid);
2141            buf.append(" uid=");
2142            buf.append(uid);
2143            buf.append(" gids={");
2144            if (gids != null) {
2145                for (int gi=0; gi<gids.length; gi++) {
2146                    if (gi != 0) buf.append(", ");
2147                    buf.append(gids[gi]);
2148
2149                }
2150            }
2151            buf.append("}");
2152            Slog.i(TAG, buf.toString());
2153            app.setPid(startResult.pid);
2154            app.usingWrapper = startResult.usingWrapper;
2155            app.removed = false;
2156            synchronized (mPidsSelfLocked) {
2157                this.mPidsSelfLocked.put(startResult.pid, app);
2158                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2159                msg.obj = app;
2160                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2161                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2162            }
2163        } catch (RuntimeException e) {
2164            // XXX do better error recovery.
2165            app.setPid(0);
2166            Slog.e(TAG, "Failure starting process " + app.processName, e);
2167        }
2168    }
2169
2170    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2171        if (resumed) {
2172            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2173        } else {
2174            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2175        }
2176    }
2177
2178    boolean startHomeActivityLocked(int userId) {
2179        if (mHeadless) {
2180            // Added because none of the other calls to ensureBootCompleted seem to fire
2181            // when running headless.
2182            ensureBootCompleted();
2183            return false;
2184        }
2185
2186        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2187                && mTopAction == null) {
2188            // We are running in factory test mode, but unable to find
2189            // the factory test app, so just sit around displaying the
2190            // error message and don't try to start anything.
2191            return false;
2192        }
2193        Intent intent = new Intent(
2194            mTopAction,
2195            mTopData != null ? Uri.parse(mTopData) : null);
2196        intent.setComponent(mTopComponent);
2197        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2198            intent.addCategory(Intent.CATEGORY_HOME);
2199        }
2200        ActivityInfo aInfo =
2201            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2202        if (aInfo != null) {
2203            intent.setComponent(new ComponentName(
2204                    aInfo.applicationInfo.packageName, aInfo.name));
2205            // Don't do this if the home app is currently being
2206            // instrumented.
2207            aInfo = new ActivityInfo(aInfo);
2208            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2209            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2210                    aInfo.applicationInfo.uid);
2211            if (app == null || app.instrumentationClass == null) {
2212                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2213                mMainStack.startActivityLocked(null, intent, null, aInfo,
2214                        null, null, 0, 0, 0, 0, null, false, null);
2215            }
2216        }
2217
2218        return true;
2219    }
2220
2221    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2222        ActivityInfo ai = null;
2223        ComponentName comp = intent.getComponent();
2224        try {
2225            if (comp != null) {
2226                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2227            } else {
2228                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2229                        intent,
2230                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2231                            flags, userId);
2232
2233                if (info != null) {
2234                    ai = info.activityInfo;
2235                }
2236            }
2237        } catch (RemoteException e) {
2238            // ignore
2239        }
2240
2241        return ai;
2242    }
2243
2244    /**
2245     * Starts the "new version setup screen" if appropriate.
2246     */
2247    void startSetupActivityLocked() {
2248        // Only do this once per boot.
2249        if (mCheckedForSetup) {
2250            return;
2251        }
2252
2253        // We will show this screen if the current one is a different
2254        // version than the last one shown, and we are not running in
2255        // low-level factory test mode.
2256        final ContentResolver resolver = mContext.getContentResolver();
2257        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2258                Settings.Secure.getInt(resolver,
2259                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2260            mCheckedForSetup = true;
2261
2262            // See if we should be showing the platform update setup UI.
2263            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2264            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2265                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2266
2267            // We don't allow third party apps to replace this.
2268            ResolveInfo ri = null;
2269            for (int i=0; ris != null && i<ris.size(); i++) {
2270                if ((ris.get(i).activityInfo.applicationInfo.flags
2271                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2272                    ri = ris.get(i);
2273                    break;
2274                }
2275            }
2276
2277            if (ri != null) {
2278                String vers = ri.activityInfo.metaData != null
2279                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2280                        : null;
2281                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2282                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2283                            Intent.METADATA_SETUP_VERSION);
2284                }
2285                String lastVers = Settings.Secure.getString(
2286                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2287                if (vers != null && !vers.equals(lastVers)) {
2288                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2289                    intent.setComponent(new ComponentName(
2290                            ri.activityInfo.packageName, ri.activityInfo.name));
2291                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2292                            null, null, 0, 0, 0, 0, null, false, null);
2293                }
2294            }
2295        }
2296    }
2297
2298    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2299        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2300    }
2301
2302    void enforceNotIsolatedCaller(String caller) {
2303        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2304            throw new SecurityException("Isolated process not allowed to call " + caller);
2305        }
2306    }
2307
2308    public int getFrontActivityScreenCompatMode() {
2309        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2310        synchronized (this) {
2311            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2312        }
2313    }
2314
2315    public void setFrontActivityScreenCompatMode(int mode) {
2316        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2317                "setFrontActivityScreenCompatMode");
2318        synchronized (this) {
2319            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2320        }
2321    }
2322
2323    public int getPackageScreenCompatMode(String packageName) {
2324        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2325        synchronized (this) {
2326            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2327        }
2328    }
2329
2330    public void setPackageScreenCompatMode(String packageName, int mode) {
2331        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2332                "setPackageScreenCompatMode");
2333        synchronized (this) {
2334            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2335        }
2336    }
2337
2338    public boolean getPackageAskScreenCompat(String packageName) {
2339        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2340        synchronized (this) {
2341            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2342        }
2343    }
2344
2345    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2346        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2347                "setPackageAskScreenCompat");
2348        synchronized (this) {
2349            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2350        }
2351    }
2352
2353    void reportResumedActivityLocked(ActivityRecord r) {
2354        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2355        updateUsageStats(r, true);
2356    }
2357
2358    private void dispatchProcessesChanged() {
2359        int N;
2360        synchronized (this) {
2361            N = mPendingProcessChanges.size();
2362            if (mActiveProcessChanges.length < N) {
2363                mActiveProcessChanges = new ProcessChangeItem[N];
2364            }
2365            mPendingProcessChanges.toArray(mActiveProcessChanges);
2366            mAvailProcessChanges.addAll(mPendingProcessChanges);
2367            mPendingProcessChanges.clear();
2368            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2369        }
2370        int i = mProcessObservers.beginBroadcast();
2371        while (i > 0) {
2372            i--;
2373            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2374            if (observer != null) {
2375                try {
2376                    for (int j=0; j<N; j++) {
2377                        ProcessChangeItem item = mActiveProcessChanges[j];
2378                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2379                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2380                                    + item.pid + " uid=" + item.uid + ": "
2381                                    + item.foregroundActivities);
2382                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2383                                    item.foregroundActivities);
2384                        }
2385                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2386                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2387                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2388                            observer.onImportanceChanged(item.pid, item.uid,
2389                                    item.importance);
2390                        }
2391                    }
2392                } catch (RemoteException e) {
2393                }
2394            }
2395        }
2396        mProcessObservers.finishBroadcast();
2397    }
2398
2399    private void dispatchProcessDied(int pid, int uid) {
2400        int i = mProcessObservers.beginBroadcast();
2401        while (i > 0) {
2402            i--;
2403            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2404            if (observer != null) {
2405                try {
2406                    observer.onProcessDied(pid, uid);
2407                } catch (RemoteException e) {
2408                }
2409            }
2410        }
2411        mProcessObservers.finishBroadcast();
2412    }
2413
2414    final void doPendingActivityLaunchesLocked(boolean doResume) {
2415        final int N = mPendingActivityLaunches.size();
2416        if (N <= 0) {
2417            return;
2418        }
2419        for (int i=0; i<N; i++) {
2420            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2421            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2422                    pal.startFlags, doResume && i == (N-1), null);
2423        }
2424        mPendingActivityLaunches.clear();
2425    }
2426
2427    public final int startActivity(IApplicationThread caller,
2428            Intent intent, String resolvedType, IBinder resultTo,
2429            String resultWho, int requestCode, int startFlags,
2430            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2431        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2432                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2433    }
2434
2435    public final int startActivityAsUser(IApplicationThread caller,
2436            Intent intent, String resolvedType, IBinder resultTo,
2437            String resultWho, int requestCode, int startFlags,
2438            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2439        enforceNotIsolatedCaller("startActivity");
2440        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2441                false, true, "startActivity", null);
2442        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2443                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2444                null, null, options, userId);
2445    }
2446
2447    public final WaitResult startActivityAndWait(IApplicationThread caller,
2448            Intent intent, String resolvedType, IBinder resultTo,
2449            String resultWho, int requestCode, int startFlags, String profileFile,
2450            ParcelFileDescriptor profileFd, Bundle options, int userId) {
2451        enforceNotIsolatedCaller("startActivityAndWait");
2452        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2453                false, true, "startActivityAndWait", null);
2454        WaitResult res = new WaitResult();
2455        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2456                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2457                res, null, options, UserHandle.getCallingUserId());
2458        return res;
2459    }
2460
2461    public final int startActivityWithConfig(IApplicationThread caller,
2462            Intent intent, String resolvedType, IBinder resultTo,
2463            String resultWho, int requestCode, int startFlags, Configuration config,
2464            Bundle options, int userId) {
2465        enforceNotIsolatedCaller("startActivityWithConfig");
2466        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2467                false, true, "startActivityWithConfig", null);
2468        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2469                resultTo, resultWho, requestCode, startFlags,
2470                null, null, null, config, options, userId);
2471        return ret;
2472    }
2473
2474    public int startActivityIntentSender(IApplicationThread caller,
2475            IntentSender intent, Intent fillInIntent, String resolvedType,
2476            IBinder resultTo, String resultWho, int requestCode,
2477            int flagsMask, int flagsValues, Bundle options) {
2478        enforceNotIsolatedCaller("startActivityIntentSender");
2479        // Refuse possible leaked file descriptors
2480        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2481            throw new IllegalArgumentException("File descriptors passed in Intent");
2482        }
2483
2484        IIntentSender sender = intent.getTarget();
2485        if (!(sender instanceof PendingIntentRecord)) {
2486            throw new IllegalArgumentException("Bad PendingIntent object");
2487        }
2488
2489        PendingIntentRecord pir = (PendingIntentRecord)sender;
2490
2491        synchronized (this) {
2492            // If this is coming from the currently resumed activity, it is
2493            // effectively saying that app switches are allowed at this point.
2494            if (mMainStack.mResumedActivity != null
2495                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2496                            Binder.getCallingUid()) {
2497                mAppSwitchesAllowedTime = 0;
2498            }
2499        }
2500        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2501                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2502        return ret;
2503    }
2504
2505    public boolean startNextMatchingActivity(IBinder callingActivity,
2506            Intent intent, Bundle options) {
2507        // Refuse possible leaked file descriptors
2508        if (intent != null && intent.hasFileDescriptors() == true) {
2509            throw new IllegalArgumentException("File descriptors passed in Intent");
2510        }
2511
2512        synchronized (this) {
2513            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2514            if (r == null) {
2515                ActivityOptions.abort(options);
2516                return false;
2517            }
2518            if (r.app == null || r.app.thread == null) {
2519                // The caller is not running...  d'oh!
2520                ActivityOptions.abort(options);
2521                return false;
2522            }
2523            intent = new Intent(intent);
2524            // The caller is not allowed to change the data.
2525            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2526            // And we are resetting to find the next component...
2527            intent.setComponent(null);
2528
2529            ActivityInfo aInfo = null;
2530            try {
2531                List<ResolveInfo> resolves =
2532                    AppGlobals.getPackageManager().queryIntentActivities(
2533                            intent, r.resolvedType,
2534                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2535                            UserHandle.getCallingUserId());
2536
2537                // Look for the original activity in the list...
2538                final int N = resolves != null ? resolves.size() : 0;
2539                for (int i=0; i<N; i++) {
2540                    ResolveInfo rInfo = resolves.get(i);
2541                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2542                            && rInfo.activityInfo.name.equals(r.info.name)) {
2543                        // We found the current one...  the next matching is
2544                        // after it.
2545                        i++;
2546                        if (i<N) {
2547                            aInfo = resolves.get(i).activityInfo;
2548                        }
2549                        break;
2550                    }
2551                }
2552            } catch (RemoteException e) {
2553            }
2554
2555            if (aInfo == null) {
2556                // Nobody who is next!
2557                ActivityOptions.abort(options);
2558                return false;
2559            }
2560
2561            intent.setComponent(new ComponentName(
2562                    aInfo.applicationInfo.packageName, aInfo.name));
2563            intent.setFlags(intent.getFlags()&~(
2564                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2565                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2566                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2567                    Intent.FLAG_ACTIVITY_NEW_TASK));
2568
2569            // Okay now we need to start the new activity, replacing the
2570            // currently running activity.  This is a little tricky because
2571            // we want to start the new one as if the current one is finished,
2572            // but not finish the current one first so that there is no flicker.
2573            // And thus...
2574            final boolean wasFinishing = r.finishing;
2575            r.finishing = true;
2576
2577            // Propagate reply information over to the new activity.
2578            final ActivityRecord resultTo = r.resultTo;
2579            final String resultWho = r.resultWho;
2580            final int requestCode = r.requestCode;
2581            r.resultTo = null;
2582            if (resultTo != null) {
2583                resultTo.removeResultsLocked(r, resultWho, requestCode);
2584            }
2585
2586            final long origId = Binder.clearCallingIdentity();
2587            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2588                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2589                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2590                    options, false, null);
2591            Binder.restoreCallingIdentity(origId);
2592
2593            r.finishing = wasFinishing;
2594            if (res != ActivityManager.START_SUCCESS) {
2595                return false;
2596            }
2597            return true;
2598        }
2599    }
2600
2601    final int startActivityInPackage(int uid,
2602            Intent intent, String resolvedType, IBinder resultTo,
2603            String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
2604
2605        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2606                false, true, "startActivityInPackage", null);
2607
2608        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2609                resultTo, resultWho, requestCode, startFlags,
2610                null, null, null, null, options, userId);
2611        return ret;
2612    }
2613
2614    public final int startActivities(IApplicationThread caller,
2615            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
2616        enforceNotIsolatedCaller("startActivities");
2617        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2618                options, UserHandle.getCallingUserId());
2619        return ret;
2620    }
2621
2622    final int startActivitiesInPackage(int uid,
2623            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2624            Bundle options, int userId) {
2625
2626        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2627                false, true, "startActivityInPackage", null);
2628        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2629                options, userId);
2630        return ret;
2631    }
2632
2633    final void addRecentTaskLocked(TaskRecord task) {
2634        int N = mRecentTasks.size();
2635        // Quick case: check if the top-most recent task is the same.
2636        if (N > 0 && mRecentTasks.get(0) == task) {
2637            return;
2638        }
2639        // Remove any existing entries that are the same kind of task.
2640        for (int i=0; i<N; i++) {
2641            TaskRecord tr = mRecentTasks.get(i);
2642            if (task.userId == tr.userId
2643                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2644                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2645                mRecentTasks.remove(i);
2646                i--;
2647                N--;
2648                if (task.intent == null) {
2649                    // If the new recent task we are adding is not fully
2650                    // specified, then replace it with the existing recent task.
2651                    task = tr;
2652                }
2653            }
2654        }
2655        if (N >= MAX_RECENT_TASKS) {
2656            mRecentTasks.remove(N-1);
2657        }
2658        mRecentTasks.add(0, task);
2659    }
2660
2661    public void setRequestedOrientation(IBinder token,
2662            int requestedOrientation) {
2663        synchronized (this) {
2664            ActivityRecord r = mMainStack.isInStackLocked(token);
2665            if (r == null) {
2666                return;
2667            }
2668            final long origId = Binder.clearCallingIdentity();
2669            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2670            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2671                    mConfiguration,
2672                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2673            if (config != null) {
2674                r.frozenBeforeDestroy = true;
2675                if (!updateConfigurationLocked(config, r, false, false)) {
2676                    mMainStack.resumeTopActivityLocked(null);
2677                }
2678            }
2679            Binder.restoreCallingIdentity(origId);
2680        }
2681    }
2682
2683    public int getRequestedOrientation(IBinder token) {
2684        synchronized (this) {
2685            ActivityRecord r = mMainStack.isInStackLocked(token);
2686            if (r == null) {
2687                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2688            }
2689            return mWindowManager.getAppOrientation(r.appToken);
2690        }
2691    }
2692
2693    /**
2694     * This is the internal entry point for handling Activity.finish().
2695     *
2696     * @param token The Binder token referencing the Activity we want to finish.
2697     * @param resultCode Result code, if any, from this Activity.
2698     * @param resultData Result data (Intent), if any, from this Activity.
2699     *
2700     * @return Returns true if the activity successfully finished, or false if it is still running.
2701     */
2702    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2703        // Refuse possible leaked file descriptors
2704        if (resultData != null && resultData.hasFileDescriptors() == true) {
2705            throw new IllegalArgumentException("File descriptors passed in Intent");
2706        }
2707
2708        synchronized(this) {
2709            if (mController != null) {
2710                // Find the first activity that is not finishing.
2711                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2712                if (next != null) {
2713                    // ask watcher if this is allowed
2714                    boolean resumeOK = true;
2715                    try {
2716                        resumeOK = mController.activityResuming(next.packageName);
2717                    } catch (RemoteException e) {
2718                        mController = null;
2719                    }
2720
2721                    if (!resumeOK) {
2722                        return false;
2723                    }
2724                }
2725            }
2726            final long origId = Binder.clearCallingIdentity();
2727            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2728                    resultData, "app-request", true);
2729            Binder.restoreCallingIdentity(origId);
2730            return res;
2731        }
2732    }
2733
2734    public final void finishHeavyWeightApp() {
2735        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2736                != PackageManager.PERMISSION_GRANTED) {
2737            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2738                    + Binder.getCallingPid()
2739                    + ", uid=" + Binder.getCallingUid()
2740                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2741            Slog.w(TAG, msg);
2742            throw new SecurityException(msg);
2743        }
2744
2745        synchronized(this) {
2746            if (mHeavyWeightProcess == null) {
2747                return;
2748            }
2749
2750            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2751                    mHeavyWeightProcess.activities);
2752            for (int i=0; i<activities.size(); i++) {
2753                ActivityRecord r = activities.get(i);
2754                if (!r.finishing) {
2755                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2756                    if (index >= 0) {
2757                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2758                                null, "finish-heavy", true);
2759                    }
2760                }
2761            }
2762
2763            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
2764                    mHeavyWeightProcess.userId, 0));
2765            mHeavyWeightProcess = null;
2766        }
2767    }
2768
2769    public void crashApplication(int uid, int initialPid, String packageName,
2770            String message) {
2771        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2772                != PackageManager.PERMISSION_GRANTED) {
2773            String msg = "Permission Denial: crashApplication() from pid="
2774                    + Binder.getCallingPid()
2775                    + ", uid=" + Binder.getCallingUid()
2776                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2777            Slog.w(TAG, msg);
2778            throw new SecurityException(msg);
2779        }
2780
2781        synchronized(this) {
2782            ProcessRecord proc = null;
2783
2784            // Figure out which process to kill.  We don't trust that initialPid
2785            // still has any relation to current pids, so must scan through the
2786            // list.
2787            synchronized (mPidsSelfLocked) {
2788                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2789                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2790                    if (p.uid != uid) {
2791                        continue;
2792                    }
2793                    if (p.pid == initialPid) {
2794                        proc = p;
2795                        break;
2796                    }
2797                    for (String str : p.pkgList) {
2798                        if (str.equals(packageName)) {
2799                            proc = p;
2800                        }
2801                    }
2802                }
2803            }
2804
2805            if (proc == null) {
2806                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2807                        + " initialPid=" + initialPid
2808                        + " packageName=" + packageName);
2809                return;
2810            }
2811
2812            if (proc.thread != null) {
2813                if (proc.pid == Process.myPid()) {
2814                    Log.w(TAG, "crashApplication: trying to crash self!");
2815                    return;
2816                }
2817                long ident = Binder.clearCallingIdentity();
2818                try {
2819                    proc.thread.scheduleCrash(message);
2820                } catch (RemoteException e) {
2821                }
2822                Binder.restoreCallingIdentity(ident);
2823            }
2824        }
2825    }
2826
2827    public final void finishSubActivity(IBinder token, String resultWho,
2828            int requestCode) {
2829        synchronized(this) {
2830            final long origId = Binder.clearCallingIdentity();
2831            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2832            Binder.restoreCallingIdentity(origId);
2833        }
2834    }
2835
2836    public boolean finishActivityAffinity(IBinder token) {
2837        synchronized(this) {
2838            final long origId = Binder.clearCallingIdentity();
2839            boolean res = mMainStack.finishActivityAffinityLocked(token);
2840            Binder.restoreCallingIdentity(origId);
2841            return res;
2842        }
2843    }
2844
2845    public boolean willActivityBeVisible(IBinder token) {
2846        synchronized(this) {
2847            int i;
2848            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2849                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2850                if (r.appToken == token) {
2851                    return true;
2852                }
2853                if (r.fullscreen && !r.finishing) {
2854                    return false;
2855                }
2856            }
2857            return true;
2858        }
2859    }
2860
2861    public void overridePendingTransition(IBinder token, String packageName,
2862            int enterAnim, int exitAnim) {
2863        synchronized(this) {
2864            ActivityRecord self = mMainStack.isInStackLocked(token);
2865            if (self == null) {
2866                return;
2867            }
2868
2869            final long origId = Binder.clearCallingIdentity();
2870
2871            if (self.state == ActivityState.RESUMED
2872                    || self.state == ActivityState.PAUSING) {
2873                mWindowManager.overridePendingAppTransition(packageName,
2874                        enterAnim, exitAnim, null);
2875            }
2876
2877            Binder.restoreCallingIdentity(origId);
2878        }
2879    }
2880
2881    /**
2882     * Main function for removing an existing process from the activity manager
2883     * as a result of that process going away.  Clears out all connections
2884     * to the process.
2885     */
2886    private final void handleAppDiedLocked(ProcessRecord app,
2887            boolean restarting, boolean allowRestart) {
2888        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2889        if (!restarting) {
2890            mLruProcesses.remove(app);
2891        }
2892
2893        if (mProfileProc == app) {
2894            clearProfilerLocked();
2895        }
2896
2897        // Just in case...
2898        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2899            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2900            mMainStack.mPausingActivity = null;
2901        }
2902        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2903            mMainStack.mLastPausedActivity = null;
2904        }
2905
2906        // Remove this application's activities from active lists.
2907        mMainStack.removeHistoryRecordsForAppLocked(app);
2908
2909        boolean atTop = true;
2910        boolean hasVisibleActivities = false;
2911
2912        // Clean out the history list.
2913        int i = mMainStack.mHistory.size();
2914        if (localLOGV) Slog.v(
2915            TAG, "Removing app " + app + " from history with " + i + " entries");
2916        while (i > 0) {
2917            i--;
2918            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2919            if (localLOGV) Slog.v(
2920                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2921            if (r.app == app) {
2922                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2923                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2924                        RuntimeException here = new RuntimeException("here");
2925                        here.fillInStackTrace();
2926                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2927                                + ": haveState=" + r.haveState
2928                                + " stateNotNeeded=" + r.stateNotNeeded
2929                                + " finishing=" + r.finishing
2930                                + " state=" + r.state, here);
2931                    }
2932                    if (!r.finishing) {
2933                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2934                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2935                                System.identityHashCode(r),
2936                                r.task.taskId, r.shortComponentName,
2937                                "proc died without state saved");
2938                    }
2939                    mMainStack.removeActivityFromHistoryLocked(r);
2940
2941                } else {
2942                    // We have the current state for this activity, so
2943                    // it can be restarted later when needed.
2944                    if (localLOGV) Slog.v(
2945                        TAG, "Keeping entry, setting app to null");
2946                    if (r.visible) {
2947                        hasVisibleActivities = true;
2948                    }
2949                    r.app = null;
2950                    r.nowVisible = false;
2951                    if (!r.haveState) {
2952                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2953                                "App died, clearing saved state of " + r);
2954                        r.icicle = null;
2955                    }
2956                }
2957
2958                r.stack.cleanUpActivityLocked(r, true, true);
2959            }
2960            atTop = false;
2961        }
2962
2963        app.activities.clear();
2964
2965        if (app.instrumentationClass != null) {
2966            Slog.w(TAG, "Crash of app " + app.processName
2967                  + " running instrumentation " + app.instrumentationClass);
2968            Bundle info = new Bundle();
2969            info.putString("shortMsg", "Process crashed.");
2970            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2971        }
2972
2973        if (!restarting) {
2974            if (!mMainStack.resumeTopActivityLocked(null)) {
2975                // If there was nothing to resume, and we are not already
2976                // restarting this process, but there is a visible activity that
2977                // is hosted by the process...  then make sure all visible
2978                // activities are running, taking care of restarting this
2979                // process.
2980                if (hasVisibleActivities) {
2981                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2982                }
2983            }
2984        }
2985    }
2986
2987    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2988        IBinder threadBinder = thread.asBinder();
2989        // Find the application record.
2990        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2991            ProcessRecord rec = mLruProcesses.get(i);
2992            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2993                return i;
2994            }
2995        }
2996        return -1;
2997    }
2998
2999    final ProcessRecord getRecordForAppLocked(
3000            IApplicationThread thread) {
3001        if (thread == null) {
3002            return null;
3003        }
3004
3005        int appIndex = getLRURecordIndexForAppLocked(thread);
3006        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3007    }
3008
3009    final void appDiedLocked(ProcessRecord app, int pid,
3010            IApplicationThread thread) {
3011
3012        mProcDeaths[0]++;
3013
3014        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3015        synchronized (stats) {
3016            stats.noteProcessDiedLocked(app.info.uid, pid);
3017        }
3018
3019        // Clean up already done if the process has been re-started.
3020        if (app.pid == pid && app.thread != null &&
3021                app.thread.asBinder() == thread.asBinder()) {
3022            if (!app.killedBackground) {
3023                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3024                        + ") has died.");
3025            }
3026            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
3027            if (localLOGV) Slog.v(
3028                TAG, "Dying app: " + app + ", pid: " + pid
3029                + ", thread: " + thread.asBinder());
3030            boolean doLowMem = app.instrumentationClass == null;
3031            handleAppDiedLocked(app, false, true);
3032
3033            if (doLowMem) {
3034                // If there are no longer any background processes running,
3035                // and the app that died was not running instrumentation,
3036                // then tell everyone we are now low on memory.
3037                boolean haveBg = false;
3038                for (int i=mLruProcesses.size()-1; i>=0; i--) {
3039                    ProcessRecord rec = mLruProcesses.get(i);
3040                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3041                        haveBg = true;
3042                        break;
3043                    }
3044                }
3045
3046                if (!haveBg) {
3047                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3048                    long now = SystemClock.uptimeMillis();
3049                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
3050                        ProcessRecord rec = mLruProcesses.get(i);
3051                        if (rec != app && rec.thread != null &&
3052                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3053                            // The low memory report is overriding any current
3054                            // state for a GC request.  Make sure to do
3055                            // heavy/important/visible/foreground processes first.
3056                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3057                                rec.lastRequestedGc = 0;
3058                            } else {
3059                                rec.lastRequestedGc = rec.lastLowMemory;
3060                            }
3061                            rec.reportLowMemory = true;
3062                            rec.lastLowMemory = now;
3063                            mProcessesToGc.remove(rec);
3064                            addProcessToGcListLocked(rec);
3065                        }
3066                    }
3067                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3068                    scheduleAppGcsLocked();
3069                }
3070            }
3071        } else if (app.pid != pid) {
3072            // A new process has already been started.
3073            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3074                    + ") has died and restarted (pid " + app.pid + ").");
3075            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
3076        } else if (DEBUG_PROCESSES) {
3077            Slog.d(TAG, "Received spurious death notification for thread "
3078                    + thread.asBinder());
3079        }
3080    }
3081
3082    /**
3083     * If a stack trace dump file is configured, dump process stack traces.
3084     * @param clearTraces causes the dump file to be erased prior to the new
3085     *    traces being written, if true; when false, the new traces will be
3086     *    appended to any existing file content.
3087     * @param firstPids of dalvik VM processes to dump stack traces for first
3088     * @param lastPids of dalvik VM processes to dump stack traces for last
3089     * @param nativeProcs optional list of native process names to dump stack crawls
3090     * @return file containing stack traces, or null if no dump file is configured
3091     */
3092    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3093            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3094        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3095        if (tracesPath == null || tracesPath.length() == 0) {
3096            return null;
3097        }
3098
3099        File tracesFile = new File(tracesPath);
3100        try {
3101            File tracesDir = tracesFile.getParentFile();
3102            if (!tracesDir.exists()) {
3103                tracesFile.mkdirs();
3104                if (!SELinux.restorecon(tracesDir)) {
3105                    return null;
3106                }
3107            }
3108            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3109
3110            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3111            tracesFile.createNewFile();
3112            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3113        } catch (IOException e) {
3114            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3115            return null;
3116        }
3117
3118        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3119        return tracesFile;
3120    }
3121
3122    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3123            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3124        // Use a FileObserver to detect when traces finish writing.
3125        // The order of traces is considered important to maintain for legibility.
3126        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3127            public synchronized void onEvent(int event, String path) { notify(); }
3128        };
3129
3130        try {
3131            observer.startWatching();
3132
3133            // First collect all of the stacks of the most important pids.
3134            if (firstPids != null) {
3135                try {
3136                    int num = firstPids.size();
3137                    for (int i = 0; i < num; i++) {
3138                        synchronized (observer) {
3139                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3140                            observer.wait(200);  // Wait for write-close, give up after 200msec
3141                        }
3142                    }
3143                } catch (InterruptedException e) {
3144                    Log.wtf(TAG, e);
3145                }
3146            }
3147
3148            // Next measure CPU usage.
3149            if (processStats != null) {
3150                processStats.init();
3151                System.gc();
3152                processStats.update();
3153                try {
3154                    synchronized (processStats) {
3155                        processStats.wait(500); // measure over 1/2 second.
3156                    }
3157                } catch (InterruptedException e) {
3158                }
3159                processStats.update();
3160
3161                // We'll take the stack crawls of just the top apps using CPU.
3162                final int N = processStats.countWorkingStats();
3163                int numProcs = 0;
3164                for (int i=0; i<N && numProcs<5; i++) {
3165                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3166                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3167                        numProcs++;
3168                        try {
3169                            synchronized (observer) {
3170                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3171                                observer.wait(200);  // Wait for write-close, give up after 200msec
3172                            }
3173                        } catch (InterruptedException e) {
3174                            Log.wtf(TAG, e);
3175                        }
3176
3177                    }
3178                }
3179            }
3180
3181        } finally {
3182            observer.stopWatching();
3183        }
3184
3185        if (nativeProcs != null) {
3186            int[] pids = Process.getPidsForCommands(nativeProcs);
3187            if (pids != null) {
3188                for (int pid : pids) {
3189                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3190                }
3191            }
3192        }
3193    }
3194
3195    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3196        if (true || IS_USER_BUILD) {
3197            return;
3198        }
3199        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3200        if (tracesPath == null || tracesPath.length() == 0) {
3201            return;
3202        }
3203
3204        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3205        StrictMode.allowThreadDiskWrites();
3206        try {
3207            final File tracesFile = new File(tracesPath);
3208            final File tracesDir = tracesFile.getParentFile();
3209            final File tracesTmp = new File(tracesDir, "__tmp__");
3210            try {
3211                if (!tracesDir.exists()) {
3212                    tracesFile.mkdirs();
3213                    if (!SELinux.restorecon(tracesDir.getPath())) {
3214                        return;
3215                    }
3216                }
3217                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3218
3219                if (tracesFile.exists()) {
3220                    tracesTmp.delete();
3221                    tracesFile.renameTo(tracesTmp);
3222                }
3223                StringBuilder sb = new StringBuilder();
3224                Time tobj = new Time();
3225                tobj.set(System.currentTimeMillis());
3226                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3227                sb.append(": ");
3228                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3229                sb.append(" since ");
3230                sb.append(msg);
3231                FileOutputStream fos = new FileOutputStream(tracesFile);
3232                fos.write(sb.toString().getBytes());
3233                if (app == null) {
3234                    fos.write("\n*** No application process!".getBytes());
3235                }
3236                fos.close();
3237                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3238            } catch (IOException e) {
3239                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3240                return;
3241            }
3242
3243            if (app != null) {
3244                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3245                firstPids.add(app.pid);
3246                dumpStackTraces(tracesPath, firstPids, null, null, null);
3247            }
3248
3249            File lastTracesFile = null;
3250            File curTracesFile = null;
3251            for (int i=9; i>=0; i--) {
3252                String name = String.format("slow%02d.txt", i);
3253                curTracesFile = new File(tracesDir, name);
3254                if (curTracesFile.exists()) {
3255                    if (lastTracesFile != null) {
3256                        curTracesFile.renameTo(lastTracesFile);
3257                    } else {
3258                        curTracesFile.delete();
3259                    }
3260                }
3261                lastTracesFile = curTracesFile;
3262            }
3263            tracesFile.renameTo(curTracesFile);
3264            if (tracesTmp.exists()) {
3265                tracesTmp.renameTo(tracesFile);
3266            }
3267        } finally {
3268            StrictMode.setThreadPolicy(oldPolicy);
3269        }
3270    }
3271
3272    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3273            ActivityRecord parent, final String annotation) {
3274        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3275        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3276
3277        if (mController != null) {
3278            try {
3279                // 0 == continue, -1 = kill process immediately
3280                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3281                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3282            } catch (RemoteException e) {
3283                mController = null;
3284            }
3285        }
3286
3287        long anrTime = SystemClock.uptimeMillis();
3288        if (MONITOR_CPU_USAGE) {
3289            updateCpuStatsNow();
3290        }
3291
3292        synchronized (this) {
3293            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3294            if (mShuttingDown) {
3295                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3296                return;
3297            } else if (app.notResponding) {
3298                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3299                return;
3300            } else if (app.crashing) {
3301                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3302                return;
3303            }
3304
3305            // In case we come through here for the same app before completing
3306            // this one, mark as anring now so we will bail out.
3307            app.notResponding = true;
3308
3309            // Log the ANR to the event log.
3310            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3311                    annotation);
3312
3313            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3314            firstPids.add(app.pid);
3315
3316            int parentPid = app.pid;
3317            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3318            if (parentPid != app.pid) firstPids.add(parentPid);
3319
3320            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3321
3322            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3323                ProcessRecord r = mLruProcesses.get(i);
3324                if (r != null && r.thread != null) {
3325                    int pid = r.pid;
3326                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3327                        if (r.persistent) {
3328                            firstPids.add(pid);
3329                        } else {
3330                            lastPids.put(pid, Boolean.TRUE);
3331                        }
3332                    }
3333                }
3334            }
3335        }
3336
3337        // Log the ANR to the main log.
3338        StringBuilder info = new StringBuilder();
3339        info.setLength(0);
3340        info.append("ANR in ").append(app.processName);
3341        if (activity != null && activity.shortComponentName != null) {
3342            info.append(" (").append(activity.shortComponentName).append(")");
3343        }
3344        info.append("\n");
3345        if (annotation != null) {
3346            info.append("Reason: ").append(annotation).append("\n");
3347        }
3348        if (parent != null && parent != activity) {
3349            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3350        }
3351
3352        final ProcessStats processStats = new ProcessStats(true);
3353
3354        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3355
3356        String cpuInfo = null;
3357        if (MONITOR_CPU_USAGE) {
3358            updateCpuStatsNow();
3359            synchronized (mProcessStatsThread) {
3360                cpuInfo = mProcessStats.printCurrentState(anrTime);
3361            }
3362            info.append(processStats.printCurrentLoad());
3363            info.append(cpuInfo);
3364        }
3365
3366        info.append(processStats.printCurrentState(anrTime));
3367
3368        Slog.e(TAG, info.toString());
3369        if (tracesFile == null) {
3370            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3371            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3372        }
3373
3374        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3375                cpuInfo, tracesFile, null);
3376
3377        if (mController != null) {
3378            try {
3379                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3380                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3381                if (res != 0) {
3382                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3383                    return;
3384                }
3385            } catch (RemoteException e) {
3386                mController = null;
3387            }
3388        }
3389
3390        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3391        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3392                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3393
3394        synchronized (this) {
3395            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3396                Slog.w(TAG, "Killing " + app + ": background ANR");
3397                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3398                        app.processName, app.setAdj, "background ANR");
3399                Process.killProcessQuiet(app.pid);
3400                return;
3401            }
3402
3403            // Set the app's notResponding state, and look up the errorReportReceiver
3404            makeAppNotRespondingLocked(app,
3405                    activity != null ? activity.shortComponentName : null,
3406                    annotation != null ? "ANR " + annotation : "ANR",
3407                    info.toString());
3408
3409            // Bring up the infamous App Not Responding dialog
3410            Message msg = Message.obtain();
3411            HashMap map = new HashMap();
3412            msg.what = SHOW_NOT_RESPONDING_MSG;
3413            msg.obj = map;
3414            map.put("app", app);
3415            if (activity != null) {
3416                map.put("activity", activity);
3417            }
3418
3419            mHandler.sendMessage(msg);
3420        }
3421    }
3422
3423    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3424        if (!mLaunchWarningShown) {
3425            mLaunchWarningShown = true;
3426            mHandler.post(new Runnable() {
3427                @Override
3428                public void run() {
3429                    synchronized (ActivityManagerService.this) {
3430                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3431                        d.show();
3432                        mHandler.postDelayed(new Runnable() {
3433                            @Override
3434                            public void run() {
3435                                synchronized (ActivityManagerService.this) {
3436                                    d.dismiss();
3437                                    mLaunchWarningShown = false;
3438                                }
3439                            }
3440                        }, 4000);
3441                    }
3442                }
3443            });
3444        }
3445    }
3446
3447    public boolean clearApplicationUserData(final String packageName,
3448            final IPackageDataObserver observer, int userId) {
3449        enforceNotIsolatedCaller("clearApplicationUserData");
3450        int uid = Binder.getCallingUid();
3451        int pid = Binder.getCallingPid();
3452        userId = handleIncomingUserLocked(pid, uid,
3453                userId, false, true, "clearApplicationUserData", null);
3454        long callingId = Binder.clearCallingIdentity();
3455        try {
3456            IPackageManager pm = AppGlobals.getPackageManager();
3457            int pkgUid = -1;
3458            synchronized(this) {
3459                try {
3460                    pkgUid = pm.getPackageUid(packageName, userId);
3461                } catch (RemoteException e) {
3462                }
3463                if (pkgUid == -1) {
3464                    Slog.w(TAG, "Invalid packageName:" + packageName);
3465                    return false;
3466                }
3467                if (uid == pkgUid || checkComponentPermission(
3468                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3469                        pid, uid, -1, true)
3470                        == PackageManager.PERMISSION_GRANTED) {
3471                    forceStopPackageLocked(packageName, pkgUid);
3472                } else {
3473                    throw new SecurityException(pid+" does not have permission:"+
3474                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3475                                    "for process:"+packageName);
3476                }
3477            }
3478
3479            try {
3480                //clear application user data
3481                pm.clearApplicationUserData(packageName, observer, userId);
3482                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3483                        Uri.fromParts("package", packageName, null));
3484                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3485                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3486                        null, null, 0, null, null, null, false, false, userId);
3487            } catch (RemoteException e) {
3488            }
3489        } finally {
3490            Binder.restoreCallingIdentity(callingId);
3491        }
3492        return true;
3493    }
3494
3495    public void killBackgroundProcesses(final String packageName, int userId) {
3496        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3497                != PackageManager.PERMISSION_GRANTED &&
3498                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3499                        != PackageManager.PERMISSION_GRANTED) {
3500            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3501                    + Binder.getCallingPid()
3502                    + ", uid=" + Binder.getCallingUid()
3503                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3504            Slog.w(TAG, msg);
3505            throw new SecurityException(msg);
3506        }
3507
3508        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
3509                userId, true, true, "killBackgroundProcesses", null);
3510        long callingId = Binder.clearCallingIdentity();
3511        try {
3512            IPackageManager pm = AppGlobals.getPackageManager();
3513            synchronized(this) {
3514                int appId = -1;
3515                try {
3516                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
3517                } catch (RemoteException e) {
3518                }
3519                if (appId == -1) {
3520                    Slog.w(TAG, "Invalid packageName: " + packageName);
3521                    return;
3522                }
3523                killPackageProcessesLocked(packageName, appId, userId,
3524                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3525            }
3526        } finally {
3527            Binder.restoreCallingIdentity(callingId);
3528        }
3529    }
3530
3531    public void killAllBackgroundProcesses() {
3532        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3533                != PackageManager.PERMISSION_GRANTED) {
3534            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3535                    + Binder.getCallingPid()
3536                    + ", uid=" + Binder.getCallingUid()
3537                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3538            Slog.w(TAG, msg);
3539            throw new SecurityException(msg);
3540        }
3541
3542        long callingId = Binder.clearCallingIdentity();
3543        try {
3544            synchronized(this) {
3545                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3546                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3547                    final int NA = apps.size();
3548                    for (int ia=0; ia<NA; ia++) {
3549                        ProcessRecord app = apps.valueAt(ia);
3550                        if (app.persistent) {
3551                            // we don't kill persistent processes
3552                            continue;
3553                        }
3554                        if (app.removed) {
3555                            procs.add(app);
3556                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3557                            app.removed = true;
3558                            procs.add(app);
3559                        }
3560                    }
3561                }
3562
3563                int N = procs.size();
3564                for (int i=0; i<N; i++) {
3565                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3566                }
3567            }
3568        } finally {
3569            Binder.restoreCallingIdentity(callingId);
3570        }
3571    }
3572
3573    public void forceStopPackage(final String packageName, int userId) {
3574        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3575                != PackageManager.PERMISSION_GRANTED) {
3576            String msg = "Permission Denial: forceStopPackage() from pid="
3577                    + Binder.getCallingPid()
3578                    + ", uid=" + Binder.getCallingUid()
3579                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3580            Slog.w(TAG, msg);
3581            throw new SecurityException(msg);
3582        }
3583        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
3584                userId, true, true, "forceStopPackage", null);
3585        long callingId = Binder.clearCallingIdentity();
3586        try {
3587            IPackageManager pm = AppGlobals.getPackageManager();
3588            synchronized(this) {
3589                int[] users = userId == UserHandle.USER_ALL
3590                        ? getUsersLocked() : new int[] { userId };
3591                for (int user : users) {
3592                    int pkgUid = -1;
3593                    try {
3594                        pkgUid = pm.getPackageUid(packageName, user);
3595                    } catch (RemoteException e) {
3596                    }
3597                    if (pkgUid == -1) {
3598                        Slog.w(TAG, "Invalid packageName: " + packageName);
3599                        continue;
3600                    }
3601                    try {
3602                        pm.setPackageStoppedState(packageName, true, user);
3603                    } catch (RemoteException e) {
3604                    } catch (IllegalArgumentException e) {
3605                        Slog.w(TAG, "Failed trying to unstop package "
3606                                + packageName + ": " + e);
3607                    }
3608                    if (isUserRunningLocked(user)) {
3609                        forceStopPackageLocked(packageName, pkgUid);
3610                    }
3611                }
3612            }
3613        } finally {
3614            Binder.restoreCallingIdentity(callingId);
3615        }
3616    }
3617
3618    /*
3619     * The pkg name and app id have to be specified.
3620     */
3621    public void killApplicationWithAppId(String pkg, int appid) {
3622        if (pkg == null) {
3623            return;
3624        }
3625        // Make sure the uid is valid.
3626        if (appid < 0) {
3627            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
3628            return;
3629        }
3630        int callerUid = Binder.getCallingUid();
3631        // Only the system server can kill an application
3632        if (callerUid == Process.SYSTEM_UID) {
3633            // Post an aysnc message to kill the application
3634            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3635            msg.arg1 = appid;
3636            msg.arg2 = 0;
3637            msg.obj = pkg;
3638            mHandler.sendMessage(msg);
3639        } else {
3640            throw new SecurityException(callerUid + " cannot kill pkg: " +
3641                    pkg);
3642        }
3643    }
3644
3645    public void closeSystemDialogs(String reason) {
3646        enforceNotIsolatedCaller("closeSystemDialogs");
3647
3648        final int pid = Binder.getCallingPid();
3649        final int uid = Binder.getCallingUid();
3650        final long origId = Binder.clearCallingIdentity();
3651        try {
3652            synchronized (this) {
3653                // Only allow this from foreground processes, so that background
3654                // applications can't abuse it to prevent system UI from being shown.
3655                if (uid >= Process.FIRST_APPLICATION_UID) {
3656                    ProcessRecord proc;
3657                    synchronized (mPidsSelfLocked) {
3658                        proc = mPidsSelfLocked.get(pid);
3659                    }
3660                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
3661                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
3662                                + " from background process " + proc);
3663                        return;
3664                    }
3665                }
3666                closeSystemDialogsLocked(reason);
3667            }
3668        } finally {
3669            Binder.restoreCallingIdentity(origId);
3670        }
3671    }
3672
3673    void closeSystemDialogsLocked(String reason) {
3674        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3675        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3676        if (reason != null) {
3677            intent.putExtra("reason", reason);
3678        }
3679        mWindowManager.closeSystemDialogs(reason);
3680
3681        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3682            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3683            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3684                r.stack.finishActivityLocked(r, i,
3685                        Activity.RESULT_CANCELED, null, "close-sys", true);
3686            }
3687        }
3688
3689        broadcastIntentLocked(null, null, intent, null,
3690                null, 0, null, null, null, false, false, -1,
3691                Process.SYSTEM_UID, UserHandle.USER_ALL);
3692    }
3693
3694    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3695            throws RemoteException {
3696        enforceNotIsolatedCaller("getProcessMemoryInfo");
3697        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3698        for (int i=pids.length-1; i>=0; i--) {
3699            infos[i] = new Debug.MemoryInfo();
3700            Debug.getMemoryInfo(pids[i], infos[i]);
3701        }
3702        return infos;
3703    }
3704
3705    public long[] getProcessPss(int[] pids) throws RemoteException {
3706        enforceNotIsolatedCaller("getProcessPss");
3707        long[] pss = new long[pids.length];
3708        for (int i=pids.length-1; i>=0; i--) {
3709            pss[i] = Debug.getPss(pids[i]);
3710        }
3711        return pss;
3712    }
3713
3714    public void killApplicationProcess(String processName, int uid) {
3715        if (processName == null) {
3716            return;
3717        }
3718
3719        int callerUid = Binder.getCallingUid();
3720        // Only the system server can kill an application
3721        if (callerUid == Process.SYSTEM_UID) {
3722            synchronized (this) {
3723                ProcessRecord app = getProcessRecordLocked(processName, uid);
3724                if (app != null && app.thread != null) {
3725                    try {
3726                        app.thread.scheduleSuicide();
3727                    } catch (RemoteException e) {
3728                        // If the other end already died, then our work here is done.
3729                    }
3730                } else {
3731                    Slog.w(TAG, "Process/uid not found attempting kill of "
3732                            + processName + " / " + uid);
3733                }
3734            }
3735        } else {
3736            throw new SecurityException(callerUid + " cannot kill app process: " +
3737                    processName);
3738        }
3739    }
3740
3741    private void forceStopPackageLocked(final String packageName, int uid) {
3742        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
3743                false, true, false, UserHandle.getUserId(uid));
3744        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3745                Uri.fromParts("package", packageName, null));
3746        if (!mProcessesReady) {
3747            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3748        }
3749        intent.putExtra(Intent.EXTRA_UID, uid);
3750        broadcastIntentLocked(null, null, intent,
3751                null, null, 0, null, null, null,
3752                false, false,
3753                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3754    }
3755
3756    private void forceStopUserLocked(int userId) {
3757        forceStopPackageLocked(null, -1, false, false, true, false, userId);
3758        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
3759        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3760        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3761        broadcastIntentLocked(null, null, intent,
3762                null, null, 0, null, null, null,
3763                false, false,
3764                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
3765    }
3766
3767    private final boolean killPackageProcessesLocked(String packageName, int appId,
3768            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
3769            boolean doit, boolean evenPersistent, String reason) {
3770        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3771
3772        // Remove all processes this package may have touched: all with the
3773        // same UID (except for the system or root user), and all whose name
3774        // matches the package name.
3775        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
3776        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3777            final int NA = apps.size();
3778            for (int ia=0; ia<NA; ia++) {
3779                ProcessRecord app = apps.valueAt(ia);
3780                if (app.persistent && !evenPersistent) {
3781                    // we don't kill persistent processes
3782                    continue;
3783                }
3784                if (app.removed) {
3785                    if (doit) {
3786                        procs.add(app);
3787                    }
3788                    continue;
3789                }
3790
3791                // Skip process if it doesn't meet our oom adj requirement.
3792                if (app.setAdj < minOomAdj) {
3793                    continue;
3794                }
3795
3796                // If no package is specified, we call all processes under the
3797                // give user id.
3798                if (packageName == null) {
3799                    if (app.userId != userId) {
3800                        continue;
3801                    }
3802                // Package has been specified, we want to hit all processes
3803                // that match it.  We need to qualify this by the processes
3804                // that are running under the specified app and user ID.
3805                } else {
3806                    if (UserHandle.getAppId(app.uid) != appId) {
3807                        continue;
3808                    }
3809                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
3810                        continue;
3811                    }
3812                    if (!app.pkgList.contains(packageName)) {
3813                        continue;
3814                    }
3815                }
3816
3817                // Process has passed all conditions, kill it!
3818                if (!doit) {
3819                    return true;
3820                }
3821                app.removed = true;
3822                procs.add(app);
3823            }
3824        }
3825
3826        int N = procs.size();
3827        for (int i=0; i<N; i++) {
3828            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3829        }
3830        return N > 0;
3831    }
3832
3833    private final boolean forceStopPackageLocked(String name, int appId,
3834            boolean callerWillRestart, boolean purgeCache, boolean doit,
3835            boolean evenPersistent, int userId) {
3836        int i;
3837        int N;
3838
3839        if (userId == UserHandle.USER_ALL && name == null) {
3840            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
3841        }
3842
3843        if (appId < 0 && name != null) {
3844            try {
3845                appId = UserHandle.getAppId(
3846                        AppGlobals.getPackageManager().getPackageUid(name, 0));
3847            } catch (RemoteException e) {
3848            }
3849        }
3850
3851        if (doit) {
3852            if (name != null) {
3853                Slog.i(TAG, "Force stopping package " + name + " appid=" + appId
3854                        + " user=" + userId);
3855            } else {
3856                Slog.i(TAG, "Force stopping user " + userId);
3857            }
3858
3859            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3860            while (badApps.hasNext()) {
3861                SparseArray<Long> ba = badApps.next();
3862                for (i=ba.size()-1; i>=0; i--) {
3863                    boolean remove = false;
3864                    final int entUid = ba.keyAt(i);
3865                    if (name != null) {
3866                        if (userId == UserHandle.USER_ALL) {
3867                            if (UserHandle.getAppId(entUid) == appId) {
3868                                remove = true;
3869                            }
3870                        } else {
3871                            if (entUid == UserHandle.getUid(userId, appId)) {
3872                                remove = true;
3873                            }
3874                        }
3875                    } else if (UserHandle.getUserId(entUid) == userId) {
3876                        remove = true;
3877                    }
3878                    if (remove) {
3879                        ba.removeAt(i);
3880                    }
3881                }
3882                if (ba.size() == 0) {
3883                    badApps.remove();
3884                }
3885            }
3886        }
3887
3888        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
3889                -100, callerWillRestart, false, doit, evenPersistent,
3890                name == null ? ("force stop user " + userId) : ("force stop " + name));
3891
3892        TaskRecord lastTask = null;
3893        for (i=0; i<mMainStack.mHistory.size(); i++) {
3894            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3895            final boolean samePackage = r.packageName.equals(name)
3896                    || (name == null && r.userId == userId);
3897            if ((userId == UserHandle.USER_ALL || r.userId == userId)
3898                    && (samePackage || r.task == lastTask)
3899                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3900                if (!doit) {
3901                    if (r.finishing) {
3902                        // If this activity is just finishing, then it is not
3903                        // interesting as far as something to stop.
3904                        continue;
3905                    }
3906                    return true;
3907                }
3908                didSomething = true;
3909                Slog.i(TAG, "  Force finishing activity " + r);
3910                if (samePackage) {
3911                    if (r.app != null) {
3912                        r.app.removed = true;
3913                    }
3914                    r.app = null;
3915                }
3916                lastTask = r.task;
3917                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3918                        null, "force-stop", true)) {
3919                    i--;
3920                }
3921            }
3922        }
3923
3924        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3925            if (!doit) {
3926                return true;
3927            }
3928            didSomething = true;
3929        }
3930
3931        if (name == null) {
3932            // Remove all sticky broadcasts from this user.
3933            mStickyBroadcasts.remove(userId);
3934        }
3935
3936        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3937        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
3938                userId, providers)) {
3939            if (!doit) {
3940                return true;
3941            }
3942            didSomething = true;
3943        }
3944        N = providers.size();
3945        for (i=0; i<N; i++) {
3946            removeDyingProviderLocked(null, providers.get(i), true);
3947        }
3948
3949        if (mIntentSenderRecords.size() > 0) {
3950            Iterator<WeakReference<PendingIntentRecord>> it
3951                    = mIntentSenderRecords.values().iterator();
3952            while (it.hasNext()) {
3953                WeakReference<PendingIntentRecord> wpir = it.next();
3954                if (wpir == null) {
3955                    it.remove();
3956                    continue;
3957                }
3958                PendingIntentRecord pir = wpir.get();
3959                if (pir == null) {
3960                    it.remove();
3961                    continue;
3962                }
3963                if (name == null) {
3964                    // Stopping user, remove all objects for the user.
3965                    if (pir.key.userId != userId) {
3966                        // Not the same user, skip it.
3967                        continue;
3968                    }
3969                } else {
3970                    if (UserHandle.getAppId(pir.uid) != appId) {
3971                        // Different app id, skip it.
3972                        continue;
3973                    }
3974                    if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
3975                        // Different user, skip it.
3976                        continue;
3977                    }
3978                    if (!pir.key.packageName.equals(name)) {
3979                        // Different package, skip it.
3980                        continue;
3981                    }
3982                }
3983                if (!doit) {
3984                    return true;
3985                }
3986                didSomething = true;
3987                it.remove();
3988                pir.canceled = true;
3989                if (pir.key.activity != null) {
3990                    pir.key.activity.pendingResults.remove(pir.ref);
3991                }
3992            }
3993        }
3994
3995        if (doit) {
3996            if (purgeCache && name != null) {
3997                AttributeCache ac = AttributeCache.instance();
3998                if (ac != null) {
3999                    ac.removePackage(name);
4000                }
4001            }
4002            if (mBooted) {
4003                mMainStack.resumeTopActivityLocked(null);
4004                mMainStack.scheduleIdleLocked();
4005            }
4006        }
4007
4008        return didSomething;
4009    }
4010
4011    private final boolean removeProcessLocked(ProcessRecord app,
4012            boolean callerWillRestart, boolean allowRestart, String reason) {
4013        final String name = app.processName;
4014        final int uid = app.uid;
4015        if (DEBUG_PROCESSES) Slog.d(
4016            TAG, "Force removing proc " + app.toShortString() + " (" + name
4017            + "/" + uid + ")");
4018
4019        mProcessNames.remove(name, uid);
4020        mIsolatedProcesses.remove(app.uid);
4021        if (mHeavyWeightProcess == app) {
4022            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4023                    mHeavyWeightProcess.userId, 0));
4024            mHeavyWeightProcess = null;
4025        }
4026        boolean needRestart = false;
4027        if (app.pid > 0 && app.pid != MY_PID) {
4028            int pid = app.pid;
4029            synchronized (mPidsSelfLocked) {
4030                mPidsSelfLocked.remove(pid);
4031                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4032            }
4033            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
4034            handleAppDiedLocked(app, true, allowRestart);
4035            mLruProcesses.remove(app);
4036            Process.killProcessQuiet(pid);
4037
4038            if (app.persistent && !app.isolated) {
4039                if (!callerWillRestart) {
4040                    addAppLocked(app.info, false);
4041                } else {
4042                    needRestart = true;
4043                }
4044            }
4045        } else {
4046            mRemovedProcesses.add(app);
4047        }
4048
4049        return needRestart;
4050    }
4051
4052    private final void processStartTimedOutLocked(ProcessRecord app) {
4053        final int pid = app.pid;
4054        boolean gone = false;
4055        synchronized (mPidsSelfLocked) {
4056            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4057            if (knownApp != null && knownApp.thread == null) {
4058                mPidsSelfLocked.remove(pid);
4059                gone = true;
4060            }
4061        }
4062
4063        if (gone) {
4064            Slog.w(TAG, "Process " + app + " failed to attach");
4065            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
4066                    app.processName);
4067            mProcessNames.remove(app.processName, app.uid);
4068            mIsolatedProcesses.remove(app.uid);
4069            if (mHeavyWeightProcess == app) {
4070                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4071                        mHeavyWeightProcess.userId, 0));
4072                mHeavyWeightProcess = null;
4073            }
4074            // Take care of any launching providers waiting for this process.
4075            checkAppInLaunchingProvidersLocked(app, true);
4076            // Take care of any services that are waiting for the process.
4077            mServices.processStartTimedOutLocked(app);
4078            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
4079                    app.processName, app.setAdj, "start timeout");
4080            Process.killProcessQuiet(pid);
4081            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4082                Slog.w(TAG, "Unattached app died before backup, skipping");
4083                try {
4084                    IBackupManager bm = IBackupManager.Stub.asInterface(
4085                            ServiceManager.getService(Context.BACKUP_SERVICE));
4086                    bm.agentDisconnected(app.info.packageName);
4087                } catch (RemoteException e) {
4088                    // Can't happen; the backup manager is local
4089                }
4090            }
4091            if (isPendingBroadcastProcessLocked(pid)) {
4092                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4093                skipPendingBroadcastLocked(pid);
4094            }
4095        } else {
4096            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4097        }
4098    }
4099
4100    private final boolean attachApplicationLocked(IApplicationThread thread,
4101            int pid) {
4102
4103        // Find the application record that is being attached...  either via
4104        // the pid if we are running in multiple processes, or just pull the
4105        // next app record if we are emulating process with anonymous threads.
4106        ProcessRecord app;
4107        if (pid != MY_PID && pid >= 0) {
4108            synchronized (mPidsSelfLocked) {
4109                app = mPidsSelfLocked.get(pid);
4110            }
4111        } else {
4112            app = null;
4113        }
4114
4115        if (app == null) {
4116            Slog.w(TAG, "No pending application record for pid " + pid
4117                    + " (IApplicationThread " + thread + "); dropping process");
4118            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4119            if (pid > 0 && pid != MY_PID) {
4120                Process.killProcessQuiet(pid);
4121            } else {
4122                try {
4123                    thread.scheduleExit();
4124                } catch (Exception e) {
4125                    // Ignore exceptions.
4126                }
4127            }
4128            return false;
4129        }
4130
4131        // If this application record is still attached to a previous
4132        // process, clean it up now.
4133        if (app.thread != null) {
4134            handleAppDiedLocked(app, true, true);
4135        }
4136
4137        // Tell the process all about itself.
4138
4139        if (localLOGV) Slog.v(
4140                TAG, "Binding process pid " + pid + " to record " + app);
4141
4142        String processName = app.processName;
4143        try {
4144            AppDeathRecipient adr = new AppDeathRecipient(
4145                    app, pid, thread);
4146            thread.asBinder().linkToDeath(adr, 0);
4147            app.deathRecipient = adr;
4148        } catch (RemoteException e) {
4149            app.resetPackageList();
4150            startProcessLocked(app, "link fail", processName);
4151            return false;
4152        }
4153
4154        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
4155
4156        app.thread = thread;
4157        app.curAdj = app.setAdj = -100;
4158        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4159        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
4160        app.forcingToForeground = null;
4161        app.foregroundServices = false;
4162        app.hasShownUi = false;
4163        app.debugging = false;
4164
4165        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4166
4167        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4168        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4169
4170        if (!normalMode) {
4171            Slog.i(TAG, "Launching preboot mode app: " + app);
4172        }
4173
4174        if (localLOGV) Slog.v(
4175            TAG, "New app record " + app
4176            + " thread=" + thread.asBinder() + " pid=" + pid);
4177        try {
4178            int testMode = IApplicationThread.DEBUG_OFF;
4179            if (mDebugApp != null && mDebugApp.equals(processName)) {
4180                testMode = mWaitForDebugger
4181                    ? IApplicationThread.DEBUG_WAIT
4182                    : IApplicationThread.DEBUG_ON;
4183                app.debugging = true;
4184                if (mDebugTransient) {
4185                    mDebugApp = mOrigDebugApp;
4186                    mWaitForDebugger = mOrigWaitForDebugger;
4187                }
4188            }
4189            String profileFile = app.instrumentationProfileFile;
4190            ParcelFileDescriptor profileFd = null;
4191            boolean profileAutoStop = false;
4192            if (mProfileApp != null && mProfileApp.equals(processName)) {
4193                mProfileProc = app;
4194                profileFile = mProfileFile;
4195                profileFd = mProfileFd;
4196                profileAutoStop = mAutoStopProfiler;
4197            }
4198            boolean enableOpenGlTrace = false;
4199            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4200                enableOpenGlTrace = true;
4201                mOpenGlTraceApp = null;
4202            }
4203
4204            // If the app is being launched for restore or full backup, set it up specially
4205            boolean isRestrictedBackupMode = false;
4206            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4207                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4208                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4209                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4210            }
4211
4212            ensurePackageDexOpt(app.instrumentationInfo != null
4213                    ? app.instrumentationInfo.packageName
4214                    : app.info.packageName);
4215            if (app.instrumentationClass != null) {
4216                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4217            }
4218            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4219                    + processName + " with config " + mConfiguration);
4220            ApplicationInfo appInfo = app.instrumentationInfo != null
4221                    ? app.instrumentationInfo : app.info;
4222            app.compat = compatibilityInfoForPackageLocked(appInfo);
4223            if (profileFd != null) {
4224                profileFd = profileFd.dup();
4225            }
4226            thread.bindApplication(processName, appInfo, providers,
4227                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4228                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4229                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4230                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4231                    mCoreSettingsObserver.getCoreSettingsLocked());
4232            updateLruProcessLocked(app, false, true);
4233            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4234        } catch (Exception e) {
4235            // todo: Yikes!  What should we do?  For now we will try to
4236            // start another process, but that could easily get us in
4237            // an infinite loop of restarting processes...
4238            Slog.w(TAG, "Exception thrown during bind!", e);
4239
4240            app.resetPackageList();
4241            app.unlinkDeathRecipient();
4242            startProcessLocked(app, "bind fail", processName);
4243            return false;
4244        }
4245
4246        // Remove this record from the list of starting applications.
4247        mPersistentStartingProcesses.remove(app);
4248        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4249                "Attach application locked removing on hold: " + app);
4250        mProcessesOnHold.remove(app);
4251
4252        boolean badApp = false;
4253        boolean didSomething = false;
4254
4255        // See if the top visible activity is waiting to run in this process...
4256        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4257        if (hr != null && normalMode) {
4258            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4259                    && processName.equals(hr.processName)) {
4260                try {
4261                    if (mHeadless) {
4262                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4263                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4264                        didSomething = true;
4265                    }
4266                } catch (Exception e) {
4267                    Slog.w(TAG, "Exception in new application when starting activity "
4268                          + hr.intent.getComponent().flattenToShortString(), e);
4269                    badApp = true;
4270                }
4271            } else {
4272                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4273            }
4274        }
4275
4276        // Find any services that should be running in this process...
4277        if (!badApp) {
4278            try {
4279                didSomething |= mServices.attachApplicationLocked(app, processName);
4280            } catch (Exception e) {
4281                badApp = true;
4282            }
4283        }
4284
4285        // Check if a next-broadcast receiver is in this process...
4286        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4287            try {
4288                didSomething = sendPendingBroadcastsLocked(app);
4289            } catch (Exception e) {
4290                // If the app died trying to launch the receiver we declare it 'bad'
4291                badApp = true;
4292            }
4293        }
4294
4295        // Check whether the next backup agent is in this process...
4296        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4297            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4298            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4299            try {
4300                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4301                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4302                        mBackupTarget.backupMode);
4303            } catch (Exception e) {
4304                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4305                e.printStackTrace();
4306            }
4307        }
4308
4309        if (badApp) {
4310            // todo: Also need to kill application to deal with all
4311            // kinds of exceptions.
4312            handleAppDiedLocked(app, false, true);
4313            return false;
4314        }
4315
4316        if (!didSomething) {
4317            updateOomAdjLocked();
4318        }
4319
4320        return true;
4321    }
4322
4323    public final void attachApplication(IApplicationThread thread) {
4324        synchronized (this) {
4325            int callingPid = Binder.getCallingPid();
4326            final long origId = Binder.clearCallingIdentity();
4327            attachApplicationLocked(thread, callingPid);
4328            Binder.restoreCallingIdentity(origId);
4329        }
4330    }
4331
4332    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4333        final long origId = Binder.clearCallingIdentity();
4334        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4335        if (stopProfiling) {
4336            synchronized (this) {
4337                if (mProfileProc == r.app) {
4338                    if (mProfileFd != null) {
4339                        try {
4340                            mProfileFd.close();
4341                        } catch (IOException e) {
4342                        }
4343                        clearProfilerLocked();
4344                    }
4345                }
4346            }
4347        }
4348        Binder.restoreCallingIdentity(origId);
4349    }
4350
4351    void enableScreenAfterBoot() {
4352        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4353                SystemClock.uptimeMillis());
4354        mWindowManager.enableScreenAfterBoot();
4355
4356        synchronized (this) {
4357            updateEventDispatchingLocked();
4358        }
4359    }
4360
4361    public void showBootMessage(final CharSequence msg, final boolean always) {
4362        enforceNotIsolatedCaller("showBootMessage");
4363        mWindowManager.showBootMessage(msg, always);
4364    }
4365
4366    public void dismissKeyguardOnNextActivity() {
4367        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4368        final long token = Binder.clearCallingIdentity();
4369        try {
4370            synchronized (this) {
4371                if (mLockScreenShown) {
4372                    mLockScreenShown = false;
4373                    comeOutOfSleepIfNeededLocked();
4374                }
4375                mMainStack.dismissKeyguardOnNextActivityLocked();
4376            }
4377        } finally {
4378            Binder.restoreCallingIdentity(token);
4379        }
4380    }
4381
4382    final void finishBooting() {
4383        IntentFilter pkgFilter = new IntentFilter();
4384        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4385        pkgFilter.addDataScheme("package");
4386        mContext.registerReceiver(new BroadcastReceiver() {
4387            @Override
4388            public void onReceive(Context context, Intent intent) {
4389                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4390                if (pkgs != null) {
4391                    for (String pkg : pkgs) {
4392                        synchronized (ActivityManagerService.this) {
4393                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4394                                setResultCode(Activity.RESULT_OK);
4395                                return;
4396                            }
4397                        }
4398                    }
4399                }
4400            }
4401        }, pkgFilter);
4402
4403        synchronized (this) {
4404            // Ensure that any processes we had put on hold are now started
4405            // up.
4406            final int NP = mProcessesOnHold.size();
4407            if (NP > 0) {
4408                ArrayList<ProcessRecord> procs =
4409                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4410                for (int ip=0; ip<NP; ip++) {
4411                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4412                            + procs.get(ip));
4413                    startProcessLocked(procs.get(ip), "on-hold", null);
4414                }
4415            }
4416
4417            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4418                // Start looking for apps that are abusing wake locks.
4419                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4420                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4421                // Tell anyone interested that we are done booting!
4422                SystemProperties.set("sys.boot_completed", "1");
4423                SystemProperties.set("dev.bootcomplete", "1");
4424                for (int i=0; i<mStartedUsers.size(); i++) {
4425                    UserStartedState uss = mStartedUsers.valueAt(i);
4426                    if (uss.mState == UserStartedState.STATE_BOOTING) {
4427                        uss.mState = UserStartedState.STATE_RUNNING;
4428                        final int userId = mStartedUsers.keyAt(i);
4429                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
4430                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4431                        broadcastIntentLocked(null, null, intent,
4432                                null, null, 0, null, null,
4433                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4434                                false, false, MY_PID, Process.SYSTEM_UID, userId);
4435                    }
4436                }
4437            }
4438        }
4439    }
4440
4441    final void ensureBootCompleted() {
4442        boolean booting;
4443        boolean enableScreen;
4444        synchronized (this) {
4445            booting = mBooting;
4446            mBooting = false;
4447            enableScreen = !mBooted;
4448            mBooted = true;
4449        }
4450
4451        if (booting) {
4452            finishBooting();
4453        }
4454
4455        if (enableScreen) {
4456            enableScreenAfterBoot();
4457        }
4458    }
4459
4460    public final void activityResumed(IBinder token) {
4461        final long origId = Binder.clearCallingIdentity();
4462        mMainStack.activityResumed(token);
4463        Binder.restoreCallingIdentity(origId);
4464    }
4465
4466    public final void activityPaused(IBinder token) {
4467        final long origId = Binder.clearCallingIdentity();
4468        mMainStack.activityPaused(token, false);
4469        Binder.restoreCallingIdentity(origId);
4470    }
4471
4472    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4473            CharSequence description) {
4474        if (localLOGV) Slog.v(
4475            TAG, "Activity stopped: token=" + token);
4476
4477        // Refuse possible leaked file descriptors
4478        if (icicle != null && icicle.hasFileDescriptors()) {
4479            throw new IllegalArgumentException("File descriptors passed in Bundle");
4480        }
4481
4482        ActivityRecord r = null;
4483
4484        final long origId = Binder.clearCallingIdentity();
4485
4486        synchronized (this) {
4487            r = mMainStack.isInStackLocked(token);
4488            if (r != null) {
4489                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4490            }
4491        }
4492
4493        if (r != null) {
4494            sendPendingThumbnail(r, null, null, null, false);
4495        }
4496
4497        trimApplications();
4498
4499        Binder.restoreCallingIdentity(origId);
4500    }
4501
4502    public final void activityDestroyed(IBinder token) {
4503        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4504        mMainStack.activityDestroyed(token);
4505    }
4506
4507    public String getCallingPackage(IBinder token) {
4508        synchronized (this) {
4509            ActivityRecord r = getCallingRecordLocked(token);
4510            return r != null && r.app != null ? r.info.packageName : null;
4511        }
4512    }
4513
4514    public ComponentName getCallingActivity(IBinder token) {
4515        synchronized (this) {
4516            ActivityRecord r = getCallingRecordLocked(token);
4517            return r != null ? r.intent.getComponent() : null;
4518        }
4519    }
4520
4521    private ActivityRecord getCallingRecordLocked(IBinder token) {
4522        ActivityRecord r = mMainStack.isInStackLocked(token);
4523        if (r == null) {
4524            return null;
4525        }
4526        return r.resultTo;
4527    }
4528
4529    public ComponentName getActivityClassForToken(IBinder token) {
4530        synchronized(this) {
4531            ActivityRecord r = mMainStack.isInStackLocked(token);
4532            if (r == null) {
4533                return null;
4534            }
4535            return r.intent.getComponent();
4536        }
4537    }
4538
4539    public String getPackageForToken(IBinder token) {
4540        synchronized(this) {
4541            ActivityRecord r = mMainStack.isInStackLocked(token);
4542            if (r == null) {
4543                return null;
4544            }
4545            return r.packageName;
4546        }
4547    }
4548
4549    public IIntentSender getIntentSender(int type,
4550            String packageName, IBinder token, String resultWho,
4551            int requestCode, Intent[] intents, String[] resolvedTypes,
4552            int flags, Bundle options, int userId) {
4553        enforceNotIsolatedCaller("getIntentSender");
4554        // Refuse possible leaked file descriptors
4555        if (intents != null) {
4556            if (intents.length < 1) {
4557                throw new IllegalArgumentException("Intents array length must be >= 1");
4558            }
4559            for (int i=0; i<intents.length; i++) {
4560                Intent intent = intents[i];
4561                if (intent != null) {
4562                    if (intent.hasFileDescriptors()) {
4563                        throw new IllegalArgumentException("File descriptors passed in Intent");
4564                    }
4565                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4566                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4567                        throw new IllegalArgumentException(
4568                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4569                    }
4570                    intents[i] = new Intent(intent);
4571                }
4572            }
4573            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4574                throw new IllegalArgumentException(
4575                        "Intent array length does not match resolvedTypes length");
4576            }
4577        }
4578        if (options != null) {
4579            if (options.hasFileDescriptors()) {
4580                throw new IllegalArgumentException("File descriptors passed in options");
4581            }
4582        }
4583
4584        synchronized(this) {
4585            int callingUid = Binder.getCallingUid();
4586            userId = handleIncomingUserLocked(Binder.getCallingPid(), callingUid, userId,
4587                    false, true, "getIntentSender", null);
4588            try {
4589                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4590                    int uid = AppGlobals.getPackageManager()
4591                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4592                    if (!UserHandle.isSameApp(callingUid, uid)) {
4593                        String msg = "Permission Denial: getIntentSender() from pid="
4594                            + Binder.getCallingPid()
4595                            + ", uid=" + Binder.getCallingUid()
4596                            + ", (need uid=" + uid + ")"
4597                            + " is not allowed to send as package " + packageName;
4598                        Slog.w(TAG, msg);
4599                        throw new SecurityException(msg);
4600                    }
4601                }
4602
4603                return getIntentSenderLocked(type, packageName, callingUid, userId,
4604                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4605
4606            } catch (RemoteException e) {
4607                throw new SecurityException(e);
4608            }
4609        }
4610    }
4611
4612    IIntentSender getIntentSenderLocked(int type, String packageName,
4613            int callingUid, int userId, IBinder token, String resultWho,
4614            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4615            Bundle options) {
4616        if (DEBUG_MU)
4617            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4618        ActivityRecord activity = null;
4619        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4620            activity = mMainStack.isInStackLocked(token);
4621            if (activity == null) {
4622                return null;
4623            }
4624            if (activity.finishing) {
4625                return null;
4626            }
4627        }
4628
4629        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4630        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4631        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4632        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4633                |PendingIntent.FLAG_UPDATE_CURRENT);
4634
4635        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4636                type, packageName, activity, resultWho,
4637                requestCode, intents, resolvedTypes, flags, options, userId);
4638        WeakReference<PendingIntentRecord> ref;
4639        ref = mIntentSenderRecords.get(key);
4640        PendingIntentRecord rec = ref != null ? ref.get() : null;
4641        if (rec != null) {
4642            if (!cancelCurrent) {
4643                if (updateCurrent) {
4644                    if (rec.key.requestIntent != null) {
4645                        rec.key.requestIntent.replaceExtras(intents != null ?
4646                                intents[intents.length - 1] : null);
4647                    }
4648                    if (intents != null) {
4649                        intents[intents.length-1] = rec.key.requestIntent;
4650                        rec.key.allIntents = intents;
4651                        rec.key.allResolvedTypes = resolvedTypes;
4652                    } else {
4653                        rec.key.allIntents = null;
4654                        rec.key.allResolvedTypes = null;
4655                    }
4656                }
4657                return rec;
4658            }
4659            rec.canceled = true;
4660            mIntentSenderRecords.remove(key);
4661        }
4662        if (noCreate) {
4663            return rec;
4664        }
4665        rec = new PendingIntentRecord(this, key, callingUid);
4666        mIntentSenderRecords.put(key, rec.ref);
4667        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4668            if (activity.pendingResults == null) {
4669                activity.pendingResults
4670                        = new HashSet<WeakReference<PendingIntentRecord>>();
4671            }
4672            activity.pendingResults.add(rec.ref);
4673        }
4674        return rec;
4675    }
4676
4677    public void cancelIntentSender(IIntentSender sender) {
4678        if (!(sender instanceof PendingIntentRecord)) {
4679            return;
4680        }
4681        synchronized(this) {
4682            PendingIntentRecord rec = (PendingIntentRecord)sender;
4683            try {
4684                int uid = AppGlobals.getPackageManager()
4685                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4686                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4687                    String msg = "Permission Denial: cancelIntentSender() from pid="
4688                        + Binder.getCallingPid()
4689                        + ", uid=" + Binder.getCallingUid()
4690                        + " is not allowed to cancel packges "
4691                        + rec.key.packageName;
4692                    Slog.w(TAG, msg);
4693                    throw new SecurityException(msg);
4694                }
4695            } catch (RemoteException e) {
4696                throw new SecurityException(e);
4697            }
4698            cancelIntentSenderLocked(rec, true);
4699        }
4700    }
4701
4702    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4703        rec.canceled = true;
4704        mIntentSenderRecords.remove(rec.key);
4705        if (cleanActivity && rec.key.activity != null) {
4706            rec.key.activity.pendingResults.remove(rec.ref);
4707        }
4708    }
4709
4710    public String getPackageForIntentSender(IIntentSender pendingResult) {
4711        if (!(pendingResult instanceof PendingIntentRecord)) {
4712            return null;
4713        }
4714        try {
4715            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4716            return res.key.packageName;
4717        } catch (ClassCastException e) {
4718        }
4719        return null;
4720    }
4721
4722    public int getUidForIntentSender(IIntentSender sender) {
4723        if (sender instanceof PendingIntentRecord) {
4724            try {
4725                PendingIntentRecord res = (PendingIntentRecord)sender;
4726                return res.uid;
4727            } catch (ClassCastException e) {
4728            }
4729        }
4730        return -1;
4731    }
4732
4733    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4734        if (!(pendingResult instanceof PendingIntentRecord)) {
4735            return false;
4736        }
4737        try {
4738            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4739            if (res.key.allIntents == null) {
4740                return false;
4741            }
4742            for (int i=0; i<res.key.allIntents.length; i++) {
4743                Intent intent = res.key.allIntents[i];
4744                if (intent.getPackage() != null && intent.getComponent() != null) {
4745                    return false;
4746                }
4747            }
4748            return true;
4749        } catch (ClassCastException e) {
4750        }
4751        return false;
4752    }
4753
4754    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4755        if (!(pendingResult instanceof PendingIntentRecord)) {
4756            return false;
4757        }
4758        try {
4759            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4760            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4761                return true;
4762            }
4763            return false;
4764        } catch (ClassCastException e) {
4765        }
4766        return false;
4767    }
4768
4769    public void setProcessLimit(int max) {
4770        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4771                "setProcessLimit()");
4772        synchronized (this) {
4773            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4774            mProcessLimitOverride = max;
4775        }
4776        trimApplications();
4777    }
4778
4779    public int getProcessLimit() {
4780        synchronized (this) {
4781            return mProcessLimitOverride;
4782        }
4783    }
4784
4785    void foregroundTokenDied(ForegroundToken token) {
4786        synchronized (ActivityManagerService.this) {
4787            synchronized (mPidsSelfLocked) {
4788                ForegroundToken cur
4789                    = mForegroundProcesses.get(token.pid);
4790                if (cur != token) {
4791                    return;
4792                }
4793                mForegroundProcesses.remove(token.pid);
4794                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4795                if (pr == null) {
4796                    return;
4797                }
4798                pr.forcingToForeground = null;
4799                pr.foregroundServices = false;
4800            }
4801            updateOomAdjLocked();
4802        }
4803    }
4804
4805    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4806        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4807                "setProcessForeground()");
4808        synchronized(this) {
4809            boolean changed = false;
4810
4811            synchronized (mPidsSelfLocked) {
4812                ProcessRecord pr = mPidsSelfLocked.get(pid);
4813                if (pr == null && isForeground) {
4814                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4815                    return;
4816                }
4817                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4818                if (oldToken != null) {
4819                    oldToken.token.unlinkToDeath(oldToken, 0);
4820                    mForegroundProcesses.remove(pid);
4821                    if (pr != null) {
4822                        pr.forcingToForeground = null;
4823                    }
4824                    changed = true;
4825                }
4826                if (isForeground && token != null) {
4827                    ForegroundToken newToken = new ForegroundToken() {
4828                        public void binderDied() {
4829                            foregroundTokenDied(this);
4830                        }
4831                    };
4832                    newToken.pid = pid;
4833                    newToken.token = token;
4834                    try {
4835                        token.linkToDeath(newToken, 0);
4836                        mForegroundProcesses.put(pid, newToken);
4837                        pr.forcingToForeground = token;
4838                        changed = true;
4839                    } catch (RemoteException e) {
4840                        // If the process died while doing this, we will later
4841                        // do the cleanup with the process death link.
4842                    }
4843                }
4844            }
4845
4846            if (changed) {
4847                updateOomAdjLocked();
4848            }
4849        }
4850    }
4851
4852    // =========================================================
4853    // PERMISSIONS
4854    // =========================================================
4855
4856    static class PermissionController extends IPermissionController.Stub {
4857        ActivityManagerService mActivityManagerService;
4858        PermissionController(ActivityManagerService activityManagerService) {
4859            mActivityManagerService = activityManagerService;
4860        }
4861
4862        public boolean checkPermission(String permission, int pid, int uid) {
4863            return mActivityManagerService.checkPermission(permission, pid,
4864                    uid) == PackageManager.PERMISSION_GRANTED;
4865        }
4866    }
4867
4868    /**
4869     * This can be called with or without the global lock held.
4870     */
4871    int checkComponentPermission(String permission, int pid, int uid,
4872            int owningUid, boolean exported) {
4873        // We might be performing an operation on behalf of an indirect binder
4874        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4875        // client identity accordingly before proceeding.
4876        Identity tlsIdentity = sCallerIdentity.get();
4877        if (tlsIdentity != null) {
4878            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4879                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4880            uid = tlsIdentity.uid;
4881            pid = tlsIdentity.pid;
4882        }
4883
4884        if (pid == MY_PID) {
4885            return PackageManager.PERMISSION_GRANTED;
4886        }
4887
4888        return ActivityManager.checkComponentPermission(permission, uid,
4889                owningUid, exported);
4890    }
4891
4892    /**
4893     * As the only public entry point for permissions checking, this method
4894     * can enforce the semantic that requesting a check on a null global
4895     * permission is automatically denied.  (Internally a null permission
4896     * string is used when calling {@link #checkComponentPermission} in cases
4897     * when only uid-based security is needed.)
4898     *
4899     * This can be called with or without the global lock held.
4900     */
4901    public int checkPermission(String permission, int pid, int uid) {
4902        if (permission == null) {
4903            return PackageManager.PERMISSION_DENIED;
4904        }
4905        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4906    }
4907
4908    /**
4909     * Binder IPC calls go through the public entry point.
4910     * This can be called with or without the global lock held.
4911     */
4912    int checkCallingPermission(String permission) {
4913        return checkPermission(permission,
4914                Binder.getCallingPid(),
4915                UserHandle.getAppId(Binder.getCallingUid()));
4916    }
4917
4918    /**
4919     * This can be called with or without the global lock held.
4920     */
4921    void enforceCallingPermission(String permission, String func) {
4922        if (checkCallingPermission(permission)
4923                == PackageManager.PERMISSION_GRANTED) {
4924            return;
4925        }
4926
4927        String msg = "Permission Denial: " + func + " from pid="
4928                + Binder.getCallingPid()
4929                + ", uid=" + Binder.getCallingUid()
4930                + " requires " + permission;
4931        Slog.w(TAG, msg);
4932        throw new SecurityException(msg);
4933    }
4934
4935    /**
4936     * Determine if UID is holding permissions required to access {@link Uri} in
4937     * the given {@link ProviderInfo}. Final permission checking is always done
4938     * in {@link ContentProvider}.
4939     */
4940    private final boolean checkHoldingPermissionsLocked(
4941            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4942        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4943                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4944
4945        if (pi.applicationInfo.uid == uid) {
4946            return true;
4947        } else if (!pi.exported) {
4948            return false;
4949        }
4950
4951        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4952        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4953        try {
4954            // check if target holds top-level <provider> permissions
4955            if (!readMet && pi.readPermission != null
4956                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4957                readMet = true;
4958            }
4959            if (!writeMet && pi.writePermission != null
4960                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4961                writeMet = true;
4962            }
4963
4964            // track if unprotected read/write is allowed; any denied
4965            // <path-permission> below removes this ability
4966            boolean allowDefaultRead = pi.readPermission == null;
4967            boolean allowDefaultWrite = pi.writePermission == null;
4968
4969            // check if target holds any <path-permission> that match uri
4970            final PathPermission[] pps = pi.pathPermissions;
4971            if (pps != null) {
4972                final String path = uri.getPath();
4973                int i = pps.length;
4974                while (i > 0 && (!readMet || !writeMet)) {
4975                    i--;
4976                    PathPermission pp = pps[i];
4977                    if (pp.match(path)) {
4978                        if (!readMet) {
4979                            final String pprperm = pp.getReadPermission();
4980                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4981                                    + pprperm + " for " + pp.getPath()
4982                                    + ": match=" + pp.match(path)
4983                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4984                            if (pprperm != null) {
4985                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4986                                    readMet = true;
4987                                } else {
4988                                    allowDefaultRead = false;
4989                                }
4990                            }
4991                        }
4992                        if (!writeMet) {
4993                            final String ppwperm = pp.getWritePermission();
4994                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4995                                    + ppwperm + " for " + pp.getPath()
4996                                    + ": match=" + pp.match(path)
4997                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4998                            if (ppwperm != null) {
4999                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5000                                    writeMet = true;
5001                                } else {
5002                                    allowDefaultWrite = false;
5003                                }
5004                            }
5005                        }
5006                    }
5007                }
5008            }
5009
5010            // grant unprotected <provider> read/write, if not blocked by
5011            // <path-permission> above
5012            if (allowDefaultRead) readMet = true;
5013            if (allowDefaultWrite) writeMet = true;
5014
5015        } catch (RemoteException e) {
5016            return false;
5017        }
5018
5019        return readMet && writeMet;
5020    }
5021
5022    private final boolean checkUriPermissionLocked(Uri uri, int uid,
5023            int modeFlags) {
5024        // Root gets to do everything.
5025        if (uid == 0) {
5026            return true;
5027        }
5028        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5029        if (perms == null) return false;
5030        UriPermission perm = perms.get(uri);
5031        if (perm == null) return false;
5032        return (modeFlags&perm.modeFlags) == modeFlags;
5033    }
5034
5035    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5036        enforceNotIsolatedCaller("checkUriPermission");
5037
5038        // Another redirected-binder-call permissions check as in
5039        // {@link checkComponentPermission}.
5040        Identity tlsIdentity = sCallerIdentity.get();
5041        if (tlsIdentity != null) {
5042            uid = tlsIdentity.uid;
5043            pid = tlsIdentity.pid;
5044        }
5045
5046        // Our own process gets to do everything.
5047        if (pid == MY_PID) {
5048            return PackageManager.PERMISSION_GRANTED;
5049        }
5050        synchronized(this) {
5051            return checkUriPermissionLocked(uri, uid, modeFlags)
5052                    ? PackageManager.PERMISSION_GRANTED
5053                    : PackageManager.PERMISSION_DENIED;
5054        }
5055    }
5056
5057    /**
5058     * Check if the targetPkg can be granted permission to access uri by
5059     * the callingUid using the given modeFlags.  Throws a security exception
5060     * if callingUid is not allowed to do this.  Returns the uid of the target
5061     * if the URI permission grant should be performed; returns -1 if it is not
5062     * needed (for example targetPkg already has permission to access the URI).
5063     * If you already know the uid of the target, you can supply it in
5064     * lastTargetUid else set that to -1.
5065     */
5066    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5067            Uri uri, int modeFlags, int lastTargetUid) {
5068        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5069                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5070        if (modeFlags == 0) {
5071            return -1;
5072        }
5073
5074        if (targetPkg != null) {
5075            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5076                    "Checking grant " + targetPkg + " permission to " + uri);
5077        }
5078
5079        final IPackageManager pm = AppGlobals.getPackageManager();
5080
5081        // If this is not a content: uri, we can't do anything with it.
5082        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5083            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5084                    "Can't grant URI permission for non-content URI: " + uri);
5085            return -1;
5086        }
5087
5088        String name = uri.getAuthority();
5089        ProviderInfo pi = null;
5090        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
5091                UserHandle.getUserId(callingUid));
5092        if (cpr != null) {
5093            pi = cpr.info;
5094        } else {
5095            try {
5096                pi = pm.resolveContentProvider(name,
5097                        PackageManager.GET_URI_PERMISSION_PATTERNS,
5098                        UserHandle.getUserId(callingUid));
5099            } catch (RemoteException ex) {
5100            }
5101        }
5102        if (pi == null) {
5103            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5104            return -1;
5105        }
5106
5107        int targetUid = lastTargetUid;
5108        if (targetUid < 0 && targetPkg != null) {
5109            try {
5110                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5111                if (targetUid < 0) {
5112                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5113                            "Can't grant URI permission no uid for: " + targetPkg);
5114                    return -1;
5115                }
5116            } catch (RemoteException ex) {
5117                return -1;
5118            }
5119        }
5120
5121        if (targetUid >= 0) {
5122            // First...  does the target actually need this permission?
5123            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5124                // No need to grant the target this permission.
5125                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5126                        "Target " + targetPkg + " already has full permission to " + uri);
5127                return -1;
5128            }
5129        } else {
5130            // First...  there is no target package, so can anyone access it?
5131            boolean allowed = pi.exported;
5132            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5133                if (pi.readPermission != null) {
5134                    allowed = false;
5135                }
5136            }
5137            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5138                if (pi.writePermission != null) {
5139                    allowed = false;
5140                }
5141            }
5142            if (allowed) {
5143                return -1;
5144            }
5145        }
5146
5147        // Second...  is the provider allowing granting of URI permissions?
5148        if (!pi.grantUriPermissions) {
5149            throw new SecurityException("Provider " + pi.packageName
5150                    + "/" + pi.name
5151                    + " does not allow granting of Uri permissions (uri "
5152                    + uri + ")");
5153        }
5154        if (pi.uriPermissionPatterns != null) {
5155            final int N = pi.uriPermissionPatterns.length;
5156            boolean allowed = false;
5157            for (int i=0; i<N; i++) {
5158                if (pi.uriPermissionPatterns[i] != null
5159                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5160                    allowed = true;
5161                    break;
5162                }
5163            }
5164            if (!allowed) {
5165                throw new SecurityException("Provider " + pi.packageName
5166                        + "/" + pi.name
5167                        + " does not allow granting of permission to path of Uri "
5168                        + uri);
5169            }
5170        }
5171
5172        // Third...  does the caller itself have permission to access
5173        // this uri?
5174        if (callingUid != Process.myUid()) {
5175            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5176                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5177                    throw new SecurityException("Uid " + callingUid
5178                            + " does not have permission to uri " + uri);
5179                }
5180            }
5181        }
5182
5183        return targetUid;
5184    }
5185
5186    public int checkGrantUriPermission(int callingUid, String targetPkg,
5187            Uri uri, int modeFlags) {
5188        enforceNotIsolatedCaller("checkGrantUriPermission");
5189        synchronized(this) {
5190            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5191        }
5192    }
5193
5194    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5195            Uri uri, int modeFlags, UriPermissionOwner owner) {
5196        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5197                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5198        if (modeFlags == 0) {
5199            return;
5200        }
5201
5202        // So here we are: the caller has the assumed permission
5203        // to the uri, and the target doesn't.  Let's now give this to
5204        // the target.
5205
5206        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5207                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5208
5209        HashMap<Uri, UriPermission> targetUris
5210                = mGrantedUriPermissions.get(targetUid);
5211        if (targetUris == null) {
5212            targetUris = new HashMap<Uri, UriPermission>();
5213            mGrantedUriPermissions.put(targetUid, targetUris);
5214        }
5215
5216        UriPermission perm = targetUris.get(uri);
5217        if (perm == null) {
5218            perm = new UriPermission(targetUid, uri);
5219            targetUris.put(uri, perm);
5220        }
5221
5222        perm.modeFlags |= modeFlags;
5223        if (owner == null) {
5224            perm.globalModeFlags |= modeFlags;
5225        } else {
5226            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5227                 perm.readOwners.add(owner);
5228                 owner.addReadPermission(perm);
5229            }
5230            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5231                 perm.writeOwners.add(owner);
5232                 owner.addWritePermission(perm);
5233            }
5234        }
5235    }
5236
5237    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5238            int modeFlags, UriPermissionOwner owner) {
5239        if (targetPkg == null) {
5240            throw new NullPointerException("targetPkg");
5241        }
5242
5243        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5244        if (targetUid < 0) {
5245            return;
5246        }
5247
5248        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5249    }
5250
5251    static class NeededUriGrants extends ArrayList<Uri> {
5252        final String targetPkg;
5253        final int targetUid;
5254        final int flags;
5255
5256        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5257            targetPkg = _targetPkg;
5258            targetUid = _targetUid;
5259            flags = _flags;
5260        }
5261    }
5262
5263    /**
5264     * Like checkGrantUriPermissionLocked, but takes an Intent.
5265     */
5266    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5267            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5268        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5269                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5270                + " clip=" + (intent != null ? intent.getClipData() : null)
5271                + " from " + intent + "; flags=0x"
5272                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5273
5274        if (targetPkg == null) {
5275            throw new NullPointerException("targetPkg");
5276        }
5277
5278        if (intent == null) {
5279            return null;
5280        }
5281        Uri data = intent.getData();
5282        ClipData clip = intent.getClipData();
5283        if (data == null && clip == null) {
5284            return null;
5285        }
5286        if (data != null) {
5287            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5288                mode, needed != null ? needed.targetUid : -1);
5289            if (target > 0) {
5290                if (needed == null) {
5291                    needed = new NeededUriGrants(targetPkg, target, mode);
5292                }
5293                needed.add(data);
5294            }
5295        }
5296        if (clip != null) {
5297            for (int i=0; i<clip.getItemCount(); i++) {
5298                Uri uri = clip.getItemAt(i).getUri();
5299                if (uri != null) {
5300                    int target = -1;
5301                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5302                            mode, needed != null ? needed.targetUid : -1);
5303                    if (target > 0) {
5304                        if (needed == null) {
5305                            needed = new NeededUriGrants(targetPkg, target, mode);
5306                        }
5307                        needed.add(uri);
5308                    }
5309                } else {
5310                    Intent clipIntent = clip.getItemAt(i).getIntent();
5311                    if (clipIntent != null) {
5312                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5313                                callingUid, targetPkg, clipIntent, mode, needed);
5314                        if (newNeeded != null) {
5315                            needed = newNeeded;
5316                        }
5317                    }
5318                }
5319            }
5320        }
5321
5322        return needed;
5323    }
5324
5325    /**
5326     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5327     */
5328    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5329            UriPermissionOwner owner) {
5330        if (needed != null) {
5331            for (int i=0; i<needed.size(); i++) {
5332                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5333                        needed.get(i), needed.flags, owner);
5334            }
5335        }
5336    }
5337
5338    void grantUriPermissionFromIntentLocked(int callingUid,
5339            String targetPkg, Intent intent, UriPermissionOwner owner) {
5340        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5341                intent, intent != null ? intent.getFlags() : 0, null);
5342        if (needed == null) {
5343            return;
5344        }
5345
5346        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5347    }
5348
5349    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5350            Uri uri, int modeFlags) {
5351        enforceNotIsolatedCaller("grantUriPermission");
5352        synchronized(this) {
5353            final ProcessRecord r = getRecordForAppLocked(caller);
5354            if (r == null) {
5355                throw new SecurityException("Unable to find app for caller "
5356                        + caller
5357                        + " when granting permission to uri " + uri);
5358            }
5359            if (targetPkg == null) {
5360                throw new IllegalArgumentException("null target");
5361            }
5362            if (uri == null) {
5363                throw new IllegalArgumentException("null uri");
5364            }
5365
5366            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5367                    null);
5368        }
5369    }
5370
5371    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5372        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5373                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5374            HashMap<Uri, UriPermission> perms
5375                    = mGrantedUriPermissions.get(perm.uid);
5376            if (perms != null) {
5377                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5378                        "Removing " + perm.uid + " permission to " + perm.uri);
5379                perms.remove(perm.uri);
5380                if (perms.size() == 0) {
5381                    mGrantedUriPermissions.remove(perm.uid);
5382                }
5383            }
5384        }
5385    }
5386
5387    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5388            int modeFlags) {
5389        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5390                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5391        if (modeFlags == 0) {
5392            return;
5393        }
5394
5395        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5396                "Revoking all granted permissions to " + uri);
5397
5398        final IPackageManager pm = AppGlobals.getPackageManager();
5399
5400        final String authority = uri.getAuthority();
5401        ProviderInfo pi = null;
5402        int userId = UserHandle.getUserId(callingUid);
5403        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5404        if (cpr != null) {
5405            pi = cpr.info;
5406        } else {
5407            try {
5408                pi = pm.resolveContentProvider(authority,
5409                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5410            } catch (RemoteException ex) {
5411            }
5412        }
5413        if (pi == null) {
5414            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5415            return;
5416        }
5417
5418        // Does the caller have this permission on the URI?
5419        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5420            // Right now, if you are not the original owner of the permission,
5421            // you are not allowed to revoke it.
5422            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5423                throw new SecurityException("Uid " + callingUid
5424                        + " does not have permission to uri " + uri);
5425            //}
5426        }
5427
5428        // Go through all of the permissions and remove any that match.
5429        final List<String> SEGMENTS = uri.getPathSegments();
5430        if (SEGMENTS != null) {
5431            final int NS = SEGMENTS.size();
5432            int N = mGrantedUriPermissions.size();
5433            for (int i=0; i<N; i++) {
5434                HashMap<Uri, UriPermission> perms
5435                        = mGrantedUriPermissions.valueAt(i);
5436                Iterator<UriPermission> it = perms.values().iterator();
5437            toploop:
5438                while (it.hasNext()) {
5439                    UriPermission perm = it.next();
5440                    Uri targetUri = perm.uri;
5441                    if (!authority.equals(targetUri.getAuthority())) {
5442                        continue;
5443                    }
5444                    List<String> targetSegments = targetUri.getPathSegments();
5445                    if (targetSegments == null) {
5446                        continue;
5447                    }
5448                    if (targetSegments.size() < NS) {
5449                        continue;
5450                    }
5451                    for (int j=0; j<NS; j++) {
5452                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5453                            continue toploop;
5454                        }
5455                    }
5456                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5457                            "Revoking " + perm.uid + " permission to " + perm.uri);
5458                    perm.clearModes(modeFlags);
5459                    if (perm.modeFlags == 0) {
5460                        it.remove();
5461                    }
5462                }
5463                if (perms.size() == 0) {
5464                    mGrantedUriPermissions.remove(
5465                            mGrantedUriPermissions.keyAt(i));
5466                    N--;
5467                    i--;
5468                }
5469            }
5470        }
5471    }
5472
5473    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5474            int modeFlags) {
5475        enforceNotIsolatedCaller("revokeUriPermission");
5476        synchronized(this) {
5477            final ProcessRecord r = getRecordForAppLocked(caller);
5478            if (r == null) {
5479                throw new SecurityException("Unable to find app for caller "
5480                        + caller
5481                        + " when revoking permission to uri " + uri);
5482            }
5483            if (uri == null) {
5484                Slog.w(TAG, "revokeUriPermission: null uri");
5485                return;
5486            }
5487
5488            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5489                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5490            if (modeFlags == 0) {
5491                return;
5492            }
5493
5494            final IPackageManager pm = AppGlobals.getPackageManager();
5495
5496            final String authority = uri.getAuthority();
5497            ProviderInfo pi = null;
5498            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5499            if (cpr != null) {
5500                pi = cpr.info;
5501            } else {
5502                try {
5503                    pi = pm.resolveContentProvider(authority,
5504                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5505                } catch (RemoteException ex) {
5506                }
5507            }
5508            if (pi == null) {
5509                Slog.w(TAG, "No content provider found for permission revoke: "
5510                        + uri.toSafeString());
5511                return;
5512            }
5513
5514            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5515        }
5516    }
5517
5518    @Override
5519    public IBinder newUriPermissionOwner(String name) {
5520        enforceNotIsolatedCaller("newUriPermissionOwner");
5521        synchronized(this) {
5522            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5523            return owner.getExternalTokenLocked();
5524        }
5525    }
5526
5527    @Override
5528    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5529            Uri uri, int modeFlags) {
5530        synchronized(this) {
5531            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5532            if (owner == null) {
5533                throw new IllegalArgumentException("Unknown owner: " + token);
5534            }
5535            if (fromUid != Binder.getCallingUid()) {
5536                if (Binder.getCallingUid() != Process.myUid()) {
5537                    // Only system code can grant URI permissions on behalf
5538                    // of other users.
5539                    throw new SecurityException("nice try");
5540                }
5541            }
5542            if (targetPkg == null) {
5543                throw new IllegalArgumentException("null target");
5544            }
5545            if (uri == null) {
5546                throw new IllegalArgumentException("null uri");
5547            }
5548
5549            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5550        }
5551    }
5552
5553    @Override
5554    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5555        synchronized(this) {
5556            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5557            if (owner == null) {
5558                throw new IllegalArgumentException("Unknown owner: " + token);
5559            }
5560
5561            if (uri == null) {
5562                owner.removeUriPermissionsLocked(mode);
5563            } else {
5564                owner.removeUriPermissionLocked(uri, mode);
5565            }
5566        }
5567    }
5568
5569    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5570        synchronized (this) {
5571            ProcessRecord app =
5572                who != null ? getRecordForAppLocked(who) : null;
5573            if (app == null) return;
5574
5575            Message msg = Message.obtain();
5576            msg.what = WAIT_FOR_DEBUGGER_MSG;
5577            msg.obj = app;
5578            msg.arg1 = waiting ? 1 : 0;
5579            mHandler.sendMessage(msg);
5580        }
5581    }
5582
5583    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5584        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5585        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5586        outInfo.availMem = Process.getFreeMemory();
5587        outInfo.totalMem = Process.getTotalMemory();
5588        outInfo.threshold = homeAppMem;
5589        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5590        outInfo.hiddenAppThreshold = hiddenAppMem;
5591        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5592                ProcessList.SERVICE_ADJ);
5593        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5594                ProcessList.VISIBLE_APP_ADJ);
5595        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5596                ProcessList.FOREGROUND_APP_ADJ);
5597    }
5598
5599    // =========================================================
5600    // TASK MANAGEMENT
5601    // =========================================================
5602
5603    public List getTasks(int maxNum, int flags,
5604                         IThumbnailReceiver receiver) {
5605        ArrayList list = new ArrayList();
5606
5607        PendingThumbnailsRecord pending = null;
5608        IApplicationThread topThumbnail = null;
5609        ActivityRecord topRecord = null;
5610
5611        synchronized(this) {
5612            if (localLOGV) Slog.v(
5613                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5614                + ", receiver=" + receiver);
5615
5616            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5617                    != PackageManager.PERMISSION_GRANTED) {
5618                if (receiver != null) {
5619                    // If the caller wants to wait for pending thumbnails,
5620                    // it ain't gonna get them.
5621                    try {
5622                        receiver.finished();
5623                    } catch (RemoteException ex) {
5624                    }
5625                }
5626                String msg = "Permission Denial: getTasks() from pid="
5627                        + Binder.getCallingPid()
5628                        + ", uid=" + Binder.getCallingUid()
5629                        + " requires " + android.Manifest.permission.GET_TASKS;
5630                Slog.w(TAG, msg);
5631                throw new SecurityException(msg);
5632            }
5633
5634            int pos = mMainStack.mHistory.size()-1;
5635            ActivityRecord next =
5636                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5637            ActivityRecord top = null;
5638            TaskRecord curTask = null;
5639            int numActivities = 0;
5640            int numRunning = 0;
5641            while (pos >= 0 && maxNum > 0) {
5642                final ActivityRecord r = next;
5643                pos--;
5644                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5645
5646                // Initialize state for next task if needed.
5647                if (top == null ||
5648                        (top.state == ActivityState.INITIALIZING
5649                            && top.task == r.task)) {
5650                    top = r;
5651                    curTask = r.task;
5652                    numActivities = numRunning = 0;
5653                }
5654
5655                // Add 'r' into the current task.
5656                numActivities++;
5657                if (r.app != null && r.app.thread != null) {
5658                    numRunning++;
5659                }
5660
5661                if (localLOGV) Slog.v(
5662                    TAG, r.intent.getComponent().flattenToShortString()
5663                    + ": task=" + r.task);
5664
5665                // If the next one is a different task, generate a new
5666                // TaskInfo entry for what we have.
5667                if (next == null || next.task != curTask) {
5668                    ActivityManager.RunningTaskInfo ci
5669                            = new ActivityManager.RunningTaskInfo();
5670                    ci.id = curTask.taskId;
5671                    ci.baseActivity = r.intent.getComponent();
5672                    ci.topActivity = top.intent.getComponent();
5673                    if (top.thumbHolder != null) {
5674                        ci.description = top.thumbHolder.lastDescription;
5675                    }
5676                    ci.numActivities = numActivities;
5677                    ci.numRunning = numRunning;
5678                    //System.out.println(
5679                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5680                    if (ci.thumbnail == null && receiver != null) {
5681                        if (localLOGV) Slog.v(
5682                            TAG, "State=" + top.state + "Idle=" + top.idle
5683                            + " app=" + top.app
5684                            + " thr=" + (top.app != null ? top.app.thread : null));
5685                        if (top.state == ActivityState.RESUMED
5686                                || top.state == ActivityState.PAUSING) {
5687                            if (top.idle && top.app != null
5688                                && top.app.thread != null) {
5689                                topRecord = top;
5690                                topThumbnail = top.app.thread;
5691                            } else {
5692                                top.thumbnailNeeded = true;
5693                            }
5694                        }
5695                        if (pending == null) {
5696                            pending = new PendingThumbnailsRecord(receiver);
5697                        }
5698                        pending.pendingRecords.add(top);
5699                    }
5700                    list.add(ci);
5701                    maxNum--;
5702                    top = null;
5703                }
5704            }
5705
5706            if (pending != null) {
5707                mPendingThumbnails.add(pending);
5708            }
5709        }
5710
5711        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5712
5713        if (topThumbnail != null) {
5714            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5715            try {
5716                topThumbnail.requestThumbnail(topRecord.appToken);
5717            } catch (Exception e) {
5718                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5719                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5720            }
5721        }
5722
5723        if (pending == null && receiver != null) {
5724            // In this case all thumbnails were available and the client
5725            // is being asked to be told when the remaining ones come in...
5726            // which is unusually, since the top-most currently running
5727            // activity should never have a canned thumbnail!  Oh well.
5728            try {
5729                receiver.finished();
5730            } catch (RemoteException ex) {
5731            }
5732        }
5733
5734        return list;
5735    }
5736
5737    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5738            int flags, int userId) {
5739        final int callingUid = Binder.getCallingUid();
5740        if (userId != UserHandle.getCallingUserId()) {
5741            // Check if the caller is holding permissions for cross-user requests.
5742            if (checkComponentPermission(
5743                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5744                    Binder.getCallingPid(), callingUid, -1, true)
5745                    != PackageManager.PERMISSION_GRANTED) {
5746                String msg = "Permission Denial: "
5747                        + "Request to get recent tasks for user " + userId
5748                        + " but is calling from user " + UserHandle.getUserId(callingUid)
5749                        + "; this requires "
5750                        + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
5751                Slog.w(TAG, msg);
5752                throw new SecurityException(msg);
5753            } else {
5754                if (userId == UserHandle.USER_CURRENT) {
5755                    userId = mCurrentUserId;
5756                }
5757            }
5758        }
5759
5760        synchronized (this) {
5761            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5762                    "getRecentTasks()");
5763            final boolean detailed = checkCallingPermission(
5764                    android.Manifest.permission.GET_DETAILED_TASKS)
5765                    == PackageManager.PERMISSION_GRANTED;
5766
5767            IPackageManager pm = AppGlobals.getPackageManager();
5768
5769            final int N = mRecentTasks.size();
5770            ArrayList<ActivityManager.RecentTaskInfo> res
5771                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5772                            maxNum < N ? maxNum : N);
5773            for (int i=0; i<N && maxNum > 0; i++) {
5774                TaskRecord tr = mRecentTasks.get(i);
5775                // Only add calling user's recent tasks
5776                if (tr.userId != userId) continue;
5777                // Return the entry if desired by the caller.  We always return
5778                // the first entry, because callers always expect this to be the
5779                // foreground app.  We may filter others if the caller has
5780                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5781                // we should exclude the entry.
5782
5783                if (i == 0
5784                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5785                        || (tr.intent == null)
5786                        || ((tr.intent.getFlags()
5787                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5788                    ActivityManager.RecentTaskInfo rti
5789                            = new ActivityManager.RecentTaskInfo();
5790                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5791                    rti.persistentId = tr.taskId;
5792                    rti.baseIntent = new Intent(
5793                            tr.intent != null ? tr.intent : tr.affinityIntent);
5794                    if (!detailed) {
5795                        rti.baseIntent.replaceExtras((Bundle)null);
5796                    }
5797                    rti.origActivity = tr.origActivity;
5798                    rti.description = tr.lastDescription;
5799
5800                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5801                        // Check whether this activity is currently available.
5802                        try {
5803                            if (rti.origActivity != null) {
5804                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
5805                                        == null) {
5806                                    continue;
5807                                }
5808                            } else if (rti.baseIntent != null) {
5809                                if (pm.queryIntentActivities(rti.baseIntent,
5810                                        null, 0, userId) == null) {
5811                                    continue;
5812                                }
5813                            }
5814                        } catch (RemoteException e) {
5815                            // Will never happen.
5816                        }
5817                    }
5818
5819                    res.add(rti);
5820                    maxNum--;
5821                }
5822            }
5823            return res;
5824        }
5825    }
5826
5827    private TaskRecord taskForIdLocked(int id) {
5828        final int N = mRecentTasks.size();
5829        for (int i=0; i<N; i++) {
5830            TaskRecord tr = mRecentTasks.get(i);
5831            if (tr.taskId == id) {
5832                return tr;
5833            }
5834        }
5835        return null;
5836    }
5837
5838    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5839        synchronized (this) {
5840            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5841                    "getTaskThumbnails()");
5842            TaskRecord tr = taskForIdLocked(id);
5843            if (tr != null) {
5844                return mMainStack.getTaskThumbnailsLocked(tr);
5845            }
5846        }
5847        return null;
5848    }
5849
5850    public Bitmap getTaskTopThumbnail(int id) {
5851        synchronized (this) {
5852            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5853                    "getTaskTopThumbnail()");
5854            TaskRecord tr = taskForIdLocked(id);
5855            if (tr != null) {
5856                return mMainStack.getTaskTopThumbnailLocked(tr);
5857            }
5858        }
5859        return null;
5860    }
5861
5862    public boolean removeSubTask(int taskId, int subTaskIndex) {
5863        synchronized (this) {
5864            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5865                    "removeSubTask()");
5866            long ident = Binder.clearCallingIdentity();
5867            try {
5868                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5869                        true) != null;
5870            } finally {
5871                Binder.restoreCallingIdentity(ident);
5872            }
5873        }
5874    }
5875
5876    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5877        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5878        Intent baseIntent = new Intent(
5879                tr.intent != null ? tr.intent : tr.affinityIntent);
5880        ComponentName component = baseIntent.getComponent();
5881        if (component == null) {
5882            Slog.w(TAG, "Now component for base intent of task: " + tr);
5883            return;
5884        }
5885
5886        // Find any running services associated with this app.
5887        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5888
5889        if (killProcesses) {
5890            // Find any running processes associated with this app.
5891            final String pkg = component.getPackageName();
5892            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5893            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5894            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5895                for (int i=0; i<uids.size(); i++) {
5896                    ProcessRecord proc = uids.valueAt(i);
5897                    if (proc.userId != tr.userId) {
5898                        continue;
5899                    }
5900                    if (!proc.pkgList.contains(pkg)) {
5901                        continue;
5902                    }
5903                    procs.add(proc);
5904                }
5905            }
5906
5907            // Kill the running processes.
5908            for (int i=0; i<procs.size(); i++) {
5909                ProcessRecord pr = procs.get(i);
5910                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5911                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5912                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5913                            pr.processName, pr.setAdj, "remove task");
5914                    pr.killedBackground = true;
5915                    Process.killProcessQuiet(pr.pid);
5916                } else {
5917                    pr.waitingToKill = "remove task";
5918                }
5919            }
5920        }
5921    }
5922
5923    public boolean removeTask(int taskId, int flags) {
5924        synchronized (this) {
5925            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5926                    "removeTask()");
5927            long ident = Binder.clearCallingIdentity();
5928            try {
5929                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5930                        false);
5931                if (r != null) {
5932                    mRecentTasks.remove(r.task);
5933                    cleanUpRemovedTaskLocked(r.task, flags);
5934                    return true;
5935                } else {
5936                    TaskRecord tr = null;
5937                    int i=0;
5938                    while (i < mRecentTasks.size()) {
5939                        TaskRecord t = mRecentTasks.get(i);
5940                        if (t.taskId == taskId) {
5941                            tr = t;
5942                            break;
5943                        }
5944                        i++;
5945                    }
5946                    if (tr != null) {
5947                        if (tr.numActivities <= 0) {
5948                            // Caller is just removing a recent task that is
5949                            // not actively running.  That is easy!
5950                            mRecentTasks.remove(i);
5951                            cleanUpRemovedTaskLocked(tr, flags);
5952                            return true;
5953                        } else {
5954                            Slog.w(TAG, "removeTask: task " + taskId
5955                                    + " does not have activities to remove, "
5956                                    + " but numActivities=" + tr.numActivities
5957                                    + ": " + tr);
5958                        }
5959                    }
5960                }
5961            } finally {
5962                Binder.restoreCallingIdentity(ident);
5963            }
5964        }
5965        return false;
5966    }
5967
5968    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5969        int j;
5970        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5971        TaskRecord jt = startTask;
5972
5973        // First look backwards
5974        for (j=startIndex-1; j>=0; j--) {
5975            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5976            if (r.task != jt) {
5977                jt = r.task;
5978                if (affinity.equals(jt.affinity)) {
5979                    return j;
5980                }
5981            }
5982        }
5983
5984        // Now look forwards
5985        final int N = mMainStack.mHistory.size();
5986        jt = startTask;
5987        for (j=startIndex+1; j<N; j++) {
5988            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5989            if (r.task != jt) {
5990                if (affinity.equals(jt.affinity)) {
5991                    return j;
5992                }
5993                jt = r.task;
5994            }
5995        }
5996
5997        // Might it be at the top?
5998        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5999            return N-1;
6000        }
6001
6002        return -1;
6003    }
6004
6005    /**
6006     * TODO: Add mController hook
6007     */
6008    public void moveTaskToFront(int task, int flags, Bundle options) {
6009        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6010                "moveTaskToFront()");
6011
6012        synchronized(this) {
6013            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6014                    Binder.getCallingUid(), "Task to front")) {
6015                ActivityOptions.abort(options);
6016                return;
6017            }
6018            final long origId = Binder.clearCallingIdentity();
6019            try {
6020                TaskRecord tr = taskForIdLocked(task);
6021                if (tr != null) {
6022                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6023                        mMainStack.mUserLeaving = true;
6024                    }
6025                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6026                        // Caller wants the home activity moved with it.  To accomplish this,
6027                        // we'll just move the home task to the top first.
6028                        mMainStack.moveHomeToFrontLocked();
6029                    }
6030                    mMainStack.moveTaskToFrontLocked(tr, null, options);
6031                    return;
6032                }
6033                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6034                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
6035                    if (hr.task.taskId == task) {
6036                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6037                            mMainStack.mUserLeaving = true;
6038                        }
6039                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6040                            // Caller wants the home activity moved with it.  To accomplish this,
6041                            // we'll just move the home task to the top first.
6042                            mMainStack.moveHomeToFrontLocked();
6043                        }
6044                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
6045                        return;
6046                    }
6047                }
6048            } finally {
6049                Binder.restoreCallingIdentity(origId);
6050            }
6051            ActivityOptions.abort(options);
6052        }
6053    }
6054
6055    public void moveTaskToBack(int task) {
6056        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6057                "moveTaskToBack()");
6058
6059        synchronized(this) {
6060            if (mMainStack.mResumedActivity != null
6061                    && mMainStack.mResumedActivity.task.taskId == task) {
6062                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6063                        Binder.getCallingUid(), "Task to back")) {
6064                    return;
6065                }
6066            }
6067            final long origId = Binder.clearCallingIdentity();
6068            mMainStack.moveTaskToBackLocked(task, null);
6069            Binder.restoreCallingIdentity(origId);
6070        }
6071    }
6072
6073    /**
6074     * Moves an activity, and all of the other activities within the same task, to the bottom
6075     * of the history stack.  The activity's order within the task is unchanged.
6076     *
6077     * @param token A reference to the activity we wish to move
6078     * @param nonRoot If false then this only works if the activity is the root
6079     *                of a task; if true it will work for any activity in a task.
6080     * @return Returns true if the move completed, false if not.
6081     */
6082    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
6083        enforceNotIsolatedCaller("moveActivityTaskToBack");
6084        synchronized(this) {
6085            final long origId = Binder.clearCallingIdentity();
6086            int taskId = getTaskForActivityLocked(token, !nonRoot);
6087            if (taskId >= 0) {
6088                return mMainStack.moveTaskToBackLocked(taskId, null);
6089            }
6090            Binder.restoreCallingIdentity(origId);
6091        }
6092        return false;
6093    }
6094
6095    public void moveTaskBackwards(int task) {
6096        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6097                "moveTaskBackwards()");
6098
6099        synchronized(this) {
6100            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6101                    Binder.getCallingUid(), "Task backwards")) {
6102                return;
6103            }
6104            final long origId = Binder.clearCallingIdentity();
6105            moveTaskBackwardsLocked(task);
6106            Binder.restoreCallingIdentity(origId);
6107        }
6108    }
6109
6110    private final void moveTaskBackwardsLocked(int task) {
6111        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
6112    }
6113
6114    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6115        synchronized(this) {
6116            return getTaskForActivityLocked(token, onlyRoot);
6117        }
6118    }
6119
6120    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
6121        final int N = mMainStack.mHistory.size();
6122        TaskRecord lastTask = null;
6123        for (int i=0; i<N; i++) {
6124            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
6125            if (r.appToken == token) {
6126                if (!onlyRoot || lastTask != r.task) {
6127                    return r.task.taskId;
6128                }
6129                return -1;
6130            }
6131            lastTask = r.task;
6132        }
6133
6134        return -1;
6135    }
6136
6137    // =========================================================
6138    // THUMBNAILS
6139    // =========================================================
6140
6141    public void reportThumbnail(IBinder token,
6142            Bitmap thumbnail, CharSequence description) {
6143        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6144        final long origId = Binder.clearCallingIdentity();
6145        sendPendingThumbnail(null, token, thumbnail, description, true);
6146        Binder.restoreCallingIdentity(origId);
6147    }
6148
6149    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
6150            Bitmap thumbnail, CharSequence description, boolean always) {
6151        TaskRecord task = null;
6152        ArrayList receivers = null;
6153
6154        //System.out.println("Send pending thumbnail: " + r);
6155
6156        synchronized(this) {
6157            if (r == null) {
6158                r = mMainStack.isInStackLocked(token);
6159                if (r == null) {
6160                    return;
6161                }
6162            }
6163            if (thumbnail == null && r.thumbHolder != null) {
6164                thumbnail = r.thumbHolder.lastThumbnail;
6165                description = r.thumbHolder.lastDescription;
6166            }
6167            if (thumbnail == null && !always) {
6168                // If there is no thumbnail, and this entry is not actually
6169                // going away, then abort for now and pick up the next
6170                // thumbnail we get.
6171                return;
6172            }
6173            task = r.task;
6174
6175            int N = mPendingThumbnails.size();
6176            int i=0;
6177            while (i<N) {
6178                PendingThumbnailsRecord pr =
6179                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6180                //System.out.println("Looking in " + pr.pendingRecords);
6181                if (pr.pendingRecords.remove(r)) {
6182                    if (receivers == null) {
6183                        receivers = new ArrayList();
6184                    }
6185                    receivers.add(pr);
6186                    if (pr.pendingRecords.size() == 0) {
6187                        pr.finished = true;
6188                        mPendingThumbnails.remove(i);
6189                        N--;
6190                        continue;
6191                    }
6192                }
6193                i++;
6194            }
6195        }
6196
6197        if (receivers != null) {
6198            final int N = receivers.size();
6199            for (int i=0; i<N; i++) {
6200                try {
6201                    PendingThumbnailsRecord pr =
6202                        (PendingThumbnailsRecord)receivers.get(i);
6203                    pr.receiver.newThumbnail(
6204                        task != null ? task.taskId : -1, thumbnail, description);
6205                    if (pr.finished) {
6206                        pr.receiver.finished();
6207                    }
6208                } catch (Exception e) {
6209                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6210                }
6211            }
6212        }
6213    }
6214
6215    // =========================================================
6216    // CONTENT PROVIDERS
6217    // =========================================================
6218
6219    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6220        List<ProviderInfo> providers = null;
6221        try {
6222            providers = AppGlobals.getPackageManager().
6223                queryContentProviders(app.processName, app.uid,
6224                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6225        } catch (RemoteException ex) {
6226        }
6227        if (DEBUG_MU)
6228            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6229        int userId = app.userId;
6230        if (providers != null) {
6231            int N = providers.size();
6232            for (int i=0; i<N; i++) {
6233                ProviderInfo cpi =
6234                    (ProviderInfo)providers.get(i);
6235                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6236                        cpi.name, cpi.flags);
6237                if (singleton && UserHandle.getUserId(app.uid) != 0) {
6238                    // This is a singleton provider, but a user besides the
6239                    // default user is asking to initialize a process it runs
6240                    // in...  well, no, it doesn't actually run in this process,
6241                    // it runs in the process of the default user.  Get rid of it.
6242                    providers.remove(i);
6243                    N--;
6244                    continue;
6245                }
6246
6247                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6248                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6249                if (cpr == null) {
6250                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6251                    mProviderMap.putProviderByClass(comp, cpr);
6252                }
6253                if (DEBUG_MU)
6254                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6255                app.pubProviders.put(cpi.name, cpr);
6256                app.addPackage(cpi.applicationInfo.packageName);
6257                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6258            }
6259        }
6260        return providers;
6261    }
6262
6263    /**
6264     * Check if {@link ProcessRecord} has a possible chance at accessing the
6265     * given {@link ProviderInfo}. Final permission checking is always done
6266     * in {@link ContentProvider}.
6267     */
6268    private final String checkContentProviderPermissionLocked(
6269            ProviderInfo cpi, ProcessRecord r) {
6270        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6271        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6272        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6273                cpi.applicationInfo.uid, cpi.exported)
6274                == PackageManager.PERMISSION_GRANTED) {
6275            return null;
6276        }
6277        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6278                cpi.applicationInfo.uid, cpi.exported)
6279                == PackageManager.PERMISSION_GRANTED) {
6280            return null;
6281        }
6282
6283        PathPermission[] pps = cpi.pathPermissions;
6284        if (pps != null) {
6285            int i = pps.length;
6286            while (i > 0) {
6287                i--;
6288                PathPermission pp = pps[i];
6289                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6290                        cpi.applicationInfo.uid, cpi.exported)
6291                        == PackageManager.PERMISSION_GRANTED) {
6292                    return null;
6293                }
6294                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6295                        cpi.applicationInfo.uid, cpi.exported)
6296                        == PackageManager.PERMISSION_GRANTED) {
6297                    return null;
6298                }
6299            }
6300        }
6301
6302        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6303        if (perms != null) {
6304            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6305                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6306                    return null;
6307                }
6308            }
6309        }
6310
6311        String msg;
6312        if (!cpi.exported) {
6313            msg = "Permission Denial: opening provider " + cpi.name
6314                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6315                    + ", uid=" + callingUid + ") that is not exported from uid "
6316                    + cpi.applicationInfo.uid;
6317        } else {
6318            msg = "Permission Denial: opening provider " + cpi.name
6319                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6320                    + ", uid=" + callingUid + ") requires "
6321                    + cpi.readPermission + " or " + cpi.writePermission;
6322        }
6323        Slog.w(TAG, msg);
6324        return msg;
6325    }
6326
6327    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6328            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6329        if (r != null) {
6330            for (int i=0; i<r.conProviders.size(); i++) {
6331                ContentProviderConnection conn = r.conProviders.get(i);
6332                if (conn.provider == cpr) {
6333                    if (DEBUG_PROVIDER) Slog.v(TAG,
6334                            "Adding provider requested by "
6335                            + r.processName + " from process "
6336                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6337                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6338                    if (stable) {
6339                        conn.stableCount++;
6340                        conn.numStableIncs++;
6341                    } else {
6342                        conn.unstableCount++;
6343                        conn.numUnstableIncs++;
6344                    }
6345                    return conn;
6346                }
6347            }
6348            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6349            if (stable) {
6350                conn.stableCount = 1;
6351                conn.numStableIncs = 1;
6352            } else {
6353                conn.unstableCount = 1;
6354                conn.numUnstableIncs = 1;
6355            }
6356            cpr.connections.add(conn);
6357            r.conProviders.add(conn);
6358            return conn;
6359        }
6360        cpr.addExternalProcessHandleLocked(externalProcessToken);
6361        return null;
6362    }
6363
6364    boolean decProviderCountLocked(ContentProviderConnection conn,
6365            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6366        if (conn != null) {
6367            cpr = conn.provider;
6368            if (DEBUG_PROVIDER) Slog.v(TAG,
6369                    "Removing provider requested by "
6370                    + conn.client.processName + " from process "
6371                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6372                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6373            if (stable) {
6374                conn.stableCount--;
6375            } else {
6376                conn.unstableCount--;
6377            }
6378            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6379                cpr.connections.remove(conn);
6380                conn.client.conProviders.remove(conn);
6381                return true;
6382            }
6383            return false;
6384        }
6385        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6386        return false;
6387    }
6388
6389    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6390            String name, IBinder token, boolean stable, int userId) {
6391        ContentProviderRecord cpr;
6392        ContentProviderConnection conn = null;
6393        ProviderInfo cpi = null;
6394
6395        synchronized(this) {
6396            ProcessRecord r = null;
6397            if (caller != null) {
6398                r = getRecordForAppLocked(caller);
6399                if (r == null) {
6400                    throw new SecurityException(
6401                            "Unable to find app for caller " + caller
6402                          + " (pid=" + Binder.getCallingPid()
6403                          + ") when getting content provider " + name);
6404                }
6405                if (r.userId != userId) {
6406                    throw new SecurityException("Calling requested user " + userId
6407                            + " but app is user " + r.userId);
6408                }
6409            }
6410
6411            // First check if this content provider has been published...
6412            cpr = mProviderMap.getProviderByName(name, userId);
6413            boolean providerRunning = cpr != null;
6414            if (providerRunning) {
6415                cpi = cpr.info;
6416                String msg;
6417                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6418                    throw new SecurityException(msg);
6419                }
6420
6421                if (r != null && cpr.canRunHere(r)) {
6422                    // This provider has been published or is in the process
6423                    // of being published...  but it is also allowed to run
6424                    // in the caller's process, so don't make a connection
6425                    // and just let the caller instantiate its own instance.
6426                    ContentProviderHolder holder = cpr.newHolder(null);
6427                    // don't give caller the provider object, it needs
6428                    // to make its own.
6429                    holder.provider = null;
6430                    return holder;
6431                }
6432
6433                final long origId = Binder.clearCallingIdentity();
6434
6435                // In this case the provider instance already exists, so we can
6436                // return it right away.
6437                conn = incProviderCountLocked(r, cpr, token, stable);
6438                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6439                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6440                        // If this is a perceptible app accessing the provider,
6441                        // make sure to count it as being accessed and thus
6442                        // back up on the LRU list.  This is good because
6443                        // content providers are often expensive to start.
6444                        updateLruProcessLocked(cpr.proc, false, true);
6445                    }
6446                }
6447
6448                if (cpr.proc != null) {
6449                    if (false) {
6450                        if (cpr.name.flattenToShortString().equals(
6451                                "com.android.providers.calendar/.CalendarProvider2")) {
6452                            Slog.v(TAG, "****************** KILLING "
6453                                + cpr.name.flattenToShortString());
6454                            Process.killProcess(cpr.proc.pid);
6455                        }
6456                    }
6457                    boolean success = updateOomAdjLocked(cpr.proc);
6458                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6459                    // NOTE: there is still a race here where a signal could be
6460                    // pending on the process even though we managed to update its
6461                    // adj level.  Not sure what to do about this, but at least
6462                    // the race is now smaller.
6463                    if (!success) {
6464                        // Uh oh...  it looks like the provider's process
6465                        // has been killed on us.  We need to wait for a new
6466                        // process to be started, and make sure its death
6467                        // doesn't kill our process.
6468                        Slog.i(TAG,
6469                                "Existing provider " + cpr.name.flattenToShortString()
6470                                + " is crashing; detaching " + r);
6471                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6472                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6473                        if (!lastRef) {
6474                            // This wasn't the last ref our process had on
6475                            // the provider...  we have now been killed, bail.
6476                            return null;
6477                        }
6478                        providerRunning = false;
6479                        conn = null;
6480                    }
6481                }
6482
6483                Binder.restoreCallingIdentity(origId);
6484            }
6485
6486            boolean singleton;
6487            if (!providerRunning) {
6488                try {
6489                    cpi = AppGlobals.getPackageManager().
6490                        resolveContentProvider(name,
6491                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6492                } catch (RemoteException ex) {
6493                }
6494                if (cpi == null) {
6495                    return null;
6496                }
6497                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6498                        cpi.name, cpi.flags);
6499                if (singleton) {
6500                    userId = 0;
6501                }
6502                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6503
6504                String msg;
6505                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6506                    throw new SecurityException(msg);
6507                }
6508
6509                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6510                        && !cpi.processName.equals("system")) {
6511                    // If this content provider does not run in the system
6512                    // process, and the system is not yet ready to run other
6513                    // processes, then fail fast instead of hanging.
6514                    throw new IllegalArgumentException(
6515                            "Attempt to launch content provider before system ready");
6516                }
6517
6518                // Make sure that the user who owns this provider is started.  If not,
6519                // we don't want to allow it to run.
6520                if (mStartedUsers.get(userId) == null) {
6521                    Slog.w(TAG, "Unable to launch app "
6522                            + cpi.applicationInfo.packageName + "/"
6523                            + cpi.applicationInfo.uid + " for provider "
6524                            + name + ": user " + userId + " is stopped");
6525                    return null;
6526                }
6527
6528                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6529                cpr = mProviderMap.getProviderByClass(comp, userId);
6530                final boolean firstClass = cpr == null;
6531                if (firstClass) {
6532                    try {
6533                        ApplicationInfo ai =
6534                            AppGlobals.getPackageManager().
6535                                getApplicationInfo(
6536                                        cpi.applicationInfo.packageName,
6537                                        STOCK_PM_FLAGS, userId);
6538                        if (ai == null) {
6539                            Slog.w(TAG, "No package info for content provider "
6540                                    + cpi.name);
6541                            return null;
6542                        }
6543                        ai = getAppInfoForUser(ai, userId);
6544                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6545                    } catch (RemoteException ex) {
6546                        // pm is in same process, this will never happen.
6547                    }
6548                }
6549
6550                if (r != null && cpr.canRunHere(r)) {
6551                    // If this is a multiprocess provider, then just return its
6552                    // info and allow the caller to instantiate it.  Only do
6553                    // this if the provider is the same user as the caller's
6554                    // process, or can run as root (so can be in any process).
6555                    return cpr.newHolder(null);
6556                }
6557
6558                if (DEBUG_PROVIDER) {
6559                    RuntimeException e = new RuntimeException("here");
6560                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6561                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6562                }
6563
6564                // This is single process, and our app is now connecting to it.
6565                // See if we are already in the process of launching this
6566                // provider.
6567                final int N = mLaunchingProviders.size();
6568                int i;
6569                for (i=0; i<N; i++) {
6570                    if (mLaunchingProviders.get(i) == cpr) {
6571                        break;
6572                    }
6573                }
6574
6575                // If the provider is not already being launched, then get it
6576                // started.
6577                if (i >= N) {
6578                    final long origId = Binder.clearCallingIdentity();
6579
6580                    try {
6581                        // Content provider is now in use, its package can't be stopped.
6582                        try {
6583                            AppGlobals.getPackageManager().setPackageStoppedState(
6584                                    cpr.appInfo.packageName, false, userId);
6585                        } catch (RemoteException e) {
6586                        } catch (IllegalArgumentException e) {
6587                            Slog.w(TAG, "Failed trying to unstop package "
6588                                    + cpr.appInfo.packageName + ": " + e);
6589                        }
6590
6591                        ProcessRecord proc = startProcessLocked(cpi.processName,
6592                                cpr.appInfo, false, 0, "content provider",
6593                                new ComponentName(cpi.applicationInfo.packageName,
6594                                        cpi.name), false, false);
6595                        if (proc == null) {
6596                            Slog.w(TAG, "Unable to launch app "
6597                                    + cpi.applicationInfo.packageName + "/"
6598                                    + cpi.applicationInfo.uid + " for provider "
6599                                    + name + ": process is bad");
6600                            return null;
6601                        }
6602                        cpr.launchingApp = proc;
6603                        mLaunchingProviders.add(cpr);
6604                    } finally {
6605                        Binder.restoreCallingIdentity(origId);
6606                    }
6607                }
6608
6609                // Make sure the provider is published (the same provider class
6610                // may be published under multiple names).
6611                if (firstClass) {
6612                    mProviderMap.putProviderByClass(comp, cpr);
6613                }
6614
6615                mProviderMap.putProviderByName(name, cpr);
6616                conn = incProviderCountLocked(r, cpr, token, stable);
6617                if (conn != null) {
6618                    conn.waiting = true;
6619                }
6620            }
6621        }
6622
6623        // Wait for the provider to be published...
6624        synchronized (cpr) {
6625            while (cpr.provider == null) {
6626                if (cpr.launchingApp == null) {
6627                    Slog.w(TAG, "Unable to launch app "
6628                            + cpi.applicationInfo.packageName + "/"
6629                            + cpi.applicationInfo.uid + " for provider "
6630                            + name + ": launching app became null");
6631                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6632                            cpi.applicationInfo.packageName,
6633                            cpi.applicationInfo.uid, name);
6634                    return null;
6635                }
6636                try {
6637                    if (DEBUG_MU) {
6638                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6639                                + cpr.launchingApp);
6640                    }
6641                    if (conn != null) {
6642                        conn.waiting = true;
6643                    }
6644                    cpr.wait();
6645                } catch (InterruptedException ex) {
6646                } finally {
6647                    if (conn != null) {
6648                        conn.waiting = false;
6649                    }
6650                }
6651            }
6652        }
6653        return cpr != null ? cpr.newHolder(conn) : null;
6654    }
6655
6656    public final ContentProviderHolder getContentProvider(
6657            IApplicationThread caller, String name, boolean stable) {
6658        enforceNotIsolatedCaller("getContentProvider");
6659        if (caller == null) {
6660            String msg = "null IApplicationThread when getting content provider "
6661                    + name;
6662            Slog.w(TAG, msg);
6663            throw new SecurityException(msg);
6664        }
6665
6666        return getContentProviderImpl(caller, name, null, stable,
6667                UserHandle.getCallingUserId());
6668    }
6669
6670    public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6671        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6672            "Do not have permission in call getContentProviderExternal()");
6673        return getContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6674    }
6675
6676    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
6677            IBinder token, int userId) {
6678        return getContentProviderImpl(null, name, token, true, userId);
6679    }
6680
6681    /**
6682     * Drop a content provider from a ProcessRecord's bookkeeping
6683     * @param cpr
6684     */
6685    public void removeContentProvider(IBinder connection, boolean stable) {
6686        enforceNotIsolatedCaller("removeContentProvider");
6687        synchronized (this) {
6688            ContentProviderConnection conn;
6689            try {
6690                conn = (ContentProviderConnection)connection;
6691            } catch (ClassCastException e) {
6692                String msg ="removeContentProvider: " + connection
6693                        + " not a ContentProviderConnection";
6694                Slog.w(TAG, msg);
6695                throw new IllegalArgumentException(msg);
6696            }
6697            if (conn == null) {
6698                throw new NullPointerException("connection is null");
6699            }
6700            if (decProviderCountLocked(conn, null, null, stable)) {
6701                updateOomAdjLocked();
6702            }
6703        }
6704    }
6705
6706    public void removeContentProviderExternal(String name, IBinder token) {
6707        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6708            "Do not have permission in call removeContentProviderExternal()");
6709        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6710    }
6711
6712    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
6713        synchronized (this) {
6714            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
6715            if(cpr == null) {
6716                //remove from mProvidersByClass
6717                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6718                return;
6719            }
6720
6721            //update content provider record entry info
6722            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6723            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
6724            if (localCpr.hasExternalProcessHandles()) {
6725                if (localCpr.removeExternalProcessHandleLocked(token)) {
6726                    updateOomAdjLocked();
6727                } else {
6728                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6729                            + " with no external reference for token: "
6730                            + token + ".");
6731                }
6732            } else {
6733                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6734                        + " with no external references.");
6735            }
6736        }
6737    }
6738
6739    public final void publishContentProviders(IApplicationThread caller,
6740            List<ContentProviderHolder> providers) {
6741        if (providers == null) {
6742            return;
6743        }
6744
6745        enforceNotIsolatedCaller("publishContentProviders");
6746        synchronized (this) {
6747            final ProcessRecord r = getRecordForAppLocked(caller);
6748            if (DEBUG_MU)
6749                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6750            if (r == null) {
6751                throw new SecurityException(
6752                        "Unable to find app for caller " + caller
6753                      + " (pid=" + Binder.getCallingPid()
6754                      + ") when publishing content providers");
6755            }
6756
6757            final long origId = Binder.clearCallingIdentity();
6758
6759            final int N = providers.size();
6760            for (int i=0; i<N; i++) {
6761                ContentProviderHolder src = providers.get(i);
6762                if (src == null || src.info == null || src.provider == null) {
6763                    continue;
6764                }
6765                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6766                if (DEBUG_MU)
6767                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6768                if (dst != null) {
6769                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6770                    mProviderMap.putProviderByClass(comp, dst);
6771                    String names[] = dst.info.authority.split(";");
6772                    for (int j = 0; j < names.length; j++) {
6773                        mProviderMap.putProviderByName(names[j], dst);
6774                    }
6775
6776                    int NL = mLaunchingProviders.size();
6777                    int j;
6778                    for (j=0; j<NL; j++) {
6779                        if (mLaunchingProviders.get(j) == dst) {
6780                            mLaunchingProviders.remove(j);
6781                            j--;
6782                            NL--;
6783                        }
6784                    }
6785                    synchronized (dst) {
6786                        dst.provider = src.provider;
6787                        dst.proc = r;
6788                        dst.notifyAll();
6789                    }
6790                    updateOomAdjLocked(r);
6791                }
6792            }
6793
6794            Binder.restoreCallingIdentity(origId);
6795        }
6796    }
6797
6798    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6799        ContentProviderConnection conn;
6800        try {
6801            conn = (ContentProviderConnection)connection;
6802        } catch (ClassCastException e) {
6803            String msg ="refContentProvider: " + connection
6804                    + " not a ContentProviderConnection";
6805            Slog.w(TAG, msg);
6806            throw new IllegalArgumentException(msg);
6807        }
6808        if (conn == null) {
6809            throw new NullPointerException("connection is null");
6810        }
6811
6812        synchronized (this) {
6813            if (stable > 0) {
6814                conn.numStableIncs += stable;
6815            }
6816            stable = conn.stableCount + stable;
6817            if (stable < 0) {
6818                throw new IllegalStateException("stableCount < 0: " + stable);
6819            }
6820
6821            if (unstable > 0) {
6822                conn.numUnstableIncs += unstable;
6823            }
6824            unstable = conn.unstableCount + unstable;
6825            if (unstable < 0) {
6826                throw new IllegalStateException("unstableCount < 0: " + unstable);
6827            }
6828
6829            if ((stable+unstable) <= 0) {
6830                throw new IllegalStateException("ref counts can't go to zero here: stable="
6831                        + stable + " unstable=" + unstable);
6832            }
6833            conn.stableCount = stable;
6834            conn.unstableCount = unstable;
6835            return !conn.dead;
6836        }
6837    }
6838
6839    public void unstableProviderDied(IBinder connection) {
6840        ContentProviderConnection conn;
6841        try {
6842            conn = (ContentProviderConnection)connection;
6843        } catch (ClassCastException e) {
6844            String msg ="refContentProvider: " + connection
6845                    + " not a ContentProviderConnection";
6846            Slog.w(TAG, msg);
6847            throw new IllegalArgumentException(msg);
6848        }
6849        if (conn == null) {
6850            throw new NullPointerException("connection is null");
6851        }
6852
6853        // Safely retrieve the content provider associated with the connection.
6854        IContentProvider provider;
6855        synchronized (this) {
6856            provider = conn.provider.provider;
6857        }
6858
6859        if (provider == null) {
6860            // Um, yeah, we're way ahead of you.
6861            return;
6862        }
6863
6864        // Make sure the caller is being honest with us.
6865        if (provider.asBinder().pingBinder()) {
6866            // Er, no, still looks good to us.
6867            synchronized (this) {
6868                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6869                        + " says " + conn + " died, but we don't agree");
6870                return;
6871            }
6872        }
6873
6874        // Well look at that!  It's dead!
6875        synchronized (this) {
6876            if (conn.provider.provider != provider) {
6877                // But something changed...  good enough.
6878                return;
6879            }
6880
6881            ProcessRecord proc = conn.provider.proc;
6882            if (proc == null || proc.thread == null) {
6883                // Seems like the process is already cleaned up.
6884                return;
6885            }
6886
6887            // As far as we're concerned, this is just like receiving a
6888            // death notification...  just a bit prematurely.
6889            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6890                    + ") early provider death");
6891            final long ident = Binder.clearCallingIdentity();
6892            try {
6893                appDiedLocked(proc, proc.pid, proc.thread);
6894            } finally {
6895                Binder.restoreCallingIdentity(ident);
6896            }
6897        }
6898    }
6899
6900    public static final void installSystemProviders() {
6901        List<ProviderInfo> providers;
6902        synchronized (mSelf) {
6903            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6904            providers = mSelf.generateApplicationProvidersLocked(app);
6905            if (providers != null) {
6906                for (int i=providers.size()-1; i>=0; i--) {
6907                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6908                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6909                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6910                                + ": not system .apk");
6911                        providers.remove(i);
6912                    }
6913                }
6914            }
6915        }
6916        if (providers != null) {
6917            mSystemThread.installSystemProviders(providers);
6918        }
6919
6920        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6921
6922        mSelf.mUsageStatsService.monitorPackages();
6923    }
6924
6925    /**
6926     * Allows app to retrieve the MIME type of a URI without having permission
6927     * to access its content provider.
6928     *
6929     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6930     *
6931     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6932     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6933     */
6934    public String getProviderMimeType(Uri uri, int userId) {
6935        enforceNotIsolatedCaller("getProviderMimeType");
6936        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
6937                userId, false, true, "getProviderMimeType", null);
6938        final String name = uri.getAuthority();
6939        final long ident = Binder.clearCallingIdentity();
6940        ContentProviderHolder holder = null;
6941
6942        try {
6943            holder = getContentProviderExternalUnchecked(name, null, userId);
6944            if (holder != null) {
6945                return holder.provider.getType(uri);
6946            }
6947        } catch (RemoteException e) {
6948            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6949            return null;
6950        } finally {
6951            if (holder != null) {
6952                removeContentProviderExternalUnchecked(name, null, userId);
6953            }
6954            Binder.restoreCallingIdentity(ident);
6955        }
6956
6957        return null;
6958    }
6959
6960    // =========================================================
6961    // GLOBAL MANAGEMENT
6962    // =========================================================
6963
6964    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6965            ApplicationInfo info, String customProcess, boolean isolated) {
6966        String proc = customProcess != null ? customProcess : info.processName;
6967        BatteryStatsImpl.Uid.Proc ps = null;
6968        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6969        int uid = info.uid;
6970        if (isolated) {
6971            int userId = UserHandle.getUserId(uid);
6972            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6973            uid = 0;
6974            while (true) {
6975                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6976                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6977                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6978                }
6979                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
6980                mNextIsolatedProcessUid++;
6981                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6982                    // No process for this uid, use it.
6983                    break;
6984                }
6985                stepsLeft--;
6986                if (stepsLeft <= 0) {
6987                    return null;
6988                }
6989            }
6990        }
6991        synchronized (stats) {
6992            ps = stats.getProcessStatsLocked(info.uid, proc);
6993        }
6994        return new ProcessRecord(ps, thread, info, proc, uid);
6995    }
6996
6997    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6998        ProcessRecord app;
6999        if (!isolated) {
7000            app = getProcessRecordLocked(info.processName, info.uid);
7001        } else {
7002            app = null;
7003        }
7004
7005        if (app == null) {
7006            app = newProcessRecordLocked(null, info, null, isolated);
7007            mProcessNames.put(info.processName, app.uid, app);
7008            if (isolated) {
7009                mIsolatedProcesses.put(app.uid, app);
7010            }
7011            updateLruProcessLocked(app, true, true);
7012        }
7013
7014        // This package really, really can not be stopped.
7015        try {
7016            AppGlobals.getPackageManager().setPackageStoppedState(
7017                    info.packageName, false, UserHandle.getUserId(app.uid));
7018        } catch (RemoteException e) {
7019        } catch (IllegalArgumentException e) {
7020            Slog.w(TAG, "Failed trying to unstop package "
7021                    + info.packageName + ": " + e);
7022        }
7023
7024        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
7025                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7026            app.persistent = true;
7027            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
7028        }
7029        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7030            mPersistentStartingProcesses.add(app);
7031            startProcessLocked(app, "added application", app.processName);
7032        }
7033
7034        return app;
7035    }
7036
7037    public void unhandledBack() {
7038        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7039                "unhandledBack()");
7040
7041        synchronized(this) {
7042            int count = mMainStack.mHistory.size();
7043            if (DEBUG_SWITCH) Slog.d(
7044                TAG, "Performing unhandledBack(): stack size = " + count);
7045            if (count > 1) {
7046                final long origId = Binder.clearCallingIdentity();
7047                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
7048                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true);
7049                Binder.restoreCallingIdentity(origId);
7050            }
7051        }
7052    }
7053
7054    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
7055        enforceNotIsolatedCaller("openContentUri");
7056        final int userId = UserHandle.getCallingUserId();
7057        String name = uri.getAuthority();
7058        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
7059        ParcelFileDescriptor pfd = null;
7060        if (cph != null) {
7061            // We record the binder invoker's uid in thread-local storage before
7062            // going to the content provider to open the file.  Later, in the code
7063            // that handles all permissions checks, we look for this uid and use
7064            // that rather than the Activity Manager's own uid.  The effect is that
7065            // we do the check against the caller's permissions even though it looks
7066            // to the content provider like the Activity Manager itself is making
7067            // the request.
7068            sCallerIdentity.set(new Identity(
7069                    Binder.getCallingPid(), Binder.getCallingUid()));
7070            try {
7071                pfd = cph.provider.openFile(uri, "r");
7072            } catch (FileNotFoundException e) {
7073                // do nothing; pfd will be returned null
7074            } finally {
7075                // Ensure that whatever happens, we clean up the identity state
7076                sCallerIdentity.remove();
7077            }
7078
7079            // We've got the fd now, so we're done with the provider.
7080            removeContentProviderExternalUnchecked(name, null, userId);
7081        } else {
7082            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
7083        }
7084        return pfd;
7085    }
7086
7087    // Actually is sleeping or shutting down or whatever else in the future
7088    // is an inactive state.
7089    public boolean isSleeping() {
7090        return mSleeping || mShuttingDown;
7091    }
7092
7093    public void goingToSleep() {
7094        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7095                != PackageManager.PERMISSION_GRANTED) {
7096            throw new SecurityException("Requires permission "
7097                    + android.Manifest.permission.DEVICE_POWER);
7098        }
7099
7100        synchronized(this) {
7101            mWentToSleep = true;
7102            updateEventDispatchingLocked();
7103
7104            if (!mSleeping) {
7105                mSleeping = true;
7106                mMainStack.stopIfSleepingLocked();
7107
7108                // Initialize the wake times of all processes.
7109                checkExcessivePowerUsageLocked(false);
7110                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7111                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7112                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
7113            }
7114        }
7115    }
7116
7117    public boolean shutdown(int timeout) {
7118        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7119                != PackageManager.PERMISSION_GRANTED) {
7120            throw new SecurityException("Requires permission "
7121                    + android.Manifest.permission.SHUTDOWN);
7122        }
7123
7124        boolean timedout = false;
7125
7126        synchronized(this) {
7127            mShuttingDown = true;
7128            updateEventDispatchingLocked();
7129
7130            if (mMainStack.mResumedActivity != null) {
7131                mMainStack.stopIfSleepingLocked();
7132                final long endTime = System.currentTimeMillis() + timeout;
7133                while (mMainStack.mResumedActivity != null
7134                        || mMainStack.mPausingActivity != null) {
7135                    long delay = endTime - System.currentTimeMillis();
7136                    if (delay <= 0) {
7137                        Slog.w(TAG, "Activity manager shutdown timed out");
7138                        timedout = true;
7139                        break;
7140                    }
7141                    try {
7142                        this.wait();
7143                    } catch (InterruptedException e) {
7144                    }
7145                }
7146            }
7147        }
7148
7149        mUsageStatsService.shutdown();
7150        mBatteryStatsService.shutdown();
7151
7152        return timedout;
7153    }
7154
7155    public final void activitySlept(IBinder token) {
7156        if (localLOGV) Slog.v(
7157            TAG, "Activity slept: token=" + token);
7158
7159        ActivityRecord r = null;
7160
7161        final long origId = Binder.clearCallingIdentity();
7162
7163        synchronized (this) {
7164            r = mMainStack.isInStackLocked(token);
7165            if (r != null) {
7166                mMainStack.activitySleptLocked(r);
7167            }
7168        }
7169
7170        Binder.restoreCallingIdentity(origId);
7171    }
7172
7173    private void comeOutOfSleepIfNeededLocked() {
7174        if (!mWentToSleep && !mLockScreenShown) {
7175            if (mSleeping) {
7176                mSleeping = false;
7177                mMainStack.awakeFromSleepingLocked();
7178                mMainStack.resumeTopActivityLocked(null);
7179            }
7180        }
7181    }
7182
7183    public void wakingUp() {
7184        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7185                != PackageManager.PERMISSION_GRANTED) {
7186            throw new SecurityException("Requires permission "
7187                    + android.Manifest.permission.DEVICE_POWER);
7188        }
7189
7190        synchronized(this) {
7191            mWentToSleep = false;
7192            updateEventDispatchingLocked();
7193            comeOutOfSleepIfNeededLocked();
7194        }
7195    }
7196
7197    private void updateEventDispatchingLocked() {
7198        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
7199    }
7200
7201    public void setLockScreenShown(boolean shown) {
7202        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7203                != PackageManager.PERMISSION_GRANTED) {
7204            throw new SecurityException("Requires permission "
7205                    + android.Manifest.permission.DEVICE_POWER);
7206        }
7207
7208        synchronized(this) {
7209            mLockScreenShown = shown;
7210            comeOutOfSleepIfNeededLocked();
7211        }
7212    }
7213
7214    public void stopAppSwitches() {
7215        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7216                != PackageManager.PERMISSION_GRANTED) {
7217            throw new SecurityException("Requires permission "
7218                    + android.Manifest.permission.STOP_APP_SWITCHES);
7219        }
7220
7221        synchronized(this) {
7222            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7223                    + APP_SWITCH_DELAY_TIME;
7224            mDidAppSwitch = false;
7225            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7226            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7227            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7228        }
7229    }
7230
7231    public void resumeAppSwitches() {
7232        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7233                != PackageManager.PERMISSION_GRANTED) {
7234            throw new SecurityException("Requires permission "
7235                    + android.Manifest.permission.STOP_APP_SWITCHES);
7236        }
7237
7238        synchronized(this) {
7239            // Note that we don't execute any pending app switches... we will
7240            // let those wait until either the timeout, or the next start
7241            // activity request.
7242            mAppSwitchesAllowedTime = 0;
7243        }
7244    }
7245
7246    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7247            String name) {
7248        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7249            return true;
7250        }
7251
7252        final int perm = checkComponentPermission(
7253                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7254                callingUid, -1, true);
7255        if (perm == PackageManager.PERMISSION_GRANTED) {
7256            return true;
7257        }
7258
7259        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7260        return false;
7261    }
7262
7263    public void setDebugApp(String packageName, boolean waitForDebugger,
7264            boolean persistent) {
7265        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7266                "setDebugApp()");
7267
7268        // Note that this is not really thread safe if there are multiple
7269        // callers into it at the same time, but that's not a situation we
7270        // care about.
7271        if (persistent) {
7272            final ContentResolver resolver = mContext.getContentResolver();
7273            Settings.System.putString(
7274                resolver, Settings.System.DEBUG_APP,
7275                packageName);
7276            Settings.System.putInt(
7277                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7278                waitForDebugger ? 1 : 0);
7279        }
7280
7281        synchronized (this) {
7282            if (!persistent) {
7283                mOrigDebugApp = mDebugApp;
7284                mOrigWaitForDebugger = mWaitForDebugger;
7285            }
7286            mDebugApp = packageName;
7287            mWaitForDebugger = waitForDebugger;
7288            mDebugTransient = !persistent;
7289            if (packageName != null) {
7290                final long origId = Binder.clearCallingIdentity();
7291                forceStopPackageLocked(packageName, -1, false, false, true, true,
7292                        UserHandle.USER_ALL);
7293                Binder.restoreCallingIdentity(origId);
7294            }
7295        }
7296    }
7297
7298    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7299        synchronized (this) {
7300            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7301            if (!isDebuggable) {
7302                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7303                    throw new SecurityException("Process not debuggable: " + app.packageName);
7304                }
7305            }
7306
7307            mOpenGlTraceApp = processName;
7308        }
7309    }
7310
7311    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7312            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7313        synchronized (this) {
7314            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7315            if (!isDebuggable) {
7316                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7317                    throw new SecurityException("Process not debuggable: " + app.packageName);
7318                }
7319            }
7320            mProfileApp = processName;
7321            mProfileFile = profileFile;
7322            if (mProfileFd != null) {
7323                try {
7324                    mProfileFd.close();
7325                } catch (IOException e) {
7326                }
7327                mProfileFd = null;
7328            }
7329            mProfileFd = profileFd;
7330            mProfileType = 0;
7331            mAutoStopProfiler = autoStopProfiler;
7332        }
7333    }
7334
7335    public void setAlwaysFinish(boolean enabled) {
7336        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7337                "setAlwaysFinish()");
7338
7339        Settings.System.putInt(
7340                mContext.getContentResolver(),
7341                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7342
7343        synchronized (this) {
7344            mAlwaysFinishActivities = enabled;
7345        }
7346    }
7347
7348    public void setActivityController(IActivityController controller) {
7349        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7350                "setActivityController()");
7351        synchronized (this) {
7352            mController = controller;
7353        }
7354    }
7355
7356    public boolean isUserAMonkey() {
7357        // For now the fact that there is a controller implies
7358        // we have a monkey.
7359        synchronized (this) {
7360            return mController != null;
7361        }
7362    }
7363
7364    public void registerProcessObserver(IProcessObserver observer) {
7365        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7366                "registerProcessObserver()");
7367        synchronized (this) {
7368            mProcessObservers.register(observer);
7369        }
7370    }
7371
7372    public void unregisterProcessObserver(IProcessObserver observer) {
7373        synchronized (this) {
7374            mProcessObservers.unregister(observer);
7375        }
7376    }
7377
7378    public void setImmersive(IBinder token, boolean immersive) {
7379        synchronized(this) {
7380            ActivityRecord r = mMainStack.isInStackLocked(token);
7381            if (r == null) {
7382                throw new IllegalArgumentException();
7383            }
7384            r.immersive = immersive;
7385        }
7386    }
7387
7388    public boolean isImmersive(IBinder token) {
7389        synchronized (this) {
7390            ActivityRecord r = mMainStack.isInStackLocked(token);
7391            if (r == null) {
7392                throw new IllegalArgumentException();
7393            }
7394            return r.immersive;
7395        }
7396    }
7397
7398    public boolean isTopActivityImmersive() {
7399        enforceNotIsolatedCaller("startActivity");
7400        synchronized (this) {
7401            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7402            return (r != null) ? r.immersive : false;
7403        }
7404    }
7405
7406    public final void enterSafeMode() {
7407        synchronized(this) {
7408            // It only makes sense to do this before the system is ready
7409            // and started launching other packages.
7410            if (!mSystemReady) {
7411                try {
7412                    AppGlobals.getPackageManager().enterSafeMode();
7413                } catch (RemoteException e) {
7414                }
7415            }
7416        }
7417    }
7418
7419    public final void showSafeModeOverlay() {
7420        View v = LayoutInflater.from(mContext).inflate(
7421                com.android.internal.R.layout.safe_mode, null);
7422        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7423        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7424        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7425        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7426        lp.gravity = Gravity.BOTTOM | Gravity.START;
7427        lp.format = v.getBackground().getOpacity();
7428        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7429                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7430        ((WindowManager)mContext.getSystemService(
7431                Context.WINDOW_SERVICE)).addView(v, lp);
7432    }
7433
7434    public void noteWakeupAlarm(IIntentSender sender) {
7435        if (!(sender instanceof PendingIntentRecord)) {
7436            return;
7437        }
7438        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7439        synchronized (stats) {
7440            if (mBatteryStatsService.isOnBattery()) {
7441                mBatteryStatsService.enforceCallingPermission();
7442                PendingIntentRecord rec = (PendingIntentRecord)sender;
7443                int MY_UID = Binder.getCallingUid();
7444                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7445                BatteryStatsImpl.Uid.Pkg pkg =
7446                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7447                pkg.incWakeupsLocked();
7448            }
7449        }
7450    }
7451
7452    public boolean killPids(int[] pids, String pReason, boolean secure) {
7453        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7454            throw new SecurityException("killPids only available to the system");
7455        }
7456        String reason = (pReason == null) ? "Unknown" : pReason;
7457        // XXX Note: don't acquire main activity lock here, because the window
7458        // manager calls in with its locks held.
7459
7460        boolean killed = false;
7461        synchronized (mPidsSelfLocked) {
7462            int[] types = new int[pids.length];
7463            int worstType = 0;
7464            for (int i=0; i<pids.length; i++) {
7465                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7466                if (proc != null) {
7467                    int type = proc.setAdj;
7468                    types[i] = type;
7469                    if (type > worstType) {
7470                        worstType = type;
7471                    }
7472                }
7473            }
7474
7475            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7476            // then constrain it so we will kill all hidden procs.
7477            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7478                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7479                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7480            }
7481
7482            // If this is not a secure call, don't let it kill processes that
7483            // are important.
7484            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7485                worstType = ProcessList.SERVICE_ADJ;
7486            }
7487
7488            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7489            for (int i=0; i<pids.length; i++) {
7490                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7491                if (proc == null) {
7492                    continue;
7493                }
7494                int adj = proc.setAdj;
7495                if (adj >= worstType && !proc.killedBackground) {
7496                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7497                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7498                            proc.processName, adj, reason);
7499                    killed = true;
7500                    proc.killedBackground = true;
7501                    Process.killProcessQuiet(pids[i]);
7502                }
7503            }
7504        }
7505        return killed;
7506    }
7507
7508    @Override
7509    public boolean killProcessesBelowForeground(String reason) {
7510        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7511            throw new SecurityException("killProcessesBelowForeground() only available to system");
7512        }
7513
7514        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7515    }
7516
7517    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7518        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7519            throw new SecurityException("killProcessesBelowAdj() only available to system");
7520        }
7521
7522        boolean killed = false;
7523        synchronized (mPidsSelfLocked) {
7524            final int size = mPidsSelfLocked.size();
7525            for (int i = 0; i < size; i++) {
7526                final int pid = mPidsSelfLocked.keyAt(i);
7527                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7528                if (proc == null) continue;
7529
7530                final int adj = proc.setAdj;
7531                if (adj > belowAdj && !proc.killedBackground) {
7532                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7533                    EventLog.writeEvent(
7534                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7535                    killed = true;
7536                    proc.killedBackground = true;
7537                    Process.killProcessQuiet(pid);
7538                }
7539            }
7540        }
7541        return killed;
7542    }
7543
7544    public final void startRunning(String pkg, String cls, String action,
7545            String data) {
7546        synchronized(this) {
7547            if (mStartRunning) {
7548                return;
7549            }
7550            mStartRunning = true;
7551            mTopComponent = pkg != null && cls != null
7552                    ? new ComponentName(pkg, cls) : null;
7553            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7554            mTopData = data;
7555            if (!mSystemReady) {
7556                return;
7557            }
7558        }
7559
7560        systemReady(null);
7561    }
7562
7563    private void retrieveSettings() {
7564        final ContentResolver resolver = mContext.getContentResolver();
7565        String debugApp = Settings.System.getString(
7566            resolver, Settings.System.DEBUG_APP);
7567        boolean waitForDebugger = Settings.System.getInt(
7568            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7569        boolean alwaysFinishActivities = Settings.System.getInt(
7570            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7571
7572        Configuration configuration = new Configuration();
7573        Settings.System.getConfiguration(resolver, configuration);
7574
7575        synchronized (this) {
7576            mDebugApp = mOrigDebugApp = debugApp;
7577            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7578            mAlwaysFinishActivities = alwaysFinishActivities;
7579            // This happens before any activities are started, so we can
7580            // change mConfiguration in-place.
7581            updateConfigurationLocked(configuration, null, false, true);
7582            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7583        }
7584    }
7585
7586    public boolean testIsSystemReady() {
7587        // no need to synchronize(this) just to read & return the value
7588        return mSystemReady;
7589    }
7590
7591    private static File getCalledPreBootReceiversFile() {
7592        File dataDir = Environment.getDataDirectory();
7593        File systemDir = new File(dataDir, "system");
7594        File fname = new File(systemDir, "called_pre_boots.dat");
7595        return fname;
7596    }
7597
7598    static final int LAST_DONE_VERSION = 10000;
7599
7600    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7601        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7602        File file = getCalledPreBootReceiversFile();
7603        FileInputStream fis = null;
7604        try {
7605            fis = new FileInputStream(file);
7606            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7607            int fvers = dis.readInt();
7608            if (fvers == LAST_DONE_VERSION) {
7609                String vers = dis.readUTF();
7610                String codename = dis.readUTF();
7611                String build = dis.readUTF();
7612                if (android.os.Build.VERSION.RELEASE.equals(vers)
7613                        && android.os.Build.VERSION.CODENAME.equals(codename)
7614                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7615                    int num = dis.readInt();
7616                    while (num > 0) {
7617                        num--;
7618                        String pkg = dis.readUTF();
7619                        String cls = dis.readUTF();
7620                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7621                    }
7622                }
7623            }
7624        } catch (FileNotFoundException e) {
7625        } catch (IOException e) {
7626            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7627        } finally {
7628            if (fis != null) {
7629                try {
7630                    fis.close();
7631                } catch (IOException e) {
7632                }
7633            }
7634        }
7635        return lastDoneReceivers;
7636    }
7637
7638    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7639        File file = getCalledPreBootReceiversFile();
7640        FileOutputStream fos = null;
7641        DataOutputStream dos = null;
7642        try {
7643            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7644            fos = new FileOutputStream(file);
7645            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7646            dos.writeInt(LAST_DONE_VERSION);
7647            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7648            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7649            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7650            dos.writeInt(list.size());
7651            for (int i=0; i<list.size(); i++) {
7652                dos.writeUTF(list.get(i).getPackageName());
7653                dos.writeUTF(list.get(i).getClassName());
7654            }
7655        } catch (IOException e) {
7656            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7657            file.delete();
7658        } finally {
7659            FileUtils.sync(fos);
7660            if (dos != null) {
7661                try {
7662                    dos.close();
7663                } catch (IOException e) {
7664                    // TODO Auto-generated catch block
7665                    e.printStackTrace();
7666                }
7667            }
7668        }
7669    }
7670
7671    public void systemReady(final Runnable goingCallback) {
7672        synchronized(this) {
7673            if (mSystemReady) {
7674                if (goingCallback != null) goingCallback.run();
7675                return;
7676            }
7677
7678            // Check to see if there are any update receivers to run.
7679            if (!mDidUpdate) {
7680                if (mWaitingUpdate) {
7681                    return;
7682                }
7683                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7684                List<ResolveInfo> ris = null;
7685                try {
7686                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7687                            intent, null, 0, 0);
7688                } catch (RemoteException e) {
7689                }
7690                if (ris != null) {
7691                    for (int i=ris.size()-1; i>=0; i--) {
7692                        if ((ris.get(i).activityInfo.applicationInfo.flags
7693                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7694                            ris.remove(i);
7695                        }
7696                    }
7697                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7698
7699                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7700
7701                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7702                    for (int i=0; i<ris.size(); i++) {
7703                        ActivityInfo ai = ris.get(i).activityInfo;
7704                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7705                        if (lastDoneReceivers.contains(comp)) {
7706                            ris.remove(i);
7707                            i--;
7708                        }
7709                    }
7710
7711                    final int[] users = getUsersLocked();
7712                    for (int i=0; i<ris.size(); i++) {
7713                        ActivityInfo ai = ris.get(i).activityInfo;
7714                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7715                        doneReceivers.add(comp);
7716                        intent.setComponent(comp);
7717                        for (int j=0; j<users.length; j++) {
7718                            IIntentReceiver finisher = null;
7719                            if (i == ris.size()-1 && j == users.length-1) {
7720                                finisher = new IIntentReceiver.Stub() {
7721                                    public void performReceive(Intent intent, int resultCode,
7722                                            String data, Bundle extras, boolean ordered,
7723                                            boolean sticky, int sendingUser) {
7724                                        // The raw IIntentReceiver interface is called
7725                                        // with the AM lock held, so redispatch to
7726                                        // execute our code without the lock.
7727                                        mHandler.post(new Runnable() {
7728                                            public void run() {
7729                                                synchronized (ActivityManagerService.this) {
7730                                                    mDidUpdate = true;
7731                                                }
7732                                                writeLastDonePreBootReceivers(doneReceivers);
7733                                                showBootMessage(mContext.getText(
7734                                                        R.string.android_upgrading_complete),
7735                                                        false);
7736                                                systemReady(goingCallback);
7737                                            }
7738                                        });
7739                                    }
7740                                };
7741                            }
7742                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
7743                                    + " for user " + users[j]);
7744                            broadcastIntentLocked(null, null, intent, null, finisher,
7745                                    0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7746                                    users[j]);
7747                            if (finisher != null) {
7748                                mWaitingUpdate = true;
7749                            }
7750                        }
7751                    }
7752                }
7753                if (mWaitingUpdate) {
7754                    return;
7755                }
7756                mDidUpdate = true;
7757            }
7758
7759            mSystemReady = true;
7760            if (!mStartRunning) {
7761                return;
7762            }
7763        }
7764
7765        ArrayList<ProcessRecord> procsToKill = null;
7766        synchronized(mPidsSelfLocked) {
7767            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7768                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7769                if (!isAllowedWhileBooting(proc.info)){
7770                    if (procsToKill == null) {
7771                        procsToKill = new ArrayList<ProcessRecord>();
7772                    }
7773                    procsToKill.add(proc);
7774                }
7775            }
7776        }
7777
7778        synchronized(this) {
7779            if (procsToKill != null) {
7780                for (int i=procsToKill.size()-1; i>=0; i--) {
7781                    ProcessRecord proc = procsToKill.get(i);
7782                    Slog.i(TAG, "Removing system update proc: " + proc);
7783                    removeProcessLocked(proc, true, false, "system update done");
7784                }
7785            }
7786
7787            // Now that we have cleaned up any update processes, we
7788            // are ready to start launching real processes and know that
7789            // we won't trample on them any more.
7790            mProcessesReady = true;
7791        }
7792
7793        Slog.i(TAG, "System now ready");
7794        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7795            SystemClock.uptimeMillis());
7796
7797        synchronized(this) {
7798            // Make sure we have no pre-ready processes sitting around.
7799
7800            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7801                ResolveInfo ri = mContext.getPackageManager()
7802                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7803                                STOCK_PM_FLAGS);
7804                CharSequence errorMsg = null;
7805                if (ri != null) {
7806                    ActivityInfo ai = ri.activityInfo;
7807                    ApplicationInfo app = ai.applicationInfo;
7808                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7809                        mTopAction = Intent.ACTION_FACTORY_TEST;
7810                        mTopData = null;
7811                        mTopComponent = new ComponentName(app.packageName,
7812                                ai.name);
7813                    } else {
7814                        errorMsg = mContext.getResources().getText(
7815                                com.android.internal.R.string.factorytest_not_system);
7816                    }
7817                } else {
7818                    errorMsg = mContext.getResources().getText(
7819                            com.android.internal.R.string.factorytest_no_action);
7820                }
7821                if (errorMsg != null) {
7822                    mTopAction = null;
7823                    mTopData = null;
7824                    mTopComponent = null;
7825                    Message msg = Message.obtain();
7826                    msg.what = SHOW_FACTORY_ERROR_MSG;
7827                    msg.getData().putCharSequence("msg", errorMsg);
7828                    mHandler.sendMessage(msg);
7829                }
7830            }
7831        }
7832
7833        retrieveSettings();
7834
7835        if (goingCallback != null) goingCallback.run();
7836
7837        synchronized (this) {
7838            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7839                try {
7840                    List apps = AppGlobals.getPackageManager().
7841                        getPersistentApplications(STOCK_PM_FLAGS);
7842                    if (apps != null) {
7843                        int N = apps.size();
7844                        int i;
7845                        for (i=0; i<N; i++) {
7846                            ApplicationInfo info
7847                                = (ApplicationInfo)apps.get(i);
7848                            if (info != null &&
7849                                    !info.packageName.equals("android")) {
7850                                addAppLocked(info, false);
7851                            }
7852                        }
7853                    }
7854                } catch (RemoteException ex) {
7855                    // pm is in same process, this will never happen.
7856                }
7857            }
7858
7859            // Start up initial activity.
7860            mBooting = true;
7861
7862            try {
7863                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7864                    Message msg = Message.obtain();
7865                    msg.what = SHOW_UID_ERROR_MSG;
7866                    mHandler.sendMessage(msg);
7867                }
7868            } catch (RemoteException e) {
7869            }
7870
7871            long ident = Binder.clearCallingIdentity();
7872            try {
7873                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
7874                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
7875                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
7876                broadcastIntentLocked(null, null, intent,
7877                        null, null, 0, null, null, null,
7878                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
7879            } finally {
7880                Binder.restoreCallingIdentity(ident);
7881            }
7882            mMainStack.resumeTopActivityLocked(null);
7883            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
7884        }
7885    }
7886
7887    private boolean makeAppCrashingLocked(ProcessRecord app,
7888            String shortMsg, String longMsg, String stackTrace) {
7889        app.crashing = true;
7890        app.crashingReport = generateProcessError(app,
7891                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7892        startAppProblemLocked(app);
7893        app.stopFreezingAllLocked();
7894        return handleAppCrashLocked(app);
7895    }
7896
7897    private void makeAppNotRespondingLocked(ProcessRecord app,
7898            String activity, String shortMsg, String longMsg) {
7899        app.notResponding = true;
7900        app.notRespondingReport = generateProcessError(app,
7901                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7902                activity, shortMsg, longMsg, null);
7903        startAppProblemLocked(app);
7904        app.stopFreezingAllLocked();
7905    }
7906
7907    /**
7908     * Generate a process error record, suitable for attachment to a ProcessRecord.
7909     *
7910     * @param app The ProcessRecord in which the error occurred.
7911     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7912     *                      ActivityManager.AppErrorStateInfo
7913     * @param activity The activity associated with the crash, if known.
7914     * @param shortMsg Short message describing the crash.
7915     * @param longMsg Long message describing the crash.
7916     * @param stackTrace Full crash stack trace, may be null.
7917     *
7918     * @return Returns a fully-formed AppErrorStateInfo record.
7919     */
7920    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7921            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7922        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7923
7924        report.condition = condition;
7925        report.processName = app.processName;
7926        report.pid = app.pid;
7927        report.uid = app.info.uid;
7928        report.tag = activity;
7929        report.shortMsg = shortMsg;
7930        report.longMsg = longMsg;
7931        report.stackTrace = stackTrace;
7932
7933        return report;
7934    }
7935
7936    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7937        synchronized (this) {
7938            app.crashing = false;
7939            app.crashingReport = null;
7940            app.notResponding = false;
7941            app.notRespondingReport = null;
7942            if (app.anrDialog == fromDialog) {
7943                app.anrDialog = null;
7944            }
7945            if (app.waitDialog == fromDialog) {
7946                app.waitDialog = null;
7947            }
7948            if (app.pid > 0 && app.pid != MY_PID) {
7949                handleAppCrashLocked(app);
7950                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7951                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7952                        app.processName, app.setAdj, "user's request after error");
7953                Process.killProcessQuiet(app.pid);
7954            }
7955        }
7956    }
7957
7958    private boolean handleAppCrashLocked(ProcessRecord app) {
7959        if (mHeadless) {
7960            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7961            return false;
7962        }
7963        long now = SystemClock.uptimeMillis();
7964
7965        Long crashTime;
7966        if (!app.isolated) {
7967            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7968        } else {
7969            crashTime = null;
7970        }
7971        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7972            // This process loses!
7973            Slog.w(TAG, "Process " + app.info.processName
7974                    + " has crashed too many times: killing!");
7975            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7976                    app.info.processName, app.uid);
7977            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7978                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7979                if (r.app == app) {
7980                    Slog.w(TAG, "  Force finishing activity "
7981                        + r.intent.getComponent().flattenToShortString());
7982                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
7983                            null, "crashed", false);
7984                }
7985            }
7986            if (!app.persistent) {
7987                // We don't want to start this process again until the user
7988                // explicitly does so...  but for persistent process, we really
7989                // need to keep it running.  If a persistent process is actually
7990                // repeatedly crashing, then badness for everyone.
7991                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
7992                        app.info.processName);
7993                if (!app.isolated) {
7994                    // XXX We don't have a way to mark isolated processes
7995                    // as bad, since they don't have a peristent identity.
7996                    mBadProcesses.put(app.info.processName, app.uid, now);
7997                    mProcessCrashTimes.remove(app.info.processName, app.uid);
7998                }
7999                app.bad = true;
8000                app.removed = true;
8001                // Don't let services in this process be restarted and potentially
8002                // annoy the user repeatedly.  Unless it is persistent, since those
8003                // processes run critical code.
8004                removeProcessLocked(app, false, false, "crash");
8005                mMainStack.resumeTopActivityLocked(null);
8006                return false;
8007            }
8008            mMainStack.resumeTopActivityLocked(null);
8009        } else {
8010            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
8011            if (r != null && r.app == app) {
8012                // If the top running activity is from this crashing
8013                // process, then terminate it to avoid getting in a loop.
8014                Slog.w(TAG, "  Force finishing activity "
8015                        + r.intent.getComponent().flattenToShortString());
8016                int index = mMainStack.indexOfActivityLocked(r);
8017                r.stack.finishActivityLocked(r, index,
8018                        Activity.RESULT_CANCELED, null, "crashed", false);
8019                // Also terminate any activities below it that aren't yet
8020                // stopped, to avoid a situation where one will get
8021                // re-start our crashing activity once it gets resumed again.
8022                index--;
8023                if (index >= 0) {
8024                    r = (ActivityRecord)mMainStack.mHistory.get(index);
8025                    if (r.state == ActivityState.RESUMED
8026                            || r.state == ActivityState.PAUSING
8027                            || r.state == ActivityState.PAUSED) {
8028                        if (!r.isHomeActivity || mHomeProcess != r.app) {
8029                            Slog.w(TAG, "  Force finishing activity "
8030                                    + r.intent.getComponent().flattenToShortString());
8031                            r.stack.finishActivityLocked(r, index,
8032                                    Activity.RESULT_CANCELED, null, "crashed", false);
8033                        }
8034                    }
8035                }
8036            }
8037        }
8038
8039        // Bump up the crash count of any services currently running in the proc.
8040        if (app.services.size() != 0) {
8041            // Any services running in the application need to be placed
8042            // back in the pending list.
8043            Iterator<ServiceRecord> it = app.services.iterator();
8044            while (it.hasNext()) {
8045                ServiceRecord sr = it.next();
8046                sr.crashCount++;
8047            }
8048        }
8049
8050        // If the crashing process is what we consider to be the "home process" and it has been
8051        // replaced by a third-party app, clear the package preferred activities from packages
8052        // with a home activity running in the process to prevent a repeatedly crashing app
8053        // from blocking the user to manually clear the list.
8054        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
8055                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
8056            Iterator it = mHomeProcess.activities.iterator();
8057            while (it.hasNext()) {
8058                ActivityRecord r = (ActivityRecord)it.next();
8059                if (r.isHomeActivity) {
8060                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
8061                    try {
8062                        ActivityThread.getPackageManager()
8063                                .clearPackagePreferredActivities(r.packageName);
8064                    } catch (RemoteException c) {
8065                        // pm is in same process, this will never happen.
8066                    }
8067                }
8068            }
8069        }
8070
8071        if (!app.isolated) {
8072            // XXX Can't keep track of crash times for isolated processes,
8073            // because they don't have a perisistent identity.
8074            mProcessCrashTimes.put(app.info.processName, app.uid, now);
8075        }
8076
8077        return true;
8078    }
8079
8080    void startAppProblemLocked(ProcessRecord app) {
8081        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
8082                mContext, app.info.packageName, app.info.flags);
8083        skipCurrentReceiverLocked(app);
8084    }
8085
8086    void skipCurrentReceiverLocked(ProcessRecord app) {
8087        for (BroadcastQueue queue : mBroadcastQueues) {
8088            queue.skipCurrentReceiverLocked(app);
8089        }
8090    }
8091
8092    /**
8093     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8094     * The application process will exit immediately after this call returns.
8095     * @param app object of the crashing app, null for the system server
8096     * @param crashInfo describing the exception
8097     */
8098    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
8099        ProcessRecord r = findAppProcess(app, "Crash");
8100        final String processName = app == null ? "system_server"
8101                : (r == null ? "unknown" : r.processName);
8102
8103        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
8104                processName,
8105                r == null ? -1 : r.info.flags,
8106                crashInfo.exceptionClassName,
8107                crashInfo.exceptionMessage,
8108                crashInfo.throwFileName,
8109                crashInfo.throwLineNumber);
8110
8111        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
8112
8113        crashApplication(r, crashInfo);
8114    }
8115
8116    public void handleApplicationStrictModeViolation(
8117            IBinder app,
8118            int violationMask,
8119            StrictMode.ViolationInfo info) {
8120        ProcessRecord r = findAppProcess(app, "StrictMode");
8121        if (r == null) {
8122            return;
8123        }
8124
8125        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
8126            Integer stackFingerprint = info.hashCode();
8127            boolean logIt = true;
8128            synchronized (mAlreadyLoggedViolatedStacks) {
8129                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
8130                    logIt = false;
8131                    // TODO: sub-sample into EventLog for these, with
8132                    // the info.durationMillis?  Then we'd get
8133                    // the relative pain numbers, without logging all
8134                    // the stack traces repeatedly.  We'd want to do
8135                    // likewise in the client code, which also does
8136                    // dup suppression, before the Binder call.
8137                } else {
8138                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
8139                        mAlreadyLoggedViolatedStacks.clear();
8140                    }
8141                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
8142                }
8143            }
8144            if (logIt) {
8145                logStrictModeViolationToDropBox(r, info);
8146            }
8147        }
8148
8149        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
8150            AppErrorResult result = new AppErrorResult();
8151            synchronized (this) {
8152                final long origId = Binder.clearCallingIdentity();
8153
8154                Message msg = Message.obtain();
8155                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
8156                HashMap<String, Object> data = new HashMap<String, Object>();
8157                data.put("result", result);
8158                data.put("app", r);
8159                data.put("violationMask", violationMask);
8160                data.put("info", info);
8161                msg.obj = data;
8162                mHandler.sendMessage(msg);
8163
8164                Binder.restoreCallingIdentity(origId);
8165            }
8166            int res = result.get();
8167            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
8168        }
8169    }
8170
8171    // Depending on the policy in effect, there could be a bunch of
8172    // these in quick succession so we try to batch these together to
8173    // minimize disk writes, number of dropbox entries, and maximize
8174    // compression, by having more fewer, larger records.
8175    private void logStrictModeViolationToDropBox(
8176            ProcessRecord process,
8177            StrictMode.ViolationInfo info) {
8178        if (info == null) {
8179            return;
8180        }
8181        final boolean isSystemApp = process == null ||
8182                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8183                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
8184        final String processName = process == null ? "unknown" : process.processName;
8185        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8186        final DropBoxManager dbox = (DropBoxManager)
8187                mContext.getSystemService(Context.DROPBOX_SERVICE);
8188
8189        // Exit early if the dropbox isn't configured to accept this report type.
8190        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8191
8192        boolean bufferWasEmpty;
8193        boolean needsFlush;
8194        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8195        synchronized (sb) {
8196            bufferWasEmpty = sb.length() == 0;
8197            appendDropBoxProcessHeaders(process, processName, sb);
8198            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8199            sb.append("System-App: ").append(isSystemApp).append("\n");
8200            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8201            if (info.violationNumThisLoop != 0) {
8202                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8203            }
8204            if (info.numAnimationsRunning != 0) {
8205                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8206            }
8207            if (info.broadcastIntentAction != null) {
8208                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8209            }
8210            if (info.durationMillis != -1) {
8211                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
8212            }
8213            if (info.numInstances != -1) {
8214                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8215            }
8216            if (info.tags != null) {
8217                for (String tag : info.tags) {
8218                    sb.append("Span-Tag: ").append(tag).append("\n");
8219                }
8220            }
8221            sb.append("\n");
8222            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8223                sb.append(info.crashInfo.stackTrace);
8224            }
8225            sb.append("\n");
8226
8227            // Only buffer up to ~64k.  Various logging bits truncate
8228            // things at 128k.
8229            needsFlush = (sb.length() > 64 * 1024);
8230        }
8231
8232        // Flush immediately if the buffer's grown too large, or this
8233        // is a non-system app.  Non-system apps are isolated with a
8234        // different tag & policy and not batched.
8235        //
8236        // Batching is useful during internal testing with
8237        // StrictMode settings turned up high.  Without batching,
8238        // thousands of separate files could be created on boot.
8239        if (!isSystemApp || needsFlush) {
8240            new Thread("Error dump: " + dropboxTag) {
8241                @Override
8242                public void run() {
8243                    String report;
8244                    synchronized (sb) {
8245                        report = sb.toString();
8246                        sb.delete(0, sb.length());
8247                        sb.trimToSize();
8248                    }
8249                    if (report.length() != 0) {
8250                        dbox.addText(dropboxTag, report);
8251                    }
8252                }
8253            }.start();
8254            return;
8255        }
8256
8257        // System app batching:
8258        if (!bufferWasEmpty) {
8259            // An existing dropbox-writing thread is outstanding, so
8260            // we don't need to start it up.  The existing thread will
8261            // catch the buffer appends we just did.
8262            return;
8263        }
8264
8265        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8266        // (After this point, we shouldn't access AMS internal data structures.)
8267        new Thread("Error dump: " + dropboxTag) {
8268            @Override
8269            public void run() {
8270                // 5 second sleep to let stacks arrive and be batched together
8271                try {
8272                    Thread.sleep(5000);  // 5 seconds
8273                } catch (InterruptedException e) {}
8274
8275                String errorReport;
8276                synchronized (mStrictModeBuffer) {
8277                    errorReport = mStrictModeBuffer.toString();
8278                    if (errorReport.length() == 0) {
8279                        return;
8280                    }
8281                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8282                    mStrictModeBuffer.trimToSize();
8283                }
8284                dbox.addText(dropboxTag, errorReport);
8285            }
8286        }.start();
8287    }
8288
8289    /**
8290     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8291     * @param app object of the crashing app, null for the system server
8292     * @param tag reported by the caller
8293     * @param crashInfo describing the context of the error
8294     * @return true if the process should exit immediately (WTF is fatal)
8295     */
8296    public boolean handleApplicationWtf(IBinder app, String tag,
8297            ApplicationErrorReport.CrashInfo crashInfo) {
8298        ProcessRecord r = findAppProcess(app, "WTF");
8299        final String processName = app == null ? "system_server"
8300                : (r == null ? "unknown" : r.processName);
8301
8302        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8303                processName,
8304                r == null ? -1 : r.info.flags,
8305                tag, crashInfo.exceptionMessage);
8306
8307        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8308
8309        if (r != null && r.pid != Process.myPid() &&
8310                Settings.Secure.getInt(mContext.getContentResolver(),
8311                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
8312            crashApplication(r, crashInfo);
8313            return true;
8314        } else {
8315            return false;
8316        }
8317    }
8318
8319    /**
8320     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8321     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8322     */
8323    private ProcessRecord findAppProcess(IBinder app, String reason) {
8324        if (app == null) {
8325            return null;
8326        }
8327
8328        synchronized (this) {
8329            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8330                final int NA = apps.size();
8331                for (int ia=0; ia<NA; ia++) {
8332                    ProcessRecord p = apps.valueAt(ia);
8333                    if (p.thread != null && p.thread.asBinder() == app) {
8334                        return p;
8335                    }
8336                }
8337            }
8338
8339            Slog.w(TAG, "Can't find mystery application for " + reason
8340                    + " from pid=" + Binder.getCallingPid()
8341                    + " uid=" + Binder.getCallingUid() + ": " + app);
8342            return null;
8343        }
8344    }
8345
8346    /**
8347     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8348     * to append various headers to the dropbox log text.
8349     */
8350    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8351            StringBuilder sb) {
8352        // Watchdog thread ends up invoking this function (with
8353        // a null ProcessRecord) to add the stack file to dropbox.
8354        // Do not acquire a lock on this (am) in such cases, as it
8355        // could cause a potential deadlock, if and when watchdog
8356        // is invoked due to unavailability of lock on am and it
8357        // would prevent watchdog from killing system_server.
8358        if (process == null) {
8359            sb.append("Process: ").append(processName).append("\n");
8360            return;
8361        }
8362        // Note: ProcessRecord 'process' is guarded by the service
8363        // instance.  (notably process.pkgList, which could otherwise change
8364        // concurrently during execution of this method)
8365        synchronized (this) {
8366            sb.append("Process: ").append(processName).append("\n");
8367            int flags = process.info.flags;
8368            IPackageManager pm = AppGlobals.getPackageManager();
8369            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8370            for (String pkg : process.pkgList) {
8371                sb.append("Package: ").append(pkg);
8372                try {
8373                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
8374                    if (pi != null) {
8375                        sb.append(" v").append(pi.versionCode);
8376                        if (pi.versionName != null) {
8377                            sb.append(" (").append(pi.versionName).append(")");
8378                        }
8379                    }
8380                } catch (RemoteException e) {
8381                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8382                }
8383                sb.append("\n");
8384            }
8385        }
8386    }
8387
8388    private static String processClass(ProcessRecord process) {
8389        if (process == null || process.pid == MY_PID) {
8390            return "system_server";
8391        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8392            return "system_app";
8393        } else {
8394            return "data_app";
8395        }
8396    }
8397
8398    /**
8399     * Write a description of an error (crash, WTF, ANR) to the drop box.
8400     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8401     * @param process which caused the error, null means the system server
8402     * @param activity which triggered the error, null if unknown
8403     * @param parent activity related to the error, null if unknown
8404     * @param subject line related to the error, null if absent
8405     * @param report in long form describing the error, null if absent
8406     * @param logFile to include in the report, null if none
8407     * @param crashInfo giving an application stack trace, null if absent
8408     */
8409    public void addErrorToDropBox(String eventType,
8410            ProcessRecord process, String processName, ActivityRecord activity,
8411            ActivityRecord parent, String subject,
8412            final String report, final File logFile,
8413            final ApplicationErrorReport.CrashInfo crashInfo) {
8414        // NOTE -- this must never acquire the ActivityManagerService lock,
8415        // otherwise the watchdog may be prevented from resetting the system.
8416
8417        final String dropboxTag = processClass(process) + "_" + eventType;
8418        final DropBoxManager dbox = (DropBoxManager)
8419                mContext.getSystemService(Context.DROPBOX_SERVICE);
8420
8421        // Exit early if the dropbox isn't configured to accept this report type.
8422        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8423
8424        final StringBuilder sb = new StringBuilder(1024);
8425        appendDropBoxProcessHeaders(process, processName, sb);
8426        if (activity != null) {
8427            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8428        }
8429        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8430            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8431        }
8432        if (parent != null && parent != activity) {
8433            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8434        }
8435        if (subject != null) {
8436            sb.append("Subject: ").append(subject).append("\n");
8437        }
8438        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8439        if (Debug.isDebuggerConnected()) {
8440            sb.append("Debugger: Connected\n");
8441        }
8442        sb.append("\n");
8443
8444        // Do the rest in a worker thread to avoid blocking the caller on I/O
8445        // (After this point, we shouldn't access AMS internal data structures.)
8446        Thread worker = new Thread("Error dump: " + dropboxTag) {
8447            @Override
8448            public void run() {
8449                if (report != null) {
8450                    sb.append(report);
8451                }
8452                if (logFile != null) {
8453                    try {
8454                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8455                    } catch (IOException e) {
8456                        Slog.e(TAG, "Error reading " + logFile, e);
8457                    }
8458                }
8459                if (crashInfo != null && crashInfo.stackTrace != null) {
8460                    sb.append(crashInfo.stackTrace);
8461                }
8462
8463                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8464                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8465                if (lines > 0) {
8466                    sb.append("\n");
8467
8468                    // Merge several logcat streams, and take the last N lines
8469                    InputStreamReader input = null;
8470                    try {
8471                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8472                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8473                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8474
8475                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8476                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8477                        input = new InputStreamReader(logcat.getInputStream());
8478
8479                        int num;
8480                        char[] buf = new char[8192];
8481                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8482                    } catch (IOException e) {
8483                        Slog.e(TAG, "Error running logcat", e);
8484                    } finally {
8485                        if (input != null) try { input.close(); } catch (IOException e) {}
8486                    }
8487                }
8488
8489                dbox.addText(dropboxTag, sb.toString());
8490            }
8491        };
8492
8493        if (process == null) {
8494            // If process is null, we are being called from some internal code
8495            // and may be about to die -- run this synchronously.
8496            worker.run();
8497        } else {
8498            worker.start();
8499        }
8500    }
8501
8502    /**
8503     * Bring up the "unexpected error" dialog box for a crashing app.
8504     * Deal with edge cases (intercepts from instrumented applications,
8505     * ActivityController, error intent receivers, that sort of thing).
8506     * @param r the application crashing
8507     * @param crashInfo describing the failure
8508     */
8509    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8510        long timeMillis = System.currentTimeMillis();
8511        String shortMsg = crashInfo.exceptionClassName;
8512        String longMsg = crashInfo.exceptionMessage;
8513        String stackTrace = crashInfo.stackTrace;
8514        if (shortMsg != null && longMsg != null) {
8515            longMsg = shortMsg + ": " + longMsg;
8516        } else if (shortMsg != null) {
8517            longMsg = shortMsg;
8518        }
8519
8520        AppErrorResult result = new AppErrorResult();
8521        synchronized (this) {
8522            if (mController != null) {
8523                try {
8524                    String name = r != null ? r.processName : null;
8525                    int pid = r != null ? r.pid : Binder.getCallingPid();
8526                    if (!mController.appCrashed(name, pid,
8527                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8528                        Slog.w(TAG, "Force-killing crashed app " + name
8529                                + " at watcher's request");
8530                        Process.killProcess(pid);
8531                        return;
8532                    }
8533                } catch (RemoteException e) {
8534                    mController = null;
8535                }
8536            }
8537
8538            final long origId = Binder.clearCallingIdentity();
8539
8540            // If this process is running instrumentation, finish it.
8541            if (r != null && r.instrumentationClass != null) {
8542                Slog.w(TAG, "Error in app " + r.processName
8543                      + " running instrumentation " + r.instrumentationClass + ":");
8544                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8545                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8546                Bundle info = new Bundle();
8547                info.putString("shortMsg", shortMsg);
8548                info.putString("longMsg", longMsg);
8549                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8550                Binder.restoreCallingIdentity(origId);
8551                return;
8552            }
8553
8554            // If we can't identify the process or it's already exceeded its crash quota,
8555            // quit right away without showing a crash dialog.
8556            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8557                Binder.restoreCallingIdentity(origId);
8558                return;
8559            }
8560
8561            Message msg = Message.obtain();
8562            msg.what = SHOW_ERROR_MSG;
8563            HashMap data = new HashMap();
8564            data.put("result", result);
8565            data.put("app", r);
8566            msg.obj = data;
8567            mHandler.sendMessage(msg);
8568
8569            Binder.restoreCallingIdentity(origId);
8570        }
8571
8572        int res = result.get();
8573
8574        Intent appErrorIntent = null;
8575        synchronized (this) {
8576            if (r != null && !r.isolated) {
8577                // XXX Can't keep track of crash time for isolated processes,
8578                // since they don't have a persistent identity.
8579                mProcessCrashTimes.put(r.info.processName, r.uid,
8580                        SystemClock.uptimeMillis());
8581            }
8582            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8583                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8584            }
8585        }
8586
8587        if (appErrorIntent != null) {
8588            try {
8589                mContext.startActivity(appErrorIntent);
8590            } catch (ActivityNotFoundException e) {
8591                Slog.w(TAG, "bug report receiver dissappeared", e);
8592            }
8593        }
8594    }
8595
8596    Intent createAppErrorIntentLocked(ProcessRecord r,
8597            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8598        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8599        if (report == null) {
8600            return null;
8601        }
8602        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8603        result.setComponent(r.errorReportReceiver);
8604        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8605        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8606        return result;
8607    }
8608
8609    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8610            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8611        if (r.errorReportReceiver == null) {
8612            return null;
8613        }
8614
8615        if (!r.crashing && !r.notResponding) {
8616            return null;
8617        }
8618
8619        ApplicationErrorReport report = new ApplicationErrorReport();
8620        report.packageName = r.info.packageName;
8621        report.installerPackageName = r.errorReportReceiver.getPackageName();
8622        report.processName = r.processName;
8623        report.time = timeMillis;
8624        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8625
8626        if (r.crashing) {
8627            report.type = ApplicationErrorReport.TYPE_CRASH;
8628            report.crashInfo = crashInfo;
8629        } else if (r.notResponding) {
8630            report.type = ApplicationErrorReport.TYPE_ANR;
8631            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8632
8633            report.anrInfo.activity = r.notRespondingReport.tag;
8634            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8635            report.anrInfo.info = r.notRespondingReport.longMsg;
8636        }
8637
8638        return report;
8639    }
8640
8641    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8642        enforceNotIsolatedCaller("getProcessesInErrorState");
8643        // assume our apps are happy - lazy create the list
8644        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8645
8646        final boolean allUsers = ActivityManager.checkUidPermission(
8647                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8648                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8649        int userId = UserHandle.getUserId(Binder.getCallingUid());
8650
8651        synchronized (this) {
8652
8653            // iterate across all processes
8654            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8655                ProcessRecord app = mLruProcesses.get(i);
8656                if (!allUsers && app.userId != userId) {
8657                    continue;
8658                }
8659                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8660                    // This one's in trouble, so we'll generate a report for it
8661                    // crashes are higher priority (in case there's a crash *and* an anr)
8662                    ActivityManager.ProcessErrorStateInfo report = null;
8663                    if (app.crashing) {
8664                        report = app.crashingReport;
8665                    } else if (app.notResponding) {
8666                        report = app.notRespondingReport;
8667                    }
8668
8669                    if (report != null) {
8670                        if (errList == null) {
8671                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8672                        }
8673                        errList.add(report);
8674                    } else {
8675                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8676                                " crashing = " + app.crashing +
8677                                " notResponding = " + app.notResponding);
8678                    }
8679                }
8680            }
8681        }
8682
8683        return errList;
8684    }
8685
8686    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8687        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8688            if (currApp != null) {
8689                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8690            }
8691            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8692        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8693            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8694        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8695            if (currApp != null) {
8696                currApp.lru = 0;
8697            }
8698            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8699        } else if (adj >= ProcessList.SERVICE_ADJ) {
8700            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8701        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8702            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8703        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8704            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8705        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8706            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8707        } else {
8708            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8709        }
8710    }
8711
8712    private void fillInProcMemInfo(ProcessRecord app,
8713            ActivityManager.RunningAppProcessInfo outInfo) {
8714        outInfo.pid = app.pid;
8715        outInfo.uid = app.info.uid;
8716        if (mHeavyWeightProcess == app) {
8717            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8718        }
8719        if (app.persistent) {
8720            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8721        }
8722        if (app.hasActivities) {
8723            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8724        }
8725        outInfo.lastTrimLevel = app.trimMemoryLevel;
8726        int adj = app.curAdj;
8727        outInfo.importance = oomAdjToImportance(adj, outInfo);
8728        outInfo.importanceReasonCode = app.adjTypeCode;
8729    }
8730
8731    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8732        enforceNotIsolatedCaller("getRunningAppProcesses");
8733        // Lazy instantiation of list
8734        List<ActivityManager.RunningAppProcessInfo> runList = null;
8735        final boolean allUsers = ActivityManager.checkUidPermission(
8736                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8737                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8738        int userId = UserHandle.getUserId(Binder.getCallingUid());
8739        synchronized (this) {
8740            // Iterate across all processes
8741            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8742                ProcessRecord app = mLruProcesses.get(i);
8743                if (!allUsers && app.userId != userId) {
8744                    continue;
8745                }
8746                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8747                    // Generate process state info for running application
8748                    ActivityManager.RunningAppProcessInfo currApp =
8749                        new ActivityManager.RunningAppProcessInfo(app.processName,
8750                                app.pid, app.getPackageList());
8751                    fillInProcMemInfo(app, currApp);
8752                    if (app.adjSource instanceof ProcessRecord) {
8753                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8754                        currApp.importanceReasonImportance = oomAdjToImportance(
8755                                app.adjSourceOom, null);
8756                    } else if (app.adjSource instanceof ActivityRecord) {
8757                        ActivityRecord r = (ActivityRecord)app.adjSource;
8758                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8759                    }
8760                    if (app.adjTarget instanceof ComponentName) {
8761                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8762                    }
8763                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8764                    //        + " lru=" + currApp.lru);
8765                    if (runList == null) {
8766                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8767                    }
8768                    runList.add(currApp);
8769                }
8770            }
8771        }
8772        return runList;
8773    }
8774
8775    public List<ApplicationInfo> getRunningExternalApplications() {
8776        enforceNotIsolatedCaller("getRunningExternalApplications");
8777        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8778        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8779        if (runningApps != null && runningApps.size() > 0) {
8780            Set<String> extList = new HashSet<String>();
8781            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8782                if (app.pkgList != null) {
8783                    for (String pkg : app.pkgList) {
8784                        extList.add(pkg);
8785                    }
8786                }
8787            }
8788            IPackageManager pm = AppGlobals.getPackageManager();
8789            for (String pkg : extList) {
8790                try {
8791                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8792                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8793                        retList.add(info);
8794                    }
8795                } catch (RemoteException e) {
8796                }
8797            }
8798        }
8799        return retList;
8800    }
8801
8802    @Override
8803    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8804        enforceNotIsolatedCaller("getMyMemoryState");
8805        synchronized (this) {
8806            ProcessRecord proc;
8807            synchronized (mPidsSelfLocked) {
8808                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8809            }
8810            fillInProcMemInfo(proc, outInfo);
8811        }
8812    }
8813
8814    @Override
8815    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8816        if (checkCallingPermission(android.Manifest.permission.DUMP)
8817                != PackageManager.PERMISSION_GRANTED) {
8818            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8819                    + Binder.getCallingPid()
8820                    + ", uid=" + Binder.getCallingUid()
8821                    + " without permission "
8822                    + android.Manifest.permission.DUMP);
8823            return;
8824        }
8825
8826        boolean dumpAll = false;
8827        boolean dumpClient = false;
8828        String dumpPackage = null;
8829
8830        int opti = 0;
8831        while (opti < args.length) {
8832            String opt = args[opti];
8833            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8834                break;
8835            }
8836            opti++;
8837            if ("-a".equals(opt)) {
8838                dumpAll = true;
8839            } else if ("-c".equals(opt)) {
8840                dumpClient = true;
8841            } else if ("-h".equals(opt)) {
8842                pw.println("Activity manager dump options:");
8843                pw.println("  [-a] [-c] [-h] [cmd] ...");
8844                pw.println("  cmd may be one of:");
8845                pw.println("    a[ctivities]: activity stack state");
8846                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8847                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8848                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8849                pw.println("    o[om]: out of memory management");
8850                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8851                pw.println("    provider [COMP_SPEC]: provider client-side state");
8852                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8853                pw.println("    service [COMP_SPEC]: service client-side state");
8854                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8855                pw.println("    all: dump all activities");
8856                pw.println("    top: dump the top activity");
8857                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8858                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8859                pw.println("    a partial substring in a component name, a");
8860                pw.println("    hex object identifier.");
8861                pw.println("  -a: include all available server state.");
8862                pw.println("  -c: include client state.");
8863                return;
8864            } else {
8865                pw.println("Unknown argument: " + opt + "; use -h for help");
8866            }
8867        }
8868
8869        long origId = Binder.clearCallingIdentity();
8870        boolean more = false;
8871        // Is the caller requesting to dump a particular piece of data?
8872        if (opti < args.length) {
8873            String cmd = args[opti];
8874            opti++;
8875            if ("activities".equals(cmd) || "a".equals(cmd)) {
8876                synchronized (this) {
8877                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8878                }
8879            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8880                String[] newArgs;
8881                String name;
8882                if (opti >= args.length) {
8883                    name = null;
8884                    newArgs = EMPTY_STRING_ARRAY;
8885                } else {
8886                    name = args[opti];
8887                    opti++;
8888                    newArgs = new String[args.length - opti];
8889                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8890                            args.length - opti);
8891                }
8892                synchronized (this) {
8893                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8894                }
8895            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8896                String[] newArgs;
8897                String name;
8898                if (opti >= args.length) {
8899                    name = null;
8900                    newArgs = EMPTY_STRING_ARRAY;
8901                } else {
8902                    name = args[opti];
8903                    opti++;
8904                    newArgs = new String[args.length - opti];
8905                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8906                            args.length - opti);
8907                }
8908                synchronized (this) {
8909                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8910                }
8911            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8912                String[] newArgs;
8913                String name;
8914                if (opti >= args.length) {
8915                    name = null;
8916                    newArgs = EMPTY_STRING_ARRAY;
8917                } else {
8918                    name = args[opti];
8919                    opti++;
8920                    newArgs = new String[args.length - opti];
8921                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8922                            args.length - opti);
8923                }
8924                synchronized (this) {
8925                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8926                }
8927            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8928                synchronized (this) {
8929                    dumpOomLocked(fd, pw, args, opti, true);
8930                }
8931            } else if ("provider".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, args.length - opti);
8942                }
8943                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8944                    pw.println("No providers match: " + name);
8945                    pw.println("Use -h for help.");
8946                }
8947            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8948                synchronized (this) {
8949                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8950                }
8951            } else if ("service".equals(cmd)) {
8952                String[] newArgs;
8953                String name;
8954                if (opti >= args.length) {
8955                    name = null;
8956                    newArgs = EMPTY_STRING_ARRAY;
8957                } else {
8958                    name = args[opti];
8959                    opti++;
8960                    newArgs = new String[args.length - opti];
8961                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8962                            args.length - opti);
8963                }
8964                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8965                    pw.println("No services match: " + name);
8966                    pw.println("Use -h for help.");
8967                }
8968            } else if ("package".equals(cmd)) {
8969                String[] newArgs;
8970                if (opti >= args.length) {
8971                    pw.println("package: no package name specified");
8972                    pw.println("Use -h for help.");
8973                } else {
8974                    dumpPackage = args[opti];
8975                    opti++;
8976                    newArgs = new String[args.length - opti];
8977                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8978                            args.length - opti);
8979                    args = newArgs;
8980                    opti = 0;
8981                    more = true;
8982                }
8983            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8984                synchronized (this) {
8985                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8986                }
8987            } else {
8988                // Dumping a single activity?
8989                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8990                    pw.println("Bad activity command, or no activities match: " + cmd);
8991                    pw.println("Use -h for help.");
8992                }
8993            }
8994            if (!more) {
8995                Binder.restoreCallingIdentity(origId);
8996                return;
8997            }
8998        }
8999
9000        // No piece of data specified, dump everything.
9001        synchronized (this) {
9002            boolean needSep;
9003            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9004            if (needSep) {
9005                pw.println(" ");
9006            }
9007            if (dumpAll) {
9008                pw.println("-------------------------------------------------------------------------------");
9009            }
9010            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9011            if (needSep) {
9012                pw.println(" ");
9013            }
9014            if (dumpAll) {
9015                pw.println("-------------------------------------------------------------------------------");
9016            }
9017            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9018            if (needSep) {
9019                pw.println(" ");
9020            }
9021            if (dumpAll) {
9022                pw.println("-------------------------------------------------------------------------------");
9023            }
9024            needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9025            if (needSep) {
9026                pw.println(" ");
9027            }
9028            if (dumpAll) {
9029                pw.println("-------------------------------------------------------------------------------");
9030            }
9031            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9032            if (needSep) {
9033                pw.println(" ");
9034            }
9035            if (dumpAll) {
9036                pw.println("-------------------------------------------------------------------------------");
9037            }
9038            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9039        }
9040        Binder.restoreCallingIdentity(origId);
9041    }
9042
9043    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9044            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
9045        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
9046        pw.println("  Main stack:");
9047        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
9048                dumpPackage);
9049        pw.println(" ");
9050        pw.println("  Running activities (most recent first):");
9051        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
9052                dumpPackage);
9053        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
9054            pw.println(" ");
9055            pw.println("  Activities waiting for another to become visible:");
9056            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
9057                    !dumpAll, false, dumpPackage);
9058        }
9059        if (mMainStack.mStoppingActivities.size() > 0) {
9060            pw.println(" ");
9061            pw.println("  Activities waiting to stop:");
9062            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
9063                    !dumpAll, false, dumpPackage);
9064        }
9065        if (mMainStack.mGoingToSleepActivities.size() > 0) {
9066            pw.println(" ");
9067            pw.println("  Activities waiting to sleep:");
9068            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
9069                    !dumpAll, false, dumpPackage);
9070        }
9071        if (mMainStack.mFinishingActivities.size() > 0) {
9072            pw.println(" ");
9073            pw.println("  Activities waiting to finish:");
9074            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
9075                    !dumpAll, false, dumpPackage);
9076        }
9077
9078        pw.println(" ");
9079        if (mMainStack.mPausingActivity != null) {
9080            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
9081        }
9082        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
9083        pw.println("  mFocusedActivity: " + mFocusedActivity);
9084        if (dumpAll) {
9085            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
9086            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
9087            pw.println("  mDismissKeyguardOnNextActivity: "
9088                    + mMainStack.mDismissKeyguardOnNextActivity);
9089        }
9090
9091        if (mRecentTasks.size() > 0) {
9092            pw.println();
9093            pw.println("  Recent tasks:");
9094
9095            final int N = mRecentTasks.size();
9096            for (int i=0; i<N; i++) {
9097                TaskRecord tr = mRecentTasks.get(i);
9098                if (dumpPackage != null) {
9099                    if (tr.realActivity == null ||
9100                            !dumpPackage.equals(tr.realActivity)) {
9101                        continue;
9102                    }
9103                }
9104                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
9105                        pw.println(tr);
9106                if (dumpAll) {
9107                    mRecentTasks.get(i).dump(pw, "    ");
9108                }
9109            }
9110        }
9111
9112        if (dumpAll) {
9113            pw.println(" ");
9114            pw.println("  mCurTask: " + mCurTask);
9115        }
9116
9117        return true;
9118    }
9119
9120    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9121            int opti, boolean dumpAll, String dumpPackage) {
9122        boolean needSep = false;
9123        int numPers = 0;
9124
9125        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
9126
9127        if (dumpAll) {
9128            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9129                final int NA = procs.size();
9130                for (int ia=0; ia<NA; ia++) {
9131                    ProcessRecord r = procs.valueAt(ia);
9132                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9133                        continue;
9134                    }
9135                    if (!needSep) {
9136                        pw.println("  All known processes:");
9137                        needSep = true;
9138                    }
9139                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
9140                        pw.print(" UID "); pw.print(procs.keyAt(ia));
9141                        pw.print(" "); pw.println(r);
9142                    r.dump(pw, "    ");
9143                    if (r.persistent) {
9144                        numPers++;
9145                    }
9146                }
9147            }
9148        }
9149
9150        if (mIsolatedProcesses.size() > 0) {
9151            if (needSep) pw.println(" ");
9152            needSep = true;
9153            pw.println("  Isolated process list (sorted by uid):");
9154            for (int i=0; i<mIsolatedProcesses.size(); i++) {
9155                ProcessRecord r = mIsolatedProcesses.valueAt(i);
9156                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9157                    continue;
9158                }
9159                pw.println(String.format("%sIsolated #%2d: %s",
9160                        "    ", i, r.toString()));
9161            }
9162        }
9163
9164        if (mLruProcesses.size() > 0) {
9165            if (needSep) pw.println(" ");
9166            needSep = true;
9167            pw.println("  Process LRU list (sorted by oom_adj):");
9168            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9169                    "Proc", "PERS", false, dumpPackage);
9170            needSep = true;
9171        }
9172
9173        if (dumpAll) {
9174            synchronized (mPidsSelfLocked) {
9175                boolean printed = false;
9176                for (int i=0; i<mPidsSelfLocked.size(); i++) {
9177                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
9178                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9179                        continue;
9180                    }
9181                    if (!printed) {
9182                        if (needSep) pw.println(" ");
9183                        needSep = true;
9184                        pw.println("  PID mappings:");
9185                        printed = true;
9186                    }
9187                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9188                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9189                }
9190            }
9191        }
9192
9193        if (mForegroundProcesses.size() > 0) {
9194            synchronized (mPidsSelfLocked) {
9195                boolean printed = false;
9196                for (int i=0; i<mForegroundProcesses.size(); i++) {
9197                    ProcessRecord r = mPidsSelfLocked.get(
9198                            mForegroundProcesses.valueAt(i).pid);
9199                    if (dumpPackage != null && (r == null
9200                            || !dumpPackage.equals(r.info.packageName))) {
9201                        continue;
9202                    }
9203                    if (!printed) {
9204                        if (needSep) pw.println(" ");
9205                        needSep = true;
9206                        pw.println("  Foreground Processes:");
9207                        printed = true;
9208                    }
9209                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9210                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9211                }
9212            }
9213        }
9214
9215        if (mPersistentStartingProcesses.size() > 0) {
9216            if (needSep) pw.println(" ");
9217            needSep = true;
9218            pw.println("  Persisent processes that are starting:");
9219            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
9220                    "Starting Norm", "Restarting PERS", dumpPackage);
9221        }
9222
9223        if (mRemovedProcesses.size() > 0) {
9224            if (needSep) pw.println(" ");
9225            needSep = true;
9226            pw.println("  Processes that are being removed:");
9227            dumpProcessList(pw, this, mRemovedProcesses, "    ",
9228                    "Removed Norm", "Removed PERS", dumpPackage);
9229        }
9230
9231        if (mProcessesOnHold.size() > 0) {
9232            if (needSep) pw.println(" ");
9233            needSep = true;
9234            pw.println("  Processes that are on old until the system is ready:");
9235            dumpProcessList(pw, this, mProcessesOnHold, "    ",
9236                    "OnHold Norm", "OnHold PERS", dumpPackage);
9237        }
9238
9239        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
9240
9241        if (mProcessCrashTimes.getMap().size() > 0) {
9242            boolean printed = false;
9243            long now = SystemClock.uptimeMillis();
9244            for (Map.Entry<String, SparseArray<Long>> procs
9245                    : mProcessCrashTimes.getMap().entrySet()) {
9246                String pname = procs.getKey();
9247                SparseArray<Long> uids = procs.getValue();
9248                final int N = uids.size();
9249                for (int i=0; i<N; i++) {
9250                    int puid = uids.keyAt(i);
9251                    ProcessRecord r = mProcessNames.get(pname, puid);
9252                    if (dumpPackage != null && (r == null
9253                            || !dumpPackage.equals(r.info.packageName))) {
9254                        continue;
9255                    }
9256                    if (!printed) {
9257                        if (needSep) pw.println(" ");
9258                        needSep = true;
9259                        pw.println("  Time since processes crashed:");
9260                        printed = true;
9261                    }
9262                    pw.print("    Process "); pw.print(pname);
9263                            pw.print(" uid "); pw.print(puid);
9264                            pw.print(": last crashed ");
9265                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9266                            pw.println(" ago");
9267                }
9268            }
9269        }
9270
9271        if (mBadProcesses.getMap().size() > 0) {
9272            boolean printed = false;
9273            for (Map.Entry<String, SparseArray<Long>> procs
9274                    : mBadProcesses.getMap().entrySet()) {
9275                String pname = procs.getKey();
9276                SparseArray<Long> uids = procs.getValue();
9277                final int N = uids.size();
9278                for (int i=0; i<N; i++) {
9279                    int puid = uids.keyAt(i);
9280                    ProcessRecord r = mProcessNames.get(pname, puid);
9281                    if (dumpPackage != null && (r == null
9282                            || !dumpPackage.equals(r.info.packageName))) {
9283                        continue;
9284                    }
9285                    if (!printed) {
9286                        if (needSep) pw.println(" ");
9287                        needSep = true;
9288                        pw.println("  Bad processes:");
9289                    }
9290                    pw.print("    Bad process "); pw.print(pname);
9291                            pw.print(" uid "); pw.print(puid);
9292                            pw.print(": crashed at time ");
9293                            pw.println(uids.valueAt(i));
9294                }
9295            }
9296        }
9297
9298        pw.println();
9299        pw.println("  mStartedUsers:");
9300        for (int i=0; i<mStartedUsers.size(); i++) {
9301            UserStartedState uss = mStartedUsers.valueAt(i);
9302            pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
9303                    pw.print(": "); uss.dump("", pw);
9304        }
9305        pw.print("  mUserLru: [");
9306        for (int i=0; i<mUserLru.size(); i++) {
9307            if (i > 0) pw.print(", ");
9308            pw.print(mUserLru.get(i));
9309        }
9310        pw.println("]");
9311        pw.println("  mHomeProcess: " + mHomeProcess);
9312        pw.println("  mPreviousProcess: " + mPreviousProcess);
9313        if (dumpAll) {
9314            StringBuilder sb = new StringBuilder(128);
9315            sb.append("  mPreviousProcessVisibleTime: ");
9316            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9317            pw.println(sb);
9318        }
9319        if (mHeavyWeightProcess != null) {
9320            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9321        }
9322        pw.println("  mConfiguration: " + mConfiguration);
9323        if (dumpAll) {
9324            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9325            if (mCompatModePackages.getPackages().size() > 0) {
9326                boolean printed = false;
9327                for (Map.Entry<String, Integer> entry
9328                        : mCompatModePackages.getPackages().entrySet()) {
9329                    String pkg = entry.getKey();
9330                    int mode = entry.getValue();
9331                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9332                        continue;
9333                    }
9334                    if (!printed) {
9335                        pw.println("  mScreenCompatPackages:");
9336                        printed = true;
9337                    }
9338                    pw.print("    "); pw.print(pkg); pw.print(": ");
9339                            pw.print(mode); pw.println();
9340                }
9341            }
9342        }
9343        if (mSleeping || mWentToSleep || mLockScreenShown) {
9344            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9345                    + " mLockScreenShown " + mLockScreenShown);
9346        }
9347        if (mShuttingDown) {
9348            pw.println("  mShuttingDown=" + mShuttingDown);
9349        }
9350        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9351                || mOrigWaitForDebugger) {
9352            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9353                    + " mDebugTransient=" + mDebugTransient
9354                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9355        }
9356        if (mOpenGlTraceApp != null) {
9357            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9358        }
9359        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9360                || mProfileFd != null) {
9361            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9362            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9363            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9364                    + mAutoStopProfiler);
9365        }
9366        if (mAlwaysFinishActivities || mController != null) {
9367            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9368                    + " mController=" + mController);
9369        }
9370        if (dumpAll) {
9371            pw.println("  Total persistent processes: " + numPers);
9372            pw.println("  mStartRunning=" + mStartRunning
9373                    + " mProcessesReady=" + mProcessesReady
9374                    + " mSystemReady=" + mSystemReady);
9375            pw.println("  mBooting=" + mBooting
9376                    + " mBooted=" + mBooted
9377                    + " mFactoryTest=" + mFactoryTest);
9378            pw.print("  mLastPowerCheckRealtime=");
9379                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9380                    pw.println("");
9381            pw.print("  mLastPowerCheckUptime=");
9382                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9383                    pw.println("");
9384            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9385            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9386            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9387            pw.println("  mNumNonHiddenProcs=" + mNumNonHiddenProcs
9388                    + " mNumHiddenProcs=" + mNumHiddenProcs
9389                    + " mNumServiceProcs=" + mNumServiceProcs
9390                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9391        }
9392
9393        return true;
9394    }
9395
9396    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9397            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9398        if (mProcessesToGc.size() > 0) {
9399            boolean printed = false;
9400            long now = SystemClock.uptimeMillis();
9401            for (int i=0; i<mProcessesToGc.size(); i++) {
9402                ProcessRecord proc = mProcessesToGc.get(i);
9403                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9404                    continue;
9405                }
9406                if (!printed) {
9407                    if (needSep) pw.println(" ");
9408                    needSep = true;
9409                    pw.println("  Processes that are waiting to GC:");
9410                    printed = true;
9411                }
9412                pw.print("    Process "); pw.println(proc);
9413                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9414                        pw.print(", last gced=");
9415                        pw.print(now-proc.lastRequestedGc);
9416                        pw.print(" ms ago, last lowMem=");
9417                        pw.print(now-proc.lastLowMemory);
9418                        pw.println(" ms ago");
9419
9420            }
9421        }
9422        return needSep;
9423    }
9424
9425    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9426            int opti, boolean dumpAll) {
9427        boolean needSep = false;
9428
9429        if (mLruProcesses.size() > 0) {
9430            if (needSep) pw.println(" ");
9431            needSep = true;
9432            pw.println("  OOM levels:");
9433            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9434            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9435            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9436            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9437            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9438            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9439            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9440            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9441            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9442            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9443            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9444            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9445            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9446
9447            if (needSep) pw.println(" ");
9448            needSep = true;
9449            pw.println("  Process OOM control:");
9450            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9451                    "Proc", "PERS", true, null);
9452            needSep = true;
9453        }
9454
9455        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9456
9457        pw.println();
9458        pw.println("  mHomeProcess: " + mHomeProcess);
9459        pw.println("  mPreviousProcess: " + mPreviousProcess);
9460        if (mHeavyWeightProcess != null) {
9461            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9462        }
9463
9464        return true;
9465    }
9466
9467    /**
9468     * There are three ways to call this:
9469     *  - no provider specified: dump all the providers
9470     *  - a flattened component name that matched an existing provider was specified as the
9471     *    first arg: dump that one provider
9472     *  - the first arg isn't the flattened component name of an existing provider:
9473     *    dump all providers whose component contains the first arg as a substring
9474     */
9475    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9476            int opti, boolean dumpAll) {
9477        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9478    }
9479
9480    static class ItemMatcher {
9481        ArrayList<ComponentName> components;
9482        ArrayList<String> strings;
9483        ArrayList<Integer> objects;
9484        boolean all;
9485
9486        ItemMatcher() {
9487            all = true;
9488        }
9489
9490        void build(String name) {
9491            ComponentName componentName = ComponentName.unflattenFromString(name);
9492            if (componentName != null) {
9493                if (components == null) {
9494                    components = new ArrayList<ComponentName>();
9495                }
9496                components.add(componentName);
9497                all = false;
9498            } else {
9499                int objectId = 0;
9500                // Not a '/' separated full component name; maybe an object ID?
9501                try {
9502                    objectId = Integer.parseInt(name, 16);
9503                    if (objects == null) {
9504                        objects = new ArrayList<Integer>();
9505                    }
9506                    objects.add(objectId);
9507                    all = false;
9508                } catch (RuntimeException e) {
9509                    // Not an integer; just do string match.
9510                    if (strings == null) {
9511                        strings = new ArrayList<String>();
9512                    }
9513                    strings.add(name);
9514                    all = false;
9515                }
9516            }
9517        }
9518
9519        int build(String[] args, int opti) {
9520            for (; opti<args.length; opti++) {
9521                String name = args[opti];
9522                if ("--".equals(name)) {
9523                    return opti+1;
9524                }
9525                build(name);
9526            }
9527            return opti;
9528        }
9529
9530        boolean match(Object object, ComponentName comp) {
9531            if (all) {
9532                return true;
9533            }
9534            if (components != null) {
9535                for (int i=0; i<components.size(); i++) {
9536                    if (components.get(i).equals(comp)) {
9537                        return true;
9538                    }
9539                }
9540            }
9541            if (objects != null) {
9542                for (int i=0; i<objects.size(); i++) {
9543                    if (System.identityHashCode(object) == objects.get(i)) {
9544                        return true;
9545                    }
9546                }
9547            }
9548            if (strings != null) {
9549                String flat = comp.flattenToString();
9550                for (int i=0; i<strings.size(); i++) {
9551                    if (flat.contains(strings.get(i))) {
9552                        return true;
9553                    }
9554                }
9555            }
9556            return false;
9557        }
9558    }
9559
9560    /**
9561     * There are three things that cmd can be:
9562     *  - a flattened component name that matches an existing activity
9563     *  - the cmd arg isn't the flattened component name of an existing activity:
9564     *    dump all activity whose component contains the cmd as a substring
9565     *  - A hex number of the ActivityRecord object instance.
9566     */
9567    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9568            int opti, boolean dumpAll) {
9569        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9570
9571        if ("all".equals(name)) {
9572            synchronized (this) {
9573                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9574                    activities.add(r1);
9575                }
9576            }
9577        } else if ("top".equals(name)) {
9578            synchronized (this) {
9579                final int N = mMainStack.mHistory.size();
9580                if (N > 0) {
9581                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9582                }
9583            }
9584        } else {
9585            ItemMatcher matcher = new ItemMatcher();
9586            matcher.build(name);
9587
9588            synchronized (this) {
9589                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9590                    if (matcher.match(r1, r1.intent.getComponent())) {
9591                        activities.add(r1);
9592                    }
9593                }
9594            }
9595        }
9596
9597        if (activities.size() <= 0) {
9598            return false;
9599        }
9600
9601        String[] newArgs = new String[args.length - opti];
9602        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9603
9604        TaskRecord lastTask = null;
9605        boolean needSep = false;
9606        for (int i=activities.size()-1; i>=0; i--) {
9607            ActivityRecord r = (ActivityRecord)activities.get(i);
9608            if (needSep) {
9609                pw.println();
9610            }
9611            needSep = true;
9612            synchronized (this) {
9613                if (lastTask != r.task) {
9614                    lastTask = r.task;
9615                    pw.print("TASK "); pw.print(lastTask.affinity);
9616                            pw.print(" id="); pw.println(lastTask.taskId);
9617                    if (dumpAll) {
9618                        lastTask.dump(pw, "  ");
9619                    }
9620                }
9621            }
9622            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9623        }
9624        return true;
9625    }
9626
9627    /**
9628     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9629     * there is a thread associated with the activity.
9630     */
9631    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9632            final ActivityRecord r, String[] args, boolean dumpAll) {
9633        String innerPrefix = prefix + "  ";
9634        synchronized (this) {
9635            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9636                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9637                    pw.print(" pid=");
9638                    if (r.app != null) pw.println(r.app.pid);
9639                    else pw.println("(not running)");
9640            if (dumpAll) {
9641                r.dump(pw, innerPrefix);
9642            }
9643        }
9644        if (r.app != null && r.app.thread != null) {
9645            // flush anything that is already in the PrintWriter since the thread is going
9646            // to write to the file descriptor directly
9647            pw.flush();
9648            try {
9649                TransferPipe tp = new TransferPipe();
9650                try {
9651                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9652                            r.appToken, innerPrefix, args);
9653                    tp.go(fd);
9654                } finally {
9655                    tp.kill();
9656                }
9657            } catch (IOException e) {
9658                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9659            } catch (RemoteException e) {
9660                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9661            }
9662        }
9663    }
9664
9665    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9666            int opti, boolean dumpAll, String dumpPackage) {
9667        boolean needSep = false;
9668        boolean onlyHistory = false;
9669
9670        if ("history".equals(dumpPackage)) {
9671            onlyHistory = true;
9672            dumpPackage = null;
9673        }
9674
9675        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9676        if (!onlyHistory && dumpAll) {
9677            if (mRegisteredReceivers.size() > 0) {
9678                boolean printed = false;
9679                Iterator it = mRegisteredReceivers.values().iterator();
9680                while (it.hasNext()) {
9681                    ReceiverList r = (ReceiverList)it.next();
9682                    if (dumpPackage != null && (r.app == null ||
9683                            !dumpPackage.equals(r.app.info.packageName))) {
9684                        continue;
9685                    }
9686                    if (!printed) {
9687                        pw.println("  Registered Receivers:");
9688                        needSep = true;
9689                        printed = true;
9690                    }
9691                    pw.print("  * "); pw.println(r);
9692                    r.dump(pw, "    ");
9693                }
9694            }
9695
9696            if (mReceiverResolver.dump(pw, needSep ?
9697                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9698                    "    ", dumpPackage, false)) {
9699                needSep = true;
9700            }
9701        }
9702
9703        for (BroadcastQueue q : mBroadcastQueues) {
9704            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9705        }
9706
9707        needSep = true;
9708
9709        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
9710            for (int user=0; user<mStickyBroadcasts.size(); user++) {
9711                if (needSep) {
9712                    pw.println();
9713                }
9714                needSep = true;
9715                pw.print("  Sticky broadcasts for user ");
9716                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
9717                StringBuilder sb = new StringBuilder(128);
9718                for (Map.Entry<String, ArrayList<Intent>> ent
9719                        : mStickyBroadcasts.valueAt(user).entrySet()) {
9720                    pw.print("  * Sticky action "); pw.print(ent.getKey());
9721                    if (dumpAll) {
9722                        pw.println(":");
9723                        ArrayList<Intent> intents = ent.getValue();
9724                        final int N = intents.size();
9725                        for (int i=0; i<N; i++) {
9726                            sb.setLength(0);
9727                            sb.append("    Intent: ");
9728                            intents.get(i).toShortString(sb, false, true, false, false);
9729                            pw.println(sb.toString());
9730                            Bundle bundle = intents.get(i).getExtras();
9731                            if (bundle != null) {
9732                                pw.print("      ");
9733                                pw.println(bundle.toString());
9734                            }
9735                        }
9736                    } else {
9737                        pw.println("");
9738                    }
9739                }
9740            }
9741        }
9742
9743        if (!onlyHistory && dumpAll) {
9744            pw.println();
9745            for (BroadcastQueue queue : mBroadcastQueues) {
9746                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9747                        + queue.mBroadcastsScheduled);
9748            }
9749            pw.println("  mHandler:");
9750            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9751            needSep = true;
9752        }
9753
9754        return needSep;
9755    }
9756
9757    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9758            int opti, boolean dumpAll, String dumpPackage) {
9759        boolean needSep = true;
9760
9761        ItemMatcher matcher = new ItemMatcher();
9762        matcher.build(args, opti);
9763
9764        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9765
9766        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9767
9768        if (mLaunchingProviders.size() > 0) {
9769            boolean printed = false;
9770            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9771                ContentProviderRecord r = mLaunchingProviders.get(i);
9772                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9773                    continue;
9774                }
9775                if (!printed) {
9776                    if (needSep) pw.println(" ");
9777                    needSep = true;
9778                    pw.println("  Launching content providers:");
9779                    printed = true;
9780                }
9781                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9782                        pw.println(r);
9783            }
9784        }
9785
9786        if (mGrantedUriPermissions.size() > 0) {
9787            if (needSep) pw.println();
9788            needSep = true;
9789            pw.println("Granted Uri Permissions:");
9790            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9791                int uid = mGrantedUriPermissions.keyAt(i);
9792                HashMap<Uri, UriPermission> perms
9793                        = mGrantedUriPermissions.valueAt(i);
9794                pw.print("  * UID "); pw.print(uid);
9795                        pw.println(" holds:");
9796                for (UriPermission perm : perms.values()) {
9797                    pw.print("    "); pw.println(perm);
9798                    if (dumpAll) {
9799                        perm.dump(pw, "      ");
9800                    }
9801                }
9802            }
9803            needSep = true;
9804        }
9805
9806        return needSep;
9807    }
9808
9809    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9810            int opti, boolean dumpAll, String dumpPackage) {
9811        boolean needSep = false;
9812
9813        if (mIntentSenderRecords.size() > 0) {
9814            boolean printed = false;
9815            Iterator<WeakReference<PendingIntentRecord>> it
9816                    = mIntentSenderRecords.values().iterator();
9817            while (it.hasNext()) {
9818                WeakReference<PendingIntentRecord> ref = it.next();
9819                PendingIntentRecord rec = ref != null ? ref.get(): null;
9820                if (dumpPackage != null && (rec == null
9821                        || !dumpPackage.equals(rec.key.packageName))) {
9822                    continue;
9823                }
9824                if (!printed) {
9825                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9826                    printed = true;
9827                }
9828                needSep = true;
9829                if (rec != null) {
9830                    pw.print("  * "); pw.println(rec);
9831                    if (dumpAll) {
9832                        rec.dump(pw, "    ");
9833                    }
9834                } else {
9835                    pw.print("  * "); pw.println(ref);
9836                }
9837            }
9838        }
9839
9840        return needSep;
9841    }
9842
9843    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9844            String prefix, String label, boolean complete, boolean brief, boolean client,
9845            String dumpPackage) {
9846        TaskRecord lastTask = null;
9847        boolean needNL = false;
9848        final String innerPrefix = prefix + "      ";
9849        final String[] args = new String[0];
9850        for (int i=list.size()-1; i>=0; i--) {
9851            final ActivityRecord r = (ActivityRecord)list.get(i);
9852            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9853                continue;
9854            }
9855            final boolean full = !brief && (complete || !r.isInHistory());
9856            if (needNL) {
9857                pw.println(" ");
9858                needNL = false;
9859            }
9860            if (lastTask != r.task) {
9861                lastTask = r.task;
9862                pw.print(prefix);
9863                pw.print(full ? "* " : "  ");
9864                pw.println(lastTask);
9865                if (full) {
9866                    lastTask.dump(pw, prefix + "  ");
9867                } else if (complete) {
9868                    // Complete + brief == give a summary.  Isn't that obvious?!?
9869                    if (lastTask.intent != null) {
9870                        pw.print(prefix); pw.print("  ");
9871                                pw.println(lastTask.intent.toInsecureStringWithClip());
9872                    }
9873                }
9874            }
9875            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9876            pw.print(" #"); pw.print(i); pw.print(": ");
9877            pw.println(r);
9878            if (full) {
9879                r.dump(pw, innerPrefix);
9880            } else if (complete) {
9881                // Complete + brief == give a summary.  Isn't that obvious?!?
9882                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9883                if (r.app != null) {
9884                    pw.print(innerPrefix); pw.println(r.app);
9885                }
9886            }
9887            if (client && r.app != null && r.app.thread != null) {
9888                // flush anything that is already in the PrintWriter since the thread is going
9889                // to write to the file descriptor directly
9890                pw.flush();
9891                try {
9892                    TransferPipe tp = new TransferPipe();
9893                    try {
9894                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9895                                r.appToken, innerPrefix, args);
9896                        // Short timeout, since blocking here can
9897                        // deadlock with the application.
9898                        tp.go(fd, 2000);
9899                    } finally {
9900                        tp.kill();
9901                    }
9902                } catch (IOException e) {
9903                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9904                } catch (RemoteException e) {
9905                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9906                }
9907                needNL = true;
9908            }
9909        }
9910    }
9911
9912    private static String buildOomTag(String prefix, String space, int val, int base) {
9913        if (val == base) {
9914            if (space == null) return prefix;
9915            return prefix + "  ";
9916        }
9917        return prefix + "+" + Integer.toString(val-base);
9918    }
9919
9920    private static final int dumpProcessList(PrintWriter pw,
9921            ActivityManagerService service, List list,
9922            String prefix, String normalLabel, String persistentLabel,
9923            String dumpPackage) {
9924        int numPers = 0;
9925        final int N = list.size()-1;
9926        for (int i=N; i>=0; i--) {
9927            ProcessRecord r = (ProcessRecord)list.get(i);
9928            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9929                continue;
9930            }
9931            pw.println(String.format("%s%s #%2d: %s",
9932                    prefix, (r.persistent ? persistentLabel : normalLabel),
9933                    i, r.toString()));
9934            if (r.persistent) {
9935                numPers++;
9936            }
9937        }
9938        return numPers;
9939    }
9940
9941    private static final boolean dumpProcessOomList(PrintWriter pw,
9942            ActivityManagerService service, List<ProcessRecord> origList,
9943            String prefix, String normalLabel, String persistentLabel,
9944            boolean inclDetails, String dumpPackage) {
9945
9946        ArrayList<Pair<ProcessRecord, Integer>> list
9947                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9948        for (int i=0; i<origList.size(); i++) {
9949            ProcessRecord r = origList.get(i);
9950            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9951                continue;
9952            }
9953            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9954        }
9955
9956        if (list.size() <= 0) {
9957            return false;
9958        }
9959
9960        Comparator<Pair<ProcessRecord, Integer>> comparator
9961                = new Comparator<Pair<ProcessRecord, Integer>>() {
9962            @Override
9963            public int compare(Pair<ProcessRecord, Integer> object1,
9964                    Pair<ProcessRecord, Integer> object2) {
9965                if (object1.first.setAdj != object2.first.setAdj) {
9966                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9967                }
9968                if (object1.second.intValue() != object2.second.intValue()) {
9969                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9970                }
9971                return 0;
9972            }
9973        };
9974
9975        Collections.sort(list, comparator);
9976
9977        final long curRealtime = SystemClock.elapsedRealtime();
9978        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9979        final long curUptime = SystemClock.uptimeMillis();
9980        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9981
9982        for (int i=list.size()-1; i>=0; i--) {
9983            ProcessRecord r = list.get(i).first;
9984            String oomAdj;
9985            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
9986                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
9987            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9988                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
9989            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9990                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
9991            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9992                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
9993            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9994                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
9995            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
9996                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
9997            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9998                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9999            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10000                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
10001            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
10002                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
10003            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
10004                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
10005            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
10006                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
10007            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
10008                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
10009            } else {
10010                oomAdj = Integer.toString(r.setAdj);
10011            }
10012            String schedGroup;
10013            switch (r.setSchedGroup) {
10014                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
10015                    schedGroup = "B";
10016                    break;
10017                case Process.THREAD_GROUP_DEFAULT:
10018                    schedGroup = "F";
10019                    break;
10020                default:
10021                    schedGroup = Integer.toString(r.setSchedGroup);
10022                    break;
10023            }
10024            String foreground;
10025            if (r.foregroundActivities) {
10026                foreground = "A";
10027            } else if (r.foregroundServices) {
10028                foreground = "S";
10029            } else {
10030                foreground = " ";
10031            }
10032            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
10033                    prefix, (r.persistent ? persistentLabel : normalLabel),
10034                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
10035                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
10036            if (r.adjSource != null || r.adjTarget != null) {
10037                pw.print(prefix);
10038                pw.print("    ");
10039                if (r.adjTarget instanceof ComponentName) {
10040                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
10041                } else if (r.adjTarget != null) {
10042                    pw.print(r.adjTarget.toString());
10043                } else {
10044                    pw.print("{null}");
10045                }
10046                pw.print("<=");
10047                if (r.adjSource instanceof ProcessRecord) {
10048                    pw.print("Proc{");
10049                    pw.print(((ProcessRecord)r.adjSource).toShortString());
10050                    pw.println("}");
10051                } else if (r.adjSource != null) {
10052                    pw.println(r.adjSource.toString());
10053                } else {
10054                    pw.println("{null}");
10055                }
10056            }
10057            if (inclDetails) {
10058                pw.print(prefix);
10059                pw.print("    ");
10060                pw.print("oom: max="); pw.print(r.maxAdj);
10061                pw.print(" hidden="); pw.print(r.hiddenAdj);
10062                pw.print(" empty="); pw.print(r.emptyAdj);
10063                pw.print(" curRaw="); pw.print(r.curRawAdj);
10064                pw.print(" setRaw="); pw.print(r.setRawAdj);
10065                pw.print(" cur="); pw.print(r.curAdj);
10066                pw.print(" set="); pw.println(r.setAdj);
10067                pw.print(prefix);
10068                pw.print("    ");
10069                pw.print("keeping="); pw.print(r.keeping);
10070                pw.print(" hidden="); pw.print(r.hidden);
10071                pw.print(" empty="); pw.print(r.empty);
10072                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
10073
10074                if (!r.keeping) {
10075                    if (r.lastWakeTime != 0) {
10076                        long wtime;
10077                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10078                        synchronized (stats) {
10079                            wtime = stats.getProcessWakeTime(r.info.uid,
10080                                    r.pid, curRealtime);
10081                        }
10082                        long timeUsed = wtime - r.lastWakeTime;
10083                        pw.print(prefix);
10084                        pw.print("    ");
10085                        pw.print("keep awake over ");
10086                        TimeUtils.formatDuration(realtimeSince, pw);
10087                        pw.print(" used ");
10088                        TimeUtils.formatDuration(timeUsed, pw);
10089                        pw.print(" (");
10090                        pw.print((timeUsed*100)/realtimeSince);
10091                        pw.println("%)");
10092                    }
10093                    if (r.lastCpuTime != 0) {
10094                        long timeUsed = r.curCpuTime - r.lastCpuTime;
10095                        pw.print(prefix);
10096                        pw.print("    ");
10097                        pw.print("run cpu over ");
10098                        TimeUtils.formatDuration(uptimeSince, pw);
10099                        pw.print(" used ");
10100                        TimeUtils.formatDuration(timeUsed, pw);
10101                        pw.print(" (");
10102                        pw.print((timeUsed*100)/uptimeSince);
10103                        pw.println("%)");
10104                    }
10105                }
10106            }
10107        }
10108        return true;
10109    }
10110
10111    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
10112        ArrayList<ProcessRecord> procs;
10113        synchronized (this) {
10114            if (args != null && args.length > start
10115                    && args[start].charAt(0) != '-') {
10116                procs = new ArrayList<ProcessRecord>();
10117                int pid = -1;
10118                try {
10119                    pid = Integer.parseInt(args[start]);
10120                } catch (NumberFormatException e) {
10121
10122                }
10123                for (int i=mLruProcesses.size()-1; i>=0; i--) {
10124                    ProcessRecord proc = mLruProcesses.get(i);
10125                    if (proc.pid == pid) {
10126                        procs.add(proc);
10127                    } else if (proc.processName.equals(args[start])) {
10128                        procs.add(proc);
10129                    }
10130                }
10131                if (procs.size() <= 0) {
10132                    pw.println("No process found for: " + args[start]);
10133                    return null;
10134                }
10135            } else {
10136                procs = new ArrayList<ProcessRecord>(mLruProcesses);
10137            }
10138        }
10139        return procs;
10140    }
10141
10142    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10143            PrintWriter pw, String[] args) {
10144        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10145        if (procs == null) {
10146            return;
10147        }
10148
10149        long uptime = SystemClock.uptimeMillis();
10150        long realtime = SystemClock.elapsedRealtime();
10151        pw.println("Applications Graphics Acceleration Info:");
10152        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10153
10154        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10155            ProcessRecord r = procs.get(i);
10156            if (r.thread != null) {
10157                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10158                pw.flush();
10159                try {
10160                    TransferPipe tp = new TransferPipe();
10161                    try {
10162                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10163                        tp.go(fd);
10164                    } finally {
10165                        tp.kill();
10166                    }
10167                } catch (IOException e) {
10168                    pw.println("Failure while dumping the app: " + r);
10169                    pw.flush();
10170                } catch (RemoteException e) {
10171                    pw.println("Got a RemoteException while dumping the app " + r);
10172                    pw.flush();
10173                }
10174            }
10175        }
10176    }
10177
10178    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10179        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10180        if (procs == null) {
10181            return;
10182        }
10183
10184        pw.println("Applications Database Info:");
10185
10186        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10187            ProcessRecord r = procs.get(i);
10188            if (r.thread != null) {
10189                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10190                pw.flush();
10191                try {
10192                    TransferPipe tp = new TransferPipe();
10193                    try {
10194                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10195                        tp.go(fd);
10196                    } finally {
10197                        tp.kill();
10198                    }
10199                } catch (IOException e) {
10200                    pw.println("Failure while dumping the app: " + r);
10201                    pw.flush();
10202                } catch (RemoteException e) {
10203                    pw.println("Got a RemoteException while dumping the app " + r);
10204                    pw.flush();
10205                }
10206            }
10207        }
10208    }
10209
10210    final static class MemItem {
10211        final String label;
10212        final String shortLabel;
10213        final long pss;
10214        final int id;
10215        ArrayList<MemItem> subitems;
10216
10217        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10218            label = _label;
10219            shortLabel = _shortLabel;
10220            pss = _pss;
10221            id = _id;
10222        }
10223    }
10224
10225    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10226            boolean sort) {
10227        if (sort) {
10228            Collections.sort(items, new Comparator<MemItem>() {
10229                @Override
10230                public int compare(MemItem lhs, MemItem rhs) {
10231                    if (lhs.pss < rhs.pss) {
10232                        return 1;
10233                    } else if (lhs.pss > rhs.pss) {
10234                        return -1;
10235                    }
10236                    return 0;
10237                }
10238            });
10239        }
10240
10241        for (int i=0; i<items.size(); i++) {
10242            MemItem mi = items.get(i);
10243            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10244            if (mi.subitems != null) {
10245                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10246            }
10247        }
10248    }
10249
10250    // These are in KB.
10251    static final long[] DUMP_MEM_BUCKETS = new long[] {
10252        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10253        120*1024, 160*1024, 200*1024,
10254        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10255        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10256    };
10257
10258    static final void appendMemBucket(StringBuilder out, long memKB, String label,
10259            boolean stackLike) {
10260        int start = label.lastIndexOf('.');
10261        if (start >= 0) start++;
10262        else start = 0;
10263        int end = label.length();
10264        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10265            if (DUMP_MEM_BUCKETS[i] >= memKB) {
10266                long bucket = DUMP_MEM_BUCKETS[i]/1024;
10267                out.append(bucket);
10268                out.append(stackLike ? "MB." : "MB ");
10269                out.append(label, start, end);
10270                return;
10271            }
10272        }
10273        out.append(memKB/1024);
10274        out.append(stackLike ? "MB." : "MB ");
10275        out.append(label, start, end);
10276    }
10277
10278    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10279            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10280            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10281            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10282            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10283    };
10284    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10285            "System", "Persistent", "Foreground",
10286            "Visible", "Perceptible", "Heavy Weight",
10287            "Backup", "A Services", "Home", "Previous",
10288            "B Services", "Background"
10289    };
10290
10291    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10292            PrintWriter pw, String prefix, String[] args, boolean brief,
10293            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10294        boolean dumpAll = false;
10295        boolean oomOnly = false;
10296
10297        int opti = 0;
10298        while (opti < args.length) {
10299            String opt = args[opti];
10300            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10301                break;
10302            }
10303            opti++;
10304            if ("-a".equals(opt)) {
10305                dumpAll = true;
10306            } else if ("--oom".equals(opt)) {
10307                oomOnly = true;
10308            } else if ("-h".equals(opt)) {
10309                pw.println("meminfo dump options: [-a] [--oom] [process]");
10310                pw.println("  -a: include all available information for each process.");
10311                pw.println("  --oom: only show processes organized by oom adj.");
10312                pw.println("If [process] is specified it can be the name or ");
10313                pw.println("pid of a specific process to dump.");
10314                return;
10315            } else {
10316                pw.println("Unknown argument: " + opt + "; use -h for help");
10317            }
10318        }
10319
10320        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10321        if (procs == null) {
10322            return;
10323        }
10324
10325        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10326        long uptime = SystemClock.uptimeMillis();
10327        long realtime = SystemClock.elapsedRealtime();
10328
10329        if (procs.size() == 1 || isCheckinRequest) {
10330            dumpAll = true;
10331        }
10332
10333        if (isCheckinRequest) {
10334            // short checkin version
10335            pw.println(uptime + "," + realtime);
10336            pw.flush();
10337        } else {
10338            pw.println("Applications Memory Usage (kB):");
10339            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10340        }
10341
10342        String[] innerArgs = new String[args.length-opti];
10343        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10344
10345        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10346        long nativePss=0, dalvikPss=0, otherPss=0;
10347        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10348
10349        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10350        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10351                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10352
10353        long totalPss = 0;
10354
10355        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10356            ProcessRecord r = procs.get(i);
10357            if (r.thread != null) {
10358                if (!isCheckinRequest && dumpAll) {
10359                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10360                    pw.flush();
10361                }
10362                Debug.MemoryInfo mi = null;
10363                if (dumpAll) {
10364                    try {
10365                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10366                    } catch (RemoteException e) {
10367                        if (!isCheckinRequest) {
10368                            pw.println("Got RemoteException!");
10369                            pw.flush();
10370                        }
10371                    }
10372                } else {
10373                    mi = new Debug.MemoryInfo();
10374                    Debug.getMemoryInfo(r.pid, mi);
10375                }
10376
10377                if (!isCheckinRequest && mi != null) {
10378                    long myTotalPss = mi.getTotalPss();
10379                    totalPss += myTotalPss;
10380                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10381                            r.processName, myTotalPss, 0);
10382                    procMems.add(pssItem);
10383
10384                    nativePss += mi.nativePss;
10385                    dalvikPss += mi.dalvikPss;
10386                    otherPss += mi.otherPss;
10387                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10388                        long mem = mi.getOtherPss(j);
10389                        miscPss[j] += mem;
10390                        otherPss -= mem;
10391                    }
10392
10393                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10394                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10395                                || oomIndex == (oomPss.length-1)) {
10396                            oomPss[oomIndex] += myTotalPss;
10397                            if (oomProcs[oomIndex] == null) {
10398                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10399                            }
10400                            oomProcs[oomIndex].add(pssItem);
10401                            break;
10402                        }
10403                    }
10404                }
10405            }
10406        }
10407
10408        if (!isCheckinRequest && procs.size() > 1) {
10409            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10410
10411            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10412            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10413            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10414            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10415                String label = Debug.MemoryInfo.getOtherLabel(j);
10416                catMems.add(new MemItem(label, label, miscPss[j], j));
10417            }
10418
10419            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10420            for (int j=0; j<oomPss.length; j++) {
10421                if (oomPss[j] != 0) {
10422                    String label = DUMP_MEM_OOM_LABEL[j];
10423                    MemItem item = new MemItem(label, label, oomPss[j],
10424                            DUMP_MEM_OOM_ADJ[j]);
10425                    item.subitems = oomProcs[j];
10426                    oomMems.add(item);
10427                }
10428            }
10429
10430            if (outTag != null || outStack != null) {
10431                if (outTag != null) {
10432                    appendMemBucket(outTag, totalPss, "total", false);
10433                }
10434                if (outStack != null) {
10435                    appendMemBucket(outStack, totalPss, "total", true);
10436                }
10437                boolean firstLine = true;
10438                for (int i=0; i<oomMems.size(); i++) {
10439                    MemItem miCat = oomMems.get(i);
10440                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10441                        continue;
10442                    }
10443                    if (miCat.id < ProcessList.SERVICE_ADJ
10444                            || miCat.id == ProcessList.HOME_APP_ADJ
10445                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10446                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10447                            outTag.append(" / ");
10448                        }
10449                        if (outStack != null) {
10450                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10451                                if (firstLine) {
10452                                    outStack.append(":");
10453                                    firstLine = false;
10454                                }
10455                                outStack.append("\n\t at ");
10456                            } else {
10457                                outStack.append("$");
10458                            }
10459                        }
10460                        for (int j=0; j<miCat.subitems.size(); j++) {
10461                            MemItem mi = miCat.subitems.get(j);
10462                            if (j > 0) {
10463                                if (outTag != null) {
10464                                    outTag.append(" ");
10465                                }
10466                                if (outStack != null) {
10467                                    outStack.append("$");
10468                                }
10469                            }
10470                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10471                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10472                            }
10473                            if (outStack != null) {
10474                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10475                            }
10476                        }
10477                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10478                            outStack.append("(");
10479                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10480                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10481                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10482                                    outStack.append(":");
10483                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10484                                }
10485                            }
10486                            outStack.append(")");
10487                        }
10488                    }
10489                }
10490            }
10491
10492            if (!brief && !oomOnly) {
10493                pw.println();
10494                pw.println("Total PSS by process:");
10495                dumpMemItems(pw, "  ", procMems, true);
10496                pw.println();
10497            }
10498            pw.println("Total PSS by OOM adjustment:");
10499            dumpMemItems(pw, "  ", oomMems, false);
10500            if (!oomOnly) {
10501                PrintWriter out = categoryPw != null ? categoryPw : pw;
10502                out.println();
10503                out.println("Total PSS by category:");
10504                dumpMemItems(out, "  ", catMems, true);
10505            }
10506            pw.println();
10507            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10508            final int[] SINGLE_LONG_FORMAT = new int[] {
10509                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10510            };
10511            long[] longOut = new long[1];
10512            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10513                    SINGLE_LONG_FORMAT, null, longOut, null);
10514            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10515            longOut[0] = 0;
10516            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10517                    SINGLE_LONG_FORMAT, null, longOut, null);
10518            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10519            longOut[0] = 0;
10520            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10521                    SINGLE_LONG_FORMAT, null, longOut, null);
10522            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10523            longOut[0] = 0;
10524            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10525                    SINGLE_LONG_FORMAT, null, longOut, null);
10526            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10527            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10528                    pw.print(shared); pw.println(" kB");
10529            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10530                    pw.print(voltile); pw.println(" kB volatile");
10531        }
10532    }
10533
10534    /**
10535     * Searches array of arguments for the specified string
10536     * @param args array of argument strings
10537     * @param value value to search for
10538     * @return true if the value is contained in the array
10539     */
10540    private static boolean scanArgs(String[] args, String value) {
10541        if (args != null) {
10542            for (String arg : args) {
10543                if (value.equals(arg)) {
10544                    return true;
10545                }
10546            }
10547        }
10548        return false;
10549    }
10550
10551    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10552            ContentProviderRecord cpr, boolean always) {
10553        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10554
10555        if (!inLaunching || always) {
10556            synchronized (cpr) {
10557                cpr.launchingApp = null;
10558                cpr.notifyAll();
10559            }
10560            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10561            String names[] = cpr.info.authority.split(";");
10562            for (int j = 0; j < names.length; j++) {
10563                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10564            }
10565        }
10566
10567        for (int i=0; i<cpr.connections.size(); i++) {
10568            ContentProviderConnection conn = cpr.connections.get(i);
10569            if (conn.waiting) {
10570                // If this connection is waiting for the provider, then we don't
10571                // need to mess with its process unless we are always removing
10572                // or for some reason the provider is not currently launching.
10573                if (inLaunching && !always) {
10574                    continue;
10575                }
10576            }
10577            ProcessRecord capp = conn.client;
10578            conn.dead = true;
10579            if (conn.stableCount > 0) {
10580                if (!capp.persistent && capp.thread != null
10581                        && capp.pid != 0
10582                        && capp.pid != MY_PID) {
10583                    Slog.i(TAG, "Kill " + capp.processName
10584                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10585                            + " in dying process " + (proc != null ? proc.processName : "??"));
10586                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10587                            capp.processName, capp.setAdj, "dying provider "
10588                                    + cpr.name.toShortString());
10589                    Process.killProcessQuiet(capp.pid);
10590                }
10591            } else if (capp.thread != null && conn.provider.provider != null) {
10592                try {
10593                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10594                } catch (RemoteException e) {
10595                }
10596                // In the protocol here, we don't expect the client to correctly
10597                // clean up this connection, we'll just remove it.
10598                cpr.connections.remove(i);
10599                conn.client.conProviders.remove(conn);
10600            }
10601        }
10602
10603        if (inLaunching && always) {
10604            mLaunchingProviders.remove(cpr);
10605        }
10606        return inLaunching;
10607    }
10608
10609    /**
10610     * Main code for cleaning up a process when it has gone away.  This is
10611     * called both as a result of the process dying, or directly when stopping
10612     * a process when running in single process mode.
10613     */
10614    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10615            boolean restarting, boolean allowRestart, int index) {
10616        if (index >= 0) {
10617            mLruProcesses.remove(index);
10618        }
10619
10620        mProcessesToGc.remove(app);
10621
10622        // Dismiss any open dialogs.
10623        if (app.crashDialog != null) {
10624            app.crashDialog.dismiss();
10625            app.crashDialog = null;
10626        }
10627        if (app.anrDialog != null) {
10628            app.anrDialog.dismiss();
10629            app.anrDialog = null;
10630        }
10631        if (app.waitDialog != null) {
10632            app.waitDialog.dismiss();
10633            app.waitDialog = null;
10634        }
10635
10636        app.crashing = false;
10637        app.notResponding = false;
10638
10639        app.resetPackageList();
10640        app.unlinkDeathRecipient();
10641        app.thread = null;
10642        app.forcingToForeground = null;
10643        app.foregroundServices = false;
10644        app.foregroundActivities = false;
10645        app.hasShownUi = false;
10646        app.hasAboveClient = false;
10647
10648        mServices.killServicesLocked(app, allowRestart);
10649
10650        boolean restart = false;
10651
10652        // Remove published content providers.
10653        if (!app.pubProviders.isEmpty()) {
10654            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10655            while (it.hasNext()) {
10656                ContentProviderRecord cpr = it.next();
10657
10658                final boolean always = app.bad || !allowRestart;
10659                if (removeDyingProviderLocked(app, cpr, always) || always) {
10660                    // We left the provider in the launching list, need to
10661                    // restart it.
10662                    restart = true;
10663                }
10664
10665                cpr.provider = null;
10666                cpr.proc = null;
10667            }
10668            app.pubProviders.clear();
10669        }
10670
10671        // Take care of any launching providers waiting for this process.
10672        if (checkAppInLaunchingProvidersLocked(app, false)) {
10673            restart = true;
10674        }
10675
10676        // Unregister from connected content providers.
10677        if (!app.conProviders.isEmpty()) {
10678            for (int i=0; i<app.conProviders.size(); i++) {
10679                ContentProviderConnection conn = app.conProviders.get(i);
10680                conn.provider.connections.remove(conn);
10681            }
10682            app.conProviders.clear();
10683        }
10684
10685        // At this point there may be remaining entries in mLaunchingProviders
10686        // where we were the only one waiting, so they are no longer of use.
10687        // Look for these and clean up if found.
10688        // XXX Commented out for now.  Trying to figure out a way to reproduce
10689        // the actual situation to identify what is actually going on.
10690        if (false) {
10691            for (int i=0; i<mLaunchingProviders.size(); i++) {
10692                ContentProviderRecord cpr = (ContentProviderRecord)
10693                        mLaunchingProviders.get(i);
10694                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10695                    synchronized (cpr) {
10696                        cpr.launchingApp = null;
10697                        cpr.notifyAll();
10698                    }
10699                }
10700            }
10701        }
10702
10703        skipCurrentReceiverLocked(app);
10704
10705        // Unregister any receivers.
10706        if (app.receivers.size() > 0) {
10707            Iterator<ReceiverList> it = app.receivers.iterator();
10708            while (it.hasNext()) {
10709                removeReceiverLocked(it.next());
10710            }
10711            app.receivers.clear();
10712        }
10713
10714        // If the app is undergoing backup, tell the backup manager about it
10715        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10716            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10717            try {
10718                IBackupManager bm = IBackupManager.Stub.asInterface(
10719                        ServiceManager.getService(Context.BACKUP_SERVICE));
10720                bm.agentDisconnected(app.info.packageName);
10721            } catch (RemoteException e) {
10722                // can't happen; backup manager is local
10723            }
10724        }
10725
10726        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10727            ProcessChangeItem item = mPendingProcessChanges.get(i);
10728            if (item.pid == app.pid) {
10729                mPendingProcessChanges.remove(i);
10730                mAvailProcessChanges.add(item);
10731            }
10732        }
10733        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10734
10735        // If the caller is restarting this app, then leave it in its
10736        // current lists and let the caller take care of it.
10737        if (restarting) {
10738            return;
10739        }
10740
10741        if (!app.persistent || app.isolated) {
10742            if (DEBUG_PROCESSES) Slog.v(TAG,
10743                    "Removing non-persistent process during cleanup: " + app);
10744            mProcessNames.remove(app.processName, app.uid);
10745            mIsolatedProcesses.remove(app.uid);
10746            if (mHeavyWeightProcess == app) {
10747                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
10748                        mHeavyWeightProcess.userId, 0));
10749                mHeavyWeightProcess = null;
10750            }
10751        } else if (!app.removed) {
10752            // This app is persistent, so we need to keep its record around.
10753            // If it is not already on the pending app list, add it there
10754            // and start a new process for it.
10755            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10756                mPersistentStartingProcesses.add(app);
10757                restart = true;
10758            }
10759        }
10760        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10761                "Clean-up removing on hold: " + app);
10762        mProcessesOnHold.remove(app);
10763
10764        if (app == mHomeProcess) {
10765            mHomeProcess = null;
10766        }
10767        if (app == mPreviousProcess) {
10768            mPreviousProcess = null;
10769        }
10770
10771        if (restart && !app.isolated) {
10772            // We have components that still need to be running in the
10773            // process, so re-launch it.
10774            mProcessNames.put(app.processName, app.uid, app);
10775            startProcessLocked(app, "restart", app.processName);
10776        } else if (app.pid > 0 && app.pid != MY_PID) {
10777            // Goodbye!
10778            synchronized (mPidsSelfLocked) {
10779                mPidsSelfLocked.remove(app.pid);
10780                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10781            }
10782            app.setPid(0);
10783        }
10784    }
10785
10786    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10787        // Look through the content providers we are waiting to have launched,
10788        // and if any run in this process then either schedule a restart of
10789        // the process or kill the client waiting for it if this process has
10790        // gone bad.
10791        int NL = mLaunchingProviders.size();
10792        boolean restart = false;
10793        for (int i=0; i<NL; i++) {
10794            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10795            if (cpr.launchingApp == app) {
10796                if (!alwaysBad && !app.bad) {
10797                    restart = true;
10798                } else {
10799                    removeDyingProviderLocked(app, cpr, true);
10800                    // cpr should have been removed from mLaunchingProviders
10801                    NL = mLaunchingProviders.size();
10802                    i--;
10803                }
10804            }
10805        }
10806        return restart;
10807    }
10808
10809    // =========================================================
10810    // SERVICES
10811    // =========================================================
10812
10813    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10814            int flags) {
10815        enforceNotIsolatedCaller("getServices");
10816        synchronized (this) {
10817            return mServices.getRunningServiceInfoLocked(maxNum, flags);
10818        }
10819    }
10820
10821    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10822        enforceNotIsolatedCaller("getRunningServiceControlPanel");
10823        synchronized (this) {
10824            return mServices.getRunningServiceControlPanelLocked(name);
10825        }
10826    }
10827
10828    public ComponentName startService(IApplicationThread caller, Intent service,
10829            String resolvedType, int userId) {
10830        enforceNotIsolatedCaller("startService");
10831        // Refuse possible leaked file descriptors
10832        if (service != null && service.hasFileDescriptors() == true) {
10833            throw new IllegalArgumentException("File descriptors passed in Intent");
10834        }
10835
10836        if (DEBUG_SERVICE)
10837            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10838        synchronized(this) {
10839            final int callingPid = Binder.getCallingPid();
10840            final int callingUid = Binder.getCallingUid();
10841            checkValidCaller(callingUid, userId);
10842            final long origId = Binder.clearCallingIdentity();
10843            ComponentName res = mServices.startServiceLocked(caller, service,
10844                    resolvedType, callingPid, callingUid, userId);
10845            Binder.restoreCallingIdentity(origId);
10846            return res;
10847        }
10848    }
10849
10850    ComponentName startServiceInPackage(int uid,
10851            Intent service, String resolvedType, int userId) {
10852        synchronized(this) {
10853            if (DEBUG_SERVICE)
10854                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10855            final long origId = Binder.clearCallingIdentity();
10856            ComponentName res = mServices.startServiceLocked(null, service,
10857                    resolvedType, -1, uid, userId);
10858            Binder.restoreCallingIdentity(origId);
10859            return res;
10860        }
10861    }
10862
10863    public int stopService(IApplicationThread caller, Intent service,
10864            String resolvedType, int userId) {
10865        enforceNotIsolatedCaller("stopService");
10866        // Refuse possible leaked file descriptors
10867        if (service != null && service.hasFileDescriptors() == true) {
10868            throw new IllegalArgumentException("File descriptors passed in Intent");
10869        }
10870
10871        checkValidCaller(Binder.getCallingUid(), userId);
10872
10873        synchronized(this) {
10874            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
10875        }
10876    }
10877
10878    public IBinder peekService(Intent service, String resolvedType) {
10879        enforceNotIsolatedCaller("peekService");
10880        // Refuse possible leaked file descriptors
10881        if (service != null && service.hasFileDescriptors() == true) {
10882            throw new IllegalArgumentException("File descriptors passed in Intent");
10883        }
10884        synchronized(this) {
10885            return mServices.peekServiceLocked(service, resolvedType);
10886        }
10887    }
10888
10889    public boolean stopServiceToken(ComponentName className, IBinder token,
10890            int startId) {
10891        synchronized(this) {
10892            return mServices.stopServiceTokenLocked(className, token, startId);
10893        }
10894    }
10895
10896    public void setServiceForeground(ComponentName className, IBinder token,
10897            int id, Notification notification, boolean removeNotification) {
10898        synchronized(this) {
10899            mServices.setServiceForegroundLocked(className, token, id, notification,
10900                    removeNotification);
10901        }
10902    }
10903
10904    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
10905            boolean requireFull, String name, String callerPackage) {
10906        synchronized(this) {
10907            return handleIncomingUserLocked(callingPid, callingUid, userId, allowAll,
10908                    requireFull, name, callerPackage);
10909        }
10910    }
10911
10912    int handleIncomingUserLocked(int callingPid, int callingUid, int userId, boolean allowAll,
10913            boolean requireFull, String name, String callerPackage) {
10914        final int callingUserId = UserHandle.getUserId(callingUid);
10915        if (callingUserId != userId) {
10916            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10917                if ((requireFull || checkComponentPermission(
10918                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10919                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
10920                        && checkComponentPermission(
10921                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10922                                callingPid, callingUid, -1, true)
10923                                != PackageManager.PERMISSION_GRANTED) {
10924                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
10925                        // In this case, they would like to just execute as their
10926                        // owner user instead of failing.
10927                        userId = callingUserId;
10928                    } else {
10929                        StringBuilder builder = new StringBuilder(128);
10930                        builder.append("Permission Denial: ");
10931                        builder.append(name);
10932                        if (callerPackage != null) {
10933                            builder.append(" from ");
10934                            builder.append(callerPackage);
10935                        }
10936                        builder.append(" asks to run as user ");
10937                        builder.append(userId);
10938                        builder.append(" but is calling from user ");
10939                        builder.append(UserHandle.getUserId(callingUid));
10940                        builder.append("; this requires ");
10941                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
10942                        if (!requireFull) {
10943                            builder.append(" or ");
10944                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
10945                        }
10946                        String msg = builder.toString();
10947                        Slog.w(TAG, msg);
10948                        throw new SecurityException(msg);
10949                    }
10950                }
10951            }
10952            if (userId == UserHandle.USER_CURRENT
10953                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
10954                userId = mCurrentUserId;
10955            }
10956            if (!allowAll && userId < 0) {
10957                throw new IllegalArgumentException(
10958                        "Call does not support special user #" + userId);
10959            }
10960        }
10961        return userId;
10962    }
10963
10964    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10965            String className, int flags) {
10966        boolean result = false;
10967        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
10968            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10969                if (ActivityManager.checkUidPermission(
10970                        android.Manifest.permission.INTERACT_ACROSS_USERS,
10971                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10972                    ComponentName comp = new ComponentName(aInfo.packageName, className);
10973                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
10974                            + " requests FLAG_SINGLE_USER, but app does not hold "
10975                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
10976                    Slog.w(TAG, msg);
10977                    throw new SecurityException(msg);
10978                }
10979                result = true;
10980            }
10981        } else if (componentProcessName == aInfo.packageName) {
10982            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
10983        } else if ("system".equals(componentProcessName)) {
10984            result = true;
10985        }
10986        if (DEBUG_MU) {
10987            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
10988                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
10989        }
10990        return result;
10991    }
10992
10993    public int bindService(IApplicationThread caller, IBinder token,
10994            Intent service, String resolvedType,
10995            IServiceConnection connection, int flags, int userId) {
10996        enforceNotIsolatedCaller("bindService");
10997        // Refuse possible leaked file descriptors
10998        if (service != null && service.hasFileDescriptors() == true) {
10999            throw new IllegalArgumentException("File descriptors passed in Intent");
11000        }
11001
11002        synchronized(this) {
11003            return mServices.bindServiceLocked(caller, token, service, resolvedType,
11004                    connection, flags, userId);
11005        }
11006    }
11007
11008    public boolean unbindService(IServiceConnection connection) {
11009        synchronized (this) {
11010            return mServices.unbindServiceLocked(connection);
11011        }
11012    }
11013
11014    public void publishService(IBinder token, Intent intent, IBinder service) {
11015        // Refuse possible leaked file descriptors
11016        if (intent != null && intent.hasFileDescriptors() == true) {
11017            throw new IllegalArgumentException("File descriptors passed in Intent");
11018        }
11019
11020        synchronized(this) {
11021            if (!(token instanceof ServiceRecord)) {
11022                throw new IllegalArgumentException("Invalid service token");
11023            }
11024            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
11025        }
11026    }
11027
11028    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11029        // Refuse possible leaked file descriptors
11030        if (intent != null && intent.hasFileDescriptors() == true) {
11031            throw new IllegalArgumentException("File descriptors passed in Intent");
11032        }
11033
11034        synchronized(this) {
11035            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
11036        }
11037    }
11038
11039    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
11040        synchronized(this) {
11041            if (!(token instanceof ServiceRecord)) {
11042                throw new IllegalArgumentException("Invalid service token");
11043            }
11044            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
11045        }
11046    }
11047
11048    // =========================================================
11049    // BACKUP AND RESTORE
11050    // =========================================================
11051
11052    // Cause the target app to be launched if necessary and its backup agent
11053    // instantiated.  The backup agent will invoke backupAgentCreated() on the
11054    // activity manager to announce its creation.
11055    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
11056        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
11057        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11058
11059        synchronized(this) {
11060            // !!! TODO: currently no check here that we're already bound
11061            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11062            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11063            synchronized (stats) {
11064                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11065            }
11066
11067            // Backup agent is now in use, its package can't be stopped.
11068            try {
11069                AppGlobals.getPackageManager().setPackageStoppedState(
11070                        app.packageName, false, UserHandle.getUserId(app.uid));
11071            } catch (RemoteException e) {
11072            } catch (IllegalArgumentException e) {
11073                Slog.w(TAG, "Failed trying to unstop package "
11074                        + app.packageName + ": " + e);
11075            }
11076
11077            BackupRecord r = new BackupRecord(ss, app, backupMode);
11078            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11079                    ? new ComponentName(app.packageName, app.backupAgentName)
11080                    : new ComponentName("android", "FullBackupAgent");
11081            // startProcessLocked() returns existing proc's record if it's already running
11082            ProcessRecord proc = startProcessLocked(app.processName, app,
11083                    false, 0, "backup", hostingName, false, false);
11084            if (proc == null) {
11085                Slog.e(TAG, "Unable to start backup agent process " + r);
11086                return false;
11087            }
11088
11089            r.app = proc;
11090            mBackupTarget = r;
11091            mBackupAppName = app.packageName;
11092
11093            // Try not to kill the process during backup
11094            updateOomAdjLocked(proc);
11095
11096            // If the process is already attached, schedule the creation of the backup agent now.
11097            // If it is not yet live, this will be done when it attaches to the framework.
11098            if (proc.thread != null) {
11099                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
11100                try {
11101                    proc.thread.scheduleCreateBackupAgent(app,
11102                            compatibilityInfoForPackageLocked(app), backupMode);
11103                } catch (RemoteException e) {
11104                    // Will time out on the backup manager side
11105                }
11106            } else {
11107                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
11108            }
11109            // Invariants: at this point, the target app process exists and the application
11110            // is either already running or in the process of coming up.  mBackupTarget and
11111            // mBackupAppName describe the app, so that when it binds back to the AM we
11112            // know that it's scheduled for a backup-agent operation.
11113        }
11114
11115        return true;
11116    }
11117
11118    // A backup agent has just come up
11119    public void backupAgentCreated(String agentPackageName, IBinder agent) {
11120        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
11121                + " = " + agent);
11122
11123        synchronized(this) {
11124            if (!agentPackageName.equals(mBackupAppName)) {
11125                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
11126                return;
11127            }
11128        }
11129
11130        long oldIdent = Binder.clearCallingIdentity();
11131        try {
11132            IBackupManager bm = IBackupManager.Stub.asInterface(
11133                    ServiceManager.getService(Context.BACKUP_SERVICE));
11134            bm.agentConnected(agentPackageName, agent);
11135        } catch (RemoteException e) {
11136            // can't happen; the backup manager service is local
11137        } catch (Exception e) {
11138            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11139            e.printStackTrace();
11140        } finally {
11141            Binder.restoreCallingIdentity(oldIdent);
11142        }
11143    }
11144
11145    // done with this agent
11146    public void unbindBackupAgent(ApplicationInfo appInfo) {
11147        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
11148        if (appInfo == null) {
11149            Slog.w(TAG, "unbind backup agent for null app");
11150            return;
11151        }
11152
11153        synchronized(this) {
11154            if (mBackupAppName == null) {
11155                Slog.w(TAG, "Unbinding backup agent with no active backup");
11156                return;
11157            }
11158
11159            if (!mBackupAppName.equals(appInfo.packageName)) {
11160                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11161                return;
11162            }
11163
11164            ProcessRecord proc = mBackupTarget.app;
11165            mBackupTarget = null;
11166            mBackupAppName = null;
11167
11168            // Not backing this app up any more; reset its OOM adjustment
11169            updateOomAdjLocked(proc);
11170
11171            // If the app crashed during backup, 'thread' will be null here
11172            if (proc.thread != null) {
11173                try {
11174                    proc.thread.scheduleDestroyBackupAgent(appInfo,
11175                            compatibilityInfoForPackageLocked(appInfo));
11176                } catch (Exception e) {
11177                    Slog.e(TAG, "Exception when unbinding backup agent:");
11178                    e.printStackTrace();
11179                }
11180            }
11181        }
11182    }
11183    // =========================================================
11184    // BROADCASTS
11185    // =========================================================
11186
11187    private final List getStickiesLocked(String action, IntentFilter filter,
11188            List cur, int userId) {
11189        final ContentResolver resolver = mContext.getContentResolver();
11190        HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11191        if (stickies == null) {
11192            return cur;
11193        }
11194        final ArrayList<Intent> list = stickies.get(action);
11195        if (list == null) {
11196            return cur;
11197        }
11198        int N = list.size();
11199        for (int i=0; i<N; i++) {
11200            Intent intent = list.get(i);
11201            if (filter.match(resolver, intent, true, TAG) >= 0) {
11202                if (cur == null) {
11203                    cur = new ArrayList<Intent>();
11204                }
11205                cur.add(intent);
11206            }
11207        }
11208        return cur;
11209    }
11210
11211    boolean isPendingBroadcastProcessLocked(int pid) {
11212        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
11213                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
11214    }
11215
11216    void skipPendingBroadcastLocked(int pid) {
11217            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
11218            for (BroadcastQueue queue : mBroadcastQueues) {
11219                queue.skipPendingBroadcastLocked(pid);
11220            }
11221    }
11222
11223    // The app just attached; send any pending broadcasts that it should receive
11224    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
11225        boolean didSomething = false;
11226        for (BroadcastQueue queue : mBroadcastQueues) {
11227            didSomething |= queue.sendPendingBroadcastsLocked(app);
11228        }
11229        return didSomething;
11230    }
11231
11232    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
11233            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
11234        enforceNotIsolatedCaller("registerReceiver");
11235        int callingUid;
11236        int callingPid;
11237        synchronized(this) {
11238            ProcessRecord callerApp = null;
11239            if (caller != null) {
11240                callerApp = getRecordForAppLocked(caller);
11241                if (callerApp == null) {
11242                    throw new SecurityException(
11243                            "Unable to find app for caller " + caller
11244                            + " (pid=" + Binder.getCallingPid()
11245                            + ") when registering receiver " + receiver);
11246                }
11247                if (callerApp.info.uid != Process.SYSTEM_UID &&
11248                        !callerApp.pkgList.contains(callerPackage)) {
11249                    throw new SecurityException("Given caller package " + callerPackage
11250                            + " is not running in process " + callerApp);
11251                }
11252                callingUid = callerApp.info.uid;
11253                callingPid = callerApp.pid;
11254            } else {
11255                callerPackage = null;
11256                callingUid = Binder.getCallingUid();
11257                callingPid = Binder.getCallingPid();
11258            }
11259
11260            userId = this.handleIncomingUserLocked(callingPid, callingUid, userId,
11261                    true, true, "registerReceiver", callerPackage);
11262
11263            List allSticky = null;
11264
11265            // Look for any matching sticky broadcasts...
11266            Iterator actions = filter.actionsIterator();
11267            if (actions != null) {
11268                while (actions.hasNext()) {
11269                    String action = (String)actions.next();
11270                    allSticky = getStickiesLocked(action, filter, allSticky,
11271                            UserHandle.USER_ALL);
11272                    allSticky = getStickiesLocked(action, filter, allSticky,
11273                            UserHandle.getUserId(callingUid));
11274                }
11275            } else {
11276                allSticky = getStickiesLocked(null, filter, allSticky,
11277                        UserHandle.USER_ALL);
11278                allSticky = getStickiesLocked(null, filter, allSticky,
11279                        UserHandle.getUserId(callingUid));
11280            }
11281
11282            // The first sticky in the list is returned directly back to
11283            // the client.
11284            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11285
11286            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
11287                    + ": " + sticky);
11288
11289            if (receiver == null) {
11290                return sticky;
11291            }
11292
11293            ReceiverList rl
11294                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11295            if (rl == null) {
11296                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
11297                        userId, receiver);
11298                if (rl.app != null) {
11299                    rl.app.receivers.add(rl);
11300                } else {
11301                    try {
11302                        receiver.asBinder().linkToDeath(rl, 0);
11303                    } catch (RemoteException e) {
11304                        return sticky;
11305                    }
11306                    rl.linkedToDeath = true;
11307                }
11308                mRegisteredReceivers.put(receiver.asBinder(), rl);
11309            } else if (rl.uid != callingUid) {
11310                throw new IllegalArgumentException(
11311                        "Receiver requested to register for uid " + callingUid
11312                        + " was previously registered for uid " + rl.uid);
11313            } else if (rl.pid != callingPid) {
11314                throw new IllegalArgumentException(
11315                        "Receiver requested to register for pid " + callingPid
11316                        + " was previously registered for pid " + rl.pid);
11317            } else if (rl.userId != userId) {
11318                throw new IllegalArgumentException(
11319                        "Receiver requested to register for user " + userId
11320                        + " was previously registered for user " + rl.userId);
11321            }
11322            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
11323                    permission, callingUid, userId);
11324            rl.add(bf);
11325            if (!bf.debugCheck()) {
11326                Slog.w(TAG, "==> For Dynamic broadast");
11327            }
11328            mReceiverResolver.addFilter(bf);
11329
11330            // Enqueue broadcasts for all existing stickies that match
11331            // this filter.
11332            if (allSticky != null) {
11333                ArrayList receivers = new ArrayList();
11334                receivers.add(bf);
11335
11336                int N = allSticky.size();
11337                for (int i=0; i<N; i++) {
11338                    Intent intent = (Intent)allSticky.get(i);
11339                    BroadcastQueue queue = broadcastQueueForIntent(intent);
11340                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
11341                            null, -1, -1, null, receivers, null, 0, null, null,
11342                            false, true, true, -1);
11343                    queue.enqueueParallelBroadcastLocked(r);
11344                    queue.scheduleBroadcastsLocked();
11345                }
11346            }
11347
11348            return sticky;
11349        }
11350    }
11351
11352    public void unregisterReceiver(IIntentReceiver receiver) {
11353        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11354
11355        final long origId = Binder.clearCallingIdentity();
11356        try {
11357            boolean doTrim = false;
11358
11359            synchronized(this) {
11360                ReceiverList rl
11361                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11362                if (rl != null) {
11363                    if (rl.curBroadcast != null) {
11364                        BroadcastRecord r = rl.curBroadcast;
11365                        final boolean doNext = finishReceiverLocked(
11366                                receiver.asBinder(), r.resultCode, r.resultData,
11367                                r.resultExtras, r.resultAbort, true);
11368                        if (doNext) {
11369                            doTrim = true;
11370                            r.queue.processNextBroadcast(false);
11371                        }
11372                    }
11373
11374                    if (rl.app != null) {
11375                        rl.app.receivers.remove(rl);
11376                    }
11377                    removeReceiverLocked(rl);
11378                    if (rl.linkedToDeath) {
11379                        rl.linkedToDeath = false;
11380                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
11381                    }
11382                }
11383            }
11384
11385            // If we actually concluded any broadcasts, we might now be able
11386            // to trim the recipients' apps from our working set
11387            if (doTrim) {
11388                trimApplications();
11389                return;
11390            }
11391
11392        } finally {
11393            Binder.restoreCallingIdentity(origId);
11394        }
11395    }
11396
11397    void removeReceiverLocked(ReceiverList rl) {
11398        mRegisteredReceivers.remove(rl.receiver.asBinder());
11399        int N = rl.size();
11400        for (int i=0; i<N; i++) {
11401            mReceiverResolver.removeFilter(rl.get(i));
11402        }
11403    }
11404
11405    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
11406        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11407            ProcessRecord r = mLruProcesses.get(i);
11408            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
11409                try {
11410                    r.thread.dispatchPackageBroadcast(cmd, packages);
11411                } catch (RemoteException ex) {
11412                }
11413            }
11414        }
11415    }
11416
11417    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
11418            int[] users) {
11419        List<ResolveInfo> receivers = null;
11420        try {
11421            HashSet<ComponentName> singleUserReceivers = null;
11422            boolean scannedFirstReceivers = false;
11423            for (int user : users) {
11424                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
11425                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
11426                if (newReceivers != null && newReceivers.size() == 0) {
11427                    newReceivers = null;
11428                }
11429                if (receivers == null) {
11430                    receivers = newReceivers;
11431                } else if (newReceivers != null) {
11432                    // We need to concatenate the additional receivers
11433                    // found with what we have do far.  This would be easy,
11434                    // but we also need to de-dup any receivers that are
11435                    // singleUser.
11436                    if (!scannedFirstReceivers) {
11437                        // Collect any single user receivers we had already retrieved.
11438                        scannedFirstReceivers = true;
11439                        for (int i=0; i<receivers.size(); i++) {
11440                            ResolveInfo ri = receivers.get(i);
11441                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11442                                ComponentName cn = new ComponentName(
11443                                        ri.activityInfo.packageName, ri.activityInfo.name);
11444                                if (singleUserReceivers == null) {
11445                                    singleUserReceivers = new HashSet<ComponentName>();
11446                                }
11447                                singleUserReceivers.add(cn);
11448                            }
11449                        }
11450                    }
11451                    // Add the new results to the existing results, tracking
11452                    // and de-dupping single user receivers.
11453                    for (int i=0; i<newReceivers.size(); i++) {
11454                        ResolveInfo ri = newReceivers.get(i);
11455                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11456                            ComponentName cn = new ComponentName(
11457                                    ri.activityInfo.packageName, ri.activityInfo.name);
11458                            if (singleUserReceivers == null) {
11459                                singleUserReceivers = new HashSet<ComponentName>();
11460                            }
11461                            if (!singleUserReceivers.contains(cn)) {
11462                                singleUserReceivers.add(cn);
11463                                receivers.add(ri);
11464                            }
11465                        } else {
11466                            receivers.add(ri);
11467                        }
11468                    }
11469                }
11470            }
11471        } catch (RemoteException ex) {
11472            // pm is in same process, this will never happen.
11473        }
11474        return receivers;
11475    }
11476
11477    private final int broadcastIntentLocked(ProcessRecord callerApp,
11478            String callerPackage, Intent intent, String resolvedType,
11479            IIntentReceiver resultTo, int resultCode, String resultData,
11480            Bundle map, String requiredPermission,
11481            boolean ordered, boolean sticky, int callingPid, int callingUid,
11482            int userId) {
11483        intent = new Intent(intent);
11484
11485        // By default broadcasts do not go to stopped apps.
11486        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11487
11488        if (DEBUG_BROADCAST_LIGHT) Slog.v(
11489            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11490            + " ordered=" + ordered + " userid=" + userId);
11491        if ((resultTo != null) && !ordered) {
11492            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11493        }
11494
11495        userId = handleIncomingUserLocked(callingPid, callingUid, userId,
11496                true, false, "broadcast", callerPackage);
11497
11498        // Make sure that the user who is receiving this broadcast is started
11499        // If not, we will just skip it.
11500        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
11501            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
11502                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
11503                Slog.w(TAG, "Skipping broadcast of " + intent
11504                        + ": user " + userId + " is stopped");
11505                return ActivityManager.BROADCAST_SUCCESS;
11506            }
11507        }
11508
11509        /*
11510         * Prevent non-system code (defined here to be non-persistent
11511         * processes) from sending protected broadcasts.
11512         */
11513        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11514            || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
11515            callingUid == 0) {
11516            // Always okay.
11517        } else if (callerApp == null || !callerApp.persistent) {
11518            try {
11519                if (AppGlobals.getPackageManager().isProtectedBroadcast(
11520                        intent.getAction())) {
11521                    String msg = "Permission Denial: not allowed to send broadcast "
11522                            + intent.getAction() + " from pid="
11523                            + callingPid + ", uid=" + callingUid;
11524                    Slog.w(TAG, msg);
11525                    throw new SecurityException(msg);
11526                }
11527            } catch (RemoteException e) {
11528                Slog.w(TAG, "Remote exception", e);
11529                return ActivityManager.BROADCAST_SUCCESS;
11530            }
11531        }
11532
11533        // Handle special intents: if this broadcast is from the package
11534        // manager about a package being removed, we need to remove all of
11535        // its activities from the history stack.
11536        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11537                intent.getAction());
11538        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11539                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11540                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11541                || uidRemoved) {
11542            if (checkComponentPermission(
11543                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11544                    callingPid, callingUid, -1, true)
11545                    == PackageManager.PERMISSION_GRANTED) {
11546                if (uidRemoved) {
11547                    final Bundle intentExtras = intent.getExtras();
11548                    final int uid = intentExtras != null
11549                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11550                    if (uid >= 0) {
11551                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11552                        synchronized (bs) {
11553                            bs.removeUidStatsLocked(uid);
11554                        }
11555                    }
11556                } else {
11557                    // If resources are unavailable just force stop all
11558                    // those packages and flush the attribute cache as well.
11559                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11560                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11561                        if (list != null && (list.length > 0)) {
11562                            for (String pkg : list) {
11563                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11564                            }
11565                            sendPackageBroadcastLocked(
11566                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
11567                        }
11568                    } else {
11569                        Uri data = intent.getData();
11570                        String ssp;
11571                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11572                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11573                                forceStopPackageLocked(ssp,
11574                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11575                                        false, userId);
11576                            }
11577                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11578                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11579                                        new String[] {ssp}, userId);
11580                            }
11581                        }
11582                    }
11583                }
11584            } else {
11585                String msg = "Permission Denial: " + intent.getAction()
11586                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11587                        + ", uid=" + callingUid + ")"
11588                        + " requires "
11589                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11590                Slog.w(TAG, msg);
11591                throw new SecurityException(msg);
11592            }
11593
11594        // Special case for adding a package: by default turn on compatibility
11595        // mode.
11596        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11597            Uri data = intent.getData();
11598            String ssp;
11599            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11600                mCompatModePackages.handlePackageAddedLocked(ssp,
11601                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11602            }
11603        }
11604
11605        /*
11606         * If this is the time zone changed action, queue up a message that will reset the timezone
11607         * of all currently running processes. This message will get queued up before the broadcast
11608         * happens.
11609         */
11610        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11611            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11612        }
11613
11614        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11615            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11616        }
11617
11618        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11619            ProxyProperties proxy = intent.getParcelableExtra("proxy");
11620            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11621        }
11622
11623        // Add to the sticky list if requested.
11624        if (sticky) {
11625            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11626                    callingPid, callingUid)
11627                    != PackageManager.PERMISSION_GRANTED) {
11628                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11629                        + callingPid + ", uid=" + callingUid
11630                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11631                Slog.w(TAG, msg);
11632                throw new SecurityException(msg);
11633            }
11634            if (requiredPermission != null) {
11635                Slog.w(TAG, "Can't broadcast sticky intent " + intent
11636                        + " and enforce permission " + requiredPermission);
11637                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11638            }
11639            if (intent.getComponent() != null) {
11640                throw new SecurityException(
11641                        "Sticky broadcasts can't target a specific component");
11642            }
11643            // We use userId directly here, since the "all" target is maintained
11644            // as a separate set of sticky broadcasts.
11645            if (userId != UserHandle.USER_ALL) {
11646                // But first, if this is not a broadcast to all users, then
11647                // make sure it doesn't conflict with an existing broadcast to
11648                // all users.
11649                HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
11650                        UserHandle.USER_ALL);
11651                if (stickies != null) {
11652                    ArrayList<Intent> list = stickies.get(intent.getAction());
11653                    if (list != null) {
11654                        int N = list.size();
11655                        int i;
11656                        for (i=0; i<N; i++) {
11657                            if (intent.filterEquals(list.get(i))) {
11658                                throw new IllegalArgumentException(
11659                                        "Sticky broadcast " + intent + " for user "
11660                                        + userId + " conflicts with existing global broadcast");
11661                            }
11662                        }
11663                    }
11664                }
11665            }
11666            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11667            if (stickies == null) {
11668                stickies = new HashMap<String, ArrayList<Intent>>();
11669                mStickyBroadcasts.put(userId, stickies);
11670            }
11671            ArrayList<Intent> list = stickies.get(intent.getAction());
11672            if (list == null) {
11673                list = new ArrayList<Intent>();
11674                stickies.put(intent.getAction(), list);
11675            }
11676            int N = list.size();
11677            int i;
11678            for (i=0; i<N; i++) {
11679                if (intent.filterEquals(list.get(i))) {
11680                    // This sticky already exists, replace it.
11681                    list.set(i, new Intent(intent));
11682                    break;
11683                }
11684            }
11685            if (i >= N) {
11686                list.add(new Intent(intent));
11687            }
11688        }
11689
11690        int[] users;
11691        if (userId == UserHandle.USER_ALL) {
11692            // Caller wants broadcast to go to all started users.
11693            users = new int[mStartedUsers.size()];
11694            for (int i=0; i<mStartedUsers.size(); i++) {
11695                users[i] = mStartedUsers.keyAt(i);
11696            }
11697        } else {
11698            // Caller wants broadcast to go to one specific user.
11699            users = new int[] {userId};
11700        }
11701
11702        // Figure out who all will receive this broadcast.
11703        List receivers = null;
11704        List<BroadcastFilter> registeredReceivers = null;
11705        // Need to resolve the intent to interested receivers...
11706        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11707                 == 0) {
11708            receivers = collectReceiverComponents(intent, resolvedType, users);
11709        }
11710        if (intent.getComponent() == null) {
11711            registeredReceivers = mReceiverResolver.queryIntent(intent,
11712                    resolvedType, false, userId);
11713        }
11714
11715        final boolean replacePending =
11716                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11717
11718        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11719                + " replacePending=" + replacePending);
11720
11721        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11722        if (!ordered && NR > 0) {
11723            // If we are not serializing this broadcast, then send the
11724            // registered receivers separately so they don't wait for the
11725            // components to be launched.
11726            final BroadcastQueue queue = broadcastQueueForIntent(intent);
11727            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11728                    callerPackage, callingPid, callingUid, requiredPermission,
11729                    registeredReceivers, resultTo, resultCode, resultData, map,
11730                    ordered, sticky, false, userId);
11731            if (DEBUG_BROADCAST) Slog.v(
11732                    TAG, "Enqueueing parallel broadcast " + r);
11733            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11734            if (!replaced) {
11735                queue.enqueueParallelBroadcastLocked(r);
11736                queue.scheduleBroadcastsLocked();
11737            }
11738            registeredReceivers = null;
11739            NR = 0;
11740        }
11741
11742        // Merge into one list.
11743        int ir = 0;
11744        if (receivers != null) {
11745            // A special case for PACKAGE_ADDED: do not allow the package
11746            // being added to see this broadcast.  This prevents them from
11747            // using this as a back door to get run as soon as they are
11748            // installed.  Maybe in the future we want to have a special install
11749            // broadcast or such for apps, but we'd like to deliberately make
11750            // this decision.
11751            String skipPackages[] = null;
11752            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11753                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11754                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11755                Uri data = intent.getData();
11756                if (data != null) {
11757                    String pkgName = data.getSchemeSpecificPart();
11758                    if (pkgName != null) {
11759                        skipPackages = new String[] { pkgName };
11760                    }
11761                }
11762            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11763                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11764            }
11765            if (skipPackages != null && (skipPackages.length > 0)) {
11766                for (String skipPackage : skipPackages) {
11767                    if (skipPackage != null) {
11768                        int NT = receivers.size();
11769                        for (int it=0; it<NT; it++) {
11770                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
11771                            if (curt.activityInfo.packageName.equals(skipPackage)) {
11772                                receivers.remove(it);
11773                                it--;
11774                                NT--;
11775                            }
11776                        }
11777                    }
11778                }
11779            }
11780
11781            int NT = receivers != null ? receivers.size() : 0;
11782            int it = 0;
11783            ResolveInfo curt = null;
11784            BroadcastFilter curr = null;
11785            while (it < NT && ir < NR) {
11786                if (curt == null) {
11787                    curt = (ResolveInfo)receivers.get(it);
11788                }
11789                if (curr == null) {
11790                    curr = registeredReceivers.get(ir);
11791                }
11792                if (curr.getPriority() >= curt.priority) {
11793                    // Insert this broadcast record into the final list.
11794                    receivers.add(it, curr);
11795                    ir++;
11796                    curr = null;
11797                    it++;
11798                    NT++;
11799                } else {
11800                    // Skip to the next ResolveInfo in the final list.
11801                    it++;
11802                    curt = null;
11803                }
11804            }
11805        }
11806        while (ir < NR) {
11807            if (receivers == null) {
11808                receivers = new ArrayList();
11809            }
11810            receivers.add(registeredReceivers.get(ir));
11811            ir++;
11812        }
11813
11814        if ((receivers != null && receivers.size() > 0)
11815                || resultTo != null) {
11816            BroadcastQueue queue = broadcastQueueForIntent(intent);
11817            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11818                    callerPackage, callingPid, callingUid, requiredPermission,
11819                    receivers, resultTo, resultCode, resultData, map, ordered,
11820                    sticky, false, userId);
11821            if (DEBUG_BROADCAST) Slog.v(
11822                    TAG, "Enqueueing ordered broadcast " + r
11823                    + ": prev had " + queue.mOrderedBroadcasts.size());
11824            if (DEBUG_BROADCAST) {
11825                int seq = r.intent.getIntExtra("seq", -1);
11826                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11827            }
11828            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11829            if (!replaced) {
11830                queue.enqueueOrderedBroadcastLocked(r);
11831                queue.scheduleBroadcastsLocked();
11832            }
11833        }
11834
11835        return ActivityManager.BROADCAST_SUCCESS;
11836    }
11837
11838    final Intent verifyBroadcastLocked(Intent intent) {
11839        // Refuse possible leaked file descriptors
11840        if (intent != null && intent.hasFileDescriptors() == true) {
11841            throw new IllegalArgumentException("File descriptors passed in Intent");
11842        }
11843
11844        int flags = intent.getFlags();
11845
11846        if (!mProcessesReady) {
11847            // if the caller really truly claims to know what they're doing, go
11848            // ahead and allow the broadcast without launching any receivers
11849            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11850                intent = new Intent(intent);
11851                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11852            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11853                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11854                        + " before boot completion");
11855                throw new IllegalStateException("Cannot broadcast before boot completed");
11856            }
11857        }
11858
11859        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11860            throw new IllegalArgumentException(
11861                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11862        }
11863
11864        return intent;
11865    }
11866
11867    public final int broadcastIntent(IApplicationThread caller,
11868            Intent intent, String resolvedType, IIntentReceiver resultTo,
11869            int resultCode, String resultData, Bundle map,
11870            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11871        enforceNotIsolatedCaller("broadcastIntent");
11872        synchronized(this) {
11873            intent = verifyBroadcastLocked(intent);
11874
11875            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11876            final int callingPid = Binder.getCallingPid();
11877            final int callingUid = Binder.getCallingUid();
11878            final long origId = Binder.clearCallingIdentity();
11879            int res = broadcastIntentLocked(callerApp,
11880                    callerApp != null ? callerApp.info.packageName : null,
11881                    intent, resolvedType, resultTo,
11882                    resultCode, resultData, map, requiredPermission, serialized, sticky,
11883                    callingPid, callingUid, userId);
11884            Binder.restoreCallingIdentity(origId);
11885            return res;
11886        }
11887    }
11888
11889    int broadcastIntentInPackage(String packageName, int uid,
11890            Intent intent, String resolvedType, IIntentReceiver resultTo,
11891            int resultCode, String resultData, Bundle map,
11892            String requiredPermission, boolean serialized, boolean sticky, int userId) {
11893        synchronized(this) {
11894            intent = verifyBroadcastLocked(intent);
11895
11896            final long origId = Binder.clearCallingIdentity();
11897            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11898                    resultTo, resultCode, resultData, map, requiredPermission,
11899                    serialized, sticky, -1, uid, userId);
11900            Binder.restoreCallingIdentity(origId);
11901            return res;
11902        }
11903    }
11904
11905    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
11906        // Refuse possible leaked file descriptors
11907        if (intent != null && intent.hasFileDescriptors() == true) {
11908            throw new IllegalArgumentException("File descriptors passed in Intent");
11909        }
11910
11911        userId = handleIncomingUserLocked(Binder.getCallingPid(),
11912                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
11913
11914        synchronized(this) {
11915            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11916                    != PackageManager.PERMISSION_GRANTED) {
11917                String msg = "Permission Denial: unbroadcastIntent() from pid="
11918                        + Binder.getCallingPid()
11919                        + ", uid=" + Binder.getCallingUid()
11920                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11921                Slog.w(TAG, msg);
11922                throw new SecurityException(msg);
11923            }
11924            HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11925            if (stickies != null) {
11926                ArrayList<Intent> list = stickies.get(intent.getAction());
11927                if (list != null) {
11928                    int N = list.size();
11929                    int i;
11930                    for (i=0; i<N; i++) {
11931                        if (intent.filterEquals(list.get(i))) {
11932                            list.remove(i);
11933                            break;
11934                        }
11935                    }
11936                    if (list.size() <= 0) {
11937                        stickies.remove(intent.getAction());
11938                    }
11939                }
11940                if (stickies.size() <= 0) {
11941                    mStickyBroadcasts.remove(userId);
11942                }
11943            }
11944        }
11945    }
11946
11947    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11948            String resultData, Bundle resultExtras, boolean resultAbort,
11949            boolean explicit) {
11950        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11951        if (r == null) {
11952            Slog.w(TAG, "finishReceiver called but not found on queue");
11953            return false;
11954        }
11955
11956        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11957                explicit);
11958    }
11959
11960    public void finishReceiver(IBinder who, int resultCode, String resultData,
11961            Bundle resultExtras, boolean resultAbort) {
11962        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
11963
11964        // Refuse possible leaked file descriptors
11965        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11966            throw new IllegalArgumentException("File descriptors passed in Bundle");
11967        }
11968
11969        final long origId = Binder.clearCallingIdentity();
11970        try {
11971            boolean doNext = false;
11972            BroadcastRecord r = null;
11973
11974            synchronized(this) {
11975                r = broadcastRecordForReceiverLocked(who);
11976                if (r != null) {
11977                    doNext = r.queue.finishReceiverLocked(r, resultCode,
11978                        resultData, resultExtras, resultAbort, true);
11979                }
11980            }
11981
11982            if (doNext) {
11983                r.queue.processNextBroadcast(false);
11984            }
11985            trimApplications();
11986        } finally {
11987            Binder.restoreCallingIdentity(origId);
11988        }
11989    }
11990
11991    // =========================================================
11992    // INSTRUMENTATION
11993    // =========================================================
11994
11995    public boolean startInstrumentation(ComponentName className,
11996            String profileFile, int flags, Bundle arguments,
11997            IInstrumentationWatcher watcher, int userId) {
11998        enforceNotIsolatedCaller("startInstrumentation");
11999        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
12000                userId, false, true, "startInstrumentation", null);
12001        // Refuse possible leaked file descriptors
12002        if (arguments != null && arguments.hasFileDescriptors()) {
12003            throw new IllegalArgumentException("File descriptors passed in Bundle");
12004        }
12005
12006        synchronized(this) {
12007            InstrumentationInfo ii = null;
12008            ApplicationInfo ai = null;
12009            try {
12010                ii = mContext.getPackageManager().getInstrumentationInfo(
12011                    className, STOCK_PM_FLAGS);
12012                ai = AppGlobals.getPackageManager().getApplicationInfo(
12013                        ii.targetPackage, STOCK_PM_FLAGS, userId);
12014            } catch (PackageManager.NameNotFoundException e) {
12015            } catch (RemoteException e) {
12016            }
12017            if (ii == null) {
12018                reportStartInstrumentationFailure(watcher, className,
12019                        "Unable to find instrumentation info for: " + className);
12020                return false;
12021            }
12022            if (ai == null) {
12023                reportStartInstrumentationFailure(watcher, className,
12024                        "Unable to find instrumentation target package: " + ii.targetPackage);
12025                return false;
12026            }
12027
12028            int match = mContext.getPackageManager().checkSignatures(
12029                    ii.targetPackage, ii.packageName);
12030            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12031                String msg = "Permission Denial: starting instrumentation "
12032                        + className + " from pid="
12033                        + Binder.getCallingPid()
12034                        + ", uid=" + Binder.getCallingPid()
12035                        + " not allowed because package " + ii.packageName
12036                        + " does not have a signature matching the target "
12037                        + ii.targetPackage;
12038                reportStartInstrumentationFailure(watcher, className, msg);
12039                throw new SecurityException(msg);
12040            }
12041
12042            final long origId = Binder.clearCallingIdentity();
12043            // Instrumentation can kill and relaunch even persistent processes
12044            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
12045            ProcessRecord app = addAppLocked(ai, false);
12046            app.instrumentationClass = className;
12047            app.instrumentationInfo = ai;
12048            app.instrumentationProfileFile = profileFile;
12049            app.instrumentationArguments = arguments;
12050            app.instrumentationWatcher = watcher;
12051            app.instrumentationResultClass = className;
12052            Binder.restoreCallingIdentity(origId);
12053        }
12054
12055        return true;
12056    }
12057
12058    /**
12059     * Report errors that occur while attempting to start Instrumentation.  Always writes the
12060     * error to the logs, but if somebody is watching, send the report there too.  This enables
12061     * the "am" command to report errors with more information.
12062     *
12063     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
12064     * @param cn The component name of the instrumentation.
12065     * @param report The error report.
12066     */
12067    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12068            ComponentName cn, String report) {
12069        Slog.w(TAG, report);
12070        try {
12071            if (watcher != null) {
12072                Bundle results = new Bundle();
12073                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12074                results.putString("Error", report);
12075                watcher.instrumentationStatus(cn, -1, results);
12076            }
12077        } catch (RemoteException e) {
12078            Slog.w(TAG, e);
12079        }
12080    }
12081
12082    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12083        if (app.instrumentationWatcher != null) {
12084            try {
12085                // NOTE:  IInstrumentationWatcher *must* be oneway here
12086                app.instrumentationWatcher.instrumentationFinished(
12087                    app.instrumentationClass,
12088                    resultCode,
12089                    results);
12090            } catch (RemoteException e) {
12091            }
12092        }
12093        app.instrumentationWatcher = null;
12094        app.instrumentationClass = null;
12095        app.instrumentationInfo = null;
12096        app.instrumentationProfileFile = null;
12097        app.instrumentationArguments = null;
12098
12099        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
12100    }
12101
12102    public void finishInstrumentation(IApplicationThread target,
12103            int resultCode, Bundle results) {
12104        int userId = UserHandle.getCallingUserId();
12105        // Refuse possible leaked file descriptors
12106        if (results != null && results.hasFileDescriptors()) {
12107            throw new IllegalArgumentException("File descriptors passed in Intent");
12108        }
12109
12110        synchronized(this) {
12111            ProcessRecord app = getRecordForAppLocked(target);
12112            if (app == null) {
12113                Slog.w(TAG, "finishInstrumentation: no app for " + target);
12114                return;
12115            }
12116            final long origId = Binder.clearCallingIdentity();
12117            finishInstrumentationLocked(app, resultCode, results);
12118            Binder.restoreCallingIdentity(origId);
12119        }
12120    }
12121
12122    // =========================================================
12123    // CONFIGURATION
12124    // =========================================================
12125
12126    public ConfigurationInfo getDeviceConfigurationInfo() {
12127        ConfigurationInfo config = new ConfigurationInfo();
12128        synchronized (this) {
12129            config.reqTouchScreen = mConfiguration.touchscreen;
12130            config.reqKeyboardType = mConfiguration.keyboard;
12131            config.reqNavigation = mConfiguration.navigation;
12132            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12133                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
12134                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12135            }
12136            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12137                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
12138                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12139            }
12140            config.reqGlEsVersion = GL_ES_VERSION;
12141        }
12142        return config;
12143    }
12144
12145    public Configuration getConfiguration() {
12146        Configuration ci;
12147        synchronized(this) {
12148            ci = new Configuration(mConfiguration);
12149        }
12150        return ci;
12151    }
12152
12153    public void updatePersistentConfiguration(Configuration values) {
12154        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12155                "updateConfiguration()");
12156        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12157                "updateConfiguration()");
12158        if (values == null) {
12159            throw new NullPointerException("Configuration must not be null");
12160        }
12161
12162        synchronized(this) {
12163            final long origId = Binder.clearCallingIdentity();
12164            updateConfigurationLocked(values, null, true, false);
12165            Binder.restoreCallingIdentity(origId);
12166        }
12167    }
12168
12169    public void updateConfiguration(Configuration values) {
12170        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12171                "updateConfiguration()");
12172
12173        synchronized(this) {
12174            if (values == null && mWindowManager != null) {
12175                // sentinel: fetch the current configuration from the window manager
12176                values = mWindowManager.computeNewConfiguration();
12177            }
12178
12179            if (mWindowManager != null) {
12180                mProcessList.applyDisplaySize(mWindowManager);
12181            }
12182
12183            final long origId = Binder.clearCallingIdentity();
12184            if (values != null) {
12185                Settings.System.clearConfiguration(values);
12186            }
12187            updateConfigurationLocked(values, null, false, false);
12188            Binder.restoreCallingIdentity(origId);
12189        }
12190    }
12191
12192    /**
12193     * Do either or both things: (1) change the current configuration, and (2)
12194     * make sure the given activity is running with the (now) current
12195     * configuration.  Returns true if the activity has been left running, or
12196     * false if <var>starting</var> is being destroyed to match the new
12197     * configuration.
12198     * @param persistent TODO
12199     */
12200    boolean updateConfigurationLocked(Configuration values,
12201            ActivityRecord starting, boolean persistent, boolean initLocale) {
12202        // do nothing if we are headless
12203        if (mHeadless) return true;
12204
12205        int changes = 0;
12206
12207        boolean kept = true;
12208
12209        if (values != null) {
12210            Configuration newConfig = new Configuration(mConfiguration);
12211            changes = newConfig.updateFrom(values);
12212            if (changes != 0) {
12213                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12214                    Slog.i(TAG, "Updating configuration to: " + values);
12215                }
12216
12217                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
12218
12219                if (values.locale != null && !initLocale) {
12220                    saveLocaleLocked(values.locale,
12221                                     !values.locale.equals(mConfiguration.locale),
12222                                     values.userSetLocale);
12223                }
12224
12225                mConfigurationSeq++;
12226                if (mConfigurationSeq <= 0) {
12227                    mConfigurationSeq = 1;
12228                }
12229                newConfig.seq = mConfigurationSeq;
12230                mConfiguration = newConfig;
12231                Slog.i(TAG, "Config changed: " + newConfig);
12232
12233                final Configuration configCopy = new Configuration(mConfiguration);
12234
12235                // TODO: If our config changes, should we auto dismiss any currently
12236                // showing dialogs?
12237                mShowDialogs = shouldShowDialogs(newConfig);
12238
12239                AttributeCache ac = AttributeCache.instance();
12240                if (ac != null) {
12241                    ac.updateConfiguration(configCopy);
12242                }
12243
12244                // Make sure all resources in our process are updated
12245                // right now, so that anyone who is going to retrieve
12246                // resource values after we return will be sure to get
12247                // the new ones.  This is especially important during
12248                // boot, where the first config change needs to guarantee
12249                // all resources have that config before following boot
12250                // code is executed.
12251                mSystemThread.applyConfigurationToResources(configCopy);
12252
12253                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
12254                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12255                    msg.obj = new Configuration(configCopy);
12256                    mHandler.sendMessage(msg);
12257                }
12258
12259                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12260                    ProcessRecord app = mLruProcesses.get(i);
12261                    try {
12262                        if (app.thread != null) {
12263                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
12264                                    + app.processName + " new config " + mConfiguration);
12265                            app.thread.scheduleConfigurationChanged(configCopy);
12266                        }
12267                    } catch (Exception e) {
12268                    }
12269                }
12270                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12271                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12272                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
12273                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12274                        null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12275                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12276                    broadcastIntentLocked(null, null,
12277                            new Intent(Intent.ACTION_LOCALE_CHANGED),
12278                            null, null, 0, null, null,
12279                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12280                }
12281            }
12282        }
12283
12284        if (changes != 0 && starting == null) {
12285            // If the configuration changed, and the caller is not already
12286            // in the process of starting an activity, then find the top
12287            // activity to check if its configuration needs to change.
12288            starting = mMainStack.topRunningActivityLocked(null);
12289        }
12290
12291        if (starting != null) {
12292            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
12293            // And we need to make sure at this point that all other activities
12294            // are made visible with the correct configuration.
12295            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
12296        }
12297
12298        if (values != null && mWindowManager != null) {
12299            mWindowManager.setNewConfiguration(mConfiguration);
12300        }
12301
12302        return kept;
12303    }
12304
12305    /**
12306     * Decide based on the configuration whether we should shouw the ANR,
12307     * crash, etc dialogs.  The idea is that if there is no affordnace to
12308     * press the on-screen buttons, we shouldn't show the dialog.
12309     *
12310     * A thought: SystemUI might also want to get told about this, the Power
12311     * dialog / global actions also might want different behaviors.
12312     */
12313    private static final boolean shouldShowDialogs(Configuration config) {
12314        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
12315                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
12316    }
12317
12318    /**
12319     * Save the locale.  You must be inside a synchronized (this) block.
12320     */
12321    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12322        if(isDiff) {
12323            SystemProperties.set("user.language", l.getLanguage());
12324            SystemProperties.set("user.region", l.getCountry());
12325        }
12326
12327        if(isPersist) {
12328            SystemProperties.set("persist.sys.language", l.getLanguage());
12329            SystemProperties.set("persist.sys.country", l.getCountry());
12330            SystemProperties.set("persist.sys.localevar", l.getVariant());
12331        }
12332    }
12333
12334    @Override
12335    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
12336        ActivityRecord srec = ActivityRecord.forToken(token);
12337        return srec != null && srec.task.affinity != null &&
12338                srec.task.affinity.equals(destAffinity);
12339    }
12340
12341    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
12342            Intent resultData) {
12343        ComponentName dest = destIntent.getComponent();
12344
12345        synchronized (this) {
12346            ActivityRecord srec = ActivityRecord.forToken(token);
12347            if (srec == null) {
12348                return false;
12349            }
12350            ArrayList<ActivityRecord> history = srec.stack.mHistory;
12351            final int start = history.indexOf(srec);
12352            if (start < 0) {
12353                // Current activity is not in history stack; do nothing.
12354                return false;
12355            }
12356            int finishTo = start - 1;
12357            ActivityRecord parent = null;
12358            boolean foundParentInTask = false;
12359            if (dest != null) {
12360                TaskRecord tr = srec.task;
12361                for (int i = start - 1; i >= 0; i--) {
12362                    ActivityRecord r = history.get(i);
12363                    if (tr != r.task) {
12364                        // Couldn't find parent in the same task; stop at the one above this.
12365                        // (Root of current task; in-app "home" behavior)
12366                        // Always at least finish the current activity.
12367                        finishTo = Math.min(start - 1, i + 1);
12368                        parent = history.get(finishTo);
12369                        break;
12370                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
12371                            r.info.name.equals(dest.getClassName())) {
12372                        finishTo = i;
12373                        parent = r;
12374                        foundParentInTask = true;
12375                        break;
12376                    }
12377                }
12378            }
12379
12380            if (mController != null) {
12381                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
12382                if (next != null) {
12383                    // ask watcher if this is allowed
12384                    boolean resumeOK = true;
12385                    try {
12386                        resumeOK = mController.activityResuming(next.packageName);
12387                    } catch (RemoteException e) {
12388                        mController = null;
12389                    }
12390
12391                    if (!resumeOK) {
12392                        return false;
12393                    }
12394                }
12395            }
12396            final long origId = Binder.clearCallingIdentity();
12397            for (int i = start; i > finishTo; i--) {
12398                ActivityRecord r = history.get(i);
12399                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
12400                        "navigate-up", true);
12401                // Only return the supplied result for the first activity finished
12402                resultCode = Activity.RESULT_CANCELED;
12403                resultData = null;
12404            }
12405
12406            if (parent != null && foundParentInTask) {
12407                final int parentLaunchMode = parent.info.launchMode;
12408                final int destIntentFlags = destIntent.getFlags();
12409                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
12410                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
12411                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
12412                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
12413                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
12414                } else {
12415                    try {
12416                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
12417                                destIntent.getComponent(), 0, UserHandle.getCallingUserId());
12418                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
12419                                null, aInfo, parent.appToken, null,
12420                                0, -1, parent.launchedFromUid, 0, null, true, null);
12421                        foundParentInTask = res == ActivityManager.START_SUCCESS;
12422                    } catch (RemoteException e) {
12423                        foundParentInTask = false;
12424                    }
12425                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
12426                            resultData, "navigate-up", true);
12427                }
12428            }
12429            Binder.restoreCallingIdentity(origId);
12430            return foundParentInTask;
12431        }
12432    }
12433
12434    public int getLaunchedFromUid(IBinder activityToken) {
12435        ActivityRecord srec = ActivityRecord.forToken(activityToken);
12436        if (srec == null) {
12437            return -1;
12438        }
12439        return srec.launchedFromUid;
12440    }
12441
12442    // =========================================================
12443    // LIFETIME MANAGEMENT
12444    // =========================================================
12445
12446    // Returns which broadcast queue the app is the current [or imminent] receiver
12447    // on, or 'null' if the app is not an active broadcast recipient.
12448    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12449        BroadcastRecord r = app.curReceiver;
12450        if (r != null) {
12451            return r.queue;
12452        }
12453
12454        // It's not the current receiver, but it might be starting up to become one
12455        synchronized (this) {
12456            for (BroadcastQueue queue : mBroadcastQueues) {
12457                r = queue.mPendingBroadcast;
12458                if (r != null && r.curApp == app) {
12459                    // found it; report which queue it's in
12460                    return queue;
12461                }
12462            }
12463        }
12464
12465        return null;
12466    }
12467
12468    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12469            int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12470        if (mAdjSeq == app.adjSeq) {
12471            // This adjustment has already been computed.  If we are calling
12472            // from the top, we may have already computed our adjustment with
12473            // an earlier hidden adjustment that isn't really for us... if
12474            // so, use the new hidden adjustment.
12475            if (!recursed && app.hidden) {
12476                app.curAdj = app.curRawAdj = app.nonStoppingAdj =
12477                        app.hasActivities ? hiddenAdj : emptyAdj;
12478            }
12479            return app.curRawAdj;
12480        }
12481
12482        if (app.thread == null) {
12483            app.adjSeq = mAdjSeq;
12484            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12485            return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12486        }
12487
12488        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12489        app.adjSource = null;
12490        app.adjTarget = null;
12491        app.empty = false;
12492        app.hidden = false;
12493
12494        final int activitiesSize = app.activities.size();
12495
12496        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12497            // The max adjustment doesn't allow this app to be anything
12498            // below foreground, so it is not worth doing work for it.
12499            app.adjType = "fixed";
12500            app.adjSeq = mAdjSeq;
12501            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12502            app.hasActivities = false;
12503            app.foregroundActivities = false;
12504            app.keeping = true;
12505            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12506            // System process can do UI, and when they do we want to have
12507            // them trim their memory after the user leaves the UI.  To
12508            // facilitate this, here we need to determine whether or not it
12509            // is currently showing UI.
12510            app.systemNoUi = true;
12511            if (app == TOP_APP) {
12512                app.systemNoUi = false;
12513                app.hasActivities = true;
12514            } else if (activitiesSize > 0) {
12515                for (int j = 0; j < activitiesSize; j++) {
12516                    final ActivityRecord r = app.activities.get(j);
12517                    if (r.visible) {
12518                        app.systemNoUi = false;
12519                    }
12520                    if (r.app == app) {
12521                        app.hasActivities = true;
12522                    }
12523                }
12524            }
12525            return (app.curAdj=app.maxAdj);
12526        }
12527
12528        app.keeping = false;
12529        app.systemNoUi = false;
12530        app.hasActivities = false;
12531
12532        // Determine the importance of the process, starting with most
12533        // important to least, and assign an appropriate OOM adjustment.
12534        int adj;
12535        int schedGroup;
12536        boolean foregroundActivities = false;
12537        boolean interesting = false;
12538        BroadcastQueue queue;
12539        if (app == TOP_APP) {
12540            // The last app on the list is the foreground app.
12541            adj = ProcessList.FOREGROUND_APP_ADJ;
12542            schedGroup = Process.THREAD_GROUP_DEFAULT;
12543            app.adjType = "top-activity";
12544            foregroundActivities = true;
12545            interesting = true;
12546            app.hasActivities = true;
12547        } else if (app.instrumentationClass != null) {
12548            // Don't want to kill running instrumentation.
12549            adj = ProcessList.FOREGROUND_APP_ADJ;
12550            schedGroup = Process.THREAD_GROUP_DEFAULT;
12551            app.adjType = "instrumentation";
12552            interesting = true;
12553        } else if ((queue = isReceivingBroadcast(app)) != null) {
12554            // An app that is currently receiving a broadcast also
12555            // counts as being in the foreground for OOM killer purposes.
12556            // It's placed in a sched group based on the nature of the
12557            // broadcast as reflected by which queue it's active in.
12558            adj = ProcessList.FOREGROUND_APP_ADJ;
12559            schedGroup = (queue == mFgBroadcastQueue)
12560                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12561            app.adjType = "broadcast";
12562        } else if (app.executingServices.size() > 0) {
12563            // An app that is currently executing a service callback also
12564            // counts as being in the foreground.
12565            adj = ProcessList.FOREGROUND_APP_ADJ;
12566            schedGroup = Process.THREAD_GROUP_DEFAULT;
12567            app.adjType = "exec-service";
12568        } else {
12569            // Assume process is hidden (has activities); we will correct
12570            // later if this is not the case.
12571            adj = hiddenAdj;
12572            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12573            app.hidden = true;
12574            app.adjType = "bg-activities";
12575        }
12576
12577        boolean hasStoppingActivities = false;
12578
12579        // Examine all activities if not already foreground.
12580        if (!foregroundActivities && activitiesSize > 0) {
12581            for (int j = 0; j < activitiesSize; j++) {
12582                final ActivityRecord r = app.activities.get(j);
12583                if (r.visible) {
12584                    // App has a visible activity; only upgrade adjustment.
12585                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
12586                        adj = ProcessList.VISIBLE_APP_ADJ;
12587                        app.adjType = "visible";
12588                    }
12589                    schedGroup = Process.THREAD_GROUP_DEFAULT;
12590                    app.hidden = false;
12591                    app.hasActivities = true;
12592                    foregroundActivities = true;
12593                    break;
12594                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12595                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12596                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12597                        app.adjType = "pausing";
12598                    }
12599                    app.hidden = false;
12600                    foregroundActivities = true;
12601                } else if (r.state == ActivityState.STOPPING) {
12602                    // We will apply the actual adjustment later, because
12603                    // we want to allow this process to immediately go through
12604                    // any memory trimming that is in effect.
12605                    app.hidden = false;
12606                    foregroundActivities = true;
12607                    hasStoppingActivities = true;
12608                }
12609                if (r.app == app) {
12610                    app.hasActivities = true;
12611                }
12612            }
12613        }
12614
12615        if (adj == hiddenAdj && !app.hasActivities) {
12616            // Whoops, this process is completely empty as far as we know
12617            // at this point.
12618            adj = emptyAdj;
12619            app.empty = true;
12620            app.adjType = "bg-empty";
12621        }
12622
12623        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12624            if (app.foregroundServices) {
12625                // The user is aware of this app, so make it visible.
12626                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12627                app.hidden = false;
12628                app.adjType = "foreground-service";
12629                schedGroup = Process.THREAD_GROUP_DEFAULT;
12630            } else if (app.forcingToForeground != null) {
12631                // The user is aware of this app, so make it visible.
12632                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12633                app.hidden = false;
12634                app.adjType = "force-foreground";
12635                app.adjSource = app.forcingToForeground;
12636                schedGroup = Process.THREAD_GROUP_DEFAULT;
12637            }
12638        }
12639
12640        if (app.foregroundServices) {
12641            interesting = true;
12642        }
12643
12644        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12645            // We don't want to kill the current heavy-weight process.
12646            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12647            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12648            app.hidden = false;
12649            app.adjType = "heavy";
12650        }
12651
12652        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12653            // This process is hosting what we currently consider to be the
12654            // home app, so we don't want to let it go into the background.
12655            adj = ProcessList.HOME_APP_ADJ;
12656            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12657            app.hidden = false;
12658            app.adjType = "home";
12659        }
12660
12661        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12662                && app.activities.size() > 0) {
12663            // This was the previous process that showed UI to the user.
12664            // We want to try to keep it around more aggressively, to give
12665            // a good experience around switching between two apps.
12666            adj = ProcessList.PREVIOUS_APP_ADJ;
12667            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12668            app.hidden = false;
12669            app.adjType = "previous";
12670        }
12671
12672        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12673                + " reason=" + app.adjType);
12674
12675        // By default, we use the computed adjustment.  It may be changed if
12676        // there are applications dependent on our services or providers, but
12677        // this gives us a baseline and makes sure we don't get into an
12678        // infinite recursion.
12679        app.adjSeq = mAdjSeq;
12680        app.curRawAdj = app.nonStoppingAdj = adj;
12681
12682        if (mBackupTarget != null && app == mBackupTarget.app) {
12683            // If possible we want to avoid killing apps while they're being backed up
12684            if (adj > ProcessList.BACKUP_APP_ADJ) {
12685                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12686                adj = ProcessList.BACKUP_APP_ADJ;
12687                app.adjType = "backup";
12688                app.hidden = false;
12689            }
12690        }
12691
12692        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12693                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12694            final long now = SystemClock.uptimeMillis();
12695            // This process is more important if the top activity is
12696            // bound to the service.
12697            Iterator<ServiceRecord> jt = app.services.iterator();
12698            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12699                ServiceRecord s = jt.next();
12700                if (s.startRequested) {
12701                    if (app.hasShownUi && app != mHomeProcess) {
12702                        // If this process has shown some UI, let it immediately
12703                        // go to the LRU list because it may be pretty heavy with
12704                        // UI stuff.  We'll tag it with a label just to help
12705                        // debug and understand what is going on.
12706                        if (adj > ProcessList.SERVICE_ADJ) {
12707                            app.adjType = "started-bg-ui-services";
12708                        }
12709                    } else {
12710                        if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12711                            // This service has seen some activity within
12712                            // recent memory, so we will keep its process ahead
12713                            // of the background processes.
12714                            if (adj > ProcessList.SERVICE_ADJ) {
12715                                adj = ProcessList.SERVICE_ADJ;
12716                                app.adjType = "started-services";
12717                                app.hidden = false;
12718                            }
12719                        }
12720                        // If we have let the service slide into the background
12721                        // state, still have some text describing what it is doing
12722                        // even though the service no longer has an impact.
12723                        if (adj > ProcessList.SERVICE_ADJ) {
12724                            app.adjType = "started-bg-services";
12725                        }
12726                    }
12727                    // Don't kill this process because it is doing work; it
12728                    // has said it is doing work.
12729                    app.keeping = true;
12730                }
12731                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12732                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12733                    Iterator<ArrayList<ConnectionRecord>> kt
12734                            = s.connections.values().iterator();
12735                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12736                        ArrayList<ConnectionRecord> clist = kt.next();
12737                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12738                            // XXX should compute this based on the max of
12739                            // all connected clients.
12740                            ConnectionRecord cr = clist.get(i);
12741                            if (cr.binding.client == app) {
12742                                // Binding to ourself is not interesting.
12743                                continue;
12744                            }
12745                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12746                                ProcessRecord client = cr.binding.client;
12747                                int clientAdj = adj;
12748                                int myHiddenAdj = hiddenAdj;
12749                                if (myHiddenAdj > client.hiddenAdj) {
12750                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12751                                        myHiddenAdj = client.hiddenAdj;
12752                                    } else {
12753                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12754                                    }
12755                                }
12756                                int myEmptyAdj = emptyAdj;
12757                                if (myEmptyAdj > client.emptyAdj) {
12758                                    if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12759                                        myEmptyAdj = client.emptyAdj;
12760                                    } else {
12761                                        myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12762                                    }
12763                                }
12764                                clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12765                                        myEmptyAdj, TOP_APP, true, doingAll);
12766                                String adjType = null;
12767                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12768                                    // Not doing bind OOM management, so treat
12769                                    // this guy more like a started service.
12770                                    if (app.hasShownUi && app != mHomeProcess) {
12771                                        // If this process has shown some UI, let it immediately
12772                                        // go to the LRU list because it may be pretty heavy with
12773                                        // UI stuff.  We'll tag it with a label just to help
12774                                        // debug and understand what is going on.
12775                                        if (adj > clientAdj) {
12776                                            adjType = "bound-bg-ui-services";
12777                                        }
12778                                        app.hidden = false;
12779                                        clientAdj = adj;
12780                                    } else {
12781                                        if (now >= (s.lastActivity
12782                                                + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12783                                            // This service has not seen activity within
12784                                            // recent memory, so allow it to drop to the
12785                                            // LRU list if there is no other reason to keep
12786                                            // it around.  We'll also tag it with a label just
12787                                            // to help debug and undertand what is going on.
12788                                            if (adj > clientAdj) {
12789                                                adjType = "bound-bg-services";
12790                                            }
12791                                            clientAdj = adj;
12792                                        }
12793                                    }
12794                                }
12795                                if (adj > clientAdj) {
12796                                    // If this process has recently shown UI, and
12797                                    // the process that is binding to it is less
12798                                    // important than being visible, then we don't
12799                                    // care about the binding as much as we care
12800                                    // about letting this process get into the LRU
12801                                    // list to be killed and restarted if needed for
12802                                    // memory.
12803                                    if (app.hasShownUi && app != mHomeProcess
12804                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12805                                        adjType = "bound-bg-ui-services";
12806                                    } else {
12807                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12808                                                |Context.BIND_IMPORTANT)) != 0) {
12809                                            adj = clientAdj;
12810                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12811                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12812                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12813                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12814                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12815                                            adj = clientAdj;
12816                                        } else {
12817                                            app.pendingUiClean = true;
12818                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
12819                                                adj = ProcessList.VISIBLE_APP_ADJ;
12820                                            }
12821                                        }
12822                                        if (!client.hidden) {
12823                                            app.hidden = false;
12824                                        }
12825                                        if (client.keeping) {
12826                                            app.keeping = true;
12827                                        }
12828                                        adjType = "service";
12829                                    }
12830                                }
12831                                if (adjType != null) {
12832                                    app.adjType = adjType;
12833                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12834                                            .REASON_SERVICE_IN_USE;
12835                                    app.adjSource = cr.binding.client;
12836                                    app.adjSourceOom = clientAdj;
12837                                    app.adjTarget = s.name;
12838                                }
12839                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12840                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12841                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12842                                    }
12843                                }
12844                            }
12845                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12846                                ActivityRecord a = cr.activity;
12847                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
12848                                        (a.visible || a.state == ActivityState.RESUMED
12849                                         || a.state == ActivityState.PAUSING)) {
12850                                    adj = ProcessList.FOREGROUND_APP_ADJ;
12851                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12852                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12853                                    }
12854                                    app.hidden = false;
12855                                    app.adjType = "service";
12856                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12857                                            .REASON_SERVICE_IN_USE;
12858                                    app.adjSource = a;
12859                                    app.adjSourceOom = adj;
12860                                    app.adjTarget = s.name;
12861                                }
12862                            }
12863                        }
12864                    }
12865                }
12866            }
12867
12868            // Finally, if this process has active services running in it, we
12869            // would like to avoid killing it unless it would prevent the current
12870            // application from running.  By default we put the process in
12871            // with the rest of the background processes; as we scan through
12872            // its services we may bump it up from there.
12873            if (adj > hiddenAdj) {
12874                adj = hiddenAdj;
12875                app.hidden = false;
12876                app.adjType = "bg-services";
12877            }
12878        }
12879
12880        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12881                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12882            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
12883            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
12884                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12885                ContentProviderRecord cpr = jt.next();
12886                for (int i = cpr.connections.size()-1;
12887                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12888                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12889                        i--) {
12890                    ContentProviderConnection conn = cpr.connections.get(i);
12891                    ProcessRecord client = conn.client;
12892                    if (client == app) {
12893                        // Being our own client is not interesting.
12894                        continue;
12895                    }
12896                    int myHiddenAdj = hiddenAdj;
12897                    if (myHiddenAdj > client.hiddenAdj) {
12898                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12899                            myHiddenAdj = client.hiddenAdj;
12900                        } else {
12901                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
12902                        }
12903                    }
12904                    int myEmptyAdj = emptyAdj;
12905                    if (myEmptyAdj > client.emptyAdj) {
12906                        if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
12907                            myEmptyAdj = client.emptyAdj;
12908                        } else {
12909                            myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
12910                        }
12911                    }
12912                    int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12913                            myEmptyAdj, TOP_APP, true, doingAll);
12914                    if (adj > clientAdj) {
12915                        if (app.hasShownUi && app != mHomeProcess
12916                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12917                            app.adjType = "bg-ui-provider";
12918                        } else {
12919                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12920                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12921                            app.adjType = "provider";
12922                        }
12923                        if (!client.hidden) {
12924                            app.hidden = false;
12925                        }
12926                        if (client.keeping) {
12927                            app.keeping = true;
12928                        }
12929                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12930                                .REASON_PROVIDER_IN_USE;
12931                        app.adjSource = client;
12932                        app.adjSourceOom = clientAdj;
12933                        app.adjTarget = cpr.name;
12934                    }
12935                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12936                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12937                    }
12938                }
12939                // If the provider has external (non-framework) process
12940                // dependencies, ensure that its adjustment is at least
12941                // FOREGROUND_APP_ADJ.
12942                if (cpr.hasExternalProcessHandles()) {
12943                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12944                        adj = ProcessList.FOREGROUND_APP_ADJ;
12945                        schedGroup = Process.THREAD_GROUP_DEFAULT;
12946                        app.hidden = false;
12947                        app.keeping = true;
12948                        app.adjType = "provider";
12949                        app.adjTarget = cpr.name;
12950                    }
12951                }
12952            }
12953        }
12954
12955        if (adj == ProcessList.SERVICE_ADJ) {
12956            if (doingAll) {
12957                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
12958                mNewNumServiceProcs++;
12959            }
12960            if (app.serviceb) {
12961                adj = ProcessList.SERVICE_B_ADJ;
12962            }
12963        } else {
12964            app.serviceb = false;
12965        }
12966
12967        app.nonStoppingAdj = adj;
12968
12969        if (hasStoppingActivities) {
12970            // Only upgrade adjustment.
12971            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12972                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12973                app.adjType = "stopping";
12974            }
12975        }
12976
12977        app.curRawAdj = adj;
12978
12979        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
12980        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12981        if (adj > app.maxAdj) {
12982            adj = app.maxAdj;
12983            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
12984                schedGroup = Process.THREAD_GROUP_DEFAULT;
12985            }
12986        }
12987        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12988            app.keeping = true;
12989        }
12990
12991        if (app.hasAboveClient) {
12992            // If this process has bound to any services with BIND_ABOVE_CLIENT,
12993            // then we need to drop its adjustment to be lower than the service's
12994            // in order to honor the request.  We want to drop it by one adjustment
12995            // level...  but there is special meaning applied to various levels so
12996            // we will skip some of them.
12997            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
12998                // System process will not get dropped, ever
12999            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13000                adj = ProcessList.VISIBLE_APP_ADJ;
13001            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13002                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13003            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13004                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13005            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
13006                adj++;
13007            }
13008        }
13009
13010        int importance = app.memImportance;
13011        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
13012            app.curAdj = adj;
13013            app.curSchedGroup = schedGroup;
13014            if (!interesting) {
13015                // For this reporting, if there is not something explicitly
13016                // interesting in this process then we will push it to the
13017                // background importance.
13018                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13019            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13020                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13021            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
13022                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13023            } else if (adj >= ProcessList.HOME_APP_ADJ) {
13024                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13025            } else if (adj >= ProcessList.SERVICE_ADJ) {
13026                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13027            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13028                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
13029            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
13030                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
13031            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
13032                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
13033            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
13034                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
13035            } else {
13036                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
13037            }
13038        }
13039
13040        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
13041        if (foregroundActivities != app.foregroundActivities) {
13042            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
13043        }
13044        if (changes != 0) {
13045            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
13046            app.memImportance = importance;
13047            app.foregroundActivities = foregroundActivities;
13048            int i = mPendingProcessChanges.size()-1;
13049            ProcessChangeItem item = null;
13050            while (i >= 0) {
13051                item = mPendingProcessChanges.get(i);
13052                if (item.pid == app.pid) {
13053                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
13054                    break;
13055                }
13056                i--;
13057            }
13058            if (i < 0) {
13059                // No existing item in pending changes; need a new one.
13060                final int NA = mAvailProcessChanges.size();
13061                if (NA > 0) {
13062                    item = mAvailProcessChanges.remove(NA-1);
13063                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
13064                } else {
13065                    item = new ProcessChangeItem();
13066                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
13067                }
13068                item.changes = 0;
13069                item.pid = app.pid;
13070                item.uid = app.info.uid;
13071                if (mPendingProcessChanges.size() == 0) {
13072                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
13073                            "*** Enqueueing dispatch processes changed!");
13074                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
13075                }
13076                mPendingProcessChanges.add(item);
13077            }
13078            item.changes |= changes;
13079            item.importance = importance;
13080            item.foregroundActivities = foregroundActivities;
13081            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
13082                    + Integer.toHexString(System.identityHashCode(item))
13083                    + " " + app.toShortString() + ": changes=" + item.changes
13084                    + " importance=" + item.importance
13085                    + " foreground=" + item.foregroundActivities
13086                    + " type=" + app.adjType + " source=" + app.adjSource
13087                    + " target=" + app.adjTarget);
13088        }
13089
13090        return app.curRawAdj;
13091    }
13092
13093    /**
13094     * Ask a given process to GC right now.
13095     */
13096    final void performAppGcLocked(ProcessRecord app) {
13097        try {
13098            app.lastRequestedGc = SystemClock.uptimeMillis();
13099            if (app.thread != null) {
13100                if (app.reportLowMemory) {
13101                    app.reportLowMemory = false;
13102                    app.thread.scheduleLowMemory();
13103                } else {
13104                    app.thread.processInBackground();
13105                }
13106            }
13107        } catch (Exception e) {
13108            // whatever.
13109        }
13110    }
13111
13112    /**
13113     * Returns true if things are idle enough to perform GCs.
13114     */
13115    private final boolean canGcNowLocked() {
13116        boolean processingBroadcasts = false;
13117        for (BroadcastQueue q : mBroadcastQueues) {
13118            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
13119                processingBroadcasts = true;
13120            }
13121        }
13122        return !processingBroadcasts
13123                && (mSleeping || (mMainStack.mResumedActivity != null &&
13124                        mMainStack.mResumedActivity.idle));
13125    }
13126
13127    /**
13128     * Perform GCs on all processes that are waiting for it, but only
13129     * if things are idle.
13130     */
13131    final void performAppGcsLocked() {
13132        final int N = mProcessesToGc.size();
13133        if (N <= 0) {
13134            return;
13135        }
13136        if (canGcNowLocked()) {
13137            while (mProcessesToGc.size() > 0) {
13138                ProcessRecord proc = mProcessesToGc.remove(0);
13139                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
13140                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13141                            <= SystemClock.uptimeMillis()) {
13142                        // To avoid spamming the system, we will GC processes one
13143                        // at a time, waiting a few seconds between each.
13144                        performAppGcLocked(proc);
13145                        scheduleAppGcsLocked();
13146                        return;
13147                    } else {
13148                        // It hasn't been long enough since we last GCed this
13149                        // process...  put it in the list to wait for its time.
13150                        addProcessToGcListLocked(proc);
13151                        break;
13152                    }
13153                }
13154            }
13155
13156            scheduleAppGcsLocked();
13157        }
13158    }
13159
13160    /**
13161     * If all looks good, perform GCs on all processes waiting for them.
13162     */
13163    final void performAppGcsIfAppropriateLocked() {
13164        if (canGcNowLocked()) {
13165            performAppGcsLocked();
13166            return;
13167        }
13168        // Still not idle, wait some more.
13169        scheduleAppGcsLocked();
13170    }
13171
13172    /**
13173     * Schedule the execution of all pending app GCs.
13174     */
13175    final void scheduleAppGcsLocked() {
13176        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
13177
13178        if (mProcessesToGc.size() > 0) {
13179            // Schedule a GC for the time to the next process.
13180            ProcessRecord proc = mProcessesToGc.get(0);
13181            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13182
13183            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
13184            long now = SystemClock.uptimeMillis();
13185            if (when < (now+GC_TIMEOUT)) {
13186                when = now + GC_TIMEOUT;
13187            }
13188            mHandler.sendMessageAtTime(msg, when);
13189        }
13190    }
13191
13192    /**
13193     * Add a process to the array of processes waiting to be GCed.  Keeps the
13194     * list in sorted order by the last GC time.  The process can't already be
13195     * on the list.
13196     */
13197    final void addProcessToGcListLocked(ProcessRecord proc) {
13198        boolean added = false;
13199        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13200            if (mProcessesToGc.get(i).lastRequestedGc <
13201                    proc.lastRequestedGc) {
13202                added = true;
13203                mProcessesToGc.add(i+1, proc);
13204                break;
13205            }
13206        }
13207        if (!added) {
13208            mProcessesToGc.add(0, proc);
13209        }
13210    }
13211
13212    /**
13213     * Set up to ask a process to GC itself.  This will either do it
13214     * immediately, or put it on the list of processes to gc the next
13215     * time things are idle.
13216     */
13217    final void scheduleAppGcLocked(ProcessRecord app) {
13218        long now = SystemClock.uptimeMillis();
13219        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13220            return;
13221        }
13222        if (!mProcessesToGc.contains(app)) {
13223            addProcessToGcListLocked(app);
13224            scheduleAppGcsLocked();
13225        }
13226    }
13227
13228    final void checkExcessivePowerUsageLocked(boolean doKills) {
13229        updateCpuStatsNow();
13230
13231        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13232        boolean doWakeKills = doKills;
13233        boolean doCpuKills = doKills;
13234        if (mLastPowerCheckRealtime == 0) {
13235            doWakeKills = false;
13236        }
13237        if (mLastPowerCheckUptime == 0) {
13238            doCpuKills = false;
13239        }
13240        if (stats.isScreenOn()) {
13241            doWakeKills = false;
13242        }
13243        final long curRealtime = SystemClock.elapsedRealtime();
13244        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13245        final long curUptime = SystemClock.uptimeMillis();
13246        final long uptimeSince = curUptime - mLastPowerCheckUptime;
13247        mLastPowerCheckRealtime = curRealtime;
13248        mLastPowerCheckUptime = curUptime;
13249        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13250            doWakeKills = false;
13251        }
13252        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13253            doCpuKills = false;
13254        }
13255        int i = mLruProcesses.size();
13256        while (i > 0) {
13257            i--;
13258            ProcessRecord app = mLruProcesses.get(i);
13259            if (!app.keeping) {
13260                long wtime;
13261                synchronized (stats) {
13262                    wtime = stats.getProcessWakeTime(app.info.uid,
13263                            app.pid, curRealtime);
13264                }
13265                long wtimeUsed = wtime - app.lastWakeTime;
13266                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13267                if (DEBUG_POWER) {
13268                    StringBuilder sb = new StringBuilder(128);
13269                    sb.append("Wake for ");
13270                    app.toShortString(sb);
13271                    sb.append(": over ");
13272                    TimeUtils.formatDuration(realtimeSince, sb);
13273                    sb.append(" used ");
13274                    TimeUtils.formatDuration(wtimeUsed, sb);
13275                    sb.append(" (");
13276                    sb.append((wtimeUsed*100)/realtimeSince);
13277                    sb.append("%)");
13278                    Slog.i(TAG, sb.toString());
13279                    sb.setLength(0);
13280                    sb.append("CPU for ");
13281                    app.toShortString(sb);
13282                    sb.append(": over ");
13283                    TimeUtils.formatDuration(uptimeSince, sb);
13284                    sb.append(" used ");
13285                    TimeUtils.formatDuration(cputimeUsed, sb);
13286                    sb.append(" (");
13287                    sb.append((cputimeUsed*100)/uptimeSince);
13288                    sb.append("%)");
13289                    Slog.i(TAG, sb.toString());
13290                }
13291                // If a process has held a wake lock for more
13292                // than 50% of the time during this period,
13293                // that sounds bad.  Kill!
13294                if (doWakeKills && realtimeSince > 0
13295                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
13296                    synchronized (stats) {
13297                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13298                                realtimeSince, wtimeUsed);
13299                    }
13300                    Slog.w(TAG, "Excessive wake lock in " + app.processName
13301                            + " (pid " + app.pid + "): held " + wtimeUsed
13302                            + " during " + realtimeSince);
13303                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13304                            app.processName, app.setAdj, "excessive wake lock");
13305                    Process.killProcessQuiet(app.pid);
13306                } else if (doCpuKills && uptimeSince > 0
13307                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
13308                    synchronized (stats) {
13309                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13310                                uptimeSince, cputimeUsed);
13311                    }
13312                    Slog.w(TAG, "Excessive CPU in " + app.processName
13313                            + " (pid " + app.pid + "): used " + cputimeUsed
13314                            + " during " + uptimeSince);
13315                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13316                            app.processName, app.setAdj, "excessive cpu");
13317                    Process.killProcessQuiet(app.pid);
13318                } else {
13319                    app.lastWakeTime = wtime;
13320                    app.lastCpuTime = app.curCpuTime;
13321                }
13322            }
13323        }
13324    }
13325
13326    private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
13327            int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
13328        app.hiddenAdj = hiddenAdj;
13329        app.emptyAdj = emptyAdj;
13330
13331        if (app.thread == null) {
13332            return false;
13333        }
13334
13335        final boolean wasKeeping = app.keeping;
13336
13337        boolean success = true;
13338
13339        computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll);
13340
13341        if (app.curRawAdj != app.setRawAdj) {
13342            if (wasKeeping && !app.keeping) {
13343                // This app is no longer something we want to keep.  Note
13344                // its current wake lock time to later know to kill it if
13345                // it is not behaving well.
13346                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13347                synchronized (stats) {
13348                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13349                            app.pid, SystemClock.elapsedRealtime());
13350                }
13351                app.lastCpuTime = app.curCpuTime;
13352            }
13353
13354            app.setRawAdj = app.curRawAdj;
13355        }
13356
13357        if (app.curAdj != app.setAdj) {
13358            if (Process.setOomAdj(app.pid, app.curAdj)) {
13359                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13360                    TAG, "Set " + app.pid + " " + app.processName +
13361                    " adj " + app.curAdj + ": " + app.adjType);
13362                app.setAdj = app.curAdj;
13363            } else {
13364                success = false;
13365                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
13366            }
13367        }
13368        if (app.setSchedGroup != app.curSchedGroup) {
13369            app.setSchedGroup = app.curSchedGroup;
13370            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13371                    "Setting process group of " + app.processName
13372                    + " to " + app.curSchedGroup);
13373            if (app.waitingToKill != null &&
13374                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13375                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13376                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13377                        app.processName, app.setAdj, app.waitingToKill);
13378                app.killedBackground = true;
13379                Process.killProcessQuiet(app.pid);
13380                success = false;
13381            } else {
13382                if (true) {
13383                    long oldId = Binder.clearCallingIdentity();
13384                    try {
13385                        Process.setProcessGroup(app.pid, app.curSchedGroup);
13386                    } catch (Exception e) {
13387                        Slog.w(TAG, "Failed setting process group of " + app.pid
13388                                + " to " + app.curSchedGroup);
13389                        e.printStackTrace();
13390                    } finally {
13391                        Binder.restoreCallingIdentity(oldId);
13392                    }
13393                } else {
13394                    if (app.thread != null) {
13395                        try {
13396                            app.thread.setSchedulingGroup(app.curSchedGroup);
13397                        } catch (RemoteException e) {
13398                        }
13399                    }
13400                }
13401            }
13402        }
13403        return success;
13404    }
13405
13406    private final ActivityRecord resumedAppLocked() {
13407        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
13408        if (resumedActivity == null || resumedActivity.app == null) {
13409            resumedActivity = mMainStack.mPausingActivity;
13410            if (resumedActivity == null || resumedActivity.app == null) {
13411                resumedActivity = mMainStack.topRunningActivityLocked(null);
13412            }
13413        }
13414        return resumedActivity;
13415    }
13416
13417    final boolean updateOomAdjLocked(ProcessRecord app) {
13418        final ActivityRecord TOP_ACT = resumedAppLocked();
13419        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13420        int curAdj = app.curAdj;
13421        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13422            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13423
13424        mAdjSeq++;
13425
13426        boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj,
13427                TOP_APP, false);
13428        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13429            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13430        if (nowHidden != wasHidden) {
13431            // Changed to/from hidden state, so apps after it in the LRU
13432            // list may also be changed.
13433            updateOomAdjLocked();
13434        }
13435        return success;
13436    }
13437
13438    final void updateOomAdjLocked() {
13439        final ActivityRecord TOP_ACT = resumedAppLocked();
13440        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13441
13442        if (false) {
13443            RuntimeException e = new RuntimeException();
13444            e.fillInStackTrace();
13445            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13446        }
13447
13448        mAdjSeq++;
13449        mNewNumServiceProcs = 0;
13450
13451        // Let's determine how many processes we have running vs.
13452        // how many slots we have for background processes; we may want
13453        // to put multiple processes in a slot of there are enough of
13454        // them.
13455        int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13456                - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13457        int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots;
13458        if (emptyFactor < 1) emptyFactor = 1;
13459        int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13460        if (hiddenFactor < 1) hiddenFactor = 1;
13461        int stepHidden = 0;
13462        int stepEmpty = 0;
13463        final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13464        final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13465        int numHidden = 0;
13466        int numEmpty = 0;
13467        int numTrimming = 0;
13468
13469        mNumNonHiddenProcs = 0;
13470        mNumHiddenProcs = 0;
13471
13472        // First update the OOM adjustment for each of the
13473        // application processes based on their current state.
13474        int i = mLruProcesses.size();
13475        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13476        int nextHiddenAdj = curHiddenAdj+1;
13477        int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13478        int nextEmptyAdj = curEmptyAdj+2;
13479        while (i > 0) {
13480            i--;
13481            ProcessRecord app = mLruProcesses.get(i);
13482            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13483            updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true);
13484            if (!app.killedBackground) {
13485                if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13486                    // This process was assigned as a hidden process...  step the
13487                    // hidden level.
13488                    mNumHiddenProcs++;
13489                    if (curHiddenAdj != nextHiddenAdj) {
13490                        stepHidden++;
13491                        if (stepHidden >= hiddenFactor) {
13492                            stepHidden = 0;
13493                            curHiddenAdj = nextHiddenAdj;
13494                            nextHiddenAdj += 2;
13495                            if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13496                                nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13497                            }
13498                        }
13499                    }
13500                    numHidden++;
13501                    if (numHidden > hiddenProcessLimit) {
13502                        Slog.i(TAG, "No longer want " + app.processName
13503                                + " (pid " + app.pid + "): hidden #" + numHidden);
13504                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13505                                app.processName, app.setAdj, "too many background");
13506                        app.killedBackground = true;
13507                        Process.killProcessQuiet(app.pid);
13508                    }
13509                } else {
13510                    if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13511                        // This process was assigned as an empty process...  step the
13512                        // empty level.
13513                        if (curEmptyAdj != nextEmptyAdj) {
13514                            stepEmpty++;
13515                            if (stepEmpty >= emptyFactor) {
13516                                stepEmpty = 0;
13517                                curEmptyAdj = nextEmptyAdj;
13518                                nextEmptyAdj += 2;
13519                                if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13520                                    nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13521                                }
13522                            }
13523                        }
13524                    } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13525                        mNumNonHiddenProcs++;
13526                    }
13527                    if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13528                        numEmpty++;
13529                        if (numEmpty > emptyProcessLimit) {
13530                            Slog.i(TAG, "No longer want " + app.processName
13531                                    + " (pid " + app.pid + "): empty #" + numEmpty);
13532                            EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13533                                    app.processName, app.setAdj, "too many background");
13534                            app.killedBackground = true;
13535                            Process.killProcessQuiet(app.pid);
13536                        }
13537                    }
13538                }
13539                if (app.isolated && app.services.size() <= 0) {
13540                    // If this is an isolated process, and there are no
13541                    // services running in it, then the process is no longer
13542                    // needed.  We agressively kill these because we can by
13543                    // definition not re-use the same process again, and it is
13544                    // good to avoid having whatever code was running in them
13545                    // left sitting around after no longer needed.
13546                    Slog.i(TAG, "Isolated process " + app.processName
13547                            + " (pid " + app.pid + ") no longer needed");
13548                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13549                            app.processName, app.setAdj, "isolated not needed");
13550                    app.killedBackground = true;
13551                    Process.killProcessQuiet(app.pid);
13552                }
13553                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13554                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13555                        && !app.killedBackground) {
13556                    numTrimming++;
13557                }
13558            }
13559        }
13560
13561        mNumServiceProcs = mNewNumServiceProcs;
13562
13563        // Now determine the memory trimming level of background processes.
13564        // Unfortunately we need to start at the back of the list to do this
13565        // properly.  We only do this if the number of background apps we
13566        // are managing to keep around is less than half the maximum we desire;
13567        // if we are keeping a good number around, we'll let them use whatever
13568        // memory they want.
13569        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4)
13570                && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) {
13571            final int numHiddenAndEmpty = numHidden + numEmpty;
13572            final int N = mLruProcesses.size();
13573            int factor = numTrimming/3;
13574            int minFactor = 2;
13575            if (mHomeProcess != null) minFactor++;
13576            if (mPreviousProcess != null) minFactor++;
13577            if (factor < minFactor) factor = minFactor;
13578            int step = 0;
13579            int fgTrimLevel;
13580            if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) {
13581                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13582            } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) {
13583                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13584            } else {
13585                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13586            }
13587            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13588            for (i=0; i<N; i++) {
13589                ProcessRecord app = mLruProcesses.get(i);
13590                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13591                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13592                        && !app.killedBackground) {
13593                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
13594                        try {
13595                            app.thread.scheduleTrimMemory(curLevel);
13596                        } catch (RemoteException e) {
13597                        }
13598                        if (false) {
13599                            // For now we won't do this; our memory trimming seems
13600                            // to be good enough at this point that destroying
13601                            // activities causes more harm than good.
13602                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13603                                    && app != mHomeProcess && app != mPreviousProcess) {
13604                                // Need to do this on its own message because the stack may not
13605                                // be in a consistent state at this point.
13606                                // For these apps we will also finish their activities
13607                                // to help them free memory.
13608                                mMainStack.scheduleDestroyActivities(app, false, "trim");
13609                            }
13610                        }
13611                    }
13612                    app.trimMemoryLevel = curLevel;
13613                    step++;
13614                    if (step >= factor) {
13615                        step = 0;
13616                        switch (curLevel) {
13617                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13618                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13619                                break;
13620                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13621                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13622                                break;
13623                        }
13624                    }
13625                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13626                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13627                            && app.thread != null) {
13628                        try {
13629                            app.thread.scheduleTrimMemory(
13630                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13631                        } catch (RemoteException e) {
13632                        }
13633                    }
13634                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13635                } else {
13636                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13637                            && app.pendingUiClean) {
13638                        // If this application is now in the background and it
13639                        // had done UI, then give it the special trim level to
13640                        // have it free UI resources.
13641                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13642                        if (app.trimMemoryLevel < level && app.thread != null) {
13643                            try {
13644                                app.thread.scheduleTrimMemory(level);
13645                            } catch (RemoteException e) {
13646                            }
13647                        }
13648                        app.pendingUiClean = false;
13649                    }
13650                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13651                        try {
13652                            app.thread.scheduleTrimMemory(fgTrimLevel);
13653                        } catch (RemoteException e) {
13654                        }
13655                    }
13656                    app.trimMemoryLevel = fgTrimLevel;
13657                }
13658            }
13659        } else {
13660            final int N = mLruProcesses.size();
13661            for (i=0; i<N; i++) {
13662                ProcessRecord app = mLruProcesses.get(i);
13663                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13664                        && app.pendingUiClean) {
13665                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13666                            && app.thread != null) {
13667                        try {
13668                            app.thread.scheduleTrimMemory(
13669                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13670                        } catch (RemoteException e) {
13671                        }
13672                    }
13673                    app.pendingUiClean = false;
13674                }
13675                app.trimMemoryLevel = 0;
13676            }
13677        }
13678
13679        if (mAlwaysFinishActivities) {
13680            // Need to do this on its own message because the stack may not
13681            // be in a consistent state at this point.
13682            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13683        }
13684    }
13685
13686    final void trimApplications() {
13687        synchronized (this) {
13688            int i;
13689
13690            // First remove any unused application processes whose package
13691            // has been removed.
13692            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13693                final ProcessRecord app = mRemovedProcesses.get(i);
13694                if (app.activities.size() == 0
13695                        && app.curReceiver == null && app.services.size() == 0) {
13696                    Slog.i(
13697                        TAG, "Exiting empty application process "
13698                        + app.processName + " ("
13699                        + (app.thread != null ? app.thread.asBinder() : null)
13700                        + ")\n");
13701                    if (app.pid > 0 && app.pid != MY_PID) {
13702                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13703                                app.processName, app.setAdj, "empty");
13704                        Process.killProcessQuiet(app.pid);
13705                    } else {
13706                        try {
13707                            app.thread.scheduleExit();
13708                        } catch (Exception e) {
13709                            // Ignore exceptions.
13710                        }
13711                    }
13712                    cleanUpApplicationRecordLocked(app, false, true, -1);
13713                    mRemovedProcesses.remove(i);
13714
13715                    if (app.persistent) {
13716                        if (app.persistent) {
13717                            addAppLocked(app.info, false);
13718                        }
13719                    }
13720                }
13721            }
13722
13723            // Now update the oom adj for all processes.
13724            updateOomAdjLocked();
13725        }
13726    }
13727
13728    /** This method sends the specified signal to each of the persistent apps */
13729    public void signalPersistentProcesses(int sig) throws RemoteException {
13730        if (sig != Process.SIGNAL_USR1) {
13731            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13732        }
13733
13734        synchronized (this) {
13735            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13736                    != PackageManager.PERMISSION_GRANTED) {
13737                throw new SecurityException("Requires permission "
13738                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13739            }
13740
13741            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13742                ProcessRecord r = mLruProcesses.get(i);
13743                if (r.thread != null && r.persistent) {
13744                    Process.sendSignal(r.pid, sig);
13745                }
13746            }
13747        }
13748    }
13749
13750    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13751        if (proc == null || proc == mProfileProc) {
13752            proc = mProfileProc;
13753            path = mProfileFile;
13754            profileType = mProfileType;
13755            clearProfilerLocked();
13756        }
13757        if (proc == null) {
13758            return;
13759        }
13760        try {
13761            proc.thread.profilerControl(false, path, null, profileType);
13762        } catch (RemoteException e) {
13763            throw new IllegalStateException("Process disappeared");
13764        }
13765    }
13766
13767    private void clearProfilerLocked() {
13768        if (mProfileFd != null) {
13769            try {
13770                mProfileFd.close();
13771            } catch (IOException e) {
13772            }
13773        }
13774        mProfileApp = null;
13775        mProfileProc = null;
13776        mProfileFile = null;
13777        mProfileType = 0;
13778        mAutoStopProfiler = false;
13779    }
13780
13781    public boolean profileControl(String process, int userId, boolean start,
13782            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
13783
13784        try {
13785            synchronized (this) {
13786                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13787                // its own permission.
13788                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13789                        != PackageManager.PERMISSION_GRANTED) {
13790                    throw new SecurityException("Requires permission "
13791                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13792                }
13793
13794                if (start && fd == null) {
13795                    throw new IllegalArgumentException("null fd");
13796                }
13797
13798                ProcessRecord proc = null;
13799                if (process != null) {
13800                    proc = findProcessLocked(process, userId, "profileControl");
13801                }
13802
13803                if (start && (proc == null || proc.thread == null)) {
13804                    throw new IllegalArgumentException("Unknown process: " + process);
13805                }
13806
13807                if (start) {
13808                    stopProfilerLocked(null, null, 0);
13809                    setProfileApp(proc.info, proc.processName, path, fd, false);
13810                    mProfileProc = proc;
13811                    mProfileType = profileType;
13812                    try {
13813                        fd = fd.dup();
13814                    } catch (IOException e) {
13815                        fd = null;
13816                    }
13817                    proc.thread.profilerControl(start, path, fd, profileType);
13818                    fd = null;
13819                    mProfileFd = null;
13820                } else {
13821                    stopProfilerLocked(proc, path, profileType);
13822                    if (fd != null) {
13823                        try {
13824                            fd.close();
13825                        } catch (IOException e) {
13826                        }
13827                    }
13828                }
13829
13830                return true;
13831            }
13832        } catch (RemoteException e) {
13833            throw new IllegalStateException("Process disappeared");
13834        } finally {
13835            if (fd != null) {
13836                try {
13837                    fd.close();
13838                } catch (IOException e) {
13839                }
13840            }
13841        }
13842    }
13843
13844    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
13845        userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(),
13846                userId, true, true, callName, null);
13847        ProcessRecord proc = null;
13848        try {
13849            int pid = Integer.parseInt(process);
13850            synchronized (mPidsSelfLocked) {
13851                proc = mPidsSelfLocked.get(pid);
13852            }
13853        } catch (NumberFormatException e) {
13854        }
13855
13856        if (proc == null) {
13857            HashMap<String, SparseArray<ProcessRecord>> all
13858                    = mProcessNames.getMap();
13859            SparseArray<ProcessRecord> procs = all.get(process);
13860            if (procs != null && procs.size() > 0) {
13861                proc = procs.valueAt(0);
13862                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
13863                    for (int i=1; i<procs.size(); i++) {
13864                        ProcessRecord thisProc = procs.valueAt(i);
13865                        if (thisProc.userId == userId) {
13866                            proc = thisProc;
13867                            break;
13868                        }
13869                    }
13870                }
13871            }
13872        }
13873
13874        return proc;
13875    }
13876
13877    public boolean dumpHeap(String process, int userId, boolean managed,
13878            String path, ParcelFileDescriptor fd) throws RemoteException {
13879
13880        try {
13881            synchronized (this) {
13882                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13883                // its own permission (same as profileControl).
13884                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13885                        != PackageManager.PERMISSION_GRANTED) {
13886                    throw new SecurityException("Requires permission "
13887                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13888                }
13889
13890                if (fd == null) {
13891                    throw new IllegalArgumentException("null fd");
13892                }
13893
13894                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
13895                if (proc == null || proc.thread == null) {
13896                    throw new IllegalArgumentException("Unknown process: " + process);
13897                }
13898
13899                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13900                if (!isDebuggable) {
13901                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13902                        throw new SecurityException("Process not debuggable: " + proc);
13903                    }
13904                }
13905
13906                proc.thread.dumpHeap(managed, path, fd);
13907                fd = null;
13908                return true;
13909            }
13910        } catch (RemoteException e) {
13911            throw new IllegalStateException("Process disappeared");
13912        } finally {
13913            if (fd != null) {
13914                try {
13915                    fd.close();
13916                } catch (IOException e) {
13917                }
13918            }
13919        }
13920    }
13921
13922    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13923    public void monitor() {
13924        synchronized (this) { }
13925    }
13926
13927    void onCoreSettingsChange(Bundle settings) {
13928        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13929            ProcessRecord processRecord = mLruProcesses.get(i);
13930            try {
13931                if (processRecord.thread != null) {
13932                    processRecord.thread.setCoreSettings(settings);
13933                }
13934            } catch (RemoteException re) {
13935                /* ignore */
13936            }
13937        }
13938    }
13939
13940    // Multi-user methods
13941
13942    @Override
13943    public boolean switchUser(int userId) {
13944        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13945                != PackageManager.PERMISSION_GRANTED) {
13946            String msg = "Permission Denial: switchUser() from pid="
13947                    + Binder.getCallingPid()
13948                    + ", uid=" + Binder.getCallingUid()
13949                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13950            Slog.w(TAG, msg);
13951            throw new SecurityException(msg);
13952        }
13953
13954        final long ident = Binder.clearCallingIdentity();
13955        try {
13956            synchronized (this) {
13957                final int oldUserId = mCurrentUserId;
13958                if (oldUserId == userId) {
13959                    return true;
13960                }
13961
13962                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
13963                if (userInfo == null) {
13964                    Slog.w(TAG, "No user info for user #" + userId);
13965                    return false;
13966                }
13967
13968                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
13969                        R.anim.screen_user_enter);
13970
13971                // If the user we are switching to is not currently started, then
13972                // we need to start it now.
13973                if (mStartedUsers.get(userId) == null) {
13974                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
13975                }
13976
13977                mCurrentUserId = userId;
13978                final Integer userIdInt = Integer.valueOf(userId);
13979                mUserLru.remove(userIdInt);
13980                mUserLru.add(userIdInt);
13981
13982                final UserStartedState uss = mStartedUsers.get(userId);
13983
13984                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
13985                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
13986                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
13987                        oldUserId, userId, uss));
13988                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
13989                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
13990                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13991                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13992                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
13993                broadcastIntentLocked(null, null, intent,
13994                        null, null, 0, null, null, null,
13995                        false, false, MY_PID, Process.SYSTEM_UID, userId);
13996
13997                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
13998                    if (userId != 0) {
13999                        intent = new Intent(Intent.ACTION_USER_INITIALIZE);
14000                        broadcastIntentLocked(null, null, intent, null,
14001                                new IIntentReceiver.Stub() {
14002                                    public void performReceive(Intent intent, int resultCode,
14003                                            String data, Bundle extras, boolean ordered,
14004                                            boolean sticky, int sendingUser) {
14005                                        synchronized (ActivityManagerService.this) {
14006                                            getUserManagerLocked().makeInitialized(userInfo.id);
14007                                        }
14008                                    }
14009                                }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
14010                                userId);
14011                    } else {
14012                        getUserManagerLocked().makeInitialized(userInfo.id);
14013                    }
14014                }
14015
14016                boolean haveActivities = mMainStack.switchUserLocked(userId, uss);
14017                if (!haveActivities) {
14018                    startHomeActivityLocked(userId);
14019                }
14020
14021                sendUserSwitchBroadcastsLocked(oldUserId, userId);
14022            }
14023        } finally {
14024            Binder.restoreCallingIdentity(ident);
14025        }
14026
14027        return true;
14028    }
14029
14030    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
14031        long ident = Binder.clearCallingIdentity();
14032        try {
14033            Intent intent;
14034            if (oldUserId >= 0) {
14035                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
14036                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14037                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
14038                broadcastIntentLocked(null, null, intent,
14039                        null, null, 0, null, null, null,
14040                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
14041            }
14042            if (newUserId >= 0) {
14043                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
14044                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14045                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14046                broadcastIntentLocked(null, null, intent,
14047                        null, null, 0, null, null, null,
14048                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
14049                intent = new Intent(Intent.ACTION_USER_SWITCHED);
14050                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14051                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14052                broadcastIntentLocked(null, null, intent,
14053                        null, null, 0, null, null,
14054                        android.Manifest.permission.MANAGE_USERS,
14055                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14056            }
14057        } finally {
14058            Binder.restoreCallingIdentity(ident);
14059        }
14060    }
14061
14062    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
14063            final int newUserId) {
14064        final int N = mUserSwitchObservers.beginBroadcast();
14065        if (N > 0) {
14066            final IRemoteCallback callback = new IRemoteCallback.Stub() {
14067                int mCount = 0;
14068                @Override
14069                public void sendResult(Bundle data) throws RemoteException {
14070                    synchronized (ActivityManagerService.this) {
14071                        if (mCurUserSwitchCallback == this) {
14072                            mCount++;
14073                            if (mCount == N) {
14074                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14075                            }
14076                        }
14077                    }
14078                }
14079            };
14080            synchronized (this) {
14081                mCurUserSwitchCallback = callback;
14082            }
14083            for (int i=0; i<N; i++) {
14084                try {
14085                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
14086                            newUserId, callback);
14087                } catch (RemoteException e) {
14088                }
14089            }
14090        } else {
14091            synchronized (this) {
14092                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14093            }
14094        }
14095        mUserSwitchObservers.finishBroadcast();
14096    }
14097
14098    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14099        synchronized (this) {
14100            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
14101            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14102        }
14103    }
14104
14105    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
14106        mCurUserSwitchCallback = null;
14107        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14108        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
14109                oldUserId, newUserId, uss));
14110    }
14111
14112    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14113        final int N = mUserSwitchObservers.beginBroadcast();
14114        for (int i=0; i<N; i++) {
14115            try {
14116                mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
14117            } catch (RemoteException e) {
14118            }
14119        }
14120        mUserSwitchObservers.finishBroadcast();
14121        synchronized (this) {
14122            mWindowManager.stopFreezingScreen();
14123        }
14124    }
14125
14126    void finishUserSwitch(UserStartedState uss) {
14127        synchronized (this) {
14128            if (uss.mState == UserStartedState.STATE_BOOTING
14129                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
14130                uss.mState = UserStartedState.STATE_RUNNING;
14131                final int userId = uss.mHandle.getIdentifier();
14132                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
14133                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14134                broadcastIntentLocked(null, null, intent,
14135                        null, null, 0, null, null,
14136                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
14137                        false, false, MY_PID, Process.SYSTEM_UID, userId);
14138            }
14139        }
14140    }
14141
14142    @Override
14143    public int stopUser(final int userId, final IStopUserCallback callback) {
14144        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14145                != PackageManager.PERMISSION_GRANTED) {
14146            String msg = "Permission Denial: switchUser() from pid="
14147                    + Binder.getCallingPid()
14148                    + ", uid=" + Binder.getCallingUid()
14149                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14150            Slog.w(TAG, msg);
14151            throw new SecurityException(msg);
14152        }
14153        if (userId <= 0) {
14154            throw new IllegalArgumentException("Can't stop primary user " + userId);
14155        }
14156        synchronized (this) {
14157            if (mCurrentUserId == userId) {
14158                return ActivityManager.USER_OP_IS_CURRENT;
14159            }
14160
14161            final UserStartedState uss = mStartedUsers.get(userId);
14162            if (uss == null) {
14163                // User is not started, nothing to do...  but we do need to
14164                // callback if requested.
14165                if (callback != null) {
14166                    mHandler.post(new Runnable() {
14167                        @Override
14168                        public void run() {
14169                            try {
14170                                callback.userStopped(userId);
14171                            } catch (RemoteException e) {
14172                            }
14173                        }
14174                    });
14175                }
14176                return ActivityManager.USER_OP_SUCCESS;
14177            }
14178
14179            if (callback != null) {
14180                uss.mStopCallbacks.add(callback);
14181            }
14182
14183            if (uss.mState != UserStartedState.STATE_STOPPING) {
14184                uss.mState = UserStartedState.STATE_STOPPING;
14185
14186                long ident = Binder.clearCallingIdentity();
14187                try {
14188                    // Inform of user switch
14189                    Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
14190                    final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() {
14191                        @Override
14192                        public void performReceive(Intent intent, int resultCode, String data,
14193                                Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14194                            finishUserStop(uss);
14195                        }
14196                    };
14197                    broadcastIntentLocked(null, null, intent,
14198                            null, resultReceiver, 0, null, null, null,
14199                            true, false, MY_PID, Process.SYSTEM_UID, userId);
14200                } finally {
14201                    Binder.restoreCallingIdentity(ident);
14202                }
14203            }
14204        }
14205
14206        return ActivityManager.USER_OP_SUCCESS;
14207    }
14208
14209    void finishUserStop(UserStartedState uss) {
14210        final int userId = uss.mHandle.getIdentifier();
14211        boolean stopped;
14212        ArrayList<IStopUserCallback> callbacks;
14213        synchronized (this) {
14214            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
14215            if (uss.mState != UserStartedState.STATE_STOPPING
14216                    || mStartedUsers.get(userId) != uss) {
14217                stopped = false;
14218            } else {
14219                stopped = true;
14220                // User can no longer run.
14221                mStartedUsers.remove(userId);
14222
14223                // Clean up all state and processes associated with the user.
14224                // Kill all the processes for the user.
14225                forceStopUserLocked(userId);
14226            }
14227        }
14228
14229        for (int i=0; i<callbacks.size(); i++) {
14230            try {
14231                if (stopped) callbacks.get(i).userStopped(userId);
14232                else callbacks.get(i).userStopAborted(userId);
14233            } catch (RemoteException e) {
14234            }
14235        }
14236    }
14237
14238    @Override
14239    public UserInfo getCurrentUser() {
14240        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14241                != PackageManager.PERMISSION_GRANTED) {
14242            String msg = "Permission Denial: getCurrentUser() from pid="
14243                    + Binder.getCallingPid()
14244                    + ", uid=" + Binder.getCallingUid()
14245                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14246            Slog.w(TAG, msg);
14247            throw new SecurityException(msg);
14248        }
14249        synchronized (this) {
14250            return getUserManagerLocked().getUserInfo(mCurrentUserId);
14251        }
14252    }
14253
14254    @Override
14255    public boolean isUserRunning(int userId) {
14256        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14257                != PackageManager.PERMISSION_GRANTED) {
14258            String msg = "Permission Denial: isUserRunning() from pid="
14259                    + Binder.getCallingPid()
14260                    + ", uid=" + Binder.getCallingUid()
14261                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14262            Slog.w(TAG, msg);
14263            throw new SecurityException(msg);
14264        }
14265        synchronized (this) {
14266            return isUserRunningLocked(userId);
14267        }
14268    }
14269
14270    boolean isUserRunningLocked(int userId) {
14271        UserStartedState state = mStartedUsers.get(userId);
14272        return state != null && state.mState != UserStartedState.STATE_STOPPING;
14273    }
14274
14275    @Override
14276    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
14277        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14278                != PackageManager.PERMISSION_GRANTED) {
14279            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
14280                    + Binder.getCallingPid()
14281                    + ", uid=" + Binder.getCallingUid()
14282                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14283            Slog.w(TAG, msg);
14284            throw new SecurityException(msg);
14285        }
14286
14287        mUserSwitchObservers.register(observer);
14288    }
14289
14290    @Override
14291    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
14292        mUserSwitchObservers.unregister(observer);
14293    }
14294
14295    private boolean userExists(int userId) {
14296        if (userId == 0) {
14297            return true;
14298        }
14299        UserManagerService ums = getUserManagerLocked();
14300        return ums != null ? (ums.getUserInfo(userId) != null) : false;
14301    }
14302
14303    int[] getUsersLocked() {
14304        UserManagerService ums = getUserManagerLocked();
14305        return ums != null ? ums.getUserIds() : new int[] { 0 };
14306    }
14307
14308    UserManagerService getUserManagerLocked() {
14309        if (mUserManager == null) {
14310            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
14311            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
14312        }
14313        return mUserManager;
14314    }
14315
14316    private void checkValidCaller(int uid, int userId) {
14317        if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
14318
14319        throw new SecurityException("Caller uid=" + uid
14320                + " is not privileged to communicate with user=" + userId);
14321    }
14322
14323    private int applyUserId(int uid, int userId) {
14324        return UserHandle.getUid(userId, uid);
14325    }
14326
14327    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
14328        if (info == null) return null;
14329        ApplicationInfo newInfo = new ApplicationInfo(info);
14330        newInfo.uid = applyUserId(info.uid, userId);
14331        newInfo.dataDir = USER_DATA_DIR + userId + "/"
14332                + info.packageName;
14333        return newInfo;
14334    }
14335
14336    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
14337        if (aInfo == null
14338                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
14339            return aInfo;
14340        }
14341
14342        ActivityInfo info = new ActivityInfo(aInfo);
14343        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
14344        return info;
14345    }
14346}
14347