ActivityManagerService.java revision 0f42037eb7b5118015c2caca635538324ccf0ccf
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20
21import com.android.internal.R;
22import com.android.internal.os.BatteryStatsImpl;
23import com.android.internal.os.ProcessStats;
24import com.android.server.AttributeCache;
25import com.android.server.IntentResolver;
26import com.android.server.ProcessMap;
27import com.android.server.SystemServer;
28import com.android.server.Watchdog;
29import com.android.server.am.ActivityStack.ActivityState;
30import com.android.server.wm.WindowManagerService;
31
32import dalvik.system.Zygote;
33
34import android.app.Activity;
35import android.app.ActivityManager;
36import android.app.ActivityManagerNative;
37import android.app.ActivityOptions;
38import android.app.ActivityThread;
39import android.app.AlertDialog;
40import android.app.AppGlobals;
41import android.app.ApplicationErrorReport;
42import android.app.Dialog;
43import android.app.IActivityController;
44import android.app.IApplicationThread;
45import android.app.IInstrumentationWatcher;
46import android.app.INotificationManager;
47import android.app.IProcessObserver;
48import android.app.IServiceConnection;
49import android.app.IThumbnailReceiver;
50import android.app.Instrumentation;
51import android.app.Notification;
52import android.app.NotificationManager;
53import android.app.PendingIntent;
54import android.app.Service;
55import android.app.backup.IBackupManager;
56import android.content.ActivityNotFoundException;
57import android.content.BroadcastReceiver;
58import android.content.ClipData;
59import android.content.ComponentCallbacks2;
60import android.content.ComponentName;
61import android.content.ContentProvider;
62import android.content.ContentResolver;
63import android.content.Context;
64import android.content.DialogInterface;
65import android.content.IContentProvider;
66import android.content.IIntentReceiver;
67import android.content.IIntentSender;
68import android.content.Intent;
69import android.content.IntentFilter;
70import android.content.IntentSender;
71import android.content.pm.ActivityInfo;
72import android.content.pm.ApplicationInfo;
73import android.content.pm.ConfigurationInfo;
74import android.content.pm.IPackageDataObserver;
75import android.content.pm.IPackageManager;
76import android.content.pm.InstrumentationInfo;
77import android.content.pm.PackageInfo;
78import android.content.pm.PackageManager;
79import android.content.pm.PackageManager.NameNotFoundException;
80import android.content.pm.PathPermission;
81import android.content.pm.ProviderInfo;
82import android.content.pm.ResolveInfo;
83import android.content.pm.ServiceInfo;
84import android.content.pm.UserInfo;
85import android.content.res.CompatibilityInfo;
86import android.content.res.Configuration;
87import android.graphics.Bitmap;
88import android.net.Proxy;
89import android.net.ProxyProperties;
90import android.net.Uri;
91import android.os.Binder;
92import android.os.Build;
93import android.os.Bundle;
94import android.os.Debug;
95import android.os.DropBoxManager;
96import android.os.Environment;
97import android.os.FileObserver;
98import android.os.FileUtils;
99import android.os.Handler;
100import android.os.IBinder;
101import android.os.IPermissionController;
102import android.os.Looper;
103import android.os.Message;
104import android.os.Parcel;
105import android.os.ParcelFileDescriptor;
106import android.os.Process;
107import android.os.RemoteCallbackList;
108import android.os.RemoteException;
109import android.os.ServiceManager;
110import android.os.StrictMode;
111import android.os.SystemClock;
112import android.os.SystemProperties;
113import android.os.UserId;
114import android.provider.Settings;
115import android.text.format.Time;
116import android.util.EventLog;
117import android.util.Log;
118import android.util.Pair;
119import android.util.PrintWriterPrinter;
120import android.util.Slog;
121import android.util.SparseArray;
122import android.util.SparseIntArray;
123import android.util.TimeUtils;
124import android.view.Gravity;
125import android.view.LayoutInflater;
126import android.view.View;
127import android.view.WindowManager;
128import android.view.WindowManagerPolicy;
129
130import java.io.BufferedInputStream;
131import java.io.BufferedOutputStream;
132import java.io.BufferedReader;
133import java.io.DataInputStream;
134import java.io.DataOutputStream;
135import java.io.File;
136import java.io.FileDescriptor;
137import java.io.FileInputStream;
138import java.io.FileNotFoundException;
139import java.io.FileOutputStream;
140import java.io.IOException;
141import java.io.InputStreamReader;
142import java.io.PrintWriter;
143import java.io.StringWriter;
144import java.lang.ref.WeakReference;
145import java.util.ArrayList;
146import java.util.Collection;
147import java.util.Collections;
148import java.util.Comparator;
149import java.util.HashMap;
150import java.util.HashSet;
151import java.util.Iterator;
152import java.util.List;
153import java.util.Locale;
154import java.util.Map;
155import java.util.Map.Entry;
156import java.util.Set;
157import java.util.concurrent.atomic.AtomicBoolean;
158import java.util.concurrent.atomic.AtomicLong;
159
160public final class ActivityManagerService extends ActivityManagerNative
161        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
162    private static final String USER_DATA_DIR = "/data/user/";
163    static final String TAG = "ActivityManager";
164    static final String TAG_MU = "ActivityManagerServiceMU";
165    static final boolean DEBUG = false;
166    static final boolean localLOGV = DEBUG;
167    static final boolean DEBUG_SWITCH = localLOGV || false;
168    static final boolean DEBUG_TASKS = localLOGV || false;
169    static final boolean DEBUG_PAUSE = localLOGV || false;
170    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
171    static final boolean DEBUG_TRANSITION = localLOGV || false;
172    static final boolean DEBUG_BROADCAST = localLOGV || false;
173    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
174    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
175    static final boolean DEBUG_SERVICE = localLOGV || false;
176    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
177    static final boolean DEBUG_VISBILITY = localLOGV || false;
178    static final boolean DEBUG_PROCESSES = localLOGV || false;
179    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
180    static final boolean DEBUG_PROVIDER = localLOGV || false;
181    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
182    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
183    static final boolean DEBUG_RESULTS = localLOGV || false;
184    static final boolean DEBUG_BACKUP = localLOGV || false;
185    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
186    static final boolean DEBUG_POWER = localLOGV || false;
187    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
188    static final boolean DEBUG_MU = localLOGV || false;
189    static final boolean VALIDATE_TOKENS = false;
190    static final boolean SHOW_ACTIVITY_START_TIME = true;
191
192    // Control over CPU and battery monitoring.
193    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
194    static final boolean MONITOR_CPU_USAGE = true;
195    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
196    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
197    static final boolean MONITOR_THREAD_CPU_USAGE = false;
198
199    // The flags that are set for all calls we make to the package manager.
200    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
201
202    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
203
204    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
205
206    // Maximum number of recent tasks that we can remember.
207    static final int MAX_RECENT_TASKS = 20;
208
209    // Amount of time after a call to stopAppSwitches() during which we will
210    // prevent further untrusted switches from happening.
211    static final long APP_SWITCH_DELAY_TIME = 5*1000;
212
213    // How long we wait for a launched process to attach to the activity manager
214    // before we decide it's never going to come up for real.
215    static final int PROC_START_TIMEOUT = 10*1000;
216
217    // How long we wait for a launched process to attach to the activity manager
218    // before we decide it's never going to come up for real, when the process was
219    // started with a wrapper for instrumentation (such as Valgrind) because it
220    // could take much longer than usual.
221    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
222
223    // How long to wait after going idle before forcing apps to GC.
224    static final int GC_TIMEOUT = 5*1000;
225
226    // The minimum amount of time between successive GC requests for a process.
227    static final int GC_MIN_INTERVAL = 60*1000;
228
229    // The rate at which we check for apps using excessive power -- 15 mins.
230    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
231
232    // The minimum sample duration we will allow before deciding we have
233    // enough data on wake locks to start killing things.
234    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
235
236    // The minimum sample duration we will allow before deciding we have
237    // enough data on CPU usage to start killing things.
238    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
239
240    // How long we allow a receiver to run before giving up on it.
241    static final int BROADCAST_FG_TIMEOUT = 10*1000;
242    static final int BROADCAST_BG_TIMEOUT = 60*1000;
243
244    // How long we wait for a service to finish executing.
245    static final int SERVICE_TIMEOUT = 20*1000;
246
247    // How long a service needs to be running until restarting its process
248    // is no longer considered to be a relaunch of the service.
249    static final int SERVICE_RESTART_DURATION = 5*1000;
250
251    // How long a service needs to be running until it will start back at
252    // SERVICE_RESTART_DURATION after being killed.
253    static final int SERVICE_RESET_RUN_DURATION = 60*1000;
254
255    // Multiplying factor to increase restart duration time by, for each time
256    // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
257    static final int SERVICE_RESTART_DURATION_FACTOR = 4;
258
259    // The minimum amount of time between restarting services that we allow.
260    // That is, when multiple services are restarting, we won't allow each
261    // to restart less than this amount of time from the last one.
262    static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
263
264    // Maximum amount of time for there to be no activity on a service before
265    // we consider it non-essential and allow its process to go on the
266    // LRU background list.
267    static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
268
269    // How long we wait until we timeout on key dispatching.
270    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
271
272    // How long we wait until we timeout on key dispatching during instrumentation.
273    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
274
275    static final int MY_PID = Process.myPid();
276
277    static final String[] EMPTY_STRING_ARRAY = new String[0];
278
279    public ActivityStack mMainStack;
280
281    private final boolean mHeadless;
282
283    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
284    // default actuion automatically.  Important for devices without direct input
285    // devices.
286    private boolean mShowDialogs = true;
287
288    /**
289     * Description of a request to start a new activity, which has been held
290     * due to app switches being disabled.
291     */
292    static class PendingActivityLaunch {
293        ActivityRecord r;
294        ActivityRecord sourceRecord;
295        int startFlags;
296    }
297
298    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
299            = new ArrayList<PendingActivityLaunch>();
300
301
302    BroadcastQueue mFgBroadcastQueue;
303    BroadcastQueue mBgBroadcastQueue;
304    // Convenient for easy iteration over the queues. Foreground is first
305    // so that dispatch of foreground broadcasts gets precedence.
306    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
307
308    BroadcastQueue broadcastQueueForIntent(Intent intent) {
309        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
310        if (DEBUG_BACKGROUND_BROADCAST) {
311            Slog.i(TAG, "Broadcast intent " + intent + " on "
312                    + (isFg ? "foreground" : "background")
313                    + " queue");
314        }
315        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
316    }
317
318    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
319        for (BroadcastQueue queue : mBroadcastQueues) {
320            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
321            if (r != null) {
322                return r;
323            }
324        }
325        return null;
326    }
327
328    /**
329     * Activity we have told the window manager to have key focus.
330     */
331    ActivityRecord mFocusedActivity = null;
332    /**
333     * List of intents that were used to start the most recent tasks.
334     */
335    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
336
337    /**
338     * Process management.
339     */
340    final ProcessList mProcessList = new ProcessList();
341
342    /**
343     * All of the applications we currently have running organized by name.
344     * The keys are strings of the application package name (as
345     * returned by the package manager), and the keys are ApplicationRecord
346     * objects.
347     */
348    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
349
350    /**
351     * The currently running isolated processes.
352     */
353    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
354
355    /**
356     * Counter for assigning isolated process uids, to avoid frequently reusing the
357     * same ones.
358     */
359    int mNextIsolatedProcessUid = 0;
360
361    /**
362     * The currently running heavy-weight process, if any.
363     */
364    ProcessRecord mHeavyWeightProcess = null;
365
366    /**
367     * The last time that various processes have crashed.
368     */
369    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
370
371    /**
372     * Set of applications that we consider to be bad, and will reject
373     * incoming broadcasts from (which the user has no control over).
374     * Processes are added to this set when they have crashed twice within
375     * a minimum amount of time; they are removed from it when they are
376     * later restarted (hopefully due to some user action).  The value is the
377     * time it was added to the list.
378     */
379    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
380
381    /**
382     * All of the processes we currently have running organized by pid.
383     * The keys are the pid running the application.
384     *
385     * <p>NOTE: This object is protected by its own lock, NOT the global
386     * activity manager lock!
387     */
388    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
389
390    /**
391     * All of the processes that have been forced to be foreground.  The key
392     * is the pid of the caller who requested it (we hold a death
393     * link on it).
394     */
395    abstract class ForegroundToken implements IBinder.DeathRecipient {
396        int pid;
397        IBinder token;
398    }
399    final SparseArray<ForegroundToken> mForegroundProcesses
400            = new SparseArray<ForegroundToken>();
401
402    /**
403     * List of records for processes that someone had tried to start before the
404     * system was ready.  We don't start them at that point, but ensure they
405     * are started by the time booting is complete.
406     */
407    final ArrayList<ProcessRecord> mProcessesOnHold
408            = new ArrayList<ProcessRecord>();
409
410    /**
411     * List of persistent applications that are in the process
412     * of being started.
413     */
414    final ArrayList<ProcessRecord> mPersistentStartingProcesses
415            = new ArrayList<ProcessRecord>();
416
417    /**
418     * Processes that are being forcibly torn down.
419     */
420    final ArrayList<ProcessRecord> mRemovedProcesses
421            = new ArrayList<ProcessRecord>();
422
423    /**
424     * List of running applications, sorted by recent usage.
425     * The first entry in the list is the least recently used.
426     * It contains ApplicationRecord objects.  This list does NOT include
427     * any persistent application records (since we never want to exit them).
428     */
429    final ArrayList<ProcessRecord> mLruProcesses
430            = new ArrayList<ProcessRecord>();
431
432    /**
433     * List of processes that should gc as soon as things are idle.
434     */
435    final ArrayList<ProcessRecord> mProcessesToGc
436            = new ArrayList<ProcessRecord>();
437
438    /**
439     * This is the process holding what we currently consider to be
440     * the "home" activity.
441     */
442    ProcessRecord mHomeProcess;
443
444    /**
445     * This is the process holding the activity the user last visited that
446     * is in a different process from the one they are currently in.
447     */
448    ProcessRecord mPreviousProcess;
449
450    /**
451     * The time at which the previous process was last visible.
452     */
453    long mPreviousProcessVisibleTime;
454
455    /**
456     * Packages that the user has asked to have run in screen size
457     * compatibility mode instead of filling the screen.
458     */
459    final CompatModePackages mCompatModePackages;
460
461    /**
462     * Set of PendingResultRecord objects that are currently active.
463     */
464    final HashSet mPendingResultRecords = new HashSet();
465
466    /**
467     * Set of IntentSenderRecord objects that are currently active.
468     */
469    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
470            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
471
472    /**
473     * Fingerprints (hashCode()) of stack traces that we've
474     * already logged DropBox entries for.  Guarded by itself.  If
475     * something (rogue user app) forces this over
476     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
477     */
478    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
479    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
480
481    /**
482     * Strict Mode background batched logging state.
483     *
484     * The string buffer is guarded by itself, and its lock is also
485     * used to determine if another batched write is already
486     * in-flight.
487     */
488    private final StringBuilder mStrictModeBuffer = new StringBuilder();
489
490    /**
491     * Keeps track of all IIntentReceivers that have been registered for
492     * broadcasts.  Hash keys are the receiver IBinder, hash value is
493     * a ReceiverList.
494     */
495    final HashMap mRegisteredReceivers = new HashMap();
496
497    /**
498     * Resolver for broadcast intents to registered receivers.
499     * Holds BroadcastFilter (subclass of IntentFilter).
500     */
501    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
502            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
503        @Override
504        protected boolean allowFilterResult(
505                BroadcastFilter filter, List<BroadcastFilter> dest) {
506            IBinder target = filter.receiverList.receiver.asBinder();
507            for (int i=dest.size()-1; i>=0; i--) {
508                if (dest.get(i).receiverList.receiver.asBinder() == target) {
509                    return false;
510                }
511            }
512            return true;
513        }
514
515        @Override
516        protected String packageForFilter(BroadcastFilter filter) {
517            return filter.packageName;
518        }
519    };
520
521    /**
522     * State of all active sticky broadcasts.  Keys are the action of the
523     * sticky Intent, values are an ArrayList of all broadcasted intents with
524     * that action (which should usually be one).
525     */
526    final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
527            new HashMap<String, ArrayList<Intent>>();
528
529    final ServiceMap mServiceMap = new ServiceMap();
530
531    /**
532     * All currently bound service connections.  Keys are the IBinder of
533     * the client's IServiceConnection.
534     */
535    final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
536            = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
537
538    /**
539     * List of services that we have been asked to start,
540     * but haven't yet been able to.  It is used to hold start requests
541     * while waiting for their corresponding application thread to get
542     * going.
543     */
544    final ArrayList<ServiceRecord> mPendingServices
545            = new ArrayList<ServiceRecord>();
546
547    /**
548     * List of services that are scheduled to restart following a crash.
549     */
550    final ArrayList<ServiceRecord> mRestartingServices
551            = new ArrayList<ServiceRecord>();
552
553    /**
554     * List of services that are in the process of being stopped.
555     */
556    final ArrayList<ServiceRecord> mStoppingServices
557            = new ArrayList<ServiceRecord>();
558
559    /**
560     * Backup/restore process management
561     */
562    String mBackupAppName = null;
563    BackupRecord mBackupTarget = null;
564
565    /**
566     * List of PendingThumbnailsRecord objects of clients who are still
567     * waiting to receive all of the thumbnails for a task.
568     */
569    final ArrayList mPendingThumbnails = new ArrayList();
570
571    /**
572     * List of HistoryRecord objects that have been finished and must
573     * still report back to a pending thumbnail receiver.
574     */
575    final ArrayList mCancelledThumbnails = new ArrayList();
576
577    final ProviderMap mProviderMap = new ProviderMap();
578
579    /**
580     * List of content providers who have clients waiting for them.  The
581     * application is currently being launched and the provider will be
582     * removed from this list once it is published.
583     */
584    final ArrayList<ContentProviderRecord> mLaunchingProviders
585            = new ArrayList<ContentProviderRecord>();
586
587    /**
588     * Global set of specific Uri permissions that have been granted.
589     */
590    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
591            = new SparseArray<HashMap<Uri, UriPermission>>();
592
593    CoreSettingsObserver mCoreSettingsObserver;
594
595    /**
596     * Thread-local storage used to carry caller permissions over through
597     * indirect content-provider access.
598     * @see #ActivityManagerService.openContentUri()
599     */
600    private class Identity {
601        public int pid;
602        public int uid;
603
604        Identity(int _pid, int _uid) {
605            pid = _pid;
606            uid = _uid;
607        }
608    }
609
610    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
611
612    /**
613     * All information we have collected about the runtime performance of
614     * any user id that can impact battery performance.
615     */
616    final BatteryStatsService mBatteryStatsService;
617
618    /**
619     * information about component usage
620     */
621    final UsageStatsService mUsageStatsService;
622
623    /**
624     * Current configuration information.  HistoryRecord objects are given
625     * a reference to this object to indicate which configuration they are
626     * currently running in, so this object must be kept immutable.
627     */
628    Configuration mConfiguration = new Configuration();
629
630    /**
631     * Current sequencing integer of the configuration, for skipping old
632     * configurations.
633     */
634    int mConfigurationSeq = 0;
635
636    /**
637     * Hardware-reported OpenGLES version.
638     */
639    final int GL_ES_VERSION;
640
641    /**
642     * List of initialization arguments to pass to all processes when binding applications to them.
643     * For example, references to the commonly used services.
644     */
645    HashMap<String, IBinder> mAppBindArgs;
646
647    /**
648     * Temporary to avoid allocations.  Protected by main lock.
649     */
650    final StringBuilder mStringBuilder = new StringBuilder(256);
651
652    /**
653     * Used to control how we initialize the service.
654     */
655    boolean mStartRunning = false;
656    ComponentName mTopComponent;
657    String mTopAction;
658    String mTopData;
659    boolean mProcessesReady = false;
660    boolean mSystemReady = false;
661    boolean mBooting = false;
662    boolean mWaitingUpdate = false;
663    boolean mDidUpdate = false;
664    boolean mOnBattery = false;
665    boolean mLaunchWarningShown = false;
666
667    Context mContext;
668
669    int mFactoryTest;
670
671    boolean mCheckedForSetup;
672
673    /**
674     * The time at which we will allow normal application switches again,
675     * after a call to {@link #stopAppSwitches()}.
676     */
677    long mAppSwitchesAllowedTime;
678
679    /**
680     * This is set to true after the first switch after mAppSwitchesAllowedTime
681     * is set; any switches after that will clear the time.
682     */
683    boolean mDidAppSwitch;
684
685    /**
686     * Last time (in realtime) at which we checked for power usage.
687     */
688    long mLastPowerCheckRealtime;
689
690    /**
691     * Last time (in uptime) at which we checked for power usage.
692     */
693    long mLastPowerCheckUptime;
694
695    /**
696     * Set while we are wanting to sleep, to prevent any
697     * activities from being started/resumed.
698     */
699    boolean mSleeping = false;
700
701    /**
702     * State of external calls telling us if the device is asleep.
703     */
704    boolean mWentToSleep = false;
705
706    /**
707     * State of external call telling us if the lock screen is shown.
708     */
709    boolean mLockScreenShown = false;
710
711    /**
712     * Set if we are shutting down the system, similar to sleeping.
713     */
714    boolean mShuttingDown = false;
715
716    /**
717     * Task identifier that activities are currently being started
718     * in.  Incremented each time a new task is created.
719     * todo: Replace this with a TokenSpace class that generates non-repeating
720     * integers that won't wrap.
721     */
722    int mCurTask = 1;
723
724    /**
725     * Current sequence id for oom_adj computation traversal.
726     */
727    int mAdjSeq = 0;
728
729    /**
730     * Current sequence id for process LRU updating.
731     */
732    int mLruSeq = 0;
733
734    /**
735     * Keep track of the number of service processes we last found, to
736     * determine on the next iteration which should be B services.
737     */
738    int mNumServiceProcs = 0;
739    int mNewNumServiceProcs = 0;
740
741    /**
742     * System monitoring: number of processes that died since the last
743     * N procs were started.
744     */
745    int[] mProcDeaths = new int[20];
746
747    /**
748     * This is set if we had to do a delayed dexopt of an app before launching
749     * it, to increasing the ANR timeouts in that case.
750     */
751    boolean mDidDexOpt;
752
753    String mDebugApp = null;
754    boolean mWaitForDebugger = false;
755    boolean mDebugTransient = false;
756    String mOrigDebugApp = null;
757    boolean mOrigWaitForDebugger = false;
758    boolean mAlwaysFinishActivities = false;
759    IActivityController mController = null;
760    String mProfileApp = null;
761    ProcessRecord mProfileProc = null;
762    String mProfileFile;
763    ParcelFileDescriptor mProfileFd;
764    int mProfileType = 0;
765    boolean mAutoStopProfiler = false;
766    String mOpenGlTraceApp = null;
767
768    static class ProcessChangeItem {
769        static final int CHANGE_ACTIVITIES = 1<<0;
770        static final int CHANGE_IMPORTANCE= 1<<1;
771        int changes;
772        int uid;
773        int pid;
774        int importance;
775        boolean foregroundActivities;
776    }
777
778    final RemoteCallbackList<IProcessObserver> mProcessObservers
779            = new RemoteCallbackList<IProcessObserver>();
780    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
781
782    final ArrayList<ProcessChangeItem> mPendingProcessChanges
783            = new ArrayList<ProcessChangeItem>();
784    final ArrayList<ProcessChangeItem> mAvailProcessChanges
785            = new ArrayList<ProcessChangeItem>();
786
787    /**
788     * Callback of last caller to {@link #requestPss}.
789     */
790    Runnable mRequestPssCallback;
791
792    /**
793     * Remaining processes for which we are waiting results from the last
794     * call to {@link #requestPss}.
795     */
796    final ArrayList<ProcessRecord> mRequestPssList
797            = new ArrayList<ProcessRecord>();
798
799    /**
800     * Runtime statistics collection thread.  This object's lock is used to
801     * protect all related state.
802     */
803    final Thread mProcessStatsThread;
804
805    /**
806     * Used to collect process stats when showing not responding dialog.
807     * Protected by mProcessStatsThread.
808     */
809    final ProcessStats mProcessStats = new ProcessStats(
810            MONITOR_THREAD_CPU_USAGE);
811    final AtomicLong mLastCpuTime = new AtomicLong(0);
812    final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
813
814    long mLastWriteTime = 0;
815
816    /**
817     * Set to true after the system has finished booting.
818     */
819    boolean mBooted = false;
820
821    int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
822    int mProcessLimitOverride = -1;
823
824    WindowManagerService mWindowManager;
825
826    static ActivityManagerService mSelf;
827    static ActivityThread mSystemThread;
828
829    private final class AppDeathRecipient implements IBinder.DeathRecipient {
830        final ProcessRecord mApp;
831        final int mPid;
832        final IApplicationThread mAppThread;
833
834        AppDeathRecipient(ProcessRecord app, int pid,
835                IApplicationThread thread) {
836            if (localLOGV) Slog.v(
837                TAG, "New death recipient " + this
838                + " for thread " + thread.asBinder());
839            mApp = app;
840            mPid = pid;
841            mAppThread = thread;
842        }
843
844        public void binderDied() {
845            if (localLOGV) Slog.v(
846                TAG, "Death received in " + this
847                + " for thread " + mAppThread.asBinder());
848            synchronized(ActivityManagerService.this) {
849                appDiedLocked(mApp, mPid, mAppThread);
850            }
851        }
852    }
853
854    static final int SHOW_ERROR_MSG = 1;
855    static final int SHOW_NOT_RESPONDING_MSG = 2;
856    static final int SHOW_FACTORY_ERROR_MSG = 3;
857    static final int UPDATE_CONFIGURATION_MSG = 4;
858    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
859    static final int WAIT_FOR_DEBUGGER_MSG = 6;
860    static final int SERVICE_TIMEOUT_MSG = 12;
861    static final int UPDATE_TIME_ZONE = 13;
862    static final int SHOW_UID_ERROR_MSG = 14;
863    static final int IM_FEELING_LUCKY_MSG = 15;
864    static final int PROC_START_TIMEOUT_MSG = 20;
865    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
866    static final int KILL_APPLICATION_MSG = 22;
867    static final int FINALIZE_PENDING_INTENT_MSG = 23;
868    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
869    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
870    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
871    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
872    static final int CLEAR_DNS_CACHE = 28;
873    static final int UPDATE_HTTP_PROXY = 29;
874    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
875    static final int DISPATCH_PROCESSES_CHANGED = 31;
876    static final int DISPATCH_PROCESS_DIED = 32;
877    static final int REPORT_MEM_USAGE = 33;
878
879    static final int FIRST_ACTIVITY_STACK_MSG = 100;
880    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
881    static final int FIRST_COMPAT_MODE_MSG = 300;
882
883    AlertDialog mUidAlert;
884    CompatModeDialog mCompatModeDialog;
885    long mLastMemUsageReportTime = 0;
886
887    final Handler mHandler = new Handler() {
888        //public Handler() {
889        //    if (localLOGV) Slog.v(TAG, "Handler started!");
890        //}
891
892        public void handleMessage(Message msg) {
893            switch (msg.what) {
894            case SHOW_ERROR_MSG: {
895                HashMap data = (HashMap) msg.obj;
896                synchronized (ActivityManagerService.this) {
897                    ProcessRecord proc = (ProcessRecord)data.get("app");
898                    if (proc != null && proc.crashDialog != null) {
899                        Slog.e(TAG, "App already has crash dialog: " + proc);
900                        return;
901                    }
902                    AppErrorResult res = (AppErrorResult) data.get("result");
903                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
904                        Dialog d = new AppErrorDialog(mContext, res, proc);
905                        d.show();
906                        proc.crashDialog = d;
907                    } else {
908                        // The device is asleep, so just pretend that the user
909                        // saw a crash dialog and hit "force quit".
910                        res.set(0);
911                    }
912                }
913
914                ensureBootCompleted();
915            } break;
916            case SHOW_NOT_RESPONDING_MSG: {
917                synchronized (ActivityManagerService.this) {
918                    HashMap data = (HashMap) msg.obj;
919                    ProcessRecord proc = (ProcessRecord)data.get("app");
920                    if (proc != null && proc.anrDialog != null) {
921                        Slog.e(TAG, "App already has anr dialog: " + proc);
922                        return;
923                    }
924
925                    Intent intent = new Intent("android.intent.action.ANR");
926                    if (!mProcessesReady) {
927                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
928                                | Intent.FLAG_RECEIVER_FOREGROUND);
929                    }
930                    broadcastIntentLocked(null, null, intent,
931                            null, null, 0, null, null, null,
932                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
933
934                    if (mShowDialogs) {
935                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
936                                mContext, proc, (ActivityRecord)data.get("activity"));
937                        d.show();
938                        proc.anrDialog = d;
939                    } else {
940                        // Just kill the app if there is no dialog to be shown.
941                        killAppAtUsersRequest(proc, null);
942                    }
943                }
944
945                ensureBootCompleted();
946            } break;
947            case SHOW_STRICT_MODE_VIOLATION_MSG: {
948                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
949                synchronized (ActivityManagerService.this) {
950                    ProcessRecord proc = (ProcessRecord) data.get("app");
951                    if (proc == null) {
952                        Slog.e(TAG, "App not found when showing strict mode dialog.");
953                        break;
954                    }
955                    if (proc.crashDialog != null) {
956                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
957                        return;
958                    }
959                    AppErrorResult res = (AppErrorResult) data.get("result");
960                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
961                        Dialog d = new StrictModeViolationDialog(mContext, res, proc);
962                        d.show();
963                        proc.crashDialog = d;
964                    } else {
965                        // The device is asleep, so just pretend that the user
966                        // saw a crash dialog and hit "force quit".
967                        res.set(0);
968                    }
969                }
970                ensureBootCompleted();
971            } break;
972            case SHOW_FACTORY_ERROR_MSG: {
973                Dialog d = new FactoryErrorDialog(
974                    mContext, msg.getData().getCharSequence("msg"));
975                d.show();
976                ensureBootCompleted();
977            } break;
978            case UPDATE_CONFIGURATION_MSG: {
979                final ContentResolver resolver = mContext.getContentResolver();
980                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
981            } break;
982            case GC_BACKGROUND_PROCESSES_MSG: {
983                synchronized (ActivityManagerService.this) {
984                    performAppGcsIfAppropriateLocked();
985                }
986            } break;
987            case WAIT_FOR_DEBUGGER_MSG: {
988                synchronized (ActivityManagerService.this) {
989                    ProcessRecord app = (ProcessRecord)msg.obj;
990                    if (msg.arg1 != 0) {
991                        if (!app.waitedForDebugger) {
992                            Dialog d = new AppWaitingForDebuggerDialog(
993                                    ActivityManagerService.this,
994                                    mContext, app);
995                            app.waitDialog = d;
996                            app.waitedForDebugger = true;
997                            d.show();
998                        }
999                    } else {
1000                        if (app.waitDialog != null) {
1001                            app.waitDialog.dismiss();
1002                            app.waitDialog = null;
1003                        }
1004                    }
1005                }
1006            } break;
1007            case SERVICE_TIMEOUT_MSG: {
1008                if (mDidDexOpt) {
1009                    mDidDexOpt = false;
1010                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1011                    nmsg.obj = msg.obj;
1012                    mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1013                    return;
1014                }
1015                serviceTimeout((ProcessRecord)msg.obj);
1016            } break;
1017            case UPDATE_TIME_ZONE: {
1018                synchronized (ActivityManagerService.this) {
1019                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1020                        ProcessRecord r = mLruProcesses.get(i);
1021                        if (r.thread != null) {
1022                            try {
1023                                r.thread.updateTimeZone();
1024                            } catch (RemoteException ex) {
1025                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1026                            }
1027                        }
1028                    }
1029                }
1030            } break;
1031            case CLEAR_DNS_CACHE: {
1032                synchronized (ActivityManagerService.this) {
1033                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1034                        ProcessRecord r = mLruProcesses.get(i);
1035                        if (r.thread != null) {
1036                            try {
1037                                r.thread.clearDnsCache();
1038                            } catch (RemoteException ex) {
1039                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1040                            }
1041                        }
1042                    }
1043                }
1044            } break;
1045            case UPDATE_HTTP_PROXY: {
1046                ProxyProperties proxy = (ProxyProperties)msg.obj;
1047                String host = "";
1048                String port = "";
1049                String exclList = "";
1050                if (proxy != null) {
1051                    host = proxy.getHost();
1052                    port = Integer.toString(proxy.getPort());
1053                    exclList = proxy.getExclusionList();
1054                }
1055                synchronized (ActivityManagerService.this) {
1056                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1057                        ProcessRecord r = mLruProcesses.get(i);
1058                        if (r.thread != null) {
1059                            try {
1060                                r.thread.setHttpProxy(host, port, exclList);
1061                            } catch (RemoteException ex) {
1062                                Slog.w(TAG, "Failed to update http proxy for: " +
1063                                        r.info.processName);
1064                            }
1065                        }
1066                    }
1067                }
1068            } break;
1069            case SHOW_UID_ERROR_MSG: {
1070                String title = "System UIDs Inconsistent";
1071                String text = "UIDs on the system are inconsistent, you need to wipe your"
1072                        + " data partition or your device will be unstable.";
1073                Log.e(TAG, title + ": " + text);
1074                if (mShowDialogs) {
1075                    // XXX This is a temporary dialog, no need to localize.
1076                    AlertDialog d = new BaseErrorDialog(mContext);
1077                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1078                    d.setCancelable(false);
1079                    d.setTitle(title);
1080                    d.setMessage(text);
1081                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1082                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1083                    mUidAlert = d;
1084                    d.show();
1085                }
1086            } break;
1087            case IM_FEELING_LUCKY_MSG: {
1088                if (mUidAlert != null) {
1089                    mUidAlert.dismiss();
1090                    mUidAlert = null;
1091                }
1092            } break;
1093            case PROC_START_TIMEOUT_MSG: {
1094                if (mDidDexOpt) {
1095                    mDidDexOpt = false;
1096                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1097                    nmsg.obj = msg.obj;
1098                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1099                    return;
1100                }
1101                ProcessRecord app = (ProcessRecord)msg.obj;
1102                synchronized (ActivityManagerService.this) {
1103                    processStartTimedOutLocked(app);
1104                }
1105            } break;
1106            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1107                synchronized (ActivityManagerService.this) {
1108                    doPendingActivityLaunchesLocked(true);
1109                }
1110            } break;
1111            case KILL_APPLICATION_MSG: {
1112                synchronized (ActivityManagerService.this) {
1113                    int uid = msg.arg1;
1114                    boolean restart = (msg.arg2 == 1);
1115                    String pkg = (String) msg.obj;
1116                    forceStopPackageLocked(pkg, uid, restart, false, true, false,
1117                            UserId.getUserId(uid));
1118                }
1119            } break;
1120            case FINALIZE_PENDING_INTENT_MSG: {
1121                ((PendingIntentRecord)msg.obj).completeFinalize();
1122            } break;
1123            case POST_HEAVY_NOTIFICATION_MSG: {
1124                INotificationManager inm = NotificationManager.getService();
1125                if (inm == null) {
1126                    return;
1127                }
1128
1129                ActivityRecord root = (ActivityRecord)msg.obj;
1130                ProcessRecord process = root.app;
1131                if (process == null) {
1132                    return;
1133                }
1134
1135                try {
1136                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1137                    String text = mContext.getString(R.string.heavy_weight_notification,
1138                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1139                    Notification notification = new Notification();
1140                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1141                    notification.when = 0;
1142                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1143                    notification.tickerText = text;
1144                    notification.defaults = 0; // please be quiet
1145                    notification.sound = null;
1146                    notification.vibrate = null;
1147                    notification.setLatestEventInfo(context, text,
1148                            mContext.getText(R.string.heavy_weight_notification_detail),
1149                            PendingIntent.getActivity(mContext, 0, root.intent,
1150                                    PendingIntent.FLAG_CANCEL_CURRENT));
1151
1152                    try {
1153                        int[] outId = new int[1];
1154                        inm.enqueueNotification("android", R.string.heavy_weight_notification,
1155                                notification, outId);
1156                    } catch (RuntimeException e) {
1157                        Slog.w(ActivityManagerService.TAG,
1158                                "Error showing notification for heavy-weight app", e);
1159                    } catch (RemoteException e) {
1160                    }
1161                } catch (NameNotFoundException e) {
1162                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1163                }
1164            } break;
1165            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1166                INotificationManager inm = NotificationManager.getService();
1167                if (inm == null) {
1168                    return;
1169                }
1170                try {
1171                    inm.cancelNotification("android",
1172                            R.string.heavy_weight_notification);
1173                } catch (RuntimeException e) {
1174                    Slog.w(ActivityManagerService.TAG,
1175                            "Error canceling notification for service", e);
1176                } catch (RemoteException e) {
1177                }
1178            } break;
1179            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1180                synchronized (ActivityManagerService.this) {
1181                    checkExcessivePowerUsageLocked(true);
1182                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1183                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1184                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1185                }
1186            } break;
1187            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1188                synchronized (ActivityManagerService.this) {
1189                    ActivityRecord ar = (ActivityRecord)msg.obj;
1190                    if (mCompatModeDialog != null) {
1191                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1192                                ar.info.applicationInfo.packageName)) {
1193                            return;
1194                        }
1195                        mCompatModeDialog.dismiss();
1196                        mCompatModeDialog = null;
1197                    }
1198                    if (ar != null && false) {
1199                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1200                                ar.packageName)) {
1201                            int mode = mCompatModePackages.computeCompatModeLocked(
1202                                    ar.info.applicationInfo);
1203                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1204                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1205                                mCompatModeDialog = new CompatModeDialog(
1206                                        ActivityManagerService.this, mContext,
1207                                        ar.info.applicationInfo);
1208                                mCompatModeDialog.show();
1209                            }
1210                        }
1211                    }
1212                }
1213                break;
1214            }
1215            case DISPATCH_PROCESSES_CHANGED: {
1216                dispatchProcessesChanged();
1217                break;
1218            }
1219            case DISPATCH_PROCESS_DIED: {
1220                final int pid = msg.arg1;
1221                final int uid = msg.arg2;
1222                dispatchProcessDied(pid, uid);
1223                break;
1224            }
1225            case REPORT_MEM_USAGE: {
1226                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1227                if (!isDebuggable) {
1228                    return;
1229                }
1230                synchronized (ActivityManagerService.this) {
1231                    long now = SystemClock.uptimeMillis();
1232                    if (now < (mLastMemUsageReportTime+5*60*1000)) {
1233                        // Don't report more than every 5 minutes to somewhat
1234                        // avoid spamming.
1235                        return;
1236                    }
1237                    mLastMemUsageReportTime = now;
1238                }
1239                Thread thread = new Thread() {
1240                    @Override public void run() {
1241                        StringBuilder dropBuilder = new StringBuilder(1024);
1242                        StringBuilder logBuilder = new StringBuilder(1024);
1243                        StringWriter oomSw = new StringWriter();
1244                        PrintWriter oomPw = new PrintWriter(oomSw);
1245                        StringWriter catSw = new StringWriter();
1246                        PrintWriter catPw = new PrintWriter(catSw);
1247                        String[] emptyArgs = new String[] { };
1248                        StringBuilder tag = new StringBuilder(128);
1249                        StringBuilder stack = new StringBuilder(128);
1250                        tag.append("Low on memory -- ");
1251                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
1252                                tag, stack);
1253                        dropBuilder.append(stack);
1254                        dropBuilder.append('\n');
1255                        dropBuilder.append('\n');
1256                        String oomString = oomSw.toString();
1257                        dropBuilder.append(oomString);
1258                        dropBuilder.append('\n');
1259                        logBuilder.append(oomString);
1260                        try {
1261                            java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1262                                    "procrank", });
1263                            final InputStreamReader converter = new InputStreamReader(
1264                                    proc.getInputStream());
1265                            BufferedReader in = new BufferedReader(converter);
1266                            String line;
1267                            while (true) {
1268                                line = in.readLine();
1269                                if (line == null) {
1270                                    break;
1271                                }
1272                                if (line.length() > 0) {
1273                                    logBuilder.append(line);
1274                                    logBuilder.append('\n');
1275                                }
1276                                dropBuilder.append(line);
1277                                dropBuilder.append('\n');
1278                            }
1279                            converter.close();
1280                        } catch (IOException e) {
1281                        }
1282                        synchronized (ActivityManagerService.this) {
1283                            catPw.println();
1284                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1285                            catPw.println();
1286                            dumpServicesLocked(null, catPw, emptyArgs, 0, false, false, null);
1287                            catPw.println();
1288                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1289                        }
1290                        dropBuilder.append(catSw.toString());
1291                        addErrorToDropBox("lowmem", null, "system_server", null,
1292                                null, tag.toString(), dropBuilder.toString(), null, null);
1293                        Slog.i(TAG, logBuilder.toString());
1294                        synchronized (ActivityManagerService.this) {
1295                            long now = SystemClock.uptimeMillis();
1296                            if (mLastMemUsageReportTime < now) {
1297                                mLastMemUsageReportTime = now;
1298                            }
1299                        }
1300                    }
1301                };
1302                thread.start();
1303                break;
1304            }
1305            }
1306        }
1307    };
1308
1309    public static void setSystemProcess() {
1310        try {
1311            ActivityManagerService m = mSelf;
1312
1313            ServiceManager.addService("activity", m, true);
1314            ServiceManager.addService("meminfo", new MemBinder(m));
1315            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1316            ServiceManager.addService("dbinfo", new DbBinder(m));
1317            if (MONITOR_CPU_USAGE) {
1318                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1319            }
1320            ServiceManager.addService("permission", new PermissionController(m));
1321
1322            ApplicationInfo info =
1323                mSelf.mContext.getPackageManager().getApplicationInfo(
1324                            "android", STOCK_PM_FLAGS);
1325            mSystemThread.installSystemApplicationInfo(info);
1326
1327            synchronized (mSelf) {
1328                ProcessRecord app = mSelf.newProcessRecordLocked(
1329                        mSystemThread.getApplicationThread(), info,
1330                        info.processName, false);
1331                app.persistent = true;
1332                app.pid = MY_PID;
1333                app.maxAdj = ProcessList.SYSTEM_ADJ;
1334                mSelf.mProcessNames.put(app.processName, app.uid, app);
1335                synchronized (mSelf.mPidsSelfLocked) {
1336                    mSelf.mPidsSelfLocked.put(app.pid, app);
1337                }
1338                mSelf.updateLruProcessLocked(app, true, true);
1339            }
1340        } catch (PackageManager.NameNotFoundException e) {
1341            throw new RuntimeException(
1342                    "Unable to find android system package", e);
1343        }
1344    }
1345
1346    public void setWindowManager(WindowManagerService wm) {
1347        mWindowManager = wm;
1348    }
1349
1350    public static final Context main(int factoryTest) {
1351        AThread thr = new AThread();
1352        thr.start();
1353
1354        synchronized (thr) {
1355            while (thr.mService == null) {
1356                try {
1357                    thr.wait();
1358                } catch (InterruptedException e) {
1359                }
1360            }
1361        }
1362
1363        ActivityManagerService m = thr.mService;
1364        mSelf = m;
1365        ActivityThread at = ActivityThread.systemMain();
1366        mSystemThread = at;
1367        Context context = at.getSystemContext();
1368        context.setTheme(android.R.style.Theme_Holo);
1369        m.mContext = context;
1370        m.mFactoryTest = factoryTest;
1371        m.mMainStack = new ActivityStack(m, context, true);
1372
1373        m.mBatteryStatsService.publish(context);
1374        m.mUsageStatsService.publish(context);
1375
1376        synchronized (thr) {
1377            thr.mReady = true;
1378            thr.notifyAll();
1379        }
1380
1381        m.startRunning(null, null, null, null);
1382
1383        return context;
1384    }
1385
1386    public static ActivityManagerService self() {
1387        return mSelf;
1388    }
1389
1390    static class AThread extends Thread {
1391        ActivityManagerService mService;
1392        boolean mReady = false;
1393
1394        public AThread() {
1395            super("ActivityManager");
1396        }
1397
1398        public void run() {
1399            Looper.prepare();
1400
1401            android.os.Process.setThreadPriority(
1402                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1403            android.os.Process.setCanSelfBackground(false);
1404
1405            ActivityManagerService m = new ActivityManagerService();
1406
1407            synchronized (this) {
1408                mService = m;
1409                notifyAll();
1410            }
1411
1412            synchronized (this) {
1413                while (!mReady) {
1414                    try {
1415                        wait();
1416                    } catch (InterruptedException e) {
1417                    }
1418                }
1419            }
1420
1421            // For debug builds, log event loop stalls to dropbox for analysis.
1422            if (StrictMode.conditionallyEnableDebugLogging()) {
1423                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1424            }
1425
1426            Looper.loop();
1427        }
1428    }
1429
1430    static class MemBinder extends Binder {
1431        ActivityManagerService mActivityManagerService;
1432        MemBinder(ActivityManagerService activityManagerService) {
1433            mActivityManagerService = activityManagerService;
1434        }
1435
1436        @Override
1437        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1438            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1439                    != PackageManager.PERMISSION_GRANTED) {
1440                pw.println("Permission Denial: can't dump meminfo from from pid="
1441                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1442                        + " without permission " + android.Manifest.permission.DUMP);
1443                return;
1444            }
1445
1446            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
1447                    false, null, null, null);
1448        }
1449    }
1450
1451    static class GraphicsBinder extends Binder {
1452        ActivityManagerService mActivityManagerService;
1453        GraphicsBinder(ActivityManagerService activityManagerService) {
1454            mActivityManagerService = activityManagerService;
1455        }
1456
1457        @Override
1458        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1459            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1460                    != PackageManager.PERMISSION_GRANTED) {
1461                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1462                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1463                        + " without permission " + android.Manifest.permission.DUMP);
1464                return;
1465            }
1466
1467            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1468        }
1469    }
1470
1471    static class DbBinder extends Binder {
1472        ActivityManagerService mActivityManagerService;
1473        DbBinder(ActivityManagerService activityManagerService) {
1474            mActivityManagerService = activityManagerService;
1475        }
1476
1477        @Override
1478        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1479            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1480                    != PackageManager.PERMISSION_GRANTED) {
1481                pw.println("Permission Denial: can't dump dbinfo from from pid="
1482                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1483                        + " without permission " + android.Manifest.permission.DUMP);
1484                return;
1485            }
1486
1487            mActivityManagerService.dumpDbInfo(fd, pw, args);
1488        }
1489    }
1490
1491    static class CpuBinder extends Binder {
1492        ActivityManagerService mActivityManagerService;
1493        CpuBinder(ActivityManagerService activityManagerService) {
1494            mActivityManagerService = activityManagerService;
1495        }
1496
1497        @Override
1498        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1499            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1500                    != PackageManager.PERMISSION_GRANTED) {
1501                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1502                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1503                        + " without permission " + android.Manifest.permission.DUMP);
1504                return;
1505            }
1506
1507            synchronized (mActivityManagerService.mProcessStatsThread) {
1508                pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1509                pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1510                        SystemClock.uptimeMillis()));
1511            }
1512        }
1513    }
1514
1515    private ActivityManagerService() {
1516        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1517
1518        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1519        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1520        mBroadcastQueues[0] = mFgBroadcastQueue;
1521        mBroadcastQueues[1] = mBgBroadcastQueue;
1522
1523        File dataDir = Environment.getDataDirectory();
1524        File systemDir = new File(dataDir, "system");
1525        systemDir.mkdirs();
1526        mBatteryStatsService = new BatteryStatsService(new File(
1527                systemDir, "batterystats.bin").toString());
1528        mBatteryStatsService.getActiveStatistics().readLocked();
1529        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1530        mOnBattery = DEBUG_POWER ? true
1531                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1532        mBatteryStatsService.getActiveStatistics().setCallback(this);
1533
1534        mUsageStatsService = new UsageStatsService(new File(
1535                systemDir, "usagestats").toString());
1536        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1537
1538        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1539            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1540
1541        mConfiguration.setToDefaults();
1542        mConfiguration.locale = Locale.getDefault();
1543        mConfigurationSeq = mConfiguration.seq = 1;
1544        mProcessStats.init();
1545
1546        mCompatModePackages = new CompatModePackages(this, systemDir);
1547
1548        // Add ourself to the Watchdog monitors.
1549        Watchdog.getInstance().addMonitor(this);
1550
1551        mProcessStatsThread = new Thread("ProcessStats") {
1552            public void run() {
1553                while (true) {
1554                    try {
1555                        try {
1556                            synchronized(this) {
1557                                final long now = SystemClock.uptimeMillis();
1558                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1559                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1560                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1561                                //        + ", write delay=" + nextWriteDelay);
1562                                if (nextWriteDelay < nextCpuDelay) {
1563                                    nextCpuDelay = nextWriteDelay;
1564                                }
1565                                if (nextCpuDelay > 0) {
1566                                    mProcessStatsMutexFree.set(true);
1567                                    this.wait(nextCpuDelay);
1568                                }
1569                            }
1570                        } catch (InterruptedException e) {
1571                        }
1572                        updateCpuStatsNow();
1573                    } catch (Exception e) {
1574                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1575                    }
1576                }
1577            }
1578        };
1579        mProcessStatsThread.start();
1580    }
1581
1582    @Override
1583    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1584            throws RemoteException {
1585        if (code == SYSPROPS_TRANSACTION) {
1586            // We need to tell all apps about the system property change.
1587            ArrayList<IBinder> procs = new ArrayList<IBinder>();
1588            synchronized(this) {
1589                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1590                    final int NA = apps.size();
1591                    for (int ia=0; ia<NA; ia++) {
1592                        ProcessRecord app = apps.valueAt(ia);
1593                        if (app.thread != null) {
1594                            procs.add(app.thread.asBinder());
1595                        }
1596                    }
1597                }
1598            }
1599
1600            int N = procs.size();
1601            for (int i=0; i<N; i++) {
1602                Parcel data2 = Parcel.obtain();
1603                try {
1604                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1605                } catch (RemoteException e) {
1606                }
1607                data2.recycle();
1608            }
1609        }
1610        try {
1611            return super.onTransact(code, data, reply, flags);
1612        } catch (RuntimeException e) {
1613            // The activity manager only throws security exceptions, so let's
1614            // log all others.
1615            if (!(e instanceof SecurityException)) {
1616                Slog.e(TAG, "Activity Manager Crash", e);
1617            }
1618            throw e;
1619        }
1620    }
1621
1622    void updateCpuStats() {
1623        final long now = SystemClock.uptimeMillis();
1624        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1625            return;
1626        }
1627        if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1628            synchronized (mProcessStatsThread) {
1629                mProcessStatsThread.notify();
1630            }
1631        }
1632    }
1633
1634    void updateCpuStatsNow() {
1635        synchronized (mProcessStatsThread) {
1636            mProcessStatsMutexFree.set(false);
1637            final long now = SystemClock.uptimeMillis();
1638            boolean haveNewCpuStats = false;
1639
1640            if (MONITOR_CPU_USAGE &&
1641                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1642                mLastCpuTime.set(now);
1643                haveNewCpuStats = true;
1644                mProcessStats.update();
1645                //Slog.i(TAG, mProcessStats.printCurrentState());
1646                //Slog.i(TAG, "Total CPU usage: "
1647                //        + mProcessStats.getTotalCpuPercent() + "%");
1648
1649                // Slog the cpu usage if the property is set.
1650                if ("true".equals(SystemProperties.get("events.cpu"))) {
1651                    int user = mProcessStats.getLastUserTime();
1652                    int system = mProcessStats.getLastSystemTime();
1653                    int iowait = mProcessStats.getLastIoWaitTime();
1654                    int irq = mProcessStats.getLastIrqTime();
1655                    int softIrq = mProcessStats.getLastSoftIrqTime();
1656                    int idle = mProcessStats.getLastIdleTime();
1657
1658                    int total = user + system + iowait + irq + softIrq + idle;
1659                    if (total == 0) total = 1;
1660
1661                    EventLog.writeEvent(EventLogTags.CPU,
1662                            ((user+system+iowait+irq+softIrq) * 100) / total,
1663                            (user * 100) / total,
1664                            (system * 100) / total,
1665                            (iowait * 100) / total,
1666                            (irq * 100) / total,
1667                            (softIrq * 100) / total);
1668                }
1669            }
1670
1671            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1672            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1673            synchronized(bstats) {
1674                synchronized(mPidsSelfLocked) {
1675                    if (haveNewCpuStats) {
1676                        if (mOnBattery) {
1677                            int perc = bstats.startAddingCpuLocked();
1678                            int totalUTime = 0;
1679                            int totalSTime = 0;
1680                            final int N = mProcessStats.countStats();
1681                            for (int i=0; i<N; i++) {
1682                                ProcessStats.Stats st = mProcessStats.getStats(i);
1683                                if (!st.working) {
1684                                    continue;
1685                                }
1686                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1687                                int otherUTime = (st.rel_utime*perc)/100;
1688                                int otherSTime = (st.rel_stime*perc)/100;
1689                                totalUTime += otherUTime;
1690                                totalSTime += otherSTime;
1691                                if (pr != null) {
1692                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1693                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1694                                            st.rel_stime-otherSTime);
1695                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1696                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1697                                } else {
1698                                    BatteryStatsImpl.Uid.Proc ps =
1699                                            bstats.getProcessStatsLocked(st.name, st.pid);
1700                                    if (ps != null) {
1701                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1702                                                st.rel_stime-otherSTime);
1703                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1704                                    }
1705                                }
1706                            }
1707                            bstats.finishAddingCpuLocked(perc, totalUTime,
1708                                    totalSTime, cpuSpeedTimes);
1709                        }
1710                    }
1711                }
1712
1713                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1714                    mLastWriteTime = now;
1715                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1716                }
1717            }
1718        }
1719    }
1720
1721    @Override
1722    public void batteryNeedsCpuUpdate() {
1723        updateCpuStatsNow();
1724    }
1725
1726    @Override
1727    public void batteryPowerChanged(boolean onBattery) {
1728        // When plugging in, update the CPU stats first before changing
1729        // the plug state.
1730        updateCpuStatsNow();
1731        synchronized (this) {
1732            synchronized(mPidsSelfLocked) {
1733                mOnBattery = DEBUG_POWER ? true : onBattery;
1734            }
1735        }
1736    }
1737
1738    /**
1739     * Initialize the application bind args. These are passed to each
1740     * process when the bindApplication() IPC is sent to the process. They're
1741     * lazily setup to make sure the services are running when they're asked for.
1742     */
1743    private HashMap<String, IBinder> getCommonServicesLocked() {
1744        if (mAppBindArgs == null) {
1745            mAppBindArgs = new HashMap<String, IBinder>();
1746
1747            // Setup the application init args
1748            mAppBindArgs.put("package", ServiceManager.getService("package"));
1749            mAppBindArgs.put("window", ServiceManager.getService("window"));
1750            mAppBindArgs.put(Context.ALARM_SERVICE,
1751                    ServiceManager.getService(Context.ALARM_SERVICE));
1752        }
1753        return mAppBindArgs;
1754    }
1755
1756    final void setFocusedActivityLocked(ActivityRecord r) {
1757        if (mFocusedActivity != r) {
1758            mFocusedActivity = r;
1759            if (r != null) {
1760                mWindowManager.setFocusedApp(r.appToken, true);
1761            }
1762        }
1763    }
1764
1765    private final void updateLruProcessInternalLocked(ProcessRecord app,
1766            boolean oomAdj, boolean updateActivityTime, int bestPos) {
1767        // put it on the LRU to keep track of when it should be exited.
1768        int lrui = mLruProcesses.indexOf(app);
1769        if (lrui >= 0) mLruProcesses.remove(lrui);
1770
1771        int i = mLruProcesses.size()-1;
1772        int skipTop = 0;
1773
1774        app.lruSeq = mLruSeq;
1775
1776        // compute the new weight for this process.
1777        if (updateActivityTime) {
1778            app.lastActivityTime = SystemClock.uptimeMillis();
1779        }
1780        if (app.activities.size() > 0) {
1781            // If this process has activities, we more strongly want to keep
1782            // it around.
1783            app.lruWeight = app.lastActivityTime;
1784        } else if (app.pubProviders.size() > 0) {
1785            // If this process contains content providers, we want to keep
1786            // it a little more strongly.
1787            app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1788            // Also don't let it kick out the first few "real" hidden processes.
1789            skipTop = ProcessList.MIN_HIDDEN_APPS;
1790        } else {
1791            // If this process doesn't have activities, we less strongly
1792            // want to keep it around, and generally want to avoid getting
1793            // in front of any very recently used activities.
1794            app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1795            // Also don't let it kick out the first few "real" hidden processes.
1796            skipTop = ProcessList.MIN_HIDDEN_APPS;
1797        }
1798
1799        while (i >= 0) {
1800            ProcessRecord p = mLruProcesses.get(i);
1801            // If this app shouldn't be in front of the first N background
1802            // apps, then skip over that many that are currently hidden.
1803            if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1804                skipTop--;
1805            }
1806            if (p.lruWeight <= app.lruWeight || i < bestPos) {
1807                mLruProcesses.add(i+1, app);
1808                break;
1809            }
1810            i--;
1811        }
1812        if (i < 0) {
1813            mLruProcesses.add(0, app);
1814        }
1815
1816        // If the app is currently using a content provider or service,
1817        // bump those processes as well.
1818        if (app.connections.size() > 0) {
1819            for (ConnectionRecord cr : app.connections) {
1820                if (cr.binding != null && cr.binding.service != null
1821                        && cr.binding.service.app != null
1822                        && cr.binding.service.app.lruSeq != mLruSeq) {
1823                    updateLruProcessInternalLocked(cr.binding.service.app, false,
1824                            updateActivityTime, i+1);
1825                }
1826            }
1827        }
1828        for (int j=app.conProviders.size()-1; j>=0; j--) {
1829            ContentProviderRecord cpr = app.conProviders.get(j).provider;
1830            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1831                updateLruProcessInternalLocked(cpr.proc, false,
1832                        updateActivityTime, i+1);
1833            }
1834        }
1835
1836        //Slog.i(TAG, "Putting proc to front: " + app.processName);
1837        if (oomAdj) {
1838            updateOomAdjLocked();
1839        }
1840    }
1841
1842    final void updateLruProcessLocked(ProcessRecord app,
1843            boolean oomAdj, boolean updateActivityTime) {
1844        mLruSeq++;
1845        updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1846    }
1847
1848    final ProcessRecord getProcessRecordLocked(
1849            String processName, int uid) {
1850        if (uid == Process.SYSTEM_UID) {
1851            // The system gets to run in any process.  If there are multiple
1852            // processes with the same uid, just pick the first (this
1853            // should never happen).
1854            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1855                    processName);
1856            if (procs == null) return null;
1857            final int N = procs.size();
1858            for (int i = 0; i < N; i++) {
1859                if (UserId.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1860            }
1861        }
1862        ProcessRecord proc = mProcessNames.get(processName, uid);
1863        return proc;
1864    }
1865
1866    void ensurePackageDexOpt(String packageName) {
1867        IPackageManager pm = AppGlobals.getPackageManager();
1868        try {
1869            if (pm.performDexOpt(packageName)) {
1870                mDidDexOpt = true;
1871            }
1872        } catch (RemoteException e) {
1873        }
1874    }
1875
1876    boolean isNextTransitionForward() {
1877        int transit = mWindowManager.getPendingAppTransition();
1878        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1879                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1880                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1881    }
1882
1883    final ProcessRecord startProcessLocked(String processName,
1884            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1885            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1886            boolean isolated) {
1887        ProcessRecord app;
1888        if (!isolated) {
1889            app = getProcessRecordLocked(processName, info.uid);
1890        } else {
1891            // If this is an isolated process, it can't re-use an existing process.
1892            app = null;
1893        }
1894        // We don't have to do anything more if:
1895        // (1) There is an existing application record; and
1896        // (2) The caller doesn't think it is dead, OR there is no thread
1897        //     object attached to it so we know it couldn't have crashed; and
1898        // (3) There is a pid assigned to it, so it is either starting or
1899        //     already running.
1900        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1901                + " app=" + app + " knownToBeDead=" + knownToBeDead
1902                + " thread=" + (app != null ? app.thread : null)
1903                + " pid=" + (app != null ? app.pid : -1));
1904        if (app != null && app.pid > 0) {
1905            if (!knownToBeDead || app.thread == null) {
1906                // We already have the app running, or are waiting for it to
1907                // come up (we have a pid but not yet its thread), so keep it.
1908                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
1909                // If this is a new package in the process, add the package to the list
1910                app.addPackage(info.packageName);
1911                return app;
1912            } else {
1913                // An application record is attached to a previous process,
1914                // clean it up now.
1915                if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1916                handleAppDiedLocked(app, true, true);
1917            }
1918        }
1919
1920        String hostingNameStr = hostingName != null
1921                ? hostingName.flattenToShortString() : null;
1922
1923        if (!isolated) {
1924            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1925                // If we are in the background, then check to see if this process
1926                // is bad.  If so, we will just silently fail.
1927                if (mBadProcesses.get(info.processName, info.uid) != null) {
1928                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1929                            + "/" + info.processName);
1930                    return null;
1931                }
1932            } else {
1933                // When the user is explicitly starting a process, then clear its
1934                // crash count so that we won't make it bad until they see at
1935                // least one crash dialog again, and make the process good again
1936                // if it had been bad.
1937                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1938                        + "/" + info.processName);
1939                mProcessCrashTimes.remove(info.processName, info.uid);
1940                if (mBadProcesses.get(info.processName, info.uid) != null) {
1941                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1942                            info.processName);
1943                    mBadProcesses.remove(info.processName, info.uid);
1944                    if (app != null) {
1945                        app.bad = false;
1946                    }
1947                }
1948            }
1949        }
1950
1951        if (app == null) {
1952            app = newProcessRecordLocked(null, info, processName, isolated);
1953            if (app == null) {
1954                Slog.w(TAG, "Failed making new process record for "
1955                        + processName + "/" + info.uid + " isolated=" + isolated);
1956                return null;
1957            }
1958            mProcessNames.put(processName, app.uid, app);
1959            if (isolated) {
1960                mIsolatedProcesses.put(app.uid, app);
1961            }
1962        } else {
1963            // If this is a new package in the process, add the package to the list
1964            app.addPackage(info.packageName);
1965        }
1966
1967        // If the system is not ready yet, then hold off on starting this
1968        // process until it is.
1969        if (!mProcessesReady
1970                && !isAllowedWhileBooting(info)
1971                && !allowWhileBooting) {
1972            if (!mProcessesOnHold.contains(app)) {
1973                mProcessesOnHold.add(app);
1974            }
1975            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
1976            return app;
1977        }
1978
1979        startProcessLocked(app, hostingType, hostingNameStr);
1980        return (app.pid != 0) ? app : null;
1981    }
1982
1983    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1984        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1985    }
1986
1987    private final void startProcessLocked(ProcessRecord app,
1988            String hostingType, String hostingNameStr) {
1989        if (app.pid > 0 && app.pid != MY_PID) {
1990            synchronized (mPidsSelfLocked) {
1991                mPidsSelfLocked.remove(app.pid);
1992                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1993            }
1994            app.pid = 0;
1995        }
1996
1997        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1998                "startProcessLocked removing on hold: " + app);
1999        mProcessesOnHold.remove(app);
2000
2001        updateCpuStats();
2002
2003        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
2004        mProcDeaths[0] = 0;
2005
2006        try {
2007            int uid = app.uid;
2008
2009            int[] gids = null;
2010            if (!app.isolated) {
2011                try {
2012                    gids = mContext.getPackageManager().getPackageGids(
2013                            app.info.packageName);
2014                } catch (PackageManager.NameNotFoundException e) {
2015                    Slog.w(TAG, "Unable to retrieve gids", e);
2016                }
2017            }
2018            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2019                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2020                        && mTopComponent != null
2021                        && app.processName.equals(mTopComponent.getPackageName())) {
2022                    uid = 0;
2023                }
2024                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2025                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2026                    uid = 0;
2027                }
2028            }
2029            int debugFlags = 0;
2030            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2031                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2032                // Also turn on CheckJNI for debuggable apps. It's quite
2033                // awkward to turn on otherwise.
2034                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2035            }
2036            // Run the app in safe mode if its manifest requests so or the
2037            // system is booted in safe mode.
2038            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2039                Zygote.systemInSafeMode == true) {
2040                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2041            }
2042            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2043                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2044            }
2045            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2046                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2047            }
2048            if ("1".equals(SystemProperties.get("debug.assert"))) {
2049                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2050            }
2051
2052            // Start the process.  It will either succeed and return a result containing
2053            // the PID of the new process, or else throw a RuntimeException.
2054            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2055                    app.processName, uid, uid, gids, debugFlags,
2056                    app.info.targetSdkVersion, null, null);
2057
2058            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2059            synchronized (bs) {
2060                if (bs.isOnBattery()) {
2061                    app.batteryStats.incStartsLocked();
2062                }
2063            }
2064
2065            EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
2066                    app.processName, hostingType,
2067                    hostingNameStr != null ? hostingNameStr : "");
2068
2069            if (app.persistent) {
2070                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2071            }
2072
2073            StringBuilder buf = mStringBuilder;
2074            buf.setLength(0);
2075            buf.append("Start proc ");
2076            buf.append(app.processName);
2077            buf.append(" for ");
2078            buf.append(hostingType);
2079            if (hostingNameStr != null) {
2080                buf.append(" ");
2081                buf.append(hostingNameStr);
2082            }
2083            buf.append(": pid=");
2084            buf.append(startResult.pid);
2085            buf.append(" uid=");
2086            buf.append(uid);
2087            buf.append(" gids={");
2088            if (gids != null) {
2089                for (int gi=0; gi<gids.length; gi++) {
2090                    if (gi != 0) buf.append(", ");
2091                    buf.append(gids[gi]);
2092
2093                }
2094            }
2095            buf.append("}");
2096            Slog.i(TAG, buf.toString());
2097            app.pid = startResult.pid;
2098            app.usingWrapper = startResult.usingWrapper;
2099            app.removed = false;
2100            synchronized (mPidsSelfLocked) {
2101                this.mPidsSelfLocked.put(startResult.pid, app);
2102                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2103                msg.obj = app;
2104                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2105                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2106            }
2107        } catch (RuntimeException e) {
2108            // XXX do better error recovery.
2109            app.pid = 0;
2110            Slog.e(TAG, "Failure starting process " + app.processName, e);
2111        }
2112    }
2113
2114    void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2115        if (resumed) {
2116            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2117        } else {
2118            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2119        }
2120    }
2121
2122    boolean startHomeActivityLocked(int userId) {
2123        if (mHeadless) {
2124            // Added because none of the other calls to ensureBootCompleted seem to fire
2125            // when running headless.
2126            ensureBootCompleted();
2127            return false;
2128        }
2129
2130        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2131                && mTopAction == null) {
2132            // We are running in factory test mode, but unable to find
2133            // the factory test app, so just sit around displaying the
2134            // error message and don't try to start anything.
2135            return false;
2136        }
2137        Intent intent = new Intent(
2138            mTopAction,
2139            mTopData != null ? Uri.parse(mTopData) : null);
2140        intent.setComponent(mTopComponent);
2141        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2142            intent.addCategory(Intent.CATEGORY_HOME);
2143        }
2144        ActivityInfo aInfo =
2145            intent.resolveActivityInfo(mContext.getPackageManager(),
2146                    STOCK_PM_FLAGS);
2147        if (aInfo != null) {
2148            intent.setComponent(new ComponentName(
2149                    aInfo.applicationInfo.packageName, aInfo.name));
2150            // Don't do this if the home app is currently being
2151            // instrumented.
2152            aInfo = new ActivityInfo(aInfo);
2153            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2154            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2155                    aInfo.applicationInfo.uid);
2156            if (app == null || app.instrumentationClass == null) {
2157                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2158                mMainStack.startActivityLocked(null, intent, null, aInfo,
2159                        null, null, 0, 0, 0, 0, null, false, null);
2160            }
2161        }
2162
2163        return true;
2164    }
2165
2166    /**
2167     * Starts the "new version setup screen" if appropriate.
2168     */
2169    void startSetupActivityLocked() {
2170        // Only do this once per boot.
2171        if (mCheckedForSetup) {
2172            return;
2173        }
2174
2175        // We will show this screen if the current one is a different
2176        // version than the last one shown, and we are not running in
2177        // low-level factory test mode.
2178        final ContentResolver resolver = mContext.getContentResolver();
2179        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2180                Settings.Secure.getInt(resolver,
2181                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2182            mCheckedForSetup = true;
2183
2184            // See if we should be showing the platform update setup UI.
2185            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2186            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2187                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2188
2189            // We don't allow third party apps to replace this.
2190            ResolveInfo ri = null;
2191            for (int i=0; ris != null && i<ris.size(); i++) {
2192                if ((ris.get(i).activityInfo.applicationInfo.flags
2193                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2194                    ri = ris.get(i);
2195                    break;
2196                }
2197            }
2198
2199            if (ri != null) {
2200                String vers = ri.activityInfo.metaData != null
2201                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2202                        : null;
2203                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2204                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2205                            Intent.METADATA_SETUP_VERSION);
2206                }
2207                String lastVers = Settings.Secure.getString(
2208                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2209                if (vers != null && !vers.equals(lastVers)) {
2210                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2211                    intent.setComponent(new ComponentName(
2212                            ri.activityInfo.packageName, ri.activityInfo.name));
2213                    mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2214                            null, null, 0, 0, 0, 0, null, false, null);
2215                }
2216            }
2217        }
2218    }
2219
2220    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2221        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2222    }
2223
2224    void enforceNotIsolatedCaller(String caller) {
2225        if (UserId.isIsolated(Binder.getCallingUid())) {
2226            throw new SecurityException("Isolated process not allowed to call " + caller);
2227        }
2228    }
2229
2230    public int getFrontActivityScreenCompatMode() {
2231        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2232        synchronized (this) {
2233            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2234        }
2235    }
2236
2237    public void setFrontActivityScreenCompatMode(int mode) {
2238        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2239                "setFrontActivityScreenCompatMode");
2240        synchronized (this) {
2241            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2242        }
2243    }
2244
2245    public int getPackageScreenCompatMode(String packageName) {
2246        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2247        synchronized (this) {
2248            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2249        }
2250    }
2251
2252    public void setPackageScreenCompatMode(String packageName, int mode) {
2253        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2254                "setPackageScreenCompatMode");
2255        synchronized (this) {
2256            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2257        }
2258    }
2259
2260    public boolean getPackageAskScreenCompat(String packageName) {
2261        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2262        synchronized (this) {
2263            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2264        }
2265    }
2266
2267    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2268        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2269                "setPackageAskScreenCompat");
2270        synchronized (this) {
2271            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2272        }
2273    }
2274
2275    void reportResumedActivityLocked(ActivityRecord r) {
2276        //Slog.i(TAG, "**** REPORT RESUME: " + r);
2277        updateUsageStats(r, true);
2278    }
2279
2280    private void dispatchProcessesChanged() {
2281        int N;
2282        synchronized (this) {
2283            N = mPendingProcessChanges.size();
2284            if (mActiveProcessChanges.length < N) {
2285                mActiveProcessChanges = new ProcessChangeItem[N];
2286            }
2287            mPendingProcessChanges.toArray(mActiveProcessChanges);
2288            mAvailProcessChanges.addAll(mPendingProcessChanges);
2289            mPendingProcessChanges.clear();
2290            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2291        }
2292        int i = mProcessObservers.beginBroadcast();
2293        while (i > 0) {
2294            i--;
2295            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2296            if (observer != null) {
2297                try {
2298                    for (int j=0; j<N; j++) {
2299                        ProcessChangeItem item = mActiveProcessChanges[j];
2300                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2301                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2302                                    + item.pid + " uid=" + item.uid + ": "
2303                                    + item.foregroundActivities);
2304                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
2305                                    item.foregroundActivities);
2306                        }
2307                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2308                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2309                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
2310                            observer.onImportanceChanged(item.pid, item.uid,
2311                                    item.importance);
2312                        }
2313                    }
2314                } catch (RemoteException e) {
2315                }
2316            }
2317        }
2318        mProcessObservers.finishBroadcast();
2319    }
2320
2321    private void dispatchProcessDied(int pid, int uid) {
2322        int i = mProcessObservers.beginBroadcast();
2323        while (i > 0) {
2324            i--;
2325            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2326            if (observer != null) {
2327                try {
2328                    observer.onProcessDied(pid, uid);
2329                } catch (RemoteException e) {
2330                }
2331            }
2332        }
2333        mProcessObservers.finishBroadcast();
2334    }
2335
2336    final void doPendingActivityLaunchesLocked(boolean doResume) {
2337        final int N = mPendingActivityLaunches.size();
2338        if (N <= 0) {
2339            return;
2340        }
2341        for (int i=0; i<N; i++) {
2342            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2343            mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2344                    pal.startFlags, doResume && i == (N-1), null);
2345        }
2346        mPendingActivityLaunches.clear();
2347    }
2348
2349    public final int startActivity(IApplicationThread caller,
2350            Intent intent, String resolvedType, IBinder resultTo,
2351            String resultWho, int requestCode, int startFlags,
2352            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2353        enforceNotIsolatedCaller("startActivity");
2354        int userId = 0;
2355        if (intent.getCategories() != null && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
2356            // Requesting home, set the identity to the current user
2357            // HACK!
2358            userId = mCurrentUserId;
2359        } else {
2360            // TODO: Fix this in a better way - calls coming from SystemUI should probably carry
2361            // the current user's userId
2362            if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) {
2363                userId = 0;
2364            } else {
2365                userId = Binder.getOrigCallingUser();
2366            }
2367        }
2368        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2369                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2370                null, null, options, userId);
2371    }
2372
2373    public final WaitResult startActivityAndWait(IApplicationThread caller,
2374            Intent intent, String resolvedType, IBinder resultTo,
2375            String resultWho, int requestCode, int startFlags, String profileFile,
2376            ParcelFileDescriptor profileFd, Bundle options) {
2377        enforceNotIsolatedCaller("startActivityAndWait");
2378        WaitResult res = new WaitResult();
2379        int userId = Binder.getOrigCallingUser();
2380        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2381                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2382                res, null, options, userId);
2383        return res;
2384    }
2385
2386    public final int startActivityWithConfig(IApplicationThread caller,
2387            Intent intent, String resolvedType, IBinder resultTo,
2388            String resultWho, int requestCode, int startFlags, Configuration config,
2389            Bundle options) {
2390        enforceNotIsolatedCaller("startActivityWithConfig");
2391        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2392                resultTo, resultWho, requestCode, startFlags,
2393                null, null, null, config, options, Binder.getOrigCallingUser());
2394        return ret;
2395    }
2396
2397    public int startActivityIntentSender(IApplicationThread caller,
2398            IntentSender intent, Intent fillInIntent, String resolvedType,
2399            IBinder resultTo, String resultWho, int requestCode,
2400            int flagsMask, int flagsValues, Bundle options) {
2401        enforceNotIsolatedCaller("startActivityIntentSender");
2402        // Refuse possible leaked file descriptors
2403        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2404            throw new IllegalArgumentException("File descriptors passed in Intent");
2405        }
2406
2407        IIntentSender sender = intent.getTarget();
2408        if (!(sender instanceof PendingIntentRecord)) {
2409            throw new IllegalArgumentException("Bad PendingIntent object");
2410        }
2411
2412        PendingIntentRecord pir = (PendingIntentRecord)sender;
2413
2414        synchronized (this) {
2415            // If this is coming from the currently resumed activity, it is
2416            // effectively saying that app switches are allowed at this point.
2417            if (mMainStack.mResumedActivity != null
2418                    && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2419                            Binder.getCallingUid()) {
2420                mAppSwitchesAllowedTime = 0;
2421            }
2422        }
2423        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2424                resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2425        return ret;
2426    }
2427
2428    public boolean startNextMatchingActivity(IBinder callingActivity,
2429            Intent intent, Bundle options) {
2430        // Refuse possible leaked file descriptors
2431        if (intent != null && intent.hasFileDescriptors() == true) {
2432            throw new IllegalArgumentException("File descriptors passed in Intent");
2433        }
2434
2435        synchronized (this) {
2436            ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2437            if (r == null) {
2438                ActivityOptions.abort(options);
2439                return false;
2440            }
2441            if (r.app == null || r.app.thread == null) {
2442                // The caller is not running...  d'oh!
2443                ActivityOptions.abort(options);
2444                return false;
2445            }
2446            intent = new Intent(intent);
2447            // The caller is not allowed to change the data.
2448            intent.setDataAndType(r.intent.getData(), r.intent.getType());
2449            // And we are resetting to find the next component...
2450            intent.setComponent(null);
2451
2452            ActivityInfo aInfo = null;
2453            try {
2454                List<ResolveInfo> resolves =
2455                    AppGlobals.getPackageManager().queryIntentActivities(
2456                            intent, r.resolvedType,
2457                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2458                            UserId.getCallingUserId());
2459
2460                // Look for the original activity in the list...
2461                final int N = resolves != null ? resolves.size() : 0;
2462                for (int i=0; i<N; i++) {
2463                    ResolveInfo rInfo = resolves.get(i);
2464                    if (rInfo.activityInfo.packageName.equals(r.packageName)
2465                            && rInfo.activityInfo.name.equals(r.info.name)) {
2466                        // We found the current one...  the next matching is
2467                        // after it.
2468                        i++;
2469                        if (i<N) {
2470                            aInfo = resolves.get(i).activityInfo;
2471                        }
2472                        break;
2473                    }
2474                }
2475            } catch (RemoteException e) {
2476            }
2477
2478            if (aInfo == null) {
2479                // Nobody who is next!
2480                ActivityOptions.abort(options);
2481                return false;
2482            }
2483
2484            intent.setComponent(new ComponentName(
2485                    aInfo.applicationInfo.packageName, aInfo.name));
2486            intent.setFlags(intent.getFlags()&~(
2487                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2488                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
2489                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2490                    Intent.FLAG_ACTIVITY_NEW_TASK));
2491
2492            // Okay now we need to start the new activity, replacing the
2493            // currently running activity.  This is a little tricky because
2494            // we want to start the new one as if the current one is finished,
2495            // but not finish the current one first so that there is no flicker.
2496            // And thus...
2497            final boolean wasFinishing = r.finishing;
2498            r.finishing = true;
2499
2500            // Propagate reply information over to the new activity.
2501            final ActivityRecord resultTo = r.resultTo;
2502            final String resultWho = r.resultWho;
2503            final int requestCode = r.requestCode;
2504            r.resultTo = null;
2505            if (resultTo != null) {
2506                resultTo.removeResultsLocked(r, resultWho, requestCode);
2507            }
2508
2509            final long origId = Binder.clearCallingIdentity();
2510            int res = mMainStack.startActivityLocked(r.app.thread, intent,
2511                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2512                    resultWho, requestCode, -1, r.launchedFromUid, 0,
2513                    options, false, null);
2514            Binder.restoreCallingIdentity(origId);
2515
2516            r.finishing = wasFinishing;
2517            if (res != ActivityManager.START_SUCCESS) {
2518                return false;
2519            }
2520            return true;
2521        }
2522    }
2523
2524    public final int startActivityInPackage(int uid,
2525            Intent intent, String resolvedType, IBinder resultTo,
2526            String resultWho, int requestCode, int startFlags, Bundle options) {
2527
2528        // This is so super not safe, that only the system (or okay root)
2529        // can do it.
2530        int userId = Binder.getOrigCallingUser();
2531        final int callingUid = Binder.getCallingUid();
2532        if (callingUid != 0 && callingUid != Process.myUid()) {
2533            throw new SecurityException(
2534                    "startActivityInPackage only available to the system");
2535        }
2536
2537        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2538                resultTo, resultWho, requestCode, startFlags,
2539                null, null, null, null, options, userId);
2540        return ret;
2541    }
2542
2543    public final int startActivities(IApplicationThread caller,
2544            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
2545        enforceNotIsolatedCaller("startActivities");
2546        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2547                options, Binder.getOrigCallingUser());
2548        return ret;
2549    }
2550
2551    public final int startActivitiesInPackage(int uid,
2552            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2553            Bundle options) {
2554
2555        // This is so super not safe, that only the system (or okay root)
2556        // can do it.
2557        final int callingUid = Binder.getCallingUid();
2558        if (callingUid != 0 && callingUid != Process.myUid()) {
2559            throw new SecurityException(
2560                    "startActivityInPackage only available to the system");
2561        }
2562        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2563                options, UserId.getUserId(uid));
2564        return ret;
2565    }
2566
2567    final void addRecentTaskLocked(TaskRecord task) {
2568        int N = mRecentTasks.size();
2569        // Quick case: check if the top-most recent task is the same.
2570        if (N > 0 && mRecentTasks.get(0) == task) {
2571            return;
2572        }
2573        // Remove any existing entries that are the same kind of task.
2574        for (int i=0; i<N; i++) {
2575            TaskRecord tr = mRecentTasks.get(i);
2576            if (task.userId == tr.userId
2577                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
2578                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2579                mRecentTasks.remove(i);
2580                i--;
2581                N--;
2582                if (task.intent == null) {
2583                    // If the new recent task we are adding is not fully
2584                    // specified, then replace it with the existing recent task.
2585                    task = tr;
2586                }
2587            }
2588        }
2589        if (N >= MAX_RECENT_TASKS) {
2590            mRecentTasks.remove(N-1);
2591        }
2592        mRecentTasks.add(0, task);
2593    }
2594
2595    public void setRequestedOrientation(IBinder token,
2596            int requestedOrientation) {
2597        synchronized (this) {
2598            ActivityRecord r = mMainStack.isInStackLocked(token);
2599            if (r == null) {
2600                return;
2601            }
2602            final long origId = Binder.clearCallingIdentity();
2603            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2604            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2605                    mConfiguration,
2606                    r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2607            if (config != null) {
2608                r.frozenBeforeDestroy = true;
2609                if (!updateConfigurationLocked(config, r, false, false)) {
2610                    mMainStack.resumeTopActivityLocked(null);
2611                }
2612            }
2613            Binder.restoreCallingIdentity(origId);
2614        }
2615    }
2616
2617    public int getRequestedOrientation(IBinder token) {
2618        synchronized (this) {
2619            ActivityRecord r = mMainStack.isInStackLocked(token);
2620            if (r == null) {
2621                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2622            }
2623            return mWindowManager.getAppOrientation(r.appToken);
2624        }
2625    }
2626
2627    /**
2628     * This is the internal entry point for handling Activity.finish().
2629     *
2630     * @param token The Binder token referencing the Activity we want to finish.
2631     * @param resultCode Result code, if any, from this Activity.
2632     * @param resultData Result data (Intent), if any, from this Activity.
2633     *
2634     * @return Returns true if the activity successfully finished, or false if it is still running.
2635     */
2636    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2637        // Refuse possible leaked file descriptors
2638        if (resultData != null && resultData.hasFileDescriptors() == true) {
2639            throw new IllegalArgumentException("File descriptors passed in Intent");
2640        }
2641
2642        synchronized(this) {
2643            if (mController != null) {
2644                // Find the first activity that is not finishing.
2645                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2646                if (next != null) {
2647                    // ask watcher if this is allowed
2648                    boolean resumeOK = true;
2649                    try {
2650                        resumeOK = mController.activityResuming(next.packageName);
2651                    } catch (RemoteException e) {
2652                        mController = null;
2653                    }
2654
2655                    if (!resumeOK) {
2656                        return false;
2657                    }
2658                }
2659            }
2660            final long origId = Binder.clearCallingIdentity();
2661            boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2662                    resultData, "app-request");
2663            Binder.restoreCallingIdentity(origId);
2664            return res;
2665        }
2666    }
2667
2668    public final void finishHeavyWeightApp() {
2669        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2670                != PackageManager.PERMISSION_GRANTED) {
2671            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2672                    + Binder.getCallingPid()
2673                    + ", uid=" + Binder.getCallingUid()
2674                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2675            Slog.w(TAG, msg);
2676            throw new SecurityException(msg);
2677        }
2678
2679        synchronized(this) {
2680            if (mHeavyWeightProcess == null) {
2681                return;
2682            }
2683
2684            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2685                    mHeavyWeightProcess.activities);
2686            for (int i=0; i<activities.size(); i++) {
2687                ActivityRecord r = activities.get(i);
2688                if (!r.finishing) {
2689                    int index = mMainStack.indexOfTokenLocked(r.appToken);
2690                    if (index >= 0) {
2691                        mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2692                                null, "finish-heavy");
2693                    }
2694                }
2695            }
2696
2697            mHeavyWeightProcess = null;
2698            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2699        }
2700    }
2701
2702    public void crashApplication(int uid, int initialPid, String packageName,
2703            String message) {
2704        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2705                != PackageManager.PERMISSION_GRANTED) {
2706            String msg = "Permission Denial: crashApplication() from pid="
2707                    + Binder.getCallingPid()
2708                    + ", uid=" + Binder.getCallingUid()
2709                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2710            Slog.w(TAG, msg);
2711            throw new SecurityException(msg);
2712        }
2713
2714        synchronized(this) {
2715            ProcessRecord proc = null;
2716
2717            // Figure out which process to kill.  We don't trust that initialPid
2718            // still has any relation to current pids, so must scan through the
2719            // list.
2720            synchronized (mPidsSelfLocked) {
2721                for (int i=0; i<mPidsSelfLocked.size(); i++) {
2722                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
2723                    if (p.uid != uid) {
2724                        continue;
2725                    }
2726                    if (p.pid == initialPid) {
2727                        proc = p;
2728                        break;
2729                    }
2730                    for (String str : p.pkgList) {
2731                        if (str.equals(packageName)) {
2732                            proc = p;
2733                        }
2734                    }
2735                }
2736            }
2737
2738            if (proc == null) {
2739                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2740                        + " initialPid=" + initialPid
2741                        + " packageName=" + packageName);
2742                return;
2743            }
2744
2745            if (proc.thread != null) {
2746                if (proc.pid == Process.myPid()) {
2747                    Log.w(TAG, "crashApplication: trying to crash self!");
2748                    return;
2749                }
2750                long ident = Binder.clearCallingIdentity();
2751                try {
2752                    proc.thread.scheduleCrash(message);
2753                } catch (RemoteException e) {
2754                }
2755                Binder.restoreCallingIdentity(ident);
2756            }
2757        }
2758    }
2759
2760    public final void finishSubActivity(IBinder token, String resultWho,
2761            int requestCode) {
2762        synchronized(this) {
2763            final long origId = Binder.clearCallingIdentity();
2764            mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2765            Binder.restoreCallingIdentity(origId);
2766        }
2767    }
2768
2769    public boolean finishActivityAffinity(IBinder token) {
2770        synchronized(this) {
2771            final long origId = Binder.clearCallingIdentity();
2772            boolean res = mMainStack.finishActivityAffinityLocked(token);
2773            Binder.restoreCallingIdentity(origId);
2774            return res;
2775        }
2776    }
2777
2778    public boolean willActivityBeVisible(IBinder token) {
2779        synchronized(this) {
2780            int i;
2781            for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2782                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2783                if (r.appToken == token) {
2784                    return true;
2785                }
2786                if (r.fullscreen && !r.finishing) {
2787                    return false;
2788                }
2789            }
2790            return true;
2791        }
2792    }
2793
2794    public void overridePendingTransition(IBinder token, String packageName,
2795            int enterAnim, int exitAnim) {
2796        synchronized(this) {
2797            ActivityRecord self = mMainStack.isInStackLocked(token);
2798            if (self == null) {
2799                return;
2800            }
2801
2802            final long origId = Binder.clearCallingIdentity();
2803
2804            if (self.state == ActivityState.RESUMED
2805                    || self.state == ActivityState.PAUSING) {
2806                mWindowManager.overridePendingAppTransition(packageName,
2807                        enterAnim, exitAnim, null);
2808            }
2809
2810            Binder.restoreCallingIdentity(origId);
2811        }
2812    }
2813
2814    /**
2815     * Main function for removing an existing process from the activity manager
2816     * as a result of that process going away.  Clears out all connections
2817     * to the process.
2818     */
2819    private final void handleAppDiedLocked(ProcessRecord app,
2820            boolean restarting, boolean allowRestart) {
2821        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2822        if (!restarting) {
2823            mLruProcesses.remove(app);
2824        }
2825
2826        if (mProfileProc == app) {
2827            clearProfilerLocked();
2828        }
2829
2830        // Just in case...
2831        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2832            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2833            mMainStack.mPausingActivity = null;
2834        }
2835        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2836            mMainStack.mLastPausedActivity = null;
2837        }
2838
2839        // Remove this application's activities from active lists.
2840        mMainStack.removeHistoryRecordsForAppLocked(app);
2841
2842        boolean atTop = true;
2843        boolean hasVisibleActivities = false;
2844
2845        // Clean out the history list.
2846        int i = mMainStack.mHistory.size();
2847        if (localLOGV) Slog.v(
2848            TAG, "Removing app " + app + " from history with " + i + " entries");
2849        while (i > 0) {
2850            i--;
2851            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2852            if (localLOGV) Slog.v(
2853                TAG, "Record #" + i + " " + r + ": app=" + r.app);
2854            if (r.app == app) {
2855                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2856                    if (ActivityStack.DEBUG_ADD_REMOVE) {
2857                        RuntimeException here = new RuntimeException("here");
2858                        here.fillInStackTrace();
2859                        Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2860                                + ": haveState=" + r.haveState
2861                                + " stateNotNeeded=" + r.stateNotNeeded
2862                                + " finishing=" + r.finishing
2863                                + " state=" + r.state, here);
2864                    }
2865                    if (!r.finishing) {
2866                        Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2867                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2868                                System.identityHashCode(r),
2869                                r.task.taskId, r.shortComponentName,
2870                                "proc died without state saved");
2871                    }
2872                    mMainStack.removeActivityFromHistoryLocked(r);
2873
2874                } else {
2875                    // We have the current state for this activity, so
2876                    // it can be restarted later when needed.
2877                    if (localLOGV) Slog.v(
2878                        TAG, "Keeping entry, setting app to null");
2879                    if (r.visible) {
2880                        hasVisibleActivities = true;
2881                    }
2882                    r.app = null;
2883                    r.nowVisible = false;
2884                    if (!r.haveState) {
2885                        if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2886                                "App died, clearing saved state of " + r);
2887                        r.icicle = null;
2888                    }
2889                }
2890
2891                r.stack.cleanUpActivityLocked(r, true, true);
2892            }
2893            atTop = false;
2894        }
2895
2896        app.activities.clear();
2897
2898        if (app.instrumentationClass != null) {
2899            Slog.w(TAG, "Crash of app " + app.processName
2900                  + " running instrumentation " + app.instrumentationClass);
2901            Bundle info = new Bundle();
2902            info.putString("shortMsg", "Process crashed.");
2903            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2904        }
2905
2906        if (!restarting) {
2907            if (!mMainStack.resumeTopActivityLocked(null)) {
2908                // If there was nothing to resume, and we are not already
2909                // restarting this process, but there is a visible activity that
2910                // is hosted by the process...  then make sure all visible
2911                // activities are running, taking care of restarting this
2912                // process.
2913                if (hasVisibleActivities) {
2914                    mMainStack.ensureActivitiesVisibleLocked(null, 0);
2915                }
2916            }
2917        }
2918    }
2919
2920    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2921        IBinder threadBinder = thread.asBinder();
2922        // Find the application record.
2923        for (int i=mLruProcesses.size()-1; i>=0; i--) {
2924            ProcessRecord rec = mLruProcesses.get(i);
2925            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2926                return i;
2927            }
2928        }
2929        return -1;
2930    }
2931
2932    final ProcessRecord getRecordForAppLocked(
2933            IApplicationThread thread) {
2934        if (thread == null) {
2935            return null;
2936        }
2937
2938        int appIndex = getLRURecordIndexForAppLocked(thread);
2939        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
2940    }
2941
2942    final void appDiedLocked(ProcessRecord app, int pid,
2943            IApplicationThread thread) {
2944
2945        mProcDeaths[0]++;
2946
2947        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2948        synchronized (stats) {
2949            stats.noteProcessDiedLocked(app.info.uid, pid);
2950        }
2951
2952        // Clean up already done if the process has been re-started.
2953        if (app.pid == pid && app.thread != null &&
2954                app.thread.asBinder() == thread.asBinder()) {
2955            if (!app.killedBackground) {
2956                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2957                        + ") has died.");
2958            }
2959            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
2960            if (localLOGV) Slog.v(
2961                TAG, "Dying app: " + app + ", pid: " + pid
2962                + ", thread: " + thread.asBinder());
2963            boolean doLowMem = app.instrumentationClass == null;
2964            handleAppDiedLocked(app, false, true);
2965
2966            if (doLowMem) {
2967                // If there are no longer any background processes running,
2968                // and the app that died was not running instrumentation,
2969                // then tell everyone we are now low on memory.
2970                boolean haveBg = false;
2971                for (int i=mLruProcesses.size()-1; i>=0; i--) {
2972                    ProcessRecord rec = mLruProcesses.get(i);
2973                    if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
2974                        haveBg = true;
2975                        break;
2976                    }
2977                }
2978
2979                if (!haveBg) {
2980                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
2981                    long now = SystemClock.uptimeMillis();
2982                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
2983                        ProcessRecord rec = mLruProcesses.get(i);
2984                        if (rec != app && rec.thread != null &&
2985                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2986                            // The low memory report is overriding any current
2987                            // state for a GC request.  Make sure to do
2988                            // heavy/important/visible/foreground processes first.
2989                            if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
2990                                rec.lastRequestedGc = 0;
2991                            } else {
2992                                rec.lastRequestedGc = rec.lastLowMemory;
2993                            }
2994                            rec.reportLowMemory = true;
2995                            rec.lastLowMemory = now;
2996                            mProcessesToGc.remove(rec);
2997                            addProcessToGcListLocked(rec);
2998                        }
2999                    }
3000                    mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3001                    scheduleAppGcsLocked();
3002                }
3003            }
3004        } else if (app.pid != pid) {
3005            // A new process has already been started.
3006            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3007                    + ") has died and restarted (pid " + app.pid + ").");
3008            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
3009        } else if (DEBUG_PROCESSES) {
3010            Slog.d(TAG, "Received spurious death notification for thread "
3011                    + thread.asBinder());
3012        }
3013    }
3014
3015    /**
3016     * If a stack trace dump file is configured, dump process stack traces.
3017     * @param clearTraces causes the dump file to be erased prior to the new
3018     *    traces being written, if true; when false, the new traces will be
3019     *    appended to any existing file content.
3020     * @param firstPids of dalvik VM processes to dump stack traces for first
3021     * @param lastPids of dalvik VM processes to dump stack traces for last
3022     * @param nativeProcs optional list of native process names to dump stack crawls
3023     * @return file containing stack traces, or null if no dump file is configured
3024     */
3025    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3026            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3027        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3028        if (tracesPath == null || tracesPath.length() == 0) {
3029            return null;
3030        }
3031
3032        File tracesFile = new File(tracesPath);
3033        try {
3034            File tracesDir = tracesFile.getParentFile();
3035            if (!tracesDir.exists()) tracesFile.mkdirs();
3036            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3037
3038            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3039            tracesFile.createNewFile();
3040            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3041        } catch (IOException e) {
3042            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3043            return null;
3044        }
3045
3046        dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3047        return tracesFile;
3048    }
3049
3050    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3051            ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3052        // Use a FileObserver to detect when traces finish writing.
3053        // The order of traces is considered important to maintain for legibility.
3054        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3055            public synchronized void onEvent(int event, String path) { notify(); }
3056        };
3057
3058        try {
3059            observer.startWatching();
3060
3061            // First collect all of the stacks of the most important pids.
3062            if (firstPids != null) {
3063                try {
3064                    int num = firstPids.size();
3065                    for (int i = 0; i < num; i++) {
3066                        synchronized (observer) {
3067                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3068                            observer.wait(200);  // Wait for write-close, give up after 200msec
3069                        }
3070                    }
3071                } catch (InterruptedException e) {
3072                    Log.wtf(TAG, e);
3073                }
3074            }
3075
3076            // Next measure CPU usage.
3077            if (processStats != null) {
3078                processStats.init();
3079                System.gc();
3080                processStats.update();
3081                try {
3082                    synchronized (processStats) {
3083                        processStats.wait(500); // measure over 1/2 second.
3084                    }
3085                } catch (InterruptedException e) {
3086                }
3087                processStats.update();
3088
3089                // We'll take the stack crawls of just the top apps using CPU.
3090                final int N = processStats.countWorkingStats();
3091                int numProcs = 0;
3092                for (int i=0; i<N && numProcs<5; i++) {
3093                    ProcessStats.Stats stats = processStats.getWorkingStats(i);
3094                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3095                        numProcs++;
3096                        try {
3097                            synchronized (observer) {
3098                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3099                                observer.wait(200);  // Wait for write-close, give up after 200msec
3100                            }
3101                        } catch (InterruptedException e) {
3102                            Log.wtf(TAG, e);
3103                        }
3104
3105                    }
3106                }
3107            }
3108
3109        } finally {
3110            observer.stopWatching();
3111        }
3112
3113        if (nativeProcs != null) {
3114            int[] pids = Process.getPidsForCommands(nativeProcs);
3115            if (pids != null) {
3116                for (int pid : pids) {
3117                    Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3118                }
3119            }
3120        }
3121    }
3122
3123    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3124        if (true || IS_USER_BUILD) {
3125            return;
3126        }
3127        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3128        if (tracesPath == null || tracesPath.length() == 0) {
3129            return;
3130        }
3131
3132        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3133        StrictMode.allowThreadDiskWrites();
3134        try {
3135            final File tracesFile = new File(tracesPath);
3136            final File tracesDir = tracesFile.getParentFile();
3137            final File tracesTmp = new File(tracesDir, "__tmp__");
3138            try {
3139                if (!tracesDir.exists()) tracesFile.mkdirs();
3140                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3141
3142                if (tracesFile.exists()) {
3143                    tracesTmp.delete();
3144                    tracesFile.renameTo(tracesTmp);
3145                }
3146                StringBuilder sb = new StringBuilder();
3147                Time tobj = new Time();
3148                tobj.set(System.currentTimeMillis());
3149                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3150                sb.append(": ");
3151                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3152                sb.append(" since ");
3153                sb.append(msg);
3154                FileOutputStream fos = new FileOutputStream(tracesFile);
3155                fos.write(sb.toString().getBytes());
3156                if (app == null) {
3157                    fos.write("\n*** No application process!".getBytes());
3158                }
3159                fos.close();
3160                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3161            } catch (IOException e) {
3162                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3163                return;
3164            }
3165
3166            if (app != null) {
3167                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3168                firstPids.add(app.pid);
3169                dumpStackTraces(tracesPath, firstPids, null, null, null);
3170            }
3171
3172            File lastTracesFile = null;
3173            File curTracesFile = null;
3174            for (int i=9; i>=0; i--) {
3175                String name = String.format("slow%02d.txt", i);
3176                curTracesFile = new File(tracesDir, name);
3177                if (curTracesFile.exists()) {
3178                    if (lastTracesFile != null) {
3179                        curTracesFile.renameTo(lastTracesFile);
3180                    } else {
3181                        curTracesFile.delete();
3182                    }
3183                }
3184                lastTracesFile = curTracesFile;
3185            }
3186            tracesFile.renameTo(curTracesFile);
3187            if (tracesTmp.exists()) {
3188                tracesTmp.renameTo(tracesFile);
3189            }
3190        } finally {
3191            StrictMode.setThreadPolicy(oldPolicy);
3192        }
3193    }
3194
3195    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3196            ActivityRecord parent, final String annotation) {
3197        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3198        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3199
3200        if (mController != null) {
3201            try {
3202                // 0 == continue, -1 = kill process immediately
3203                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3204                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3205            } catch (RemoteException e) {
3206                mController = null;
3207            }
3208        }
3209
3210        long anrTime = SystemClock.uptimeMillis();
3211        if (MONITOR_CPU_USAGE) {
3212            updateCpuStatsNow();
3213        }
3214
3215        synchronized (this) {
3216            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3217            if (mShuttingDown) {
3218                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3219                return;
3220            } else if (app.notResponding) {
3221                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3222                return;
3223            } else if (app.crashing) {
3224                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3225                return;
3226            }
3227
3228            // In case we come through here for the same app before completing
3229            // this one, mark as anring now so we will bail out.
3230            app.notResponding = true;
3231
3232            // Log the ANR to the event log.
3233            EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3234                    annotation);
3235
3236            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3237            firstPids.add(app.pid);
3238
3239            int parentPid = app.pid;
3240            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3241            if (parentPid != app.pid) firstPids.add(parentPid);
3242
3243            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3244
3245            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3246                ProcessRecord r = mLruProcesses.get(i);
3247                if (r != null && r.thread != null) {
3248                    int pid = r.pid;
3249                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3250                        if (r.persistent) {
3251                            firstPids.add(pid);
3252                        } else {
3253                            lastPids.put(pid, Boolean.TRUE);
3254                        }
3255                    }
3256                }
3257            }
3258        }
3259
3260        // Log the ANR to the main log.
3261        StringBuilder info = new StringBuilder();
3262        info.setLength(0);
3263        info.append("ANR in ").append(app.processName);
3264        if (activity != null && activity.shortComponentName != null) {
3265            info.append(" (").append(activity.shortComponentName).append(")");
3266        }
3267        info.append("\n");
3268        if (annotation != null) {
3269            info.append("Reason: ").append(annotation).append("\n");
3270        }
3271        if (parent != null && parent != activity) {
3272            info.append("Parent: ").append(parent.shortComponentName).append("\n");
3273        }
3274
3275        final ProcessStats processStats = new ProcessStats(true);
3276
3277        File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3278
3279        String cpuInfo = null;
3280        if (MONITOR_CPU_USAGE) {
3281            updateCpuStatsNow();
3282            synchronized (mProcessStatsThread) {
3283                cpuInfo = mProcessStats.printCurrentState(anrTime);
3284            }
3285            info.append(processStats.printCurrentLoad());
3286            info.append(cpuInfo);
3287        }
3288
3289        info.append(processStats.printCurrentState(anrTime));
3290
3291        Slog.e(TAG, info.toString());
3292        if (tracesFile == null) {
3293            // There is no trace file, so dump (only) the alleged culprit's threads to the log
3294            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3295        }
3296
3297        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3298                cpuInfo, tracesFile, null);
3299
3300        if (mController != null) {
3301            try {
3302                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3303                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3304                if (res != 0) {
3305                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3306                    return;
3307                }
3308            } catch (RemoteException e) {
3309                mController = null;
3310            }
3311        }
3312
3313        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3314        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3315                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3316
3317        synchronized (this) {
3318            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3319                Slog.w(TAG, "Killing " + app + ": background ANR");
3320                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3321                        app.processName, app.setAdj, "background ANR");
3322                Process.killProcessQuiet(app.pid);
3323                return;
3324            }
3325
3326            // Set the app's notResponding state, and look up the errorReportReceiver
3327            makeAppNotRespondingLocked(app,
3328                    activity != null ? activity.shortComponentName : null,
3329                    annotation != null ? "ANR " + annotation : "ANR",
3330                    info.toString());
3331
3332            // Bring up the infamous App Not Responding dialog
3333            Message msg = Message.obtain();
3334            HashMap map = new HashMap();
3335            msg.what = SHOW_NOT_RESPONDING_MSG;
3336            msg.obj = map;
3337            map.put("app", app);
3338            if (activity != null) {
3339                map.put("activity", activity);
3340            }
3341
3342            mHandler.sendMessage(msg);
3343        }
3344    }
3345
3346    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3347        if (!mLaunchWarningShown) {
3348            mLaunchWarningShown = true;
3349            mHandler.post(new Runnable() {
3350                @Override
3351                public void run() {
3352                    synchronized (ActivityManagerService.this) {
3353                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3354                        d.show();
3355                        mHandler.postDelayed(new Runnable() {
3356                            @Override
3357                            public void run() {
3358                                synchronized (ActivityManagerService.this) {
3359                                    d.dismiss();
3360                                    mLaunchWarningShown = false;
3361                                }
3362                            }
3363                        }, 4000);
3364                    }
3365                }
3366            });
3367        }
3368    }
3369
3370    public boolean clearApplicationUserData(final String packageName,
3371            final IPackageDataObserver observer, final int userId) {
3372        enforceNotIsolatedCaller("clearApplicationUserData");
3373        int uid = Binder.getCallingUid();
3374        int pid = Binder.getCallingPid();
3375        long callingId = Binder.clearCallingIdentity();
3376        try {
3377            IPackageManager pm = AppGlobals.getPackageManager();
3378            int pkgUid = -1;
3379            synchronized(this) {
3380                try {
3381                    pkgUid = pm.getPackageUid(packageName, userId);
3382                } catch (RemoteException e) {
3383                }
3384                if (pkgUid == -1) {
3385                    Slog.w(TAG, "Invalid packageName:" + packageName);
3386                    return false;
3387                }
3388                if (uid == pkgUid || checkComponentPermission(
3389                        android.Manifest.permission.CLEAR_APP_USER_DATA,
3390                        pid, uid, -1, true)
3391                        == PackageManager.PERMISSION_GRANTED) {
3392                    forceStopPackageLocked(packageName, pkgUid);
3393                } else {
3394                    throw new SecurityException(pid+" does not have permission:"+
3395                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3396                                    "for process:"+packageName);
3397                }
3398            }
3399
3400            try {
3401                //clear application user data
3402                pm.clearApplicationUserData(packageName, observer, userId);
3403                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3404                        Uri.fromParts("package", packageName, null));
3405                intent.putExtra(Intent.EXTRA_UID, pkgUid);
3406                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3407                        null, null, 0, null, null, null, false, false, userId);
3408            } catch (RemoteException e) {
3409            }
3410        } finally {
3411            Binder.restoreCallingIdentity(callingId);
3412        }
3413        return true;
3414    }
3415
3416    public void killBackgroundProcesses(final String packageName) {
3417        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3418                != PackageManager.PERMISSION_GRANTED &&
3419                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3420                        != PackageManager.PERMISSION_GRANTED) {
3421            String msg = "Permission Denial: killBackgroundProcesses() from pid="
3422                    + Binder.getCallingPid()
3423                    + ", uid=" + Binder.getCallingUid()
3424                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3425            Slog.w(TAG, msg);
3426            throw new SecurityException(msg);
3427        }
3428
3429        int userId = UserId.getCallingUserId();
3430        long callingId = Binder.clearCallingIdentity();
3431        try {
3432            IPackageManager pm = AppGlobals.getPackageManager();
3433            int pkgUid = -1;
3434            synchronized(this) {
3435                try {
3436                    pkgUid = pm.getPackageUid(packageName, userId);
3437                } catch (RemoteException e) {
3438                }
3439                if (pkgUid == -1) {
3440                    Slog.w(TAG, "Invalid packageName: " + packageName);
3441                    return;
3442                }
3443                killPackageProcessesLocked(packageName, pkgUid,
3444                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3445            }
3446        } finally {
3447            Binder.restoreCallingIdentity(callingId);
3448        }
3449    }
3450
3451    public void killAllBackgroundProcesses() {
3452        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3453                != PackageManager.PERMISSION_GRANTED) {
3454            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3455                    + Binder.getCallingPid()
3456                    + ", uid=" + Binder.getCallingUid()
3457                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3458            Slog.w(TAG, msg);
3459            throw new SecurityException(msg);
3460        }
3461
3462        long callingId = Binder.clearCallingIdentity();
3463        try {
3464            synchronized(this) {
3465                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3466                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3467                    final int NA = apps.size();
3468                    for (int ia=0; ia<NA; ia++) {
3469                        ProcessRecord app = apps.valueAt(ia);
3470                        if (app.persistent) {
3471                            // we don't kill persistent processes
3472                            continue;
3473                        }
3474                        if (app.removed) {
3475                            procs.add(app);
3476                        } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3477                            app.removed = true;
3478                            procs.add(app);
3479                        }
3480                    }
3481                }
3482
3483                int N = procs.size();
3484                for (int i=0; i<N; i++) {
3485                    removeProcessLocked(procs.get(i), false, true, "kill all background");
3486                }
3487            }
3488        } finally {
3489            Binder.restoreCallingIdentity(callingId);
3490        }
3491    }
3492
3493    public void forceStopPackage(final String packageName) {
3494        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3495                != PackageManager.PERMISSION_GRANTED) {
3496            String msg = "Permission Denial: forceStopPackage() from pid="
3497                    + Binder.getCallingPid()
3498                    + ", uid=" + Binder.getCallingUid()
3499                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3500            Slog.w(TAG, msg);
3501            throw new SecurityException(msg);
3502        }
3503        final int userId = UserId.getCallingUserId();
3504        long callingId = Binder.clearCallingIdentity();
3505        try {
3506            IPackageManager pm = AppGlobals.getPackageManager();
3507            int pkgUid = -1;
3508            synchronized(this) {
3509                try {
3510                    pkgUid = pm.getPackageUid(packageName, userId);
3511                } catch (RemoteException e) {
3512                }
3513                if (pkgUid == -1) {
3514                    Slog.w(TAG, "Invalid packageName: " + packageName);
3515                    return;
3516                }
3517                forceStopPackageLocked(packageName, pkgUid);
3518                try {
3519                    pm.setPackageStoppedState(packageName, true, userId);
3520                } catch (RemoteException e) {
3521                } catch (IllegalArgumentException e) {
3522                    Slog.w(TAG, "Failed trying to unstop package "
3523                            + packageName + ": " + e);
3524                }
3525            }
3526        } finally {
3527            Binder.restoreCallingIdentity(callingId);
3528        }
3529    }
3530
3531    /*
3532     * The pkg name and uid have to be specified.
3533     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3534     */
3535    public void killApplicationWithUid(String pkg, int uid) {
3536        if (pkg == null) {
3537            return;
3538        }
3539        // Make sure the uid is valid.
3540        if (uid < 0) {
3541            Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
3542            return;
3543        }
3544        int callerUid = Binder.getCallingUid();
3545        // Only the system server can kill an application
3546        if (callerUid == Process.SYSTEM_UID) {
3547            // Post an aysnc message to kill the application
3548            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3549            msg.arg1 = uid;
3550            msg.arg2 = 0;
3551            msg.obj = pkg;
3552            mHandler.sendMessage(msg);
3553        } else {
3554            throw new SecurityException(callerUid + " cannot kill pkg: " +
3555                    pkg);
3556        }
3557    }
3558
3559    public void closeSystemDialogs(String reason) {
3560        enforceNotIsolatedCaller("closeSystemDialogs");
3561
3562        final int uid = Binder.getCallingUid();
3563        final long origId = Binder.clearCallingIdentity();
3564        synchronized (this) {
3565            closeSystemDialogsLocked(uid, reason);
3566        }
3567        Binder.restoreCallingIdentity(origId);
3568    }
3569
3570    void closeSystemDialogsLocked(int callingUid, String reason) {
3571        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3572        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3573        if (reason != null) {
3574            intent.putExtra("reason", reason);
3575        }
3576        mWindowManager.closeSystemDialogs(reason);
3577
3578        for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3579            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3580            if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3581                r.stack.finishActivityLocked(r, i,
3582                        Activity.RESULT_CANCELED, null, "close-sys");
3583            }
3584        }
3585
3586        broadcastIntentLocked(null, null, intent, null,
3587                null, 0, null, null, null, false, false, -1,
3588                callingUid, 0 /* TODO: Verify */);
3589    }
3590
3591    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3592            throws RemoteException {
3593        enforceNotIsolatedCaller("getProcessMemoryInfo");
3594        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3595        for (int i=pids.length-1; i>=0; i--) {
3596            infos[i] = new Debug.MemoryInfo();
3597            Debug.getMemoryInfo(pids[i], infos[i]);
3598        }
3599        return infos;
3600    }
3601
3602    public long[] getProcessPss(int[] pids) throws RemoteException {
3603        enforceNotIsolatedCaller("getProcessPss");
3604        long[] pss = new long[pids.length];
3605        for (int i=pids.length-1; i>=0; i--) {
3606            pss[i] = Debug.getPss(pids[i]);
3607        }
3608        return pss;
3609    }
3610
3611    public void killApplicationProcess(String processName, int uid) {
3612        if (processName == null) {
3613            return;
3614        }
3615
3616        int callerUid = Binder.getCallingUid();
3617        // Only the system server can kill an application
3618        if (callerUid == Process.SYSTEM_UID) {
3619            synchronized (this) {
3620                ProcessRecord app = getProcessRecordLocked(processName, uid);
3621                if (app != null && app.thread != null) {
3622                    try {
3623                        app.thread.scheduleSuicide();
3624                    } catch (RemoteException e) {
3625                        // If the other end already died, then our work here is done.
3626                    }
3627                } else {
3628                    Slog.w(TAG, "Process/uid not found attempting kill of "
3629                            + processName + " / " + uid);
3630                }
3631            }
3632        } else {
3633            throw new SecurityException(callerUid + " cannot kill app process: " +
3634                    processName);
3635        }
3636    }
3637
3638    private void forceStopPackageLocked(final String packageName, int uid) {
3639        forceStopPackageLocked(packageName, uid, false, false, true, false, UserId.getUserId(uid));
3640        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3641                Uri.fromParts("package", packageName, null));
3642        if (!mProcessesReady) {
3643            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3644        }
3645        intent.putExtra(Intent.EXTRA_UID, uid);
3646        broadcastIntentLocked(null, null, intent,
3647                null, null, 0, null, null, null,
3648                false, false,
3649                MY_PID, Process.SYSTEM_UID, UserId.getUserId(uid));
3650    }
3651
3652    private final boolean killPackageProcessesLocked(String packageName, int uid,
3653            int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
3654            boolean evenPersistent, String reason) {
3655        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3656
3657        // Remove all processes this package may have touched: all with the
3658        // same UID (except for the system or root user), and all whose name
3659        // matches the package name.
3660        final String procNamePrefix = packageName + ":";
3661        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3662            final int NA = apps.size();
3663            for (int ia=0; ia<NA; ia++) {
3664                ProcessRecord app = apps.valueAt(ia);
3665                if (app.persistent && !evenPersistent) {
3666                    // we don't kill persistent processes
3667                    continue;
3668                }
3669                if (app.removed) {
3670                    if (doit) {
3671                        procs.add(app);
3672                    }
3673                // If uid is specified and the uid and process name match
3674                // Or, the uid is not specified and the process name matches
3675                } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3676                            || ((app.processName.equals(packageName)
3677                                 || app.processName.startsWith(procNamePrefix))
3678                                && uid < 0))) {
3679                    if (app.setAdj >= minOomAdj) {
3680                        if (!doit) {
3681                            return true;
3682                        }
3683                        app.removed = true;
3684                        procs.add(app);
3685                    }
3686                }
3687            }
3688        }
3689
3690        int N = procs.size();
3691        for (int i=0; i<N; i++) {
3692            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3693        }
3694        return N > 0;
3695    }
3696
3697    private final boolean forceStopPackageLocked(String name, int uid,
3698            boolean callerWillRestart, boolean purgeCache, boolean doit,
3699            boolean evenPersistent, int userId) {
3700        int i;
3701        int N;
3702
3703        if (uid < 0) {
3704            try {
3705                uid = AppGlobals.getPackageManager().getPackageUid(name, userId);
3706            } catch (RemoteException e) {
3707            }
3708        }
3709
3710        if (doit) {
3711            Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
3712
3713            Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3714            while (badApps.hasNext()) {
3715                SparseArray<Long> ba = badApps.next();
3716                if (ba.get(uid) != null) {
3717                    badApps.remove();
3718                }
3719            }
3720        }
3721
3722        boolean didSomething = killPackageProcessesLocked(name, uid, -100,
3723                callerWillRestart, false, doit, evenPersistent, "force stop");
3724
3725        TaskRecord lastTask = null;
3726        for (i=0; i<mMainStack.mHistory.size(); i++) {
3727            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3728            final boolean samePackage = r.packageName.equals(name);
3729            if (r.userId == userId
3730                    && (samePackage || r.task == lastTask)
3731                    && (r.app == null || evenPersistent || !r.app.persistent)) {
3732                if (!doit) {
3733                    if (r.finishing) {
3734                        // If this activity is just finishing, then it is not
3735                        // interesting as far as something to stop.
3736                        continue;
3737                    }
3738                    return true;
3739                }
3740                didSomething = true;
3741                Slog.i(TAG, "  Force finishing activity " + r);
3742                if (samePackage) {
3743                    if (r.app != null) {
3744                        r.app.removed = true;
3745                    }
3746                    r.app = null;
3747                }
3748                lastTask = r.task;
3749                if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3750                        null, "force-stop", true)) {
3751                    i--;
3752                }
3753            }
3754        }
3755
3756        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3757        for (ServiceRecord service : mServiceMap.getAllServices(userId)) {
3758            if (service.packageName.equals(name)
3759                    && (service.app == null || evenPersistent || !service.app.persistent)) {
3760                if (!doit) {
3761                    return true;
3762                }
3763                didSomething = true;
3764                Slog.i(TAG, "  Force stopping service " + service);
3765                if (service.app != null) {
3766                    service.app.removed = true;
3767                }
3768                service.app = null;
3769                service.isolatedProc = null;
3770                services.add(service);
3771            }
3772        }
3773
3774        N = services.size();
3775        for (i=0; i<N; i++) {
3776            bringDownServiceLocked(services.get(i), true);
3777        }
3778
3779        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3780        for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) {
3781            if (provider.info.packageName.equals(name)
3782                    && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3783                if (!doit) {
3784                    return true;
3785                }
3786                didSomething = true;
3787                providers.add(provider);
3788            }
3789        }
3790
3791        N = providers.size();
3792        for (i=0; i<N; i++) {
3793            removeDyingProviderLocked(null, providers.get(i), true);
3794        }
3795
3796        if (doit) {
3797            if (purgeCache) {
3798                AttributeCache ac = AttributeCache.instance();
3799                if (ac != null) {
3800                    ac.removePackage(name);
3801                }
3802            }
3803            if (mBooted) {
3804                mMainStack.resumeTopActivityLocked(null);
3805                mMainStack.scheduleIdleLocked();
3806            }
3807        }
3808
3809        return didSomething;
3810    }
3811
3812    private final boolean removeProcessLocked(ProcessRecord app,
3813            boolean callerWillRestart, boolean allowRestart, String reason) {
3814        final String name = app.processName;
3815        final int uid = app.uid;
3816        if (DEBUG_PROCESSES) Slog.d(
3817            TAG, "Force removing proc " + app.toShortString() + " (" + name
3818            + "/" + uid + ")");
3819
3820        mProcessNames.remove(name, uid);
3821        mIsolatedProcesses.remove(app.uid);
3822        if (mHeavyWeightProcess == app) {
3823            mHeavyWeightProcess = null;
3824            mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3825        }
3826        boolean needRestart = false;
3827        if (app.pid > 0 && app.pid != MY_PID) {
3828            int pid = app.pid;
3829            synchronized (mPidsSelfLocked) {
3830                mPidsSelfLocked.remove(pid);
3831                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3832            }
3833            Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
3834            handleAppDiedLocked(app, true, allowRestart);
3835            mLruProcesses.remove(app);
3836            Process.killProcessQuiet(pid);
3837
3838            if (app.persistent && !app.isolated) {
3839                if (!callerWillRestart) {
3840                    addAppLocked(app.info, false);
3841                } else {
3842                    needRestart = true;
3843                }
3844            }
3845        } else {
3846            mRemovedProcesses.add(app);
3847        }
3848
3849        return needRestart;
3850    }
3851
3852    private final void processStartTimedOutLocked(ProcessRecord app) {
3853        final int pid = app.pid;
3854        boolean gone = false;
3855        synchronized (mPidsSelfLocked) {
3856            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3857            if (knownApp != null && knownApp.thread == null) {
3858                mPidsSelfLocked.remove(pid);
3859                gone = true;
3860            }
3861        }
3862
3863        if (gone) {
3864            Slog.w(TAG, "Process " + app + " failed to attach");
3865            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
3866                    app.processName);
3867            mProcessNames.remove(app.processName, app.uid);
3868            mIsolatedProcesses.remove(app.uid);
3869            if (mHeavyWeightProcess == app) {
3870                mHeavyWeightProcess = null;
3871                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3872            }
3873            // Take care of any launching providers waiting for this process.
3874            checkAppInLaunchingProvidersLocked(app, true);
3875            // Take care of any services that are waiting for the process.
3876            for (int i=0; i<mPendingServices.size(); i++) {
3877                ServiceRecord sr = mPendingServices.get(i);
3878                if ((app.uid == sr.appInfo.uid
3879                        && app.processName.equals(sr.processName))
3880                        || sr.isolatedProc == app) {
3881                    Slog.w(TAG, "Forcing bringing down service: " + sr);
3882                    sr.isolatedProc = null;
3883                    mPendingServices.remove(i);
3884                    i--;
3885                    bringDownServiceLocked(sr, true);
3886                }
3887            }
3888            EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3889                    app.processName, app.setAdj, "start timeout");
3890            Process.killProcessQuiet(pid);
3891            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
3892                Slog.w(TAG, "Unattached app died before backup, skipping");
3893                try {
3894                    IBackupManager bm = IBackupManager.Stub.asInterface(
3895                            ServiceManager.getService(Context.BACKUP_SERVICE));
3896                    bm.agentDisconnected(app.info.packageName);
3897                } catch (RemoteException e) {
3898                    // Can't happen; the backup manager is local
3899                }
3900            }
3901            if (isPendingBroadcastProcessLocked(pid)) {
3902                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
3903                skipPendingBroadcastLocked(pid);
3904            }
3905        } else {
3906            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
3907        }
3908    }
3909
3910    private final boolean attachApplicationLocked(IApplicationThread thread,
3911            int pid) {
3912
3913        // Find the application record that is being attached...  either via
3914        // the pid if we are running in multiple processes, or just pull the
3915        // next app record if we are emulating process with anonymous threads.
3916        ProcessRecord app;
3917        if (pid != MY_PID && pid >= 0) {
3918            synchronized (mPidsSelfLocked) {
3919                app = mPidsSelfLocked.get(pid);
3920            }
3921        } else {
3922            app = null;
3923        }
3924
3925        if (app == null) {
3926            Slog.w(TAG, "No pending application record for pid " + pid
3927                    + " (IApplicationThread " + thread + "); dropping process");
3928            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
3929            if (pid > 0 && pid != MY_PID) {
3930                Process.killProcessQuiet(pid);
3931            } else {
3932                try {
3933                    thread.scheduleExit();
3934                } catch (Exception e) {
3935                    // Ignore exceptions.
3936                }
3937            }
3938            return false;
3939        }
3940
3941        // If this application record is still attached to a previous
3942        // process, clean it up now.
3943        if (app.thread != null) {
3944            handleAppDiedLocked(app, true, true);
3945        }
3946
3947        // Tell the process all about itself.
3948
3949        if (localLOGV) Slog.v(
3950                TAG, "Binding process pid " + pid + " to record " + app);
3951
3952        String processName = app.processName;
3953        try {
3954            AppDeathRecipient adr = new AppDeathRecipient(
3955                    app, pid, thread);
3956            thread.asBinder().linkToDeath(adr, 0);
3957            app.deathRecipient = adr;
3958        } catch (RemoteException e) {
3959            app.resetPackageList();
3960            startProcessLocked(app, "link fail", processName);
3961            return false;
3962        }
3963
3964        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
3965
3966        app.thread = thread;
3967        app.curAdj = app.setAdj = -100;
3968        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3969        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
3970        app.forcingToForeground = null;
3971        app.foregroundServices = false;
3972        app.hasShownUi = false;
3973        app.debugging = false;
3974
3975        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3976
3977        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
3978        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
3979
3980        if (!normalMode) {
3981            Slog.i(TAG, "Launching preboot mode app: " + app);
3982        }
3983
3984        if (localLOGV) Slog.v(
3985            TAG, "New app record " + app
3986            + " thread=" + thread.asBinder() + " pid=" + pid);
3987        try {
3988            int testMode = IApplicationThread.DEBUG_OFF;
3989            if (mDebugApp != null && mDebugApp.equals(processName)) {
3990                testMode = mWaitForDebugger
3991                    ? IApplicationThread.DEBUG_WAIT
3992                    : IApplicationThread.DEBUG_ON;
3993                app.debugging = true;
3994                if (mDebugTransient) {
3995                    mDebugApp = mOrigDebugApp;
3996                    mWaitForDebugger = mOrigWaitForDebugger;
3997                }
3998            }
3999            String profileFile = app.instrumentationProfileFile;
4000            ParcelFileDescriptor profileFd = null;
4001            boolean profileAutoStop = false;
4002            if (mProfileApp != null && mProfileApp.equals(processName)) {
4003                mProfileProc = app;
4004                profileFile = mProfileFile;
4005                profileFd = mProfileFd;
4006                profileAutoStop = mAutoStopProfiler;
4007            }
4008            boolean enableOpenGlTrace = false;
4009            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4010                enableOpenGlTrace = true;
4011                mOpenGlTraceApp = null;
4012            }
4013
4014            // If the app is being launched for restore or full backup, set it up specially
4015            boolean isRestrictedBackupMode = false;
4016            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4017                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4018                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4019                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4020            }
4021
4022            ensurePackageDexOpt(app.instrumentationInfo != null
4023                    ? app.instrumentationInfo.packageName
4024                    : app.info.packageName);
4025            if (app.instrumentationClass != null) {
4026                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4027            }
4028            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4029                    + processName + " with config " + mConfiguration);
4030            ApplicationInfo appInfo = app.instrumentationInfo != null
4031                    ? app.instrumentationInfo : app.info;
4032            app.compat = compatibilityInfoForPackageLocked(appInfo);
4033            if (profileFd != null) {
4034                profileFd = profileFd.dup();
4035            }
4036            thread.bindApplication(processName, appInfo, providers,
4037                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4038                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4039                    enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4040                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4041                    mCoreSettingsObserver.getCoreSettingsLocked());
4042            updateLruProcessLocked(app, false, true);
4043            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4044        } catch (Exception e) {
4045            // todo: Yikes!  What should we do?  For now we will try to
4046            // start another process, but that could easily get us in
4047            // an infinite loop of restarting processes...
4048            Slog.w(TAG, "Exception thrown during bind!", e);
4049
4050            app.resetPackageList();
4051            app.unlinkDeathRecipient();
4052            startProcessLocked(app, "bind fail", processName);
4053            return false;
4054        }
4055
4056        // Remove this record from the list of starting applications.
4057        mPersistentStartingProcesses.remove(app);
4058        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4059                "Attach application locked removing on hold: " + app);
4060        mProcessesOnHold.remove(app);
4061
4062        boolean badApp = false;
4063        boolean didSomething = false;
4064
4065        // See if the top visible activity is waiting to run in this process...
4066        ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4067        if (hr != null && normalMode) {
4068            if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4069                    && processName.equals(hr.processName)) {
4070                try {
4071                    if (mHeadless) {
4072                        Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4073                    } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4074                        didSomething = true;
4075                    }
4076                } catch (Exception e) {
4077                    Slog.w(TAG, "Exception in new application when starting activity "
4078                          + hr.intent.getComponent().flattenToShortString(), e);
4079                    badApp = true;
4080                }
4081            } else {
4082                mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4083            }
4084        }
4085
4086        // Find any services that should be running in this process...
4087        if (!badApp && mPendingServices.size() > 0) {
4088            ServiceRecord sr = null;
4089            try {
4090                for (int i=0; i<mPendingServices.size(); i++) {
4091                    sr = mPendingServices.get(i);
4092                    if (app != sr.isolatedProc && (app.uid != sr.appInfo.uid
4093                            || !processName.equals(sr.processName))) {
4094                        continue;
4095                    }
4096
4097                    mPendingServices.remove(i);
4098                    i--;
4099                    realStartServiceLocked(sr, app);
4100                    didSomething = true;
4101                }
4102            } catch (Exception e) {
4103                Slog.w(TAG, "Exception in new application when starting service "
4104                      + sr.shortName, e);
4105                badApp = true;
4106            }
4107        }
4108
4109        // Check if a next-broadcast receiver is in this process...
4110        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4111            try {
4112                didSomething = sendPendingBroadcastsLocked(app);
4113            } catch (Exception e) {
4114                // If the app died trying to launch the receiver we declare it 'bad'
4115                badApp = true;
4116            }
4117        }
4118
4119        // Check whether the next backup agent is in this process...
4120        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4121            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4122            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4123            try {
4124                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4125                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4126                        mBackupTarget.backupMode);
4127            } catch (Exception e) {
4128                Slog.w(TAG, "Exception scheduling backup agent creation: ");
4129                e.printStackTrace();
4130            }
4131        }
4132
4133        if (badApp) {
4134            // todo: Also need to kill application to deal with all
4135            // kinds of exceptions.
4136            handleAppDiedLocked(app, false, true);
4137            return false;
4138        }
4139
4140        if (!didSomething) {
4141            updateOomAdjLocked();
4142        }
4143
4144        return true;
4145    }
4146
4147    public final void attachApplication(IApplicationThread thread) {
4148        synchronized (this) {
4149            int callingPid = Binder.getCallingPid();
4150            final long origId = Binder.clearCallingIdentity();
4151            attachApplicationLocked(thread, callingPid);
4152            Binder.restoreCallingIdentity(origId);
4153        }
4154    }
4155
4156    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4157        final long origId = Binder.clearCallingIdentity();
4158        ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4159        if (stopProfiling) {
4160            synchronized (this) {
4161                if (mProfileProc == r.app) {
4162                    if (mProfileFd != null) {
4163                        try {
4164                            mProfileFd.close();
4165                        } catch (IOException e) {
4166                        }
4167                        clearProfilerLocked();
4168                    }
4169                }
4170            }
4171        }
4172        Binder.restoreCallingIdentity(origId);
4173    }
4174
4175    void enableScreenAfterBoot() {
4176        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4177                SystemClock.uptimeMillis());
4178        mWindowManager.enableScreenAfterBoot();
4179
4180        synchronized (this) {
4181            updateEventDispatchingLocked();
4182        }
4183    }
4184
4185    public void showBootMessage(final CharSequence msg, final boolean always) {
4186        enforceNotIsolatedCaller("showBootMessage");
4187        mWindowManager.showBootMessage(msg, always);
4188    }
4189
4190    public void dismissKeyguardOnNextActivity() {
4191        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4192        final long token = Binder.clearCallingIdentity();
4193        try {
4194            synchronized (this) {
4195                if (mLockScreenShown) {
4196                    mLockScreenShown = false;
4197                    comeOutOfSleepIfNeededLocked();
4198                }
4199                mMainStack.dismissKeyguardOnNextActivityLocked();
4200            }
4201        } finally {
4202            Binder.restoreCallingIdentity(token);
4203        }
4204    }
4205
4206    final void finishBooting() {
4207        IntentFilter pkgFilter = new IntentFilter();
4208        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4209        pkgFilter.addDataScheme("package");
4210        mContext.registerReceiver(new BroadcastReceiver() {
4211            @Override
4212            public void onReceive(Context context, Intent intent) {
4213                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4214                if (pkgs != null) {
4215                    for (String pkg : pkgs) {
4216                        synchronized (ActivityManagerService.this) {
4217                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4218                                setResultCode(Activity.RESULT_OK);
4219                                return;
4220                            }
4221                        }
4222                    }
4223                }
4224            }
4225        }, pkgFilter);
4226
4227        IntentFilter userFilter = new IntentFilter();
4228        userFilter.addAction(Intent.ACTION_USER_REMOVED);
4229        mContext.registerReceiver(new BroadcastReceiver() {
4230            @Override
4231            public void onReceive(Context context, Intent intent) {
4232                onUserRemoved(intent);
4233            }
4234        }, userFilter);
4235
4236        synchronized (this) {
4237            // Ensure that any processes we had put on hold are now started
4238            // up.
4239            final int NP = mProcessesOnHold.size();
4240            if (NP > 0) {
4241                ArrayList<ProcessRecord> procs =
4242                    new ArrayList<ProcessRecord>(mProcessesOnHold);
4243                for (int ip=0; ip<NP; ip++) {
4244                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4245                            + procs.get(ip));
4246                    startProcessLocked(procs.get(ip), "on-hold", null);
4247                }
4248            }
4249
4250            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4251                // Start looking for apps that are abusing wake locks.
4252                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4253                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4254                // Tell anyone interested that we are done booting!
4255                SystemProperties.set("sys.boot_completed", "1");
4256                SystemProperties.set("dev.bootcomplete", "1");
4257                /* TODO: Send this to all users that are to be logged in on startup */
4258                broadcastIntentLocked(null, null,
4259                        new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4260                        null, null, 0, null, null,
4261                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4262                        false, false, MY_PID, Process.SYSTEM_UID, Binder.getOrigCallingUser());
4263            }
4264        }
4265    }
4266
4267    final void ensureBootCompleted() {
4268        boolean booting;
4269        boolean enableScreen;
4270        synchronized (this) {
4271            booting = mBooting;
4272            mBooting = false;
4273            enableScreen = !mBooted;
4274            mBooted = true;
4275        }
4276
4277        if (booting) {
4278            finishBooting();
4279        }
4280
4281        if (enableScreen) {
4282            enableScreenAfterBoot();
4283        }
4284    }
4285
4286    public final void activityPaused(IBinder token) {
4287        final long origId = Binder.clearCallingIdentity();
4288        mMainStack.activityPaused(token, false);
4289        Binder.restoreCallingIdentity(origId);
4290    }
4291
4292    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4293            CharSequence description) {
4294        if (localLOGV) Slog.v(
4295            TAG, "Activity stopped: token=" + token);
4296
4297        // Refuse possible leaked file descriptors
4298        if (icicle != null && icicle.hasFileDescriptors()) {
4299            throw new IllegalArgumentException("File descriptors passed in Bundle");
4300        }
4301
4302        ActivityRecord r = null;
4303
4304        final long origId = Binder.clearCallingIdentity();
4305
4306        synchronized (this) {
4307            r = mMainStack.isInStackLocked(token);
4308            if (r != null) {
4309                r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4310            }
4311        }
4312
4313        if (r != null) {
4314            sendPendingThumbnail(r, null, null, null, false);
4315        }
4316
4317        trimApplications();
4318
4319        Binder.restoreCallingIdentity(origId);
4320    }
4321
4322    public final void activityDestroyed(IBinder token) {
4323        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4324        mMainStack.activityDestroyed(token);
4325    }
4326
4327    public String getCallingPackage(IBinder token) {
4328        synchronized (this) {
4329            ActivityRecord r = getCallingRecordLocked(token);
4330            return r != null && r.app != null ? r.info.packageName : null;
4331        }
4332    }
4333
4334    public ComponentName getCallingActivity(IBinder token) {
4335        synchronized (this) {
4336            ActivityRecord r = getCallingRecordLocked(token);
4337            return r != null ? r.intent.getComponent() : null;
4338        }
4339    }
4340
4341    private ActivityRecord getCallingRecordLocked(IBinder token) {
4342        ActivityRecord r = mMainStack.isInStackLocked(token);
4343        if (r == null) {
4344            return null;
4345        }
4346        return r.resultTo;
4347    }
4348
4349    public ComponentName getActivityClassForToken(IBinder token) {
4350        synchronized(this) {
4351            ActivityRecord r = mMainStack.isInStackLocked(token);
4352            if (r == null) {
4353                return null;
4354            }
4355            return r.intent.getComponent();
4356        }
4357    }
4358
4359    public String getPackageForToken(IBinder token) {
4360        synchronized(this) {
4361            ActivityRecord r = mMainStack.isInStackLocked(token);
4362            if (r == null) {
4363                return null;
4364            }
4365            return r.packageName;
4366        }
4367    }
4368
4369    public IIntentSender getIntentSender(int type,
4370            String packageName, IBinder token, String resultWho,
4371            int requestCode, Intent[] intents, String[] resolvedTypes,
4372            int flags, Bundle options) {
4373        enforceNotIsolatedCaller("getIntentSender");
4374        // Refuse possible leaked file descriptors
4375        if (intents != null) {
4376            if (intents.length < 1) {
4377                throw new IllegalArgumentException("Intents array length must be >= 1");
4378            }
4379            for (int i=0; i<intents.length; i++) {
4380                Intent intent = intents[i];
4381                if (intent != null) {
4382                    if (intent.hasFileDescriptors()) {
4383                        throw new IllegalArgumentException("File descriptors passed in Intent");
4384                    }
4385                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4386                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4387                        throw new IllegalArgumentException(
4388                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4389                    }
4390                    intents[i] = new Intent(intent);
4391                }
4392            }
4393            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4394                throw new IllegalArgumentException(
4395                        "Intent array length does not match resolvedTypes length");
4396            }
4397        }
4398        if (options != null) {
4399            if (options.hasFileDescriptors()) {
4400                throw new IllegalArgumentException("File descriptors passed in options");
4401            }
4402        }
4403
4404        synchronized(this) {
4405            int callingUid = Binder.getCallingUid();
4406            try {
4407                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4408                    int uid = AppGlobals.getPackageManager()
4409                            .getPackageUid(packageName, UserId.getUserId(callingUid));
4410                    if (!UserId.isSameApp(callingUid, uid)) {
4411                        String msg = "Permission Denial: getIntentSender() from pid="
4412                            + Binder.getCallingPid()
4413                            + ", uid=" + Binder.getCallingUid()
4414                            + ", (need uid=" + uid + ")"
4415                            + " is not allowed to send as package " + packageName;
4416                        Slog.w(TAG, msg);
4417                        throw new SecurityException(msg);
4418                    }
4419                }
4420
4421                if (DEBUG_MU)
4422                    Slog.i(TAG_MU, "Getting intent sender for origCallingUid="
4423                            + Binder.getOrigCallingUid());
4424                return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(),
4425                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4426
4427            } catch (RemoteException e) {
4428                throw new SecurityException(e);
4429            }
4430        }
4431    }
4432
4433    IIntentSender getIntentSenderLocked(int type,
4434            String packageName, int callingUid, IBinder token, String resultWho,
4435            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4436            Bundle options) {
4437        if (DEBUG_MU)
4438            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4439        ActivityRecord activity = null;
4440        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4441            activity = mMainStack.isInStackLocked(token);
4442            if (activity == null) {
4443                return null;
4444            }
4445            if (activity.finishing) {
4446                return null;
4447            }
4448        }
4449
4450        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4451        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4452        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4453        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4454                |PendingIntent.FLAG_UPDATE_CURRENT);
4455
4456        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4457                type, packageName, activity, resultWho,
4458                requestCode, intents, resolvedTypes, flags, options);
4459        WeakReference<PendingIntentRecord> ref;
4460        ref = mIntentSenderRecords.get(key);
4461        PendingIntentRecord rec = ref != null ? ref.get() : null;
4462        if (rec != null) {
4463            if (!cancelCurrent) {
4464                if (updateCurrent) {
4465                    if (rec.key.requestIntent != null) {
4466                        rec.key.requestIntent.replaceExtras(intents != null ?
4467                                intents[intents.length - 1] : null);
4468                    }
4469                    if (intents != null) {
4470                        intents[intents.length-1] = rec.key.requestIntent;
4471                        rec.key.allIntents = intents;
4472                        rec.key.allResolvedTypes = resolvedTypes;
4473                    } else {
4474                        rec.key.allIntents = null;
4475                        rec.key.allResolvedTypes = null;
4476                    }
4477                }
4478                return rec;
4479            }
4480            rec.canceled = true;
4481            mIntentSenderRecords.remove(key);
4482        }
4483        if (noCreate) {
4484            return rec;
4485        }
4486        rec = new PendingIntentRecord(this, key, callingUid);
4487        mIntentSenderRecords.put(key, rec.ref);
4488        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4489            if (activity.pendingResults == null) {
4490                activity.pendingResults
4491                        = new HashSet<WeakReference<PendingIntentRecord>>();
4492            }
4493            activity.pendingResults.add(rec.ref);
4494        }
4495        return rec;
4496    }
4497
4498    public void cancelIntentSender(IIntentSender sender) {
4499        if (!(sender instanceof PendingIntentRecord)) {
4500            return;
4501        }
4502        synchronized(this) {
4503            PendingIntentRecord rec = (PendingIntentRecord)sender;
4504            try {
4505                int uid = AppGlobals.getPackageManager()
4506                        .getPackageUid(rec.key.packageName, UserId.getCallingUserId());
4507                if (!UserId.isSameApp(uid, Binder.getCallingUid())) {
4508                    String msg = "Permission Denial: cancelIntentSender() from pid="
4509                        + Binder.getCallingPid()
4510                        + ", uid=" + Binder.getCallingUid()
4511                        + " is not allowed to cancel packges "
4512                        + rec.key.packageName;
4513                    Slog.w(TAG, msg);
4514                    throw new SecurityException(msg);
4515                }
4516            } catch (RemoteException e) {
4517                throw new SecurityException(e);
4518            }
4519            cancelIntentSenderLocked(rec, true);
4520        }
4521    }
4522
4523    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4524        rec.canceled = true;
4525        mIntentSenderRecords.remove(rec.key);
4526        if (cleanActivity && rec.key.activity != null) {
4527            rec.key.activity.pendingResults.remove(rec.ref);
4528        }
4529    }
4530
4531    public String getPackageForIntentSender(IIntentSender pendingResult) {
4532        if (!(pendingResult instanceof PendingIntentRecord)) {
4533            return null;
4534        }
4535        try {
4536            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4537            return res.key.packageName;
4538        } catch (ClassCastException e) {
4539        }
4540        return null;
4541    }
4542
4543    public int getUidForIntentSender(IIntentSender sender) {
4544        if (sender instanceof PendingIntentRecord) {
4545            try {
4546                PendingIntentRecord res = (PendingIntentRecord)sender;
4547                return res.uid;
4548            } catch (ClassCastException e) {
4549            }
4550        }
4551        return -1;
4552    }
4553
4554    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4555        if (!(pendingResult instanceof PendingIntentRecord)) {
4556            return false;
4557        }
4558        try {
4559            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4560            if (res.key.allIntents == null) {
4561                return false;
4562            }
4563            for (int i=0; i<res.key.allIntents.length; i++) {
4564                Intent intent = res.key.allIntents[i];
4565                if (intent.getPackage() != null && intent.getComponent() != null) {
4566                    return false;
4567                }
4568            }
4569            return true;
4570        } catch (ClassCastException e) {
4571        }
4572        return false;
4573    }
4574
4575    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4576        if (!(pendingResult instanceof PendingIntentRecord)) {
4577            return false;
4578        }
4579        try {
4580            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4581            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4582                return true;
4583            }
4584            return false;
4585        } catch (ClassCastException e) {
4586        }
4587        return false;
4588    }
4589
4590    public void setProcessLimit(int max) {
4591        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4592                "setProcessLimit()");
4593        synchronized (this) {
4594            mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4595            mProcessLimitOverride = max;
4596        }
4597        trimApplications();
4598    }
4599
4600    public int getProcessLimit() {
4601        synchronized (this) {
4602            return mProcessLimitOverride;
4603        }
4604    }
4605
4606    void foregroundTokenDied(ForegroundToken token) {
4607        synchronized (ActivityManagerService.this) {
4608            synchronized (mPidsSelfLocked) {
4609                ForegroundToken cur
4610                    = mForegroundProcesses.get(token.pid);
4611                if (cur != token) {
4612                    return;
4613                }
4614                mForegroundProcesses.remove(token.pid);
4615                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4616                if (pr == null) {
4617                    return;
4618                }
4619                pr.forcingToForeground = null;
4620                pr.foregroundServices = false;
4621            }
4622            updateOomAdjLocked();
4623        }
4624    }
4625
4626    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4627        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4628                "setProcessForeground()");
4629        synchronized(this) {
4630            boolean changed = false;
4631
4632            synchronized (mPidsSelfLocked) {
4633                ProcessRecord pr = mPidsSelfLocked.get(pid);
4634                if (pr == null && isForeground) {
4635                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4636                    return;
4637                }
4638                ForegroundToken oldToken = mForegroundProcesses.get(pid);
4639                if (oldToken != null) {
4640                    oldToken.token.unlinkToDeath(oldToken, 0);
4641                    mForegroundProcesses.remove(pid);
4642                    if (pr != null) {
4643                        pr.forcingToForeground = null;
4644                    }
4645                    changed = true;
4646                }
4647                if (isForeground && token != null) {
4648                    ForegroundToken newToken = new ForegroundToken() {
4649                        public void binderDied() {
4650                            foregroundTokenDied(this);
4651                        }
4652                    };
4653                    newToken.pid = pid;
4654                    newToken.token = token;
4655                    try {
4656                        token.linkToDeath(newToken, 0);
4657                        mForegroundProcesses.put(pid, newToken);
4658                        pr.forcingToForeground = token;
4659                        changed = true;
4660                    } catch (RemoteException e) {
4661                        // If the process died while doing this, we will later
4662                        // do the cleanup with the process death link.
4663                    }
4664                }
4665            }
4666
4667            if (changed) {
4668                updateOomAdjLocked();
4669            }
4670        }
4671    }
4672
4673    // =========================================================
4674    // PERMISSIONS
4675    // =========================================================
4676
4677    static class PermissionController extends IPermissionController.Stub {
4678        ActivityManagerService mActivityManagerService;
4679        PermissionController(ActivityManagerService activityManagerService) {
4680            mActivityManagerService = activityManagerService;
4681        }
4682
4683        public boolean checkPermission(String permission, int pid, int uid) {
4684            return mActivityManagerService.checkPermission(permission, pid,
4685                    uid) == PackageManager.PERMISSION_GRANTED;
4686        }
4687    }
4688
4689    /**
4690     * This can be called with or without the global lock held.
4691     */
4692    int checkComponentPermission(String permission, int pid, int uid,
4693            int owningUid, boolean exported) {
4694        // We might be performing an operation on behalf of an indirect binder
4695        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
4696        // client identity accordingly before proceeding.
4697        Identity tlsIdentity = sCallerIdentity.get();
4698        if (tlsIdentity != null) {
4699            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4700                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4701            uid = tlsIdentity.uid;
4702            pid = tlsIdentity.pid;
4703        }
4704
4705        if (pid == MY_PID) {
4706            return PackageManager.PERMISSION_GRANTED;
4707        }
4708
4709        return ActivityManager.checkComponentPermission(permission, uid,
4710                owningUid, exported);
4711    }
4712
4713    /**
4714     * As the only public entry point for permissions checking, this method
4715     * can enforce the semantic that requesting a check on a null global
4716     * permission is automatically denied.  (Internally a null permission
4717     * string is used when calling {@link #checkComponentPermission} in cases
4718     * when only uid-based security is needed.)
4719     *
4720     * This can be called with or without the global lock held.
4721     */
4722    public int checkPermission(String permission, int pid, int uid) {
4723        if (permission == null) {
4724            return PackageManager.PERMISSION_DENIED;
4725        }
4726        return checkComponentPermission(permission, pid, UserId.getAppId(uid), -1, true);
4727    }
4728
4729    /**
4730     * Binder IPC calls go through the public entry point.
4731     * This can be called with or without the global lock held.
4732     */
4733    int checkCallingPermission(String permission) {
4734        return checkPermission(permission,
4735                Binder.getCallingPid(),
4736                UserId.getAppId(Binder.getCallingUid()));
4737    }
4738
4739    /**
4740     * This can be called with or without the global lock held.
4741     */
4742    void enforceCallingPermission(String permission, String func) {
4743        if (checkCallingPermission(permission)
4744                == PackageManager.PERMISSION_GRANTED) {
4745            return;
4746        }
4747
4748        String msg = "Permission Denial: " + func + " from pid="
4749                + Binder.getCallingPid()
4750                + ", uid=" + Binder.getCallingUid()
4751                + " requires " + permission;
4752        Slog.w(TAG, msg);
4753        throw new SecurityException(msg);
4754    }
4755
4756    /**
4757     * Determine if UID is holding permissions required to access {@link Uri} in
4758     * the given {@link ProviderInfo}. Final permission checking is always done
4759     * in {@link ContentProvider}.
4760     */
4761    private final boolean checkHoldingPermissionsLocked(
4762            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4763        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4764                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4765
4766        if (pi.applicationInfo.uid == uid) {
4767            return true;
4768        } else if (!pi.exported) {
4769            return false;
4770        }
4771
4772        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4773        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4774        try {
4775            // check if target holds top-level <provider> permissions
4776            if (!readMet && pi.readPermission != null
4777                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4778                readMet = true;
4779            }
4780            if (!writeMet && pi.writePermission != null
4781                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4782                writeMet = true;
4783            }
4784
4785            // track if unprotected read/write is allowed; any denied
4786            // <path-permission> below removes this ability
4787            boolean allowDefaultRead = pi.readPermission == null;
4788            boolean allowDefaultWrite = pi.writePermission == null;
4789
4790            // check if target holds any <path-permission> that match uri
4791            final PathPermission[] pps = pi.pathPermissions;
4792            if (pps != null) {
4793                final String path = uri.getPath();
4794                int i = pps.length;
4795                while (i > 0 && (!readMet || !writeMet)) {
4796                    i--;
4797                    PathPermission pp = pps[i];
4798                    if (pp.match(path)) {
4799                        if (!readMet) {
4800                            final String pprperm = pp.getReadPermission();
4801                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4802                                    + pprperm + " for " + pp.getPath()
4803                                    + ": match=" + pp.match(path)
4804                                    + " check=" + pm.checkUidPermission(pprperm, uid));
4805                            if (pprperm != null) {
4806                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4807                                    readMet = true;
4808                                } else {
4809                                    allowDefaultRead = false;
4810                                }
4811                            }
4812                        }
4813                        if (!writeMet) {
4814                            final String ppwperm = pp.getWritePermission();
4815                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4816                                    + ppwperm + " for " + pp.getPath()
4817                                    + ": match=" + pp.match(path)
4818                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
4819                            if (ppwperm != null) {
4820                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4821                                    writeMet = true;
4822                                } else {
4823                                    allowDefaultWrite = false;
4824                                }
4825                            }
4826                        }
4827                    }
4828                }
4829            }
4830
4831            // grant unprotected <provider> read/write, if not blocked by
4832            // <path-permission> above
4833            if (allowDefaultRead) readMet = true;
4834            if (allowDefaultWrite) writeMet = true;
4835
4836        } catch (RemoteException e) {
4837            return false;
4838        }
4839
4840        return readMet && writeMet;
4841    }
4842
4843    private final boolean checkUriPermissionLocked(Uri uri, int uid,
4844            int modeFlags) {
4845        // Root gets to do everything.
4846        if (uid == 0) {
4847            return true;
4848        }
4849        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4850        if (perms == null) return false;
4851        UriPermission perm = perms.get(uri);
4852        if (perm == null) return false;
4853        return (modeFlags&perm.modeFlags) == modeFlags;
4854    }
4855
4856    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4857        enforceNotIsolatedCaller("checkUriPermission");
4858
4859        // Another redirected-binder-call permissions check as in
4860        // {@link checkComponentPermission}.
4861        Identity tlsIdentity = sCallerIdentity.get();
4862        if (tlsIdentity != null) {
4863            uid = tlsIdentity.uid;
4864            pid = tlsIdentity.pid;
4865        }
4866
4867        uid = UserId.getAppId(uid);
4868        // Our own process gets to do everything.
4869        if (pid == MY_PID) {
4870            return PackageManager.PERMISSION_GRANTED;
4871        }
4872        synchronized(this) {
4873            return checkUriPermissionLocked(uri, uid, modeFlags)
4874                    ? PackageManager.PERMISSION_GRANTED
4875                    : PackageManager.PERMISSION_DENIED;
4876        }
4877    }
4878
4879    /**
4880     * Check if the targetPkg can be granted permission to access uri by
4881     * the callingUid using the given modeFlags.  Throws a security exception
4882     * if callingUid is not allowed to do this.  Returns the uid of the target
4883     * if the URI permission grant should be performed; returns -1 if it is not
4884     * needed (for example targetPkg already has permission to access the URI).
4885     * If you already know the uid of the target, you can supply it in
4886     * lastTargetUid else set that to -1.
4887     */
4888    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4889            Uri uri, int modeFlags, int lastTargetUid) {
4890        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4891                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4892        if (modeFlags == 0) {
4893            return -1;
4894        }
4895
4896        if (targetPkg != null) {
4897            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4898                    "Checking grant " + targetPkg + " permission to " + uri);
4899        }
4900
4901        final IPackageManager pm = AppGlobals.getPackageManager();
4902
4903        // If this is not a content: uri, we can't do anything with it.
4904        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
4905            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4906                    "Can't grant URI permission for non-content URI: " + uri);
4907            return -1;
4908        }
4909
4910        String name = uri.getAuthority();
4911        ProviderInfo pi = null;
4912        ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
4913                UserId.getUserId(callingUid));
4914        if (cpr != null) {
4915            pi = cpr.info;
4916        } else {
4917            try {
4918                pi = pm.resolveContentProvider(name,
4919                        PackageManager.GET_URI_PERMISSION_PATTERNS, UserId.getUserId(callingUid));
4920            } catch (RemoteException ex) {
4921            }
4922        }
4923        if (pi == null) {
4924            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
4925            return -1;
4926        }
4927
4928        int targetUid = lastTargetUid;
4929        if (targetUid < 0 && targetPkg != null) {
4930            try {
4931                targetUid = pm.getPackageUid(targetPkg, UserId.getUserId(callingUid));
4932                if (targetUid < 0) {
4933                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4934                            "Can't grant URI permission no uid for: " + targetPkg);
4935                    return -1;
4936                }
4937            } catch (RemoteException ex) {
4938                return -1;
4939            }
4940        }
4941
4942        if (targetUid >= 0) {
4943            // First...  does the target actually need this permission?
4944            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4945                // No need to grant the target this permission.
4946                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4947                        "Target " + targetPkg + " already has full permission to " + uri);
4948                return -1;
4949            }
4950        } else {
4951            // First...  there is no target package, so can anyone access it?
4952            boolean allowed = pi.exported;
4953            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4954                if (pi.readPermission != null) {
4955                    allowed = false;
4956                }
4957            }
4958            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4959                if (pi.writePermission != null) {
4960                    allowed = false;
4961                }
4962            }
4963            if (allowed) {
4964                return -1;
4965            }
4966        }
4967
4968        // Second...  is the provider allowing granting of URI permissions?
4969        if (!pi.grantUriPermissions) {
4970            throw new SecurityException("Provider " + pi.packageName
4971                    + "/" + pi.name
4972                    + " does not allow granting of Uri permissions (uri "
4973                    + uri + ")");
4974        }
4975        if (pi.uriPermissionPatterns != null) {
4976            final int N = pi.uriPermissionPatterns.length;
4977            boolean allowed = false;
4978            for (int i=0; i<N; i++) {
4979                if (pi.uriPermissionPatterns[i] != null
4980                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4981                    allowed = true;
4982                    break;
4983                }
4984            }
4985            if (!allowed) {
4986                throw new SecurityException("Provider " + pi.packageName
4987                        + "/" + pi.name
4988                        + " does not allow granting of permission to path of Uri "
4989                        + uri);
4990            }
4991        }
4992
4993        // Third...  does the caller itself have permission to access
4994        // this uri?
4995        if (callingUid != Process.myUid()) {
4996            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4997                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4998                    throw new SecurityException("Uid " + callingUid
4999                            + " does not have permission to uri " + uri);
5000                }
5001            }
5002        }
5003
5004        return targetUid;
5005    }
5006
5007    public int checkGrantUriPermission(int callingUid, String targetPkg,
5008            Uri uri, int modeFlags) {
5009        enforceNotIsolatedCaller("checkGrantUriPermission");
5010        synchronized(this) {
5011            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5012        }
5013    }
5014
5015    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5016            Uri uri, int modeFlags, UriPermissionOwner owner) {
5017        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5018                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5019        if (modeFlags == 0) {
5020            return;
5021        }
5022
5023        // So here we are: the caller has the assumed permission
5024        // to the uri, and the target doesn't.  Let's now give this to
5025        // the target.
5026
5027        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5028                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5029
5030        HashMap<Uri, UriPermission> targetUris
5031                = mGrantedUriPermissions.get(targetUid);
5032        if (targetUris == null) {
5033            targetUris = new HashMap<Uri, UriPermission>();
5034            mGrantedUriPermissions.put(targetUid, targetUris);
5035        }
5036
5037        UriPermission perm = targetUris.get(uri);
5038        if (perm == null) {
5039            perm = new UriPermission(targetUid, uri);
5040            targetUris.put(uri, perm);
5041        }
5042
5043        perm.modeFlags |= modeFlags;
5044        if (owner == null) {
5045            perm.globalModeFlags |= modeFlags;
5046        } else {
5047            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5048                 perm.readOwners.add(owner);
5049                 owner.addReadPermission(perm);
5050            }
5051            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5052                 perm.writeOwners.add(owner);
5053                 owner.addWritePermission(perm);
5054            }
5055        }
5056    }
5057
5058    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5059            int modeFlags, UriPermissionOwner owner) {
5060        if (targetPkg == null) {
5061            throw new NullPointerException("targetPkg");
5062        }
5063
5064        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5065        if (targetUid < 0) {
5066            return;
5067        }
5068
5069        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5070    }
5071
5072    static class NeededUriGrants extends ArrayList<Uri> {
5073        final String targetPkg;
5074        final int targetUid;
5075        final int flags;
5076
5077        NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5078            targetPkg = _targetPkg;
5079            targetUid = _targetUid;
5080            flags = _flags;
5081        }
5082    }
5083
5084    /**
5085     * Like checkGrantUriPermissionLocked, but takes an Intent.
5086     */
5087    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5088            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5089        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5090                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5091                + " clip=" + (intent != null ? intent.getClipData() : null)
5092                + " from " + intent + "; flags=0x"
5093                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5094
5095        if (targetPkg == null) {
5096            throw new NullPointerException("targetPkg");
5097        }
5098
5099        if (intent == null) {
5100            return null;
5101        }
5102        Uri data = intent.getData();
5103        ClipData clip = intent.getClipData();
5104        if (data == null && clip == null) {
5105            return null;
5106        }
5107        if (data != null) {
5108            int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5109                mode, needed != null ? needed.targetUid : -1);
5110            if (target > 0) {
5111                if (needed == null) {
5112                    needed = new NeededUriGrants(targetPkg, target, mode);
5113                }
5114                needed.add(data);
5115            }
5116        }
5117        if (clip != null) {
5118            for (int i=0; i<clip.getItemCount(); i++) {
5119                Uri uri = clip.getItemAt(i).getUri();
5120                if (uri != null) {
5121                    int target = -1;
5122                    target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5123                            mode, needed != null ? needed.targetUid : -1);
5124                    if (target > 0) {
5125                        if (needed == null) {
5126                            needed = new NeededUriGrants(targetPkg, target, mode);
5127                        }
5128                        needed.add(uri);
5129                    }
5130                } else {
5131                    Intent clipIntent = clip.getItemAt(i).getIntent();
5132                    if (clipIntent != null) {
5133                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5134                                callingUid, targetPkg, clipIntent, mode, needed);
5135                        if (newNeeded != null) {
5136                            needed = newNeeded;
5137                        }
5138                    }
5139                }
5140            }
5141        }
5142
5143        return needed;
5144    }
5145
5146    /**
5147     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5148     */
5149    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5150            UriPermissionOwner owner) {
5151        if (needed != null) {
5152            for (int i=0; i<needed.size(); i++) {
5153                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5154                        needed.get(i), needed.flags, owner);
5155            }
5156        }
5157    }
5158
5159    void grantUriPermissionFromIntentLocked(int callingUid,
5160            String targetPkg, Intent intent, UriPermissionOwner owner) {
5161        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5162                intent, intent != null ? intent.getFlags() : 0, null);
5163        if (needed == null) {
5164            return;
5165        }
5166
5167        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5168    }
5169
5170    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5171            Uri uri, int modeFlags) {
5172        enforceNotIsolatedCaller("grantUriPermission");
5173        synchronized(this) {
5174            final ProcessRecord r = getRecordForAppLocked(caller);
5175            if (r == null) {
5176                throw new SecurityException("Unable to find app for caller "
5177                        + caller
5178                        + " when granting permission to uri " + uri);
5179            }
5180            if (targetPkg == null) {
5181                throw new IllegalArgumentException("null target");
5182            }
5183            if (uri == null) {
5184                throw new IllegalArgumentException("null uri");
5185            }
5186
5187            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5188                    null);
5189        }
5190    }
5191
5192    void removeUriPermissionIfNeededLocked(UriPermission perm) {
5193        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5194                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5195            HashMap<Uri, UriPermission> perms
5196                    = mGrantedUriPermissions.get(perm.uid);
5197            if (perms != null) {
5198                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5199                        "Removing " + perm.uid + " permission to " + perm.uri);
5200                perms.remove(perm.uri);
5201                if (perms.size() == 0) {
5202                    mGrantedUriPermissions.remove(perm.uid);
5203                }
5204            }
5205        }
5206    }
5207
5208    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5209            int modeFlags) {
5210        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5211                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5212        if (modeFlags == 0) {
5213            return;
5214        }
5215
5216        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5217                "Revoking all granted permissions to " + uri);
5218
5219        final IPackageManager pm = AppGlobals.getPackageManager();
5220
5221        final String authority = uri.getAuthority();
5222        ProviderInfo pi = null;
5223        int userId = UserId.getUserId(callingUid);
5224        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5225        if (cpr != null) {
5226            pi = cpr.info;
5227        } else {
5228            try {
5229                pi = pm.resolveContentProvider(authority,
5230                        PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5231            } catch (RemoteException ex) {
5232            }
5233        }
5234        if (pi == null) {
5235            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5236            return;
5237        }
5238
5239        // Does the caller have this permission on the URI?
5240        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5241            // Right now, if you are not the original owner of the permission,
5242            // you are not allowed to revoke it.
5243            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5244                throw new SecurityException("Uid " + callingUid
5245                        + " does not have permission to uri " + uri);
5246            //}
5247        }
5248
5249        // Go through all of the permissions and remove any that match.
5250        final List<String> SEGMENTS = uri.getPathSegments();
5251        if (SEGMENTS != null) {
5252            final int NS = SEGMENTS.size();
5253            int N = mGrantedUriPermissions.size();
5254            for (int i=0; i<N; i++) {
5255                HashMap<Uri, UriPermission> perms
5256                        = mGrantedUriPermissions.valueAt(i);
5257                Iterator<UriPermission> it = perms.values().iterator();
5258            toploop:
5259                while (it.hasNext()) {
5260                    UriPermission perm = it.next();
5261                    Uri targetUri = perm.uri;
5262                    if (!authority.equals(targetUri.getAuthority())) {
5263                        continue;
5264                    }
5265                    List<String> targetSegments = targetUri.getPathSegments();
5266                    if (targetSegments == null) {
5267                        continue;
5268                    }
5269                    if (targetSegments.size() < NS) {
5270                        continue;
5271                    }
5272                    for (int j=0; j<NS; j++) {
5273                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5274                            continue toploop;
5275                        }
5276                    }
5277                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5278                            "Revoking " + perm.uid + " permission to " + perm.uri);
5279                    perm.clearModes(modeFlags);
5280                    if (perm.modeFlags == 0) {
5281                        it.remove();
5282                    }
5283                }
5284                if (perms.size() == 0) {
5285                    mGrantedUriPermissions.remove(
5286                            mGrantedUriPermissions.keyAt(i));
5287                    N--;
5288                    i--;
5289                }
5290            }
5291        }
5292    }
5293
5294    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5295            int modeFlags) {
5296        enforceNotIsolatedCaller("revokeUriPermission");
5297        synchronized(this) {
5298            final ProcessRecord r = getRecordForAppLocked(caller);
5299            if (r == null) {
5300                throw new SecurityException("Unable to find app for caller "
5301                        + caller
5302                        + " when revoking permission to uri " + uri);
5303            }
5304            if (uri == null) {
5305                Slog.w(TAG, "revokeUriPermission: null uri");
5306                return;
5307            }
5308
5309            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5310                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5311            if (modeFlags == 0) {
5312                return;
5313            }
5314
5315            final IPackageManager pm = AppGlobals.getPackageManager();
5316
5317            final String authority = uri.getAuthority();
5318            ProviderInfo pi = null;
5319            ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5320            if (cpr != null) {
5321                pi = cpr.info;
5322            } else {
5323                try {
5324                    pi = pm.resolveContentProvider(authority,
5325                            PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5326                } catch (RemoteException ex) {
5327                }
5328            }
5329            if (pi == null) {
5330                Slog.w(TAG, "No content provider found for permission revoke: "
5331                        + uri.toSafeString());
5332                return;
5333            }
5334
5335            revokeUriPermissionLocked(r.uid, uri, modeFlags);
5336        }
5337    }
5338
5339    @Override
5340    public IBinder newUriPermissionOwner(String name) {
5341        enforceNotIsolatedCaller("newUriPermissionOwner");
5342        synchronized(this) {
5343            UriPermissionOwner owner = new UriPermissionOwner(this, name);
5344            return owner.getExternalTokenLocked();
5345        }
5346    }
5347
5348    @Override
5349    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5350            Uri uri, int modeFlags) {
5351        synchronized(this) {
5352            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5353            if (owner == null) {
5354                throw new IllegalArgumentException("Unknown owner: " + token);
5355            }
5356            if (fromUid != Binder.getCallingUid()) {
5357                if (Binder.getCallingUid() != Process.myUid()) {
5358                    // Only system code can grant URI permissions on behalf
5359                    // of other users.
5360                    throw new SecurityException("nice try");
5361                }
5362            }
5363            if (targetPkg == null) {
5364                throw new IllegalArgumentException("null target");
5365            }
5366            if (uri == null) {
5367                throw new IllegalArgumentException("null uri");
5368            }
5369
5370            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5371        }
5372    }
5373
5374    @Override
5375    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5376        synchronized(this) {
5377            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5378            if (owner == null) {
5379                throw new IllegalArgumentException("Unknown owner: " + token);
5380            }
5381
5382            if (uri == null) {
5383                owner.removeUriPermissionsLocked(mode);
5384            } else {
5385                owner.removeUriPermissionLocked(uri, mode);
5386            }
5387        }
5388    }
5389
5390    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5391        synchronized (this) {
5392            ProcessRecord app =
5393                who != null ? getRecordForAppLocked(who) : null;
5394            if (app == null) return;
5395
5396            Message msg = Message.obtain();
5397            msg.what = WAIT_FOR_DEBUGGER_MSG;
5398            msg.obj = app;
5399            msg.arg1 = waiting ? 1 : 0;
5400            mHandler.sendMessage(msg);
5401        }
5402    }
5403
5404    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5405        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5406        final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5407        outInfo.availMem = Process.getFreeMemory();
5408        outInfo.totalMem = Process.getTotalMemory();
5409        outInfo.threshold = homeAppMem;
5410        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5411        outInfo.hiddenAppThreshold = hiddenAppMem;
5412        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5413                ProcessList.SERVICE_ADJ);
5414        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5415                ProcessList.VISIBLE_APP_ADJ);
5416        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5417                ProcessList.FOREGROUND_APP_ADJ);
5418    }
5419
5420    // =========================================================
5421    // TASK MANAGEMENT
5422    // =========================================================
5423
5424    public List getTasks(int maxNum, int flags,
5425                         IThumbnailReceiver receiver) {
5426        ArrayList list = new ArrayList();
5427
5428        PendingThumbnailsRecord pending = null;
5429        IApplicationThread topThumbnail = null;
5430        ActivityRecord topRecord = null;
5431
5432        synchronized(this) {
5433            if (localLOGV) Slog.v(
5434                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5435                + ", receiver=" + receiver);
5436
5437            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5438                    != PackageManager.PERMISSION_GRANTED) {
5439                if (receiver != null) {
5440                    // If the caller wants to wait for pending thumbnails,
5441                    // it ain't gonna get them.
5442                    try {
5443                        receiver.finished();
5444                    } catch (RemoteException ex) {
5445                    }
5446                }
5447                String msg = "Permission Denial: getTasks() from pid="
5448                        + Binder.getCallingPid()
5449                        + ", uid=" + Binder.getCallingUid()
5450                        + " requires " + android.Manifest.permission.GET_TASKS;
5451                Slog.w(TAG, msg);
5452                throw new SecurityException(msg);
5453            }
5454
5455            int pos = mMainStack.mHistory.size()-1;
5456            ActivityRecord next =
5457                pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5458            ActivityRecord top = null;
5459            TaskRecord curTask = null;
5460            int numActivities = 0;
5461            int numRunning = 0;
5462            while (pos >= 0 && maxNum > 0) {
5463                final ActivityRecord r = next;
5464                pos--;
5465                next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5466
5467                // Initialize state for next task if needed.
5468                if (top == null ||
5469                        (top.state == ActivityState.INITIALIZING
5470                            && top.task == r.task)) {
5471                    top = r;
5472                    curTask = r.task;
5473                    numActivities = numRunning = 0;
5474                }
5475
5476                // Add 'r' into the current task.
5477                numActivities++;
5478                if (r.app != null && r.app.thread != null) {
5479                    numRunning++;
5480                }
5481
5482                if (localLOGV) Slog.v(
5483                    TAG, r.intent.getComponent().flattenToShortString()
5484                    + ": task=" + r.task);
5485
5486                // If the next one is a different task, generate a new
5487                // TaskInfo entry for what we have.
5488                if (next == null || next.task != curTask) {
5489                    ActivityManager.RunningTaskInfo ci
5490                            = new ActivityManager.RunningTaskInfo();
5491                    ci.id = curTask.taskId;
5492                    ci.baseActivity = r.intent.getComponent();
5493                    ci.topActivity = top.intent.getComponent();
5494                    if (top.thumbHolder != null) {
5495                        ci.description = top.thumbHolder.lastDescription;
5496                    }
5497                    ci.numActivities = numActivities;
5498                    ci.numRunning = numRunning;
5499                    //System.out.println(
5500                    //    "#" + maxNum + ": " + " descr=" + ci.description);
5501                    if (ci.thumbnail == null && receiver != null) {
5502                        if (localLOGV) Slog.v(
5503                            TAG, "State=" + top.state + "Idle=" + top.idle
5504                            + " app=" + top.app
5505                            + " thr=" + (top.app != null ? top.app.thread : null));
5506                        if (top.state == ActivityState.RESUMED
5507                                || top.state == ActivityState.PAUSING) {
5508                            if (top.idle && top.app != null
5509                                && top.app.thread != null) {
5510                                topRecord = top;
5511                                topThumbnail = top.app.thread;
5512                            } else {
5513                                top.thumbnailNeeded = true;
5514                            }
5515                        }
5516                        if (pending == null) {
5517                            pending = new PendingThumbnailsRecord(receiver);
5518                        }
5519                        pending.pendingRecords.add(top);
5520                    }
5521                    list.add(ci);
5522                    maxNum--;
5523                    top = null;
5524                }
5525            }
5526
5527            if (pending != null) {
5528                mPendingThumbnails.add(pending);
5529            }
5530        }
5531
5532        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5533
5534        if (topThumbnail != null) {
5535            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5536            try {
5537                topThumbnail.requestThumbnail(topRecord.appToken);
5538            } catch (Exception e) {
5539                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5540                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5541            }
5542        }
5543
5544        if (pending == null && receiver != null) {
5545            // In this case all thumbnails were available and the client
5546            // is being asked to be told when the remaining ones come in...
5547            // which is unusually, since the top-most currently running
5548            // activity should never have a canned thumbnail!  Oh well.
5549            try {
5550                receiver.finished();
5551            } catch (RemoteException ex) {
5552            }
5553        }
5554
5555        return list;
5556    }
5557
5558    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5559            int flags) {
5560        final int callingUid = Binder.getCallingUid();
5561        // If it's the system uid asking, then use the current user id.
5562        // TODO: Make sure that there aren't any other legitimate calls from the system uid that
5563        // require the entire list.
5564        final int callingUserId = callingUid == Process.SYSTEM_UID
5565                ? mCurrentUserId : UserId.getUserId(callingUid);
5566        synchronized (this) {
5567            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5568                    "getRecentTasks()");
5569            final boolean detailed = checkCallingPermission(
5570                    android.Manifest.permission.GET_DETAILED_TASKS)
5571                    == PackageManager.PERMISSION_GRANTED;
5572
5573            IPackageManager pm = AppGlobals.getPackageManager();
5574
5575            final int N = mRecentTasks.size();
5576            ArrayList<ActivityManager.RecentTaskInfo> res
5577                    = new ArrayList<ActivityManager.RecentTaskInfo>(
5578                            maxNum < N ? maxNum : N);
5579            for (int i=0; i<N && maxNum > 0; i++) {
5580                TaskRecord tr = mRecentTasks.get(i);
5581                // Only add calling user's recent tasks
5582                if (tr.userId != callingUserId) continue;
5583                // Return the entry if desired by the caller.  We always return
5584                // the first entry, because callers always expect this to be the
5585                // foreground app.  We may filter others if the caller has
5586                // not supplied RECENT_WITH_EXCLUDED and there is some reason
5587                // we should exclude the entry.
5588
5589                if (i == 0
5590                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5591                        || (tr.intent == null)
5592                        || ((tr.intent.getFlags()
5593                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5594                    ActivityManager.RecentTaskInfo rti
5595                            = new ActivityManager.RecentTaskInfo();
5596                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5597                    rti.persistentId = tr.taskId;
5598                    rti.baseIntent = new Intent(
5599                            tr.intent != null ? tr.intent : tr.affinityIntent);
5600                    if (!detailed) {
5601                        rti.baseIntent.replaceExtras((Bundle)null);
5602                    }
5603                    rti.origActivity = tr.origActivity;
5604                    rti.description = tr.lastDescription;
5605
5606                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5607                        // Check whether this activity is currently available.
5608                        try {
5609                            if (rti.origActivity != null) {
5610                                if (pm.getActivityInfo(rti.origActivity, 0, callingUserId)
5611                                        == null) {
5612                                    continue;
5613                                }
5614                            } else if (rti.baseIntent != null) {
5615                                if (pm.queryIntentActivities(rti.baseIntent,
5616                                        null, 0, callingUserId) == null) {
5617                                    continue;
5618                                }
5619                            }
5620                        } catch (RemoteException e) {
5621                            // Will never happen.
5622                        }
5623                    }
5624
5625                    res.add(rti);
5626                    maxNum--;
5627                }
5628            }
5629            return res;
5630        }
5631    }
5632
5633    private TaskRecord taskForIdLocked(int id) {
5634        final int N = mRecentTasks.size();
5635        for (int i=0; i<N; i++) {
5636            TaskRecord tr = mRecentTasks.get(i);
5637            if (tr.taskId == id) {
5638                return tr;
5639            }
5640        }
5641        return null;
5642    }
5643
5644    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5645        synchronized (this) {
5646            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5647                    "getTaskThumbnails()");
5648            TaskRecord tr = taskForIdLocked(id);
5649            if (tr != null) {
5650                return mMainStack.getTaskThumbnailsLocked(tr);
5651            }
5652        }
5653        return null;
5654    }
5655
5656    public boolean removeSubTask(int taskId, int subTaskIndex) {
5657        synchronized (this) {
5658            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5659                    "removeSubTask()");
5660            long ident = Binder.clearCallingIdentity();
5661            try {
5662                return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5663                        true) != null;
5664            } finally {
5665                Binder.restoreCallingIdentity(ident);
5666            }
5667        }
5668    }
5669
5670    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5671        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5672        Intent baseIntent = new Intent(
5673                tr.intent != null ? tr.intent : tr.affinityIntent);
5674        ComponentName component = baseIntent.getComponent();
5675        if (component == null) {
5676            Slog.w(TAG, "Now component for base intent of task: " + tr);
5677            return;
5678        }
5679
5680        // Find any running services associated with this app.
5681        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5682        for (ServiceRecord sr : mServiceMap.getAllServices(tr.userId)) {
5683            if (sr.packageName.equals(component.getPackageName())) {
5684                services.add(sr);
5685            }
5686        }
5687
5688        // Take care of any running services associated with the app.
5689        for (int i=0; i<services.size(); i++) {
5690            ServiceRecord sr = services.get(i);
5691            if (sr.startRequested) {
5692                if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
5693                    Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
5694                    stopServiceLocked(sr);
5695                } else {
5696                    sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5697                            sr.makeNextStartId(), baseIntent, null));
5698                    if (sr.app != null && sr.app.thread != null) {
5699                        sendServiceArgsLocked(sr, false);
5700                    }
5701                }
5702            }
5703        }
5704
5705        if (killProcesses) {
5706            // Find any running processes associated with this app.
5707            final String pkg = component.getPackageName();
5708            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5709            HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5710            for (SparseArray<ProcessRecord> uids : pmap.values()) {
5711                for (int i=0; i<uids.size(); i++) {
5712                    ProcessRecord proc = uids.valueAt(i);
5713                    if (proc.userId != tr.userId) {
5714                        continue;
5715                    }
5716                    if (!proc.pkgList.contains(pkg)) {
5717                        continue;
5718                    }
5719                    procs.add(proc);
5720                }
5721            }
5722
5723            // Kill the running processes.
5724            for (int i=0; i<procs.size(); i++) {
5725                ProcessRecord pr = procs.get(i);
5726                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5727                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5728                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5729                            pr.processName, pr.setAdj, "remove task");
5730                    pr.killedBackground = true;
5731                    Process.killProcessQuiet(pr.pid);
5732                } else {
5733                    pr.waitingToKill = "remove task";
5734                }
5735            }
5736        }
5737    }
5738
5739    public boolean removeTask(int taskId, int flags) {
5740        synchronized (this) {
5741            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5742                    "removeTask()");
5743            long ident = Binder.clearCallingIdentity();
5744            try {
5745                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5746                        false);
5747                if (r != null) {
5748                    mRecentTasks.remove(r.task);
5749                    cleanUpRemovedTaskLocked(r.task, flags);
5750                    return true;
5751                } else {
5752                    TaskRecord tr = null;
5753                    int i=0;
5754                    while (i < mRecentTasks.size()) {
5755                        TaskRecord t = mRecentTasks.get(i);
5756                        if (t.taskId == taskId) {
5757                            tr = t;
5758                            break;
5759                        }
5760                        i++;
5761                    }
5762                    if (tr != null) {
5763                        if (tr.numActivities <= 0) {
5764                            // Caller is just removing a recent task that is
5765                            // not actively running.  That is easy!
5766                            mRecentTasks.remove(i);
5767                            cleanUpRemovedTaskLocked(tr, flags);
5768                            return true;
5769                        } else {
5770                            Slog.w(TAG, "removeTask: task " + taskId
5771                                    + " does not have activities to remove, "
5772                                    + " but numActivities=" + tr.numActivities
5773                                    + ": " + tr);
5774                        }
5775                    }
5776                }
5777            } finally {
5778                Binder.restoreCallingIdentity(ident);
5779            }
5780        }
5781        return false;
5782    }
5783
5784    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5785        int j;
5786        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5787        TaskRecord jt = startTask;
5788
5789        // First look backwards
5790        for (j=startIndex-1; j>=0; j--) {
5791            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5792            if (r.task != jt) {
5793                jt = r.task;
5794                if (affinity.equals(jt.affinity)) {
5795                    return j;
5796                }
5797            }
5798        }
5799
5800        // Now look forwards
5801        final int N = mMainStack.mHistory.size();
5802        jt = startTask;
5803        for (j=startIndex+1; j<N; j++) {
5804            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5805            if (r.task != jt) {
5806                if (affinity.equals(jt.affinity)) {
5807                    return j;
5808                }
5809                jt = r.task;
5810            }
5811        }
5812
5813        // Might it be at the top?
5814        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5815            return N-1;
5816        }
5817
5818        return -1;
5819    }
5820
5821    /**
5822     * TODO: Add mController hook
5823     */
5824    public void moveTaskToFront(int task, int flags, Bundle options) {
5825        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5826                "moveTaskToFront()");
5827
5828        synchronized(this) {
5829            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5830                    Binder.getCallingUid(), "Task to front")) {
5831                ActivityOptions.abort(options);
5832                return;
5833            }
5834            final long origId = Binder.clearCallingIdentity();
5835            try {
5836                TaskRecord tr = taskForIdLocked(task);
5837                if (tr != null) {
5838                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5839                        mMainStack.mUserLeaving = true;
5840                    }
5841                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5842                        // Caller wants the home activity moved with it.  To accomplish this,
5843                        // we'll just move the home task to the top first.
5844                        mMainStack.moveHomeToFrontLocked();
5845                    }
5846                    mMainStack.moveTaskToFrontLocked(tr, null, options);
5847                    return;
5848                }
5849                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5850                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
5851                    if (hr.task.taskId == task) {
5852                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5853                            mMainStack.mUserLeaving = true;
5854                        }
5855                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5856                            // Caller wants the home activity moved with it.  To accomplish this,
5857                            // we'll just move the home task to the top first.
5858                            mMainStack.moveHomeToFrontLocked();
5859                        }
5860                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
5861                        return;
5862                    }
5863                }
5864            } finally {
5865                Binder.restoreCallingIdentity(origId);
5866            }
5867            ActivityOptions.abort(options);
5868        }
5869    }
5870
5871    public void moveTaskToBack(int task) {
5872        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5873                "moveTaskToBack()");
5874
5875        synchronized(this) {
5876            if (mMainStack.mResumedActivity != null
5877                    && mMainStack.mResumedActivity.task.taskId == task) {
5878                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5879                        Binder.getCallingUid(), "Task to back")) {
5880                    return;
5881                }
5882            }
5883            final long origId = Binder.clearCallingIdentity();
5884            mMainStack.moveTaskToBackLocked(task, null);
5885            Binder.restoreCallingIdentity(origId);
5886        }
5887    }
5888
5889    /**
5890     * Moves an activity, and all of the other activities within the same task, to the bottom
5891     * of the history stack.  The activity's order within the task is unchanged.
5892     *
5893     * @param token A reference to the activity we wish to move
5894     * @param nonRoot If false then this only works if the activity is the root
5895     *                of a task; if true it will work for any activity in a task.
5896     * @return Returns true if the move completed, false if not.
5897     */
5898    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5899        enforceNotIsolatedCaller("moveActivityTaskToBack");
5900        synchronized(this) {
5901            final long origId = Binder.clearCallingIdentity();
5902            int taskId = getTaskForActivityLocked(token, !nonRoot);
5903            if (taskId >= 0) {
5904                return mMainStack.moveTaskToBackLocked(taskId, null);
5905            }
5906            Binder.restoreCallingIdentity(origId);
5907        }
5908        return false;
5909    }
5910
5911    public void moveTaskBackwards(int task) {
5912        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5913                "moveTaskBackwards()");
5914
5915        synchronized(this) {
5916            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5917                    Binder.getCallingUid(), "Task backwards")) {
5918                return;
5919            }
5920            final long origId = Binder.clearCallingIdentity();
5921            moveTaskBackwardsLocked(task);
5922            Binder.restoreCallingIdentity(origId);
5923        }
5924    }
5925
5926    private final void moveTaskBackwardsLocked(int task) {
5927        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
5928    }
5929
5930    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5931        synchronized(this) {
5932            return getTaskForActivityLocked(token, onlyRoot);
5933        }
5934    }
5935
5936    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
5937        final int N = mMainStack.mHistory.size();
5938        TaskRecord lastTask = null;
5939        for (int i=0; i<N; i++) {
5940            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5941            if (r.appToken == token) {
5942                if (!onlyRoot || lastTask != r.task) {
5943                    return r.task.taskId;
5944                }
5945                return -1;
5946            }
5947            lastTask = r.task;
5948        }
5949
5950        return -1;
5951    }
5952
5953    // =========================================================
5954    // THUMBNAILS
5955    // =========================================================
5956
5957    public void reportThumbnail(IBinder token,
5958            Bitmap thumbnail, CharSequence description) {
5959        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5960        final long origId = Binder.clearCallingIdentity();
5961        sendPendingThumbnail(null, token, thumbnail, description, true);
5962        Binder.restoreCallingIdentity(origId);
5963    }
5964
5965    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
5966            Bitmap thumbnail, CharSequence description, boolean always) {
5967        TaskRecord task = null;
5968        ArrayList receivers = null;
5969
5970        //System.out.println("Send pending thumbnail: " + r);
5971
5972        synchronized(this) {
5973            if (r == null) {
5974                r = mMainStack.isInStackLocked(token);
5975                if (r == null) {
5976                    return;
5977                }
5978            }
5979            if (thumbnail == null && r.thumbHolder != null) {
5980                thumbnail = r.thumbHolder.lastThumbnail;
5981                description = r.thumbHolder.lastDescription;
5982            }
5983            if (thumbnail == null && !always) {
5984                // If there is no thumbnail, and this entry is not actually
5985                // going away, then abort for now and pick up the next
5986                // thumbnail we get.
5987                return;
5988            }
5989            task = r.task;
5990
5991            int N = mPendingThumbnails.size();
5992            int i=0;
5993            while (i<N) {
5994                PendingThumbnailsRecord pr =
5995                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5996                //System.out.println("Looking in " + pr.pendingRecords);
5997                if (pr.pendingRecords.remove(r)) {
5998                    if (receivers == null) {
5999                        receivers = new ArrayList();
6000                    }
6001                    receivers.add(pr);
6002                    if (pr.pendingRecords.size() == 0) {
6003                        pr.finished = true;
6004                        mPendingThumbnails.remove(i);
6005                        N--;
6006                        continue;
6007                    }
6008                }
6009                i++;
6010            }
6011        }
6012
6013        if (receivers != null) {
6014            final int N = receivers.size();
6015            for (int i=0; i<N; i++) {
6016                try {
6017                    PendingThumbnailsRecord pr =
6018                        (PendingThumbnailsRecord)receivers.get(i);
6019                    pr.receiver.newThumbnail(
6020                        task != null ? task.taskId : -1, thumbnail, description);
6021                    if (pr.finished) {
6022                        pr.receiver.finished();
6023                    }
6024                } catch (Exception e) {
6025                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6026                }
6027            }
6028        }
6029    }
6030
6031    // =========================================================
6032    // CONTENT PROVIDERS
6033    // =========================================================
6034
6035    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6036        List<ProviderInfo> providers = null;
6037        try {
6038            providers = AppGlobals.getPackageManager().
6039                queryContentProviders(app.processName, app.uid,
6040                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6041        } catch (RemoteException ex) {
6042        }
6043        if (DEBUG_MU)
6044            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6045        int userId = app.userId;
6046        if (providers != null) {
6047            final int N = providers.size();
6048            for (int i=0; i<N; i++) {
6049                ProviderInfo cpi =
6050                    (ProviderInfo)providers.get(i);
6051
6052                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6053                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6054                if (cpr == null) {
6055                    cpr = new ContentProviderRecord(this, cpi, app.info, comp);
6056                    mProviderMap.putProviderByClass(comp, cpr);
6057                }
6058                if (DEBUG_MU)
6059                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6060                app.pubProviders.put(cpi.name, cpr);
6061                app.addPackage(cpi.applicationInfo.packageName);
6062                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6063            }
6064        }
6065        return providers;
6066    }
6067
6068    /**
6069     * Check if {@link ProcessRecord} has a possible chance at accessing the
6070     * given {@link ProviderInfo}. Final permission checking is always done
6071     * in {@link ContentProvider}.
6072     */
6073    private final String checkContentProviderPermissionLocked(
6074            ProviderInfo cpi, ProcessRecord r) {
6075        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6076        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6077        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6078                cpi.applicationInfo.uid, cpi.exported)
6079                == PackageManager.PERMISSION_GRANTED) {
6080            return null;
6081        }
6082        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6083                cpi.applicationInfo.uid, cpi.exported)
6084                == PackageManager.PERMISSION_GRANTED) {
6085            return null;
6086        }
6087
6088        PathPermission[] pps = cpi.pathPermissions;
6089        if (pps != null) {
6090            int i = pps.length;
6091            while (i > 0) {
6092                i--;
6093                PathPermission pp = pps[i];
6094                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6095                        cpi.applicationInfo.uid, cpi.exported)
6096                        == PackageManager.PERMISSION_GRANTED) {
6097                    return null;
6098                }
6099                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6100                        cpi.applicationInfo.uid, cpi.exported)
6101                        == PackageManager.PERMISSION_GRANTED) {
6102                    return null;
6103                }
6104            }
6105        }
6106
6107        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6108        if (perms != null) {
6109            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6110                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6111                    return null;
6112                }
6113            }
6114        }
6115
6116        String msg;
6117        if (!cpi.exported) {
6118            msg = "Permission Denial: opening provider " + cpi.name
6119                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6120                    + ", uid=" + callingUid + ") that is not exported from uid "
6121                    + cpi.applicationInfo.uid;
6122        } else {
6123            msg = "Permission Denial: opening provider " + cpi.name
6124                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6125                    + ", uid=" + callingUid + ") requires "
6126                    + cpi.readPermission + " or " + cpi.writePermission;
6127        }
6128        Slog.w(TAG, msg);
6129        return msg;
6130    }
6131
6132    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6133            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6134        if (r != null) {
6135            for (int i=0; i<r.conProviders.size(); i++) {
6136                ContentProviderConnection conn = r.conProviders.get(i);
6137                if (conn.provider == cpr) {
6138                    if (DEBUG_PROVIDER) Slog.v(TAG,
6139                            "Adding provider requested by "
6140                            + r.processName + " from process "
6141                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6142                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6143                    if (stable) {
6144                        conn.stableCount++;
6145                        conn.numStableIncs++;
6146                    } else {
6147                        conn.unstableCount++;
6148                        conn.numUnstableIncs++;
6149                    }
6150                    return conn;
6151                }
6152            }
6153            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6154            if (stable) {
6155                conn.stableCount = 1;
6156                conn.numStableIncs = 1;
6157            } else {
6158                conn.unstableCount = 1;
6159                conn.numUnstableIncs = 1;
6160            }
6161            cpr.connections.add(conn);
6162            r.conProviders.add(conn);
6163            return conn;
6164        }
6165        cpr.addExternalProcessHandleLocked(externalProcessToken);
6166        return null;
6167    }
6168
6169    boolean decProviderCountLocked(ContentProviderConnection conn,
6170            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6171        if (conn != null) {
6172            cpr = conn.provider;
6173            if (DEBUG_PROVIDER) Slog.v(TAG,
6174                    "Removing provider requested by "
6175                    + conn.client.processName + " from process "
6176                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6177                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6178            if (stable) {
6179                conn.stableCount--;
6180            } else {
6181                conn.unstableCount--;
6182            }
6183            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6184                cpr.connections.remove(conn);
6185                conn.client.conProviders.remove(conn);
6186                return true;
6187            }
6188            return false;
6189        }
6190        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6191        return false;
6192    }
6193
6194    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6195            String name, IBinder token, boolean stable) {
6196        ContentProviderRecord cpr;
6197        ContentProviderConnection conn = null;
6198        ProviderInfo cpi = null;
6199
6200        synchronized(this) {
6201            ProcessRecord r = null;
6202            if (caller != null) {
6203                r = getRecordForAppLocked(caller);
6204                if (r == null) {
6205                    throw new SecurityException(
6206                            "Unable to find app for caller " + caller
6207                          + " (pid=" + Binder.getCallingPid()
6208                          + ") when getting content provider " + name);
6209                }
6210            }
6211
6212            // First check if this content provider has been published...
6213            int userId = UserId.getUserId(r != null ? r.uid : Binder.getCallingUid());
6214            cpr = mProviderMap.getProviderByName(name, userId);
6215            boolean providerRunning = cpr != null;
6216            if (providerRunning) {
6217                cpi = cpr.info;
6218                String msg;
6219                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6220                    throw new SecurityException(msg);
6221                }
6222
6223                if (r != null && cpr.canRunHere(r)) {
6224                    // This provider has been published or is in the process
6225                    // of being published...  but it is also allowed to run
6226                    // in the caller's process, so don't make a connection
6227                    // and just let the caller instantiate its own instance.
6228                    ContentProviderHolder holder = cpr.newHolder(null);
6229                    // don't give caller the provider object, it needs
6230                    // to make its own.
6231                    holder.provider = null;
6232                    return holder;
6233                }
6234
6235                final long origId = Binder.clearCallingIdentity();
6236
6237                // In this case the provider instance already exists, so we can
6238                // return it right away.
6239                conn = incProviderCountLocked(r, cpr, token, stable);
6240                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6241                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6242                        // If this is a perceptible app accessing the provider,
6243                        // make sure to count it as being accessed and thus
6244                        // back up on the LRU list.  This is good because
6245                        // content providers are often expensive to start.
6246                        updateLruProcessLocked(cpr.proc, false, true);
6247                    }
6248                }
6249
6250                if (cpr.proc != null) {
6251                    if (false) {
6252                        if (cpr.name.flattenToShortString().equals(
6253                                "com.android.providers.calendar/.CalendarProvider2")) {
6254                            Slog.v(TAG, "****************** KILLING "
6255                                + cpr.name.flattenToShortString());
6256                            Process.killProcess(cpr.proc.pid);
6257                        }
6258                    }
6259                    boolean success = updateOomAdjLocked(cpr.proc);
6260                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6261                    // NOTE: there is still a race here where a signal could be
6262                    // pending on the process even though we managed to update its
6263                    // adj level.  Not sure what to do about this, but at least
6264                    // the race is now smaller.
6265                    if (!success) {
6266                        // Uh oh...  it looks like the provider's process
6267                        // has been killed on us.  We need to wait for a new
6268                        // process to be started, and make sure its death
6269                        // doesn't kill our process.
6270                        Slog.i(TAG,
6271                                "Existing provider " + cpr.name.flattenToShortString()
6272                                + " is crashing; detaching " + r);
6273                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6274                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6275                        if (!lastRef) {
6276                            // This wasn't the last ref our process had on
6277                            // the provider...  we have now been killed, bail.
6278                            return null;
6279                        }
6280                        providerRunning = false;
6281                        conn = null;
6282                    }
6283                }
6284
6285                Binder.restoreCallingIdentity(origId);
6286            }
6287
6288            if (!providerRunning) {
6289                try {
6290                    cpi = AppGlobals.getPackageManager().
6291                        resolveContentProvider(name,
6292                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6293                } catch (RemoteException ex) {
6294                }
6295                if (cpi == null) {
6296                    return null;
6297                }
6298                if (isSingleton(cpi.processName, cpi.applicationInfo)) {
6299                    userId = 0;
6300                }
6301                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6302
6303                String msg;
6304                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6305                    throw new SecurityException(msg);
6306                }
6307
6308                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6309                        && !cpi.processName.equals("system")) {
6310                    // If this content provider does not run in the system
6311                    // process, and the system is not yet ready to run other
6312                    // processes, then fail fast instead of hanging.
6313                    throw new IllegalArgumentException(
6314                            "Attempt to launch content provider before system ready");
6315                }
6316
6317                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6318                cpr = mProviderMap.getProviderByClass(comp, userId);
6319                final boolean firstClass = cpr == null;
6320                if (firstClass) {
6321                    try {
6322                        ApplicationInfo ai =
6323                            AppGlobals.getPackageManager().
6324                                getApplicationInfo(
6325                                        cpi.applicationInfo.packageName,
6326                                        STOCK_PM_FLAGS, userId);
6327                        if (ai == null) {
6328                            Slog.w(TAG, "No package info for content provider "
6329                                    + cpi.name);
6330                            return null;
6331                        }
6332                        ai = getAppInfoForUser(ai, userId);
6333                        cpr = new ContentProviderRecord(this, cpi, ai, comp);
6334                    } catch (RemoteException ex) {
6335                        // pm is in same process, this will never happen.
6336                    }
6337                }
6338
6339                if (r != null && cpr.canRunHere(r)) {
6340                    // If this is a multiprocess provider, then just return its
6341                    // info and allow the caller to instantiate it.  Only do
6342                    // this if the provider is the same user as the caller's
6343                    // process, or can run as root (so can be in any process).
6344                    return cpr.newHolder(null);
6345                }
6346
6347                if (DEBUG_PROVIDER) {
6348                    RuntimeException e = new RuntimeException("here");
6349                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6350                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6351                }
6352
6353                // This is single process, and our app is now connecting to it.
6354                // See if we are already in the process of launching this
6355                // provider.
6356                final int N = mLaunchingProviders.size();
6357                int i;
6358                for (i=0; i<N; i++) {
6359                    if (mLaunchingProviders.get(i) == cpr) {
6360                        break;
6361                    }
6362                }
6363
6364                // If the provider is not already being launched, then get it
6365                // started.
6366                if (i >= N) {
6367                    final long origId = Binder.clearCallingIdentity();
6368
6369                    try {
6370                        // Content provider is now in use, its package can't be stopped.
6371                        try {
6372                            AppGlobals.getPackageManager().setPackageStoppedState(
6373                                    cpr.appInfo.packageName, false, userId);
6374                        } catch (RemoteException e) {
6375                        } catch (IllegalArgumentException e) {
6376                            Slog.w(TAG, "Failed trying to unstop package "
6377                                    + cpr.appInfo.packageName + ": " + e);
6378                        }
6379
6380                        ProcessRecord proc = startProcessLocked(cpi.processName,
6381                                cpr.appInfo, false, 0, "content provider",
6382                                new ComponentName(cpi.applicationInfo.packageName,
6383                                        cpi.name), false, false);
6384                        if (proc == null) {
6385                            Slog.w(TAG, "Unable to launch app "
6386                                    + cpi.applicationInfo.packageName + "/"
6387                                    + cpi.applicationInfo.uid + " for provider "
6388                                    + name + ": process is bad");
6389                            return null;
6390                        }
6391                        cpr.launchingApp = proc;
6392                        mLaunchingProviders.add(cpr);
6393                    } finally {
6394                        Binder.restoreCallingIdentity(origId);
6395                    }
6396                }
6397
6398                // Make sure the provider is published (the same provider class
6399                // may be published under multiple names).
6400                if (firstClass) {
6401                    mProviderMap.putProviderByClass(comp, cpr);
6402                }
6403
6404                mProviderMap.putProviderByName(name, cpr);
6405                conn = incProviderCountLocked(r, cpr, token, stable);
6406                if (conn != null) {
6407                    conn.waiting = true;
6408                }
6409            }
6410        }
6411
6412        // Wait for the provider to be published...
6413        synchronized (cpr) {
6414            while (cpr.provider == null) {
6415                if (cpr.launchingApp == null) {
6416                    Slog.w(TAG, "Unable to launch app "
6417                            + cpi.applicationInfo.packageName + "/"
6418                            + cpi.applicationInfo.uid + " for provider "
6419                            + name + ": launching app became null");
6420                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6421                            cpi.applicationInfo.packageName,
6422                            cpi.applicationInfo.uid, name);
6423                    return null;
6424                }
6425                try {
6426                    if (DEBUG_MU) {
6427                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6428                                + cpr.launchingApp);
6429                    }
6430                    if (conn != null) {
6431                        conn.waiting = true;
6432                    }
6433                    cpr.wait();
6434                } catch (InterruptedException ex) {
6435                } finally {
6436                    if (conn != null) {
6437                        conn.waiting = false;
6438                    }
6439                }
6440            }
6441        }
6442        return cpr != null ? cpr.newHolder(conn) : null;
6443    }
6444
6445    public final ContentProviderHolder getContentProvider(
6446            IApplicationThread caller, String name, boolean stable) {
6447        enforceNotIsolatedCaller("getContentProvider");
6448        if (caller == null) {
6449            String msg = "null IApplicationThread when getting content provider "
6450                    + name;
6451            Slog.w(TAG, msg);
6452            throw new SecurityException(msg);
6453        }
6454
6455        return getContentProviderImpl(caller, name, null, stable);
6456    }
6457
6458    public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6459        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6460            "Do not have permission in call getContentProviderExternal()");
6461        return getContentProviderExternalUnchecked(name, token);
6462    }
6463
6464    private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) {
6465        return getContentProviderImpl(null, name, token, true);
6466    }
6467
6468    /**
6469     * Drop a content provider from a ProcessRecord's bookkeeping
6470     * @param cpr
6471     */
6472    public void removeContentProvider(IBinder connection, boolean stable) {
6473        enforceNotIsolatedCaller("removeContentProvider");
6474        synchronized (this) {
6475            ContentProviderConnection conn;
6476            try {
6477                conn = (ContentProviderConnection)connection;
6478            } catch (ClassCastException e) {
6479                String msg ="removeContentProvider: " + connection
6480                        + " not a ContentProviderConnection";
6481                Slog.w(TAG, msg);
6482                throw new IllegalArgumentException(msg);
6483            }
6484            if (conn == null) {
6485                throw new NullPointerException("connection is null");
6486            }
6487            if (decProviderCountLocked(conn, null, null, stable)) {
6488                updateOomAdjLocked();
6489            }
6490        }
6491    }
6492
6493    public void removeContentProviderExternal(String name, IBinder token) {
6494        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6495            "Do not have permission in call removeContentProviderExternal()");
6496        removeContentProviderExternalUnchecked(name, token);
6497    }
6498
6499    private void removeContentProviderExternalUnchecked(String name, IBinder token) {
6500        synchronized (this) {
6501            ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
6502                    Binder.getOrigCallingUser());
6503            if(cpr == null) {
6504                //remove from mProvidersByClass
6505                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6506                return;
6507            }
6508
6509            //update content provider record entry info
6510            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6511            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
6512                    Binder.getOrigCallingUser());
6513            if (localCpr.hasExternalProcessHandles()) {
6514                if (localCpr.removeExternalProcessHandleLocked(token)) {
6515                    updateOomAdjLocked();
6516                } else {
6517                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6518                            + " with no external reference for token: "
6519                            + token + ".");
6520                }
6521            } else {
6522                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6523                        + " with no external references.");
6524            }
6525        }
6526    }
6527
6528    public final void publishContentProviders(IApplicationThread caller,
6529            List<ContentProviderHolder> providers) {
6530        if (providers == null) {
6531            return;
6532        }
6533
6534        enforceNotIsolatedCaller("publishContentProviders");
6535        synchronized (this) {
6536            final ProcessRecord r = getRecordForAppLocked(caller);
6537            if (DEBUG_MU)
6538                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6539            if (r == null) {
6540                throw new SecurityException(
6541                        "Unable to find app for caller " + caller
6542                      + " (pid=" + Binder.getCallingPid()
6543                      + ") when publishing content providers");
6544            }
6545
6546            final long origId = Binder.clearCallingIdentity();
6547
6548            final int N = providers.size();
6549            for (int i=0; i<N; i++) {
6550                ContentProviderHolder src = providers.get(i);
6551                if (src == null || src.info == null || src.provider == null) {
6552                    continue;
6553                }
6554                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6555                if (DEBUG_MU)
6556                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6557                if (dst != null) {
6558                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6559                    mProviderMap.putProviderByClass(comp, dst);
6560                    String names[] = dst.info.authority.split(";");
6561                    for (int j = 0; j < names.length; j++) {
6562                        mProviderMap.putProviderByName(names[j], dst);
6563                    }
6564
6565                    int NL = mLaunchingProviders.size();
6566                    int j;
6567                    for (j=0; j<NL; j++) {
6568                        if (mLaunchingProviders.get(j) == dst) {
6569                            mLaunchingProviders.remove(j);
6570                            j--;
6571                            NL--;
6572                        }
6573                    }
6574                    synchronized (dst) {
6575                        dst.provider = src.provider;
6576                        dst.proc = r;
6577                        dst.notifyAll();
6578                    }
6579                    updateOomAdjLocked(r);
6580                }
6581            }
6582
6583            Binder.restoreCallingIdentity(origId);
6584        }
6585    }
6586
6587    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6588        ContentProviderConnection conn;
6589        try {
6590            conn = (ContentProviderConnection)connection;
6591        } catch (ClassCastException e) {
6592            String msg ="refContentProvider: " + connection
6593                    + " not a ContentProviderConnection";
6594            Slog.w(TAG, msg);
6595            throw new IllegalArgumentException(msg);
6596        }
6597        if (conn == null) {
6598            throw new NullPointerException("connection is null");
6599        }
6600
6601        synchronized (this) {
6602            if (stable > 0) {
6603                conn.numStableIncs += stable;
6604            }
6605            stable = conn.stableCount + stable;
6606            if (stable < 0) {
6607                throw new IllegalStateException("stableCount < 0: " + stable);
6608            }
6609
6610            if (unstable > 0) {
6611                conn.numUnstableIncs += unstable;
6612            }
6613            unstable = conn.unstableCount + unstable;
6614            if (unstable < 0) {
6615                throw new IllegalStateException("unstableCount < 0: " + unstable);
6616            }
6617
6618            if ((stable+unstable) <= 0) {
6619                throw new IllegalStateException("ref counts can't go to zero here: stable="
6620                        + stable + " unstable=" + unstable);
6621            }
6622            conn.stableCount = stable;
6623            conn.unstableCount = unstable;
6624            return !conn.dead;
6625        }
6626    }
6627
6628    public void unstableProviderDied(IBinder connection) {
6629        ContentProviderConnection conn;
6630        try {
6631            conn = (ContentProviderConnection)connection;
6632        } catch (ClassCastException e) {
6633            String msg ="refContentProvider: " + connection
6634                    + " not a ContentProviderConnection";
6635            Slog.w(TAG, msg);
6636            throw new IllegalArgumentException(msg);
6637        }
6638        if (conn == null) {
6639            throw new NullPointerException("connection is null");
6640        }
6641
6642        // Safely retrieve the content provider associated with the connection.
6643        IContentProvider provider;
6644        synchronized (this) {
6645            provider = conn.provider.provider;
6646        }
6647
6648        if (provider == null) {
6649            // Um, yeah, we're way ahead of you.
6650            return;
6651        }
6652
6653        // Make sure the caller is being honest with us.
6654        if (provider.asBinder().pingBinder()) {
6655            // Er, no, still looks good to us.
6656            synchronized (this) {
6657                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6658                        + " says " + conn + " died, but we don't agree");
6659                return;
6660            }
6661        }
6662
6663        // Well look at that!  It's dead!
6664        synchronized (this) {
6665            if (conn.provider.provider != provider) {
6666                // But something changed...  good enough.
6667                return;
6668            }
6669
6670            ProcessRecord proc = conn.provider.proc;
6671            if (proc == null || proc.thread == null) {
6672                // Seems like the process is already cleaned up.
6673                return;
6674            }
6675
6676            // As far as we're concerned, this is just like receiving a
6677            // death notification...  just a bit prematurely.
6678            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6679                    + ") early provider death");
6680            final long ident = Binder.clearCallingIdentity();
6681            try {
6682                appDiedLocked(proc, proc.pid, proc.thread);
6683            } finally {
6684                Binder.restoreCallingIdentity(ident);
6685            }
6686        }
6687    }
6688
6689    public static final void installSystemProviders() {
6690        List<ProviderInfo> providers;
6691        synchronized (mSelf) {
6692            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6693            providers = mSelf.generateApplicationProvidersLocked(app);
6694            if (providers != null) {
6695                for (int i=providers.size()-1; i>=0; i--) {
6696                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6697                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6698                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6699                                + ": not system .apk");
6700                        providers.remove(i);
6701                    }
6702                }
6703            }
6704        }
6705        if (providers != null) {
6706            mSystemThread.installSystemProviders(providers);
6707        }
6708
6709        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6710
6711        mSelf.mUsageStatsService.monitorPackages();
6712    }
6713
6714    /**
6715     * Allows app to retrieve the MIME type of a URI without having permission
6716     * to access its content provider.
6717     *
6718     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6719     *
6720     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6721     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6722     */
6723    public String getProviderMimeType(Uri uri) {
6724        enforceNotIsolatedCaller("getProviderMimeType");
6725        final String name = uri.getAuthority();
6726        final long ident = Binder.clearCallingIdentity();
6727        ContentProviderHolder holder = null;
6728
6729        try {
6730            holder = getContentProviderExternalUnchecked(name, null);
6731            if (holder != null) {
6732                return holder.provider.getType(uri);
6733            }
6734        } catch (RemoteException e) {
6735            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6736            return null;
6737        } finally {
6738            if (holder != null) {
6739                removeContentProviderExternalUnchecked(name, null);
6740            }
6741            Binder.restoreCallingIdentity(ident);
6742        }
6743
6744        return null;
6745    }
6746
6747    // =========================================================
6748    // GLOBAL MANAGEMENT
6749    // =========================================================
6750
6751    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6752            ApplicationInfo info, String customProcess, boolean isolated) {
6753        String proc = customProcess != null ? customProcess : info.processName;
6754        BatteryStatsImpl.Uid.Proc ps = null;
6755        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6756        int uid = info.uid;
6757        if (isolated) {
6758            int userId = UserId.getUserId(uid);
6759            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6760            uid = 0;
6761            while (true) {
6762                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6763                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6764                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6765                }
6766                uid = UserId.getUid(userId, mNextIsolatedProcessUid);
6767                mNextIsolatedProcessUid++;
6768                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6769                    // No process for this uid, use it.
6770                    break;
6771                }
6772                stepsLeft--;
6773                if (stepsLeft <= 0) {
6774                    return null;
6775                }
6776            }
6777        }
6778        synchronized (stats) {
6779            ps = stats.getProcessStatsLocked(info.uid, proc);
6780        }
6781        return new ProcessRecord(ps, thread, info, proc, uid);
6782    }
6783
6784    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6785        ProcessRecord app;
6786        if (!isolated) {
6787            app = getProcessRecordLocked(info.processName, info.uid);
6788        } else {
6789            app = null;
6790        }
6791
6792        if (app == null) {
6793            app = newProcessRecordLocked(null, info, null, isolated);
6794            mProcessNames.put(info.processName, app.uid, app);
6795            if (isolated) {
6796                mIsolatedProcesses.put(app.uid, app);
6797            }
6798            updateLruProcessLocked(app, true, true);
6799        }
6800
6801        // This package really, really can not be stopped.
6802        try {
6803            AppGlobals.getPackageManager().setPackageStoppedState(
6804                    info.packageName, false, UserId.getUserId(app.uid));
6805        } catch (RemoteException e) {
6806        } catch (IllegalArgumentException e) {
6807            Slog.w(TAG, "Failed trying to unstop package "
6808                    + info.packageName + ": " + e);
6809        }
6810
6811        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6812                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6813            app.persistent = true;
6814            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
6815        }
6816        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6817            mPersistentStartingProcesses.add(app);
6818            startProcessLocked(app, "added application", app.processName);
6819        }
6820
6821        return app;
6822    }
6823
6824    public void unhandledBack() {
6825        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6826                "unhandledBack()");
6827
6828        synchronized(this) {
6829            int count = mMainStack.mHistory.size();
6830            if (DEBUG_SWITCH) Slog.d(
6831                TAG, "Performing unhandledBack(): stack size = " + count);
6832            if (count > 1) {
6833                final long origId = Binder.clearCallingIdentity();
6834                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
6835                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6836                Binder.restoreCallingIdentity(origId);
6837            }
6838        }
6839    }
6840
6841    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6842        enforceNotIsolatedCaller("openContentUri");
6843        String name = uri.getAuthority();
6844        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null);
6845        ParcelFileDescriptor pfd = null;
6846        if (cph != null) {
6847            // We record the binder invoker's uid in thread-local storage before
6848            // going to the content provider to open the file.  Later, in the code
6849            // that handles all permissions checks, we look for this uid and use
6850            // that rather than the Activity Manager's own uid.  The effect is that
6851            // we do the check against the caller's permissions even though it looks
6852            // to the content provider like the Activity Manager itself is making
6853            // the request.
6854            sCallerIdentity.set(new Identity(
6855                    Binder.getCallingPid(), Binder.getCallingUid()));
6856            try {
6857                pfd = cph.provider.openFile(uri, "r");
6858            } catch (FileNotFoundException e) {
6859                // do nothing; pfd will be returned null
6860            } finally {
6861                // Ensure that whatever happens, we clean up the identity state
6862                sCallerIdentity.remove();
6863            }
6864
6865            // We've got the fd now, so we're done with the provider.
6866            removeContentProviderExternalUnchecked(name, null);
6867        } else {
6868            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
6869        }
6870        return pfd;
6871    }
6872
6873    // Actually is sleeping or shutting down or whatever else in the future
6874    // is an inactive state.
6875    public boolean isSleeping() {
6876        return mSleeping || mShuttingDown;
6877    }
6878
6879    public void goingToSleep() {
6880        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6881                != PackageManager.PERMISSION_GRANTED) {
6882            throw new SecurityException("Requires permission "
6883                    + android.Manifest.permission.DEVICE_POWER);
6884        }
6885
6886        synchronized(this) {
6887            mWentToSleep = true;
6888            updateEventDispatchingLocked();
6889
6890            if (!mSleeping) {
6891                mSleeping = true;
6892                mMainStack.stopIfSleepingLocked();
6893
6894                // Initialize the wake times of all processes.
6895                checkExcessivePowerUsageLocked(false);
6896                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6897                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6898                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6899            }
6900        }
6901    }
6902
6903    public boolean shutdown(int timeout) {
6904        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6905                != PackageManager.PERMISSION_GRANTED) {
6906            throw new SecurityException("Requires permission "
6907                    + android.Manifest.permission.SHUTDOWN);
6908        }
6909
6910        boolean timedout = false;
6911
6912        synchronized(this) {
6913            mShuttingDown = true;
6914            updateEventDispatchingLocked();
6915
6916            if (mMainStack.mResumedActivity != null) {
6917                mMainStack.stopIfSleepingLocked();
6918                final long endTime = System.currentTimeMillis() + timeout;
6919                while (mMainStack.mResumedActivity != null
6920                        || mMainStack.mPausingActivity != null) {
6921                    long delay = endTime - System.currentTimeMillis();
6922                    if (delay <= 0) {
6923                        Slog.w(TAG, "Activity manager shutdown timed out");
6924                        timedout = true;
6925                        break;
6926                    }
6927                    try {
6928                        this.wait();
6929                    } catch (InterruptedException e) {
6930                    }
6931                }
6932            }
6933        }
6934
6935        mUsageStatsService.shutdown();
6936        mBatteryStatsService.shutdown();
6937
6938        return timedout;
6939    }
6940
6941    public final void activitySlept(IBinder token) {
6942        if (localLOGV) Slog.v(
6943            TAG, "Activity slept: token=" + token);
6944
6945        ActivityRecord r = null;
6946
6947        final long origId = Binder.clearCallingIdentity();
6948
6949        synchronized (this) {
6950            r = mMainStack.isInStackLocked(token);
6951            if (r != null) {
6952                mMainStack.activitySleptLocked(r);
6953            }
6954        }
6955
6956        Binder.restoreCallingIdentity(origId);
6957    }
6958
6959    private void comeOutOfSleepIfNeededLocked() {
6960        if (!mWentToSleep && !mLockScreenShown) {
6961            if (mSleeping) {
6962                mSleeping = false;
6963                mMainStack.awakeFromSleepingLocked();
6964                mMainStack.resumeTopActivityLocked(null);
6965            }
6966        }
6967    }
6968
6969    public void wakingUp() {
6970        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6971                != PackageManager.PERMISSION_GRANTED) {
6972            throw new SecurityException("Requires permission "
6973                    + android.Manifest.permission.DEVICE_POWER);
6974        }
6975
6976        synchronized(this) {
6977            mWentToSleep = false;
6978            updateEventDispatchingLocked();
6979            comeOutOfSleepIfNeededLocked();
6980        }
6981    }
6982
6983    private void updateEventDispatchingLocked() {
6984        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
6985    }
6986
6987    public void setLockScreenShown(boolean shown) {
6988        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6989                != PackageManager.PERMISSION_GRANTED) {
6990            throw new SecurityException("Requires permission "
6991                    + android.Manifest.permission.DEVICE_POWER);
6992        }
6993
6994        synchronized(this) {
6995            mLockScreenShown = shown;
6996            comeOutOfSleepIfNeededLocked();
6997        }
6998    }
6999
7000    public void stopAppSwitches() {
7001        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7002                != PackageManager.PERMISSION_GRANTED) {
7003            throw new SecurityException("Requires permission "
7004                    + android.Manifest.permission.STOP_APP_SWITCHES);
7005        }
7006
7007        synchronized(this) {
7008            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7009                    + APP_SWITCH_DELAY_TIME;
7010            mDidAppSwitch = false;
7011            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7012            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7013            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7014        }
7015    }
7016
7017    public void resumeAppSwitches() {
7018        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7019                != PackageManager.PERMISSION_GRANTED) {
7020            throw new SecurityException("Requires permission "
7021                    + android.Manifest.permission.STOP_APP_SWITCHES);
7022        }
7023
7024        synchronized(this) {
7025            // Note that we don't execute any pending app switches... we will
7026            // let those wait until either the timeout, or the next start
7027            // activity request.
7028            mAppSwitchesAllowedTime = 0;
7029        }
7030    }
7031
7032    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7033            String name) {
7034        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7035            return true;
7036        }
7037
7038        final int perm = checkComponentPermission(
7039                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7040                callingUid, -1, true);
7041        if (perm == PackageManager.PERMISSION_GRANTED) {
7042            return true;
7043        }
7044
7045        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7046        return false;
7047    }
7048
7049    public void setDebugApp(String packageName, boolean waitForDebugger,
7050            boolean persistent) {
7051        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7052                "setDebugApp()");
7053
7054        // Note that this is not really thread safe if there are multiple
7055        // callers into it at the same time, but that's not a situation we
7056        // care about.
7057        if (persistent) {
7058            final ContentResolver resolver = mContext.getContentResolver();
7059            Settings.System.putString(
7060                resolver, Settings.System.DEBUG_APP,
7061                packageName);
7062            Settings.System.putInt(
7063                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7064                waitForDebugger ? 1 : 0);
7065        }
7066
7067        synchronized (this) {
7068            if (!persistent) {
7069                mOrigDebugApp = mDebugApp;
7070                mOrigWaitForDebugger = mWaitForDebugger;
7071            }
7072            mDebugApp = packageName;
7073            mWaitForDebugger = waitForDebugger;
7074            mDebugTransient = !persistent;
7075            if (packageName != null) {
7076                final long origId = Binder.clearCallingIdentity();
7077                forceStopPackageLocked(packageName, -1, false, false, true, true, 0);
7078                Binder.restoreCallingIdentity(origId);
7079            }
7080        }
7081    }
7082
7083    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7084        synchronized (this) {
7085            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7086            if (!isDebuggable) {
7087                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7088                    throw new SecurityException("Process not debuggable: " + app.packageName);
7089                }
7090            }
7091
7092            mOpenGlTraceApp = processName;
7093        }
7094    }
7095
7096    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7097            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7098        synchronized (this) {
7099            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7100            if (!isDebuggable) {
7101                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7102                    throw new SecurityException("Process not debuggable: " + app.packageName);
7103                }
7104            }
7105            mProfileApp = processName;
7106            mProfileFile = profileFile;
7107            if (mProfileFd != null) {
7108                try {
7109                    mProfileFd.close();
7110                } catch (IOException e) {
7111                }
7112                mProfileFd = null;
7113            }
7114            mProfileFd = profileFd;
7115            mProfileType = 0;
7116            mAutoStopProfiler = autoStopProfiler;
7117        }
7118    }
7119
7120    public void setAlwaysFinish(boolean enabled) {
7121        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7122                "setAlwaysFinish()");
7123
7124        Settings.System.putInt(
7125                mContext.getContentResolver(),
7126                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7127
7128        synchronized (this) {
7129            mAlwaysFinishActivities = enabled;
7130        }
7131    }
7132
7133    public void setActivityController(IActivityController controller) {
7134        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7135                "setActivityController()");
7136        synchronized (this) {
7137            mController = controller;
7138        }
7139    }
7140
7141    public boolean isUserAMonkey() {
7142        // For now the fact that there is a controller implies
7143        // we have a monkey.
7144        synchronized (this) {
7145            return mController != null;
7146        }
7147    }
7148
7149    public void registerProcessObserver(IProcessObserver observer) {
7150        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7151                "registerProcessObserver()");
7152        synchronized (this) {
7153            mProcessObservers.register(observer);
7154        }
7155    }
7156
7157    public void unregisterProcessObserver(IProcessObserver observer) {
7158        synchronized (this) {
7159            mProcessObservers.unregister(observer);
7160        }
7161    }
7162
7163    public void setImmersive(IBinder token, boolean immersive) {
7164        synchronized(this) {
7165            ActivityRecord r = mMainStack.isInStackLocked(token);
7166            if (r == null) {
7167                throw new IllegalArgumentException();
7168            }
7169            r.immersive = immersive;
7170        }
7171    }
7172
7173    public boolean isImmersive(IBinder token) {
7174        synchronized (this) {
7175            ActivityRecord r = mMainStack.isInStackLocked(token);
7176            if (r == null) {
7177                throw new IllegalArgumentException();
7178            }
7179            return r.immersive;
7180        }
7181    }
7182
7183    public boolean isTopActivityImmersive() {
7184        enforceNotIsolatedCaller("startActivity");
7185        synchronized (this) {
7186            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7187            return (r != null) ? r.immersive : false;
7188        }
7189    }
7190
7191    public final void enterSafeMode() {
7192        synchronized(this) {
7193            // It only makes sense to do this before the system is ready
7194            // and started launching other packages.
7195            if (!mSystemReady) {
7196                try {
7197                    AppGlobals.getPackageManager().enterSafeMode();
7198                } catch (RemoteException e) {
7199                }
7200            }
7201        }
7202    }
7203
7204    public final void showSafeModeOverlay() {
7205        View v = LayoutInflater.from(mContext).inflate(
7206                com.android.internal.R.layout.safe_mode, null);
7207        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7208        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7209        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7210        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7211        lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
7212        lp.format = v.getBackground().getOpacity();
7213        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7214                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7215        ((WindowManager)mContext.getSystemService(
7216                Context.WINDOW_SERVICE)).addView(v, lp);
7217    }
7218
7219    public void noteWakeupAlarm(IIntentSender sender) {
7220        if (!(sender instanceof PendingIntentRecord)) {
7221            return;
7222        }
7223        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7224        synchronized (stats) {
7225            if (mBatteryStatsService.isOnBattery()) {
7226                mBatteryStatsService.enforceCallingPermission();
7227                PendingIntentRecord rec = (PendingIntentRecord)sender;
7228                int MY_UID = Binder.getCallingUid();
7229                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7230                BatteryStatsImpl.Uid.Pkg pkg =
7231                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7232                pkg.incWakeupsLocked();
7233            }
7234        }
7235    }
7236
7237    public boolean killPids(int[] pids, String pReason, boolean secure) {
7238        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7239            throw new SecurityException("killPids only available to the system");
7240        }
7241        String reason = (pReason == null) ? "Unknown" : pReason;
7242        // XXX Note: don't acquire main activity lock here, because the window
7243        // manager calls in with its locks held.
7244
7245        boolean killed = false;
7246        synchronized (mPidsSelfLocked) {
7247            int[] types = new int[pids.length];
7248            int worstType = 0;
7249            for (int i=0; i<pids.length; i++) {
7250                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7251                if (proc != null) {
7252                    int type = proc.setAdj;
7253                    types[i] = type;
7254                    if (type > worstType) {
7255                        worstType = type;
7256                    }
7257                }
7258            }
7259
7260            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7261            // then constrain it so we will kill all hidden procs.
7262            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7263                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7264                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7265            }
7266
7267            // If this is not a secure call, don't let it kill processes that
7268            // are important.
7269            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7270                worstType = ProcessList.SERVICE_ADJ;
7271            }
7272
7273            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7274            for (int i=0; i<pids.length; i++) {
7275                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7276                if (proc == null) {
7277                    continue;
7278                }
7279                int adj = proc.setAdj;
7280                if (adj >= worstType && !proc.killedBackground) {
7281                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7282                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7283                            proc.processName, adj, reason);
7284                    killed = true;
7285                    proc.killedBackground = true;
7286                    Process.killProcessQuiet(pids[i]);
7287                }
7288            }
7289        }
7290        return killed;
7291    }
7292
7293    @Override
7294    public boolean killProcessesBelowForeground(String reason) {
7295        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7296            throw new SecurityException("killProcessesBelowForeground() only available to system");
7297        }
7298
7299        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7300    }
7301
7302    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7303        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7304            throw new SecurityException("killProcessesBelowAdj() only available to system");
7305        }
7306
7307        boolean killed = false;
7308        synchronized (mPidsSelfLocked) {
7309            final int size = mPidsSelfLocked.size();
7310            for (int i = 0; i < size; i++) {
7311                final int pid = mPidsSelfLocked.keyAt(i);
7312                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7313                if (proc == null) continue;
7314
7315                final int adj = proc.setAdj;
7316                if (adj > belowAdj && !proc.killedBackground) {
7317                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7318                    EventLog.writeEvent(
7319                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7320                    killed = true;
7321                    proc.killedBackground = true;
7322                    Process.killProcessQuiet(pid);
7323                }
7324            }
7325        }
7326        return killed;
7327    }
7328
7329    public final void startRunning(String pkg, String cls, String action,
7330            String data) {
7331        synchronized(this) {
7332            if (mStartRunning) {
7333                return;
7334            }
7335            mStartRunning = true;
7336            mTopComponent = pkg != null && cls != null
7337                    ? new ComponentName(pkg, cls) : null;
7338            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7339            mTopData = data;
7340            if (!mSystemReady) {
7341                return;
7342            }
7343        }
7344
7345        systemReady(null);
7346    }
7347
7348    private void retrieveSettings() {
7349        final ContentResolver resolver = mContext.getContentResolver();
7350        String debugApp = Settings.System.getString(
7351            resolver, Settings.System.DEBUG_APP);
7352        boolean waitForDebugger = Settings.System.getInt(
7353            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7354        boolean alwaysFinishActivities = Settings.System.getInt(
7355            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7356
7357        Configuration configuration = new Configuration();
7358        Settings.System.getConfiguration(resolver, configuration);
7359
7360        synchronized (this) {
7361            mDebugApp = mOrigDebugApp = debugApp;
7362            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7363            mAlwaysFinishActivities = alwaysFinishActivities;
7364            // This happens before any activities are started, so we can
7365            // change mConfiguration in-place.
7366            updateConfigurationLocked(configuration, null, false, true);
7367            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7368        }
7369    }
7370
7371    public boolean testIsSystemReady() {
7372        // no need to synchronize(this) just to read & return the value
7373        return mSystemReady;
7374    }
7375
7376    private static File getCalledPreBootReceiversFile() {
7377        File dataDir = Environment.getDataDirectory();
7378        File systemDir = new File(dataDir, "system");
7379        File fname = new File(systemDir, "called_pre_boots.dat");
7380        return fname;
7381    }
7382
7383    static final int LAST_DONE_VERSION = 10000;
7384
7385    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7386        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7387        File file = getCalledPreBootReceiversFile();
7388        FileInputStream fis = null;
7389        try {
7390            fis = new FileInputStream(file);
7391            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7392            int fvers = dis.readInt();
7393            if (fvers == LAST_DONE_VERSION) {
7394                String vers = dis.readUTF();
7395                String codename = dis.readUTF();
7396                String build = dis.readUTF();
7397                if (android.os.Build.VERSION.RELEASE.equals(vers)
7398                        && android.os.Build.VERSION.CODENAME.equals(codename)
7399                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7400                    int num = dis.readInt();
7401                    while (num > 0) {
7402                        num--;
7403                        String pkg = dis.readUTF();
7404                        String cls = dis.readUTF();
7405                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7406                    }
7407                }
7408            }
7409        } catch (FileNotFoundException e) {
7410        } catch (IOException e) {
7411            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7412        } finally {
7413            if (fis != null) {
7414                try {
7415                    fis.close();
7416                } catch (IOException e) {
7417                }
7418            }
7419        }
7420        return lastDoneReceivers;
7421    }
7422
7423    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7424        File file = getCalledPreBootReceiversFile();
7425        FileOutputStream fos = null;
7426        DataOutputStream dos = null;
7427        try {
7428            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7429            fos = new FileOutputStream(file);
7430            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7431            dos.writeInt(LAST_DONE_VERSION);
7432            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7433            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7434            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7435            dos.writeInt(list.size());
7436            for (int i=0; i<list.size(); i++) {
7437                dos.writeUTF(list.get(i).getPackageName());
7438                dos.writeUTF(list.get(i).getClassName());
7439            }
7440        } catch (IOException e) {
7441            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7442            file.delete();
7443        } finally {
7444            FileUtils.sync(fos);
7445            if (dos != null) {
7446                try {
7447                    dos.close();
7448                } catch (IOException e) {
7449                    // TODO Auto-generated catch block
7450                    e.printStackTrace();
7451                }
7452            }
7453        }
7454    }
7455
7456    public void systemReady(final Runnable goingCallback) {
7457        synchronized(this) {
7458            if (mSystemReady) {
7459                if (goingCallback != null) goingCallback.run();
7460                return;
7461            }
7462
7463            // Check to see if there are any update receivers to run.
7464            if (!mDidUpdate) {
7465                if (mWaitingUpdate) {
7466                    return;
7467                }
7468                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7469                List<ResolveInfo> ris = null;
7470                try {
7471                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7472                            intent, null, 0, 0);
7473                } catch (RemoteException e) {
7474                }
7475                if (ris != null) {
7476                    for (int i=ris.size()-1; i>=0; i--) {
7477                        if ((ris.get(i).activityInfo.applicationInfo.flags
7478                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7479                            ris.remove(i);
7480                        }
7481                    }
7482                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7483
7484                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7485
7486                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7487                    for (int i=0; i<ris.size(); i++) {
7488                        ActivityInfo ai = ris.get(i).activityInfo;
7489                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7490                        if (lastDoneReceivers.contains(comp)) {
7491                            ris.remove(i);
7492                            i--;
7493                        }
7494                    }
7495
7496                    for (int i=0; i<ris.size(); i++) {
7497                        ActivityInfo ai = ris.get(i).activityInfo;
7498                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7499                        doneReceivers.add(comp);
7500                        intent.setComponent(comp);
7501                        IIntentReceiver finisher = null;
7502                        if (i == ris.size()-1) {
7503                            finisher = new IIntentReceiver.Stub() {
7504                                public void performReceive(Intent intent, int resultCode,
7505                                        String data, Bundle extras, boolean ordered,
7506                                        boolean sticky) {
7507                                    // The raw IIntentReceiver interface is called
7508                                    // with the AM lock held, so redispatch to
7509                                    // execute our code without the lock.
7510                                    mHandler.post(new Runnable() {
7511                                        public void run() {
7512                                            synchronized (ActivityManagerService.this) {
7513                                                mDidUpdate = true;
7514                                            }
7515                                            writeLastDonePreBootReceivers(doneReceivers);
7516                                            showBootMessage(mContext.getText(
7517                                                    R.string.android_upgrading_complete),
7518                                                    false);
7519                                            systemReady(goingCallback);
7520                                        }
7521                                    });
7522                                }
7523                            };
7524                        }
7525                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
7526                        /* TODO: Send this to all users */
7527                        broadcastIntentLocked(null, null, intent, null, finisher,
7528                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7529                                0 /* UserId zero */);
7530                        if (finisher != null) {
7531                            mWaitingUpdate = true;
7532                        }
7533                    }
7534                }
7535                if (mWaitingUpdate) {
7536                    return;
7537                }
7538                mDidUpdate = true;
7539            }
7540
7541            mSystemReady = true;
7542            if (!mStartRunning) {
7543                return;
7544            }
7545        }
7546
7547        ArrayList<ProcessRecord> procsToKill = null;
7548        synchronized(mPidsSelfLocked) {
7549            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7550                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7551                if (!isAllowedWhileBooting(proc.info)){
7552                    if (procsToKill == null) {
7553                        procsToKill = new ArrayList<ProcessRecord>();
7554                    }
7555                    procsToKill.add(proc);
7556                }
7557            }
7558        }
7559
7560        synchronized(this) {
7561            if (procsToKill != null) {
7562                for (int i=procsToKill.size()-1; i>=0; i--) {
7563                    ProcessRecord proc = procsToKill.get(i);
7564                    Slog.i(TAG, "Removing system update proc: " + proc);
7565                    removeProcessLocked(proc, true, false, "system update done");
7566                }
7567            }
7568
7569            // Now that we have cleaned up any update processes, we
7570            // are ready to start launching real processes and know that
7571            // we won't trample on them any more.
7572            mProcessesReady = true;
7573        }
7574
7575        Slog.i(TAG, "System now ready");
7576        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7577            SystemClock.uptimeMillis());
7578
7579        synchronized(this) {
7580            // Make sure we have no pre-ready processes sitting around.
7581
7582            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7583                ResolveInfo ri = mContext.getPackageManager()
7584                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7585                                STOCK_PM_FLAGS);
7586                CharSequence errorMsg = null;
7587                if (ri != null) {
7588                    ActivityInfo ai = ri.activityInfo;
7589                    ApplicationInfo app = ai.applicationInfo;
7590                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7591                        mTopAction = Intent.ACTION_FACTORY_TEST;
7592                        mTopData = null;
7593                        mTopComponent = new ComponentName(app.packageName,
7594                                ai.name);
7595                    } else {
7596                        errorMsg = mContext.getResources().getText(
7597                                com.android.internal.R.string.factorytest_not_system);
7598                    }
7599                } else {
7600                    errorMsg = mContext.getResources().getText(
7601                            com.android.internal.R.string.factorytest_no_action);
7602                }
7603                if (errorMsg != null) {
7604                    mTopAction = null;
7605                    mTopData = null;
7606                    mTopComponent = null;
7607                    Message msg = Message.obtain();
7608                    msg.what = SHOW_FACTORY_ERROR_MSG;
7609                    msg.getData().putCharSequence("msg", errorMsg);
7610                    mHandler.sendMessage(msg);
7611                }
7612            }
7613        }
7614
7615        retrieveSettings();
7616
7617        if (goingCallback != null) goingCallback.run();
7618
7619        synchronized (this) {
7620            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7621                try {
7622                    List apps = AppGlobals.getPackageManager().
7623                        getPersistentApplications(STOCK_PM_FLAGS);
7624                    if (apps != null) {
7625                        int N = apps.size();
7626                        int i;
7627                        for (i=0; i<N; i++) {
7628                            ApplicationInfo info
7629                                = (ApplicationInfo)apps.get(i);
7630                            if (info != null &&
7631                                    !info.packageName.equals("android")) {
7632                                addAppLocked(info, false);
7633                            }
7634                        }
7635                    }
7636                } catch (RemoteException ex) {
7637                    // pm is in same process, this will never happen.
7638                }
7639            }
7640
7641            // Start up initial activity.
7642            mBooting = true;
7643
7644            try {
7645                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7646                    Message msg = Message.obtain();
7647                    msg.what = SHOW_UID_ERROR_MSG;
7648                    mHandler.sendMessage(msg);
7649                }
7650            } catch (RemoteException e) {
7651            }
7652
7653            mMainStack.resumeTopActivityLocked(null);
7654        }
7655    }
7656
7657    private boolean makeAppCrashingLocked(ProcessRecord app,
7658            String shortMsg, String longMsg, String stackTrace) {
7659        app.crashing = true;
7660        app.crashingReport = generateProcessError(app,
7661                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7662        startAppProblemLocked(app);
7663        app.stopFreezingAllLocked();
7664        return handleAppCrashLocked(app);
7665    }
7666
7667    private void makeAppNotRespondingLocked(ProcessRecord app,
7668            String activity, String shortMsg, String longMsg) {
7669        app.notResponding = true;
7670        app.notRespondingReport = generateProcessError(app,
7671                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7672                activity, shortMsg, longMsg, null);
7673        startAppProblemLocked(app);
7674        app.stopFreezingAllLocked();
7675    }
7676
7677    /**
7678     * Generate a process error record, suitable for attachment to a ProcessRecord.
7679     *
7680     * @param app The ProcessRecord in which the error occurred.
7681     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7682     *                      ActivityManager.AppErrorStateInfo
7683     * @param activity The activity associated with the crash, if known.
7684     * @param shortMsg Short message describing the crash.
7685     * @param longMsg Long message describing the crash.
7686     * @param stackTrace Full crash stack trace, may be null.
7687     *
7688     * @return Returns a fully-formed AppErrorStateInfo record.
7689     */
7690    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7691            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7692        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7693
7694        report.condition = condition;
7695        report.processName = app.processName;
7696        report.pid = app.pid;
7697        report.uid = app.info.uid;
7698        report.tag = activity;
7699        report.shortMsg = shortMsg;
7700        report.longMsg = longMsg;
7701        report.stackTrace = stackTrace;
7702
7703        return report;
7704    }
7705
7706    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7707        synchronized (this) {
7708            app.crashing = false;
7709            app.crashingReport = null;
7710            app.notResponding = false;
7711            app.notRespondingReport = null;
7712            if (app.anrDialog == fromDialog) {
7713                app.anrDialog = null;
7714            }
7715            if (app.waitDialog == fromDialog) {
7716                app.waitDialog = null;
7717            }
7718            if (app.pid > 0 && app.pid != MY_PID) {
7719                handleAppCrashLocked(app);
7720                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7721                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7722                        app.processName, app.setAdj, "user's request after error");
7723                Process.killProcessQuiet(app.pid);
7724            }
7725        }
7726    }
7727
7728    private boolean handleAppCrashLocked(ProcessRecord app) {
7729        if (mHeadless) {
7730            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7731            return false;
7732        }
7733        long now = SystemClock.uptimeMillis();
7734
7735        Long crashTime;
7736        if (!app.isolated) {
7737            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7738        } else {
7739            crashTime = null;
7740        }
7741        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7742            // This process loses!
7743            Slog.w(TAG, "Process " + app.info.processName
7744                    + " has crashed too many times: killing!");
7745            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7746                    app.info.processName, app.uid);
7747            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7748                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7749                if (r.app == app) {
7750                    Slog.w(TAG, "  Force finishing activity "
7751                        + r.intent.getComponent().flattenToShortString());
7752                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
7753                }
7754            }
7755            if (!app.persistent) {
7756                // We don't want to start this process again until the user
7757                // explicitly does so...  but for persistent process, we really
7758                // need to keep it running.  If a persistent process is actually
7759                // repeatedly crashing, then badness for everyone.
7760                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
7761                        app.info.processName);
7762                if (!app.isolated) {
7763                    // XXX We don't have a way to mark isolated processes
7764                    // as bad, since they don't have a peristent identity.
7765                    mBadProcesses.put(app.info.processName, app.uid, now);
7766                    mProcessCrashTimes.remove(app.info.processName, app.uid);
7767                }
7768                app.bad = true;
7769                app.removed = true;
7770                // Don't let services in this process be restarted and potentially
7771                // annoy the user repeatedly.  Unless it is persistent, since those
7772                // processes run critical code.
7773                removeProcessLocked(app, false, false, "crash");
7774                mMainStack.resumeTopActivityLocked(null);
7775                return false;
7776            }
7777            mMainStack.resumeTopActivityLocked(null);
7778        } else {
7779            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7780            if (r != null && r.app == app) {
7781                // If the top running activity is from this crashing
7782                // process, then terminate it to avoid getting in a loop.
7783                Slog.w(TAG, "  Force finishing activity "
7784                        + r.intent.getComponent().flattenToShortString());
7785                int index = mMainStack.indexOfActivityLocked(r);
7786                r.stack.finishActivityLocked(r, index,
7787                        Activity.RESULT_CANCELED, null, "crashed");
7788                // Also terminate any activities below it that aren't yet
7789                // stopped, to avoid a situation where one will get
7790                // re-start our crashing activity once it gets resumed again.
7791                index--;
7792                if (index >= 0) {
7793                    r = (ActivityRecord)mMainStack.mHistory.get(index);
7794                    if (r.state == ActivityState.RESUMED
7795                            || r.state == ActivityState.PAUSING
7796                            || r.state == ActivityState.PAUSED) {
7797                        if (!r.isHomeActivity || mHomeProcess != r.app) {
7798                            Slog.w(TAG, "  Force finishing activity "
7799                                    + r.intent.getComponent().flattenToShortString());
7800                            r.stack.finishActivityLocked(r, index,
7801                                    Activity.RESULT_CANCELED, null, "crashed");
7802                        }
7803                    }
7804                }
7805            }
7806        }
7807
7808        // Bump up the crash count of any services currently running in the proc.
7809        if (app.services.size() != 0) {
7810            // Any services running in the application need to be placed
7811            // back in the pending list.
7812            Iterator<ServiceRecord> it = app.services.iterator();
7813            while (it.hasNext()) {
7814                ServiceRecord sr = it.next();
7815                sr.crashCount++;
7816            }
7817        }
7818
7819        // If the crashing process is what we consider to be the "home process" and it has been
7820        // replaced by a third-party app, clear the package preferred activities from packages
7821        // with a home activity running in the process to prevent a repeatedly crashing app
7822        // from blocking the user to manually clear the list.
7823        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7824                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7825            Iterator it = mHomeProcess.activities.iterator();
7826            while (it.hasNext()) {
7827                ActivityRecord r = (ActivityRecord)it.next();
7828                if (r.isHomeActivity) {
7829                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7830                    try {
7831                        ActivityThread.getPackageManager()
7832                                .clearPackagePreferredActivities(r.packageName);
7833                    } catch (RemoteException c) {
7834                        // pm is in same process, this will never happen.
7835                    }
7836                }
7837            }
7838        }
7839
7840        if (!app.isolated) {
7841            // XXX Can't keep track of crash times for isolated processes,
7842            // because they don't have a perisistent identity.
7843            mProcessCrashTimes.put(app.info.processName, app.uid, now);
7844        }
7845
7846        return true;
7847    }
7848
7849    void startAppProblemLocked(ProcessRecord app) {
7850        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7851                mContext, app.info.packageName, app.info.flags);
7852        skipCurrentReceiverLocked(app);
7853    }
7854
7855    void skipCurrentReceiverLocked(ProcessRecord app) {
7856        for (BroadcastQueue queue : mBroadcastQueues) {
7857            queue.skipCurrentReceiverLocked(app);
7858        }
7859    }
7860
7861    /**
7862     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7863     * The application process will exit immediately after this call returns.
7864     * @param app object of the crashing app, null for the system server
7865     * @param crashInfo describing the exception
7866     */
7867    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
7868        ProcessRecord r = findAppProcess(app, "Crash");
7869        final String processName = app == null ? "system_server"
7870                : (r == null ? "unknown" : r.processName);
7871
7872        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7873                processName,
7874                r == null ? -1 : r.info.flags,
7875                crashInfo.exceptionClassName,
7876                crashInfo.exceptionMessage,
7877                crashInfo.throwFileName,
7878                crashInfo.throwLineNumber);
7879
7880        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
7881
7882        crashApplication(r, crashInfo);
7883    }
7884
7885    public void handleApplicationStrictModeViolation(
7886            IBinder app,
7887            int violationMask,
7888            StrictMode.ViolationInfo info) {
7889        ProcessRecord r = findAppProcess(app, "StrictMode");
7890        if (r == null) {
7891            return;
7892        }
7893
7894        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
7895            Integer stackFingerprint = info.hashCode();
7896            boolean logIt = true;
7897            synchronized (mAlreadyLoggedViolatedStacks) {
7898                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7899                    logIt = false;
7900                    // TODO: sub-sample into EventLog for these, with
7901                    // the info.durationMillis?  Then we'd get
7902                    // the relative pain numbers, without logging all
7903                    // the stack traces repeatedly.  We'd want to do
7904                    // likewise in the client code, which also does
7905                    // dup suppression, before the Binder call.
7906                } else {
7907                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7908                        mAlreadyLoggedViolatedStacks.clear();
7909                    }
7910                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7911                }
7912            }
7913            if (logIt) {
7914                logStrictModeViolationToDropBox(r, info);
7915            }
7916        }
7917
7918        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7919            AppErrorResult result = new AppErrorResult();
7920            synchronized (this) {
7921                final long origId = Binder.clearCallingIdentity();
7922
7923                Message msg = Message.obtain();
7924                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7925                HashMap<String, Object> data = new HashMap<String, Object>();
7926                data.put("result", result);
7927                data.put("app", r);
7928                data.put("violationMask", violationMask);
7929                data.put("info", info);
7930                msg.obj = data;
7931                mHandler.sendMessage(msg);
7932
7933                Binder.restoreCallingIdentity(origId);
7934            }
7935            int res = result.get();
7936            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
7937        }
7938    }
7939
7940    // Depending on the policy in effect, there could be a bunch of
7941    // these in quick succession so we try to batch these together to
7942    // minimize disk writes, number of dropbox entries, and maximize
7943    // compression, by having more fewer, larger records.
7944    private void logStrictModeViolationToDropBox(
7945            ProcessRecord process,
7946            StrictMode.ViolationInfo info) {
7947        if (info == null) {
7948            return;
7949        }
7950        final boolean isSystemApp = process == null ||
7951                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7952                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7953        final String processName = process == null ? "unknown" : process.processName;
7954        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7955        final DropBoxManager dbox = (DropBoxManager)
7956                mContext.getSystemService(Context.DROPBOX_SERVICE);
7957
7958        // Exit early if the dropbox isn't configured to accept this report type.
7959        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7960
7961        boolean bufferWasEmpty;
7962        boolean needsFlush;
7963        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7964        synchronized (sb) {
7965            bufferWasEmpty = sb.length() == 0;
7966            appendDropBoxProcessHeaders(process, processName, sb);
7967            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7968            sb.append("System-App: ").append(isSystemApp).append("\n");
7969            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7970            if (info.violationNumThisLoop != 0) {
7971                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7972            }
7973            if (info.numAnimationsRunning != 0) {
7974                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7975            }
7976            if (info.broadcastIntentAction != null) {
7977                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7978            }
7979            if (info.durationMillis != -1) {
7980                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
7981            }
7982            if (info.numInstances != -1) {
7983                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7984            }
7985            if (info.tags != null) {
7986                for (String tag : info.tags) {
7987                    sb.append("Span-Tag: ").append(tag).append("\n");
7988                }
7989            }
7990            sb.append("\n");
7991            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7992                sb.append(info.crashInfo.stackTrace);
7993            }
7994            sb.append("\n");
7995
7996            // Only buffer up to ~64k.  Various logging bits truncate
7997            // things at 128k.
7998            needsFlush = (sb.length() > 64 * 1024);
7999        }
8000
8001        // Flush immediately if the buffer's grown too large, or this
8002        // is a non-system app.  Non-system apps are isolated with a
8003        // different tag & policy and not batched.
8004        //
8005        // Batching is useful during internal testing with
8006        // StrictMode settings turned up high.  Without batching,
8007        // thousands of separate files could be created on boot.
8008        if (!isSystemApp || needsFlush) {
8009            new Thread("Error dump: " + dropboxTag) {
8010                @Override
8011                public void run() {
8012                    String report;
8013                    synchronized (sb) {
8014                        report = sb.toString();
8015                        sb.delete(0, sb.length());
8016                        sb.trimToSize();
8017                    }
8018                    if (report.length() != 0) {
8019                        dbox.addText(dropboxTag, report);
8020                    }
8021                }
8022            }.start();
8023            return;
8024        }
8025
8026        // System app batching:
8027        if (!bufferWasEmpty) {
8028            // An existing dropbox-writing thread is outstanding, so
8029            // we don't need to start it up.  The existing thread will
8030            // catch the buffer appends we just did.
8031            return;
8032        }
8033
8034        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8035        // (After this point, we shouldn't access AMS internal data structures.)
8036        new Thread("Error dump: " + dropboxTag) {
8037            @Override
8038            public void run() {
8039                // 5 second sleep to let stacks arrive and be batched together
8040                try {
8041                    Thread.sleep(5000);  // 5 seconds
8042                } catch (InterruptedException e) {}
8043
8044                String errorReport;
8045                synchronized (mStrictModeBuffer) {
8046                    errorReport = mStrictModeBuffer.toString();
8047                    if (errorReport.length() == 0) {
8048                        return;
8049                    }
8050                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8051                    mStrictModeBuffer.trimToSize();
8052                }
8053                dbox.addText(dropboxTag, errorReport);
8054            }
8055        }.start();
8056    }
8057
8058    /**
8059     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8060     * @param app object of the crashing app, null for the system server
8061     * @param tag reported by the caller
8062     * @param crashInfo describing the context of the error
8063     * @return true if the process should exit immediately (WTF is fatal)
8064     */
8065    public boolean handleApplicationWtf(IBinder app, String tag,
8066            ApplicationErrorReport.CrashInfo crashInfo) {
8067        ProcessRecord r = findAppProcess(app, "WTF");
8068        final String processName = app == null ? "system_server"
8069                : (r == null ? "unknown" : r.processName);
8070
8071        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8072                processName,
8073                r == null ? -1 : r.info.flags,
8074                tag, crashInfo.exceptionMessage);
8075
8076        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8077
8078        if (r != null && r.pid != Process.myPid() &&
8079                Settings.Secure.getInt(mContext.getContentResolver(),
8080                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
8081            crashApplication(r, crashInfo);
8082            return true;
8083        } else {
8084            return false;
8085        }
8086    }
8087
8088    /**
8089     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8090     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8091     */
8092    private ProcessRecord findAppProcess(IBinder app, String reason) {
8093        if (app == null) {
8094            return null;
8095        }
8096
8097        synchronized (this) {
8098            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8099                final int NA = apps.size();
8100                for (int ia=0; ia<NA; ia++) {
8101                    ProcessRecord p = apps.valueAt(ia);
8102                    if (p.thread != null && p.thread.asBinder() == app) {
8103                        return p;
8104                    }
8105                }
8106            }
8107
8108            Slog.w(TAG, "Can't find mystery application for " + reason
8109                    + " from pid=" + Binder.getCallingPid()
8110                    + " uid=" + Binder.getCallingUid() + ": " + app);
8111            return null;
8112        }
8113    }
8114
8115    /**
8116     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8117     * to append various headers to the dropbox log text.
8118     */
8119    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8120            StringBuilder sb) {
8121        // Watchdog thread ends up invoking this function (with
8122        // a null ProcessRecord) to add the stack file to dropbox.
8123        // Do not acquire a lock on this (am) in such cases, as it
8124        // could cause a potential deadlock, if and when watchdog
8125        // is invoked due to unavailability of lock on am and it
8126        // would prevent watchdog from killing system_server.
8127        if (process == null) {
8128            sb.append("Process: ").append(processName).append("\n");
8129            return;
8130        }
8131        // Note: ProcessRecord 'process' is guarded by the service
8132        // instance.  (notably process.pkgList, which could otherwise change
8133        // concurrently during execution of this method)
8134        synchronized (this) {
8135            sb.append("Process: ").append(processName).append("\n");
8136            int flags = process.info.flags;
8137            IPackageManager pm = AppGlobals.getPackageManager();
8138            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8139            for (String pkg : process.pkgList) {
8140                sb.append("Package: ").append(pkg);
8141                try {
8142                    PackageInfo pi = pm.getPackageInfo(pkg, 0, 0);
8143                    if (pi != null) {
8144                        sb.append(" v").append(pi.versionCode);
8145                        if (pi.versionName != null) {
8146                            sb.append(" (").append(pi.versionName).append(")");
8147                        }
8148                    }
8149                } catch (RemoteException e) {
8150                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8151                }
8152                sb.append("\n");
8153            }
8154        }
8155    }
8156
8157    private static String processClass(ProcessRecord process) {
8158        if (process == null || process.pid == MY_PID) {
8159            return "system_server";
8160        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8161            return "system_app";
8162        } else {
8163            return "data_app";
8164        }
8165    }
8166
8167    /**
8168     * Write a description of an error (crash, WTF, ANR) to the drop box.
8169     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8170     * @param process which caused the error, null means the system server
8171     * @param activity which triggered the error, null if unknown
8172     * @param parent activity related to the error, null if unknown
8173     * @param subject line related to the error, null if absent
8174     * @param report in long form describing the error, null if absent
8175     * @param logFile to include in the report, null if none
8176     * @param crashInfo giving an application stack trace, null if absent
8177     */
8178    public void addErrorToDropBox(String eventType,
8179            ProcessRecord process, String processName, ActivityRecord activity,
8180            ActivityRecord parent, String subject,
8181            final String report, final File logFile,
8182            final ApplicationErrorReport.CrashInfo crashInfo) {
8183        // NOTE -- this must never acquire the ActivityManagerService lock,
8184        // otherwise the watchdog may be prevented from resetting the system.
8185
8186        final String dropboxTag = processClass(process) + "_" + eventType;
8187        final DropBoxManager dbox = (DropBoxManager)
8188                mContext.getSystemService(Context.DROPBOX_SERVICE);
8189
8190        // Exit early if the dropbox isn't configured to accept this report type.
8191        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8192
8193        final StringBuilder sb = new StringBuilder(1024);
8194        appendDropBoxProcessHeaders(process, processName, sb);
8195        if (activity != null) {
8196            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8197        }
8198        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8199            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8200        }
8201        if (parent != null && parent != activity) {
8202            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8203        }
8204        if (subject != null) {
8205            sb.append("Subject: ").append(subject).append("\n");
8206        }
8207        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8208        if (Debug.isDebuggerConnected()) {
8209            sb.append("Debugger: Connected\n");
8210        }
8211        sb.append("\n");
8212
8213        // Do the rest in a worker thread to avoid blocking the caller on I/O
8214        // (After this point, we shouldn't access AMS internal data structures.)
8215        Thread worker = new Thread("Error dump: " + dropboxTag) {
8216            @Override
8217            public void run() {
8218                if (report != null) {
8219                    sb.append(report);
8220                }
8221                if (logFile != null) {
8222                    try {
8223                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8224                    } catch (IOException e) {
8225                        Slog.e(TAG, "Error reading " + logFile, e);
8226                    }
8227                }
8228                if (crashInfo != null && crashInfo.stackTrace != null) {
8229                    sb.append(crashInfo.stackTrace);
8230                }
8231
8232                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8233                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8234                if (lines > 0) {
8235                    sb.append("\n");
8236
8237                    // Merge several logcat streams, and take the last N lines
8238                    InputStreamReader input = null;
8239                    try {
8240                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8241                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8242                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8243
8244                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8245                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8246                        input = new InputStreamReader(logcat.getInputStream());
8247
8248                        int num;
8249                        char[] buf = new char[8192];
8250                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8251                    } catch (IOException e) {
8252                        Slog.e(TAG, "Error running logcat", e);
8253                    } finally {
8254                        if (input != null) try { input.close(); } catch (IOException e) {}
8255                    }
8256                }
8257
8258                dbox.addText(dropboxTag, sb.toString());
8259            }
8260        };
8261
8262        if (process == null) {
8263            // If process is null, we are being called from some internal code
8264            // and may be about to die -- run this synchronously.
8265            worker.run();
8266        } else {
8267            worker.start();
8268        }
8269    }
8270
8271    /**
8272     * Bring up the "unexpected error" dialog box for a crashing app.
8273     * Deal with edge cases (intercepts from instrumented applications,
8274     * ActivityController, error intent receivers, that sort of thing).
8275     * @param r the application crashing
8276     * @param crashInfo describing the failure
8277     */
8278    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8279        long timeMillis = System.currentTimeMillis();
8280        String shortMsg = crashInfo.exceptionClassName;
8281        String longMsg = crashInfo.exceptionMessage;
8282        String stackTrace = crashInfo.stackTrace;
8283        if (shortMsg != null && longMsg != null) {
8284            longMsg = shortMsg + ": " + longMsg;
8285        } else if (shortMsg != null) {
8286            longMsg = shortMsg;
8287        }
8288
8289        AppErrorResult result = new AppErrorResult();
8290        synchronized (this) {
8291            if (mController != null) {
8292                try {
8293                    String name = r != null ? r.processName : null;
8294                    int pid = r != null ? r.pid : Binder.getCallingPid();
8295                    if (!mController.appCrashed(name, pid,
8296                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8297                        Slog.w(TAG, "Force-killing crashed app " + name
8298                                + " at watcher's request");
8299                        Process.killProcess(pid);
8300                        return;
8301                    }
8302                } catch (RemoteException e) {
8303                    mController = null;
8304                }
8305            }
8306
8307            final long origId = Binder.clearCallingIdentity();
8308
8309            // If this process is running instrumentation, finish it.
8310            if (r != null && r.instrumentationClass != null) {
8311                Slog.w(TAG, "Error in app " + r.processName
8312                      + " running instrumentation " + r.instrumentationClass + ":");
8313                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8314                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8315                Bundle info = new Bundle();
8316                info.putString("shortMsg", shortMsg);
8317                info.putString("longMsg", longMsg);
8318                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8319                Binder.restoreCallingIdentity(origId);
8320                return;
8321            }
8322
8323            // If we can't identify the process or it's already exceeded its crash quota,
8324            // quit right away without showing a crash dialog.
8325            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8326                Binder.restoreCallingIdentity(origId);
8327                return;
8328            }
8329
8330            Message msg = Message.obtain();
8331            msg.what = SHOW_ERROR_MSG;
8332            HashMap data = new HashMap();
8333            data.put("result", result);
8334            data.put("app", r);
8335            msg.obj = data;
8336            mHandler.sendMessage(msg);
8337
8338            Binder.restoreCallingIdentity(origId);
8339        }
8340
8341        int res = result.get();
8342
8343        Intent appErrorIntent = null;
8344        synchronized (this) {
8345            if (r != null && !r.isolated) {
8346                // XXX Can't keep track of crash time for isolated processes,
8347                // since they don't have a persistent identity.
8348                mProcessCrashTimes.put(r.info.processName, r.uid,
8349                        SystemClock.uptimeMillis());
8350            }
8351            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8352                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8353            }
8354        }
8355
8356        if (appErrorIntent != null) {
8357            try {
8358                mContext.startActivity(appErrorIntent);
8359            } catch (ActivityNotFoundException e) {
8360                Slog.w(TAG, "bug report receiver dissappeared", e);
8361            }
8362        }
8363    }
8364
8365    Intent createAppErrorIntentLocked(ProcessRecord r,
8366            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8367        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8368        if (report == null) {
8369            return null;
8370        }
8371        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8372        result.setComponent(r.errorReportReceiver);
8373        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8374        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8375        return result;
8376    }
8377
8378    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8379            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8380        if (r.errorReportReceiver == null) {
8381            return null;
8382        }
8383
8384        if (!r.crashing && !r.notResponding) {
8385            return null;
8386        }
8387
8388        ApplicationErrorReport report = new ApplicationErrorReport();
8389        report.packageName = r.info.packageName;
8390        report.installerPackageName = r.errorReportReceiver.getPackageName();
8391        report.processName = r.processName;
8392        report.time = timeMillis;
8393        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8394
8395        if (r.crashing) {
8396            report.type = ApplicationErrorReport.TYPE_CRASH;
8397            report.crashInfo = crashInfo;
8398        } else if (r.notResponding) {
8399            report.type = ApplicationErrorReport.TYPE_ANR;
8400            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8401
8402            report.anrInfo.activity = r.notRespondingReport.tag;
8403            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8404            report.anrInfo.info = r.notRespondingReport.longMsg;
8405        }
8406
8407        return report;
8408    }
8409
8410    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8411        enforceNotIsolatedCaller("getProcessesInErrorState");
8412        // assume our apps are happy - lazy create the list
8413        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8414
8415        synchronized (this) {
8416
8417            // iterate across all processes
8418            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8419                ProcessRecord app = mLruProcesses.get(i);
8420                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8421                    // This one's in trouble, so we'll generate a report for it
8422                    // crashes are higher priority (in case there's a crash *and* an anr)
8423                    ActivityManager.ProcessErrorStateInfo report = null;
8424                    if (app.crashing) {
8425                        report = app.crashingReport;
8426                    } else if (app.notResponding) {
8427                        report = app.notRespondingReport;
8428                    }
8429
8430                    if (report != null) {
8431                        if (errList == null) {
8432                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8433                        }
8434                        errList.add(report);
8435                    } else {
8436                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8437                                " crashing = " + app.crashing +
8438                                " notResponding = " + app.notResponding);
8439                    }
8440                }
8441            }
8442        }
8443
8444        return errList;
8445    }
8446
8447    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8448        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8449            if (currApp != null) {
8450                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8451            }
8452            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8453        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8454            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8455        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8456            if (currApp != null) {
8457                currApp.lru = 0;
8458            }
8459            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8460        } else if (adj >= ProcessList.SERVICE_ADJ) {
8461            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8462        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8463            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8464        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8465            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8466        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8467            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8468        } else {
8469            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8470        }
8471    }
8472
8473    private void fillInProcMemInfo(ProcessRecord app,
8474            ActivityManager.RunningAppProcessInfo outInfo) {
8475        outInfo.pid = app.pid;
8476        outInfo.uid = app.info.uid;
8477        if (mHeavyWeightProcess == app) {
8478            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8479        }
8480        if (app.persistent) {
8481            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8482        }
8483        outInfo.lastTrimLevel = app.trimMemoryLevel;
8484        int adj = app.curAdj;
8485        outInfo.importance = oomAdjToImportance(adj, outInfo);
8486        outInfo.importanceReasonCode = app.adjTypeCode;
8487    }
8488
8489    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8490        enforceNotIsolatedCaller("getRunningAppProcesses");
8491        // Lazy instantiation of list
8492        List<ActivityManager.RunningAppProcessInfo> runList = null;
8493        synchronized (this) {
8494            // Iterate across all processes
8495            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8496                ProcessRecord app = mLruProcesses.get(i);
8497                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8498                    // Generate process state info for running application
8499                    ActivityManager.RunningAppProcessInfo currApp =
8500                        new ActivityManager.RunningAppProcessInfo(app.processName,
8501                                app.pid, app.getPackageList());
8502                    fillInProcMemInfo(app, currApp);
8503                    if (app.adjSource instanceof ProcessRecord) {
8504                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8505                        currApp.importanceReasonImportance = oomAdjToImportance(
8506                                app.adjSourceOom, null);
8507                    } else if (app.adjSource instanceof ActivityRecord) {
8508                        ActivityRecord r = (ActivityRecord)app.adjSource;
8509                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8510                    }
8511                    if (app.adjTarget instanceof ComponentName) {
8512                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8513                    }
8514                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8515                    //        + " lru=" + currApp.lru);
8516                    if (runList == null) {
8517                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8518                    }
8519                    runList.add(currApp);
8520                }
8521            }
8522        }
8523        return runList;
8524    }
8525
8526    public List<ApplicationInfo> getRunningExternalApplications() {
8527        enforceNotIsolatedCaller("getRunningExternalApplications");
8528        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8529        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8530        if (runningApps != null && runningApps.size() > 0) {
8531            Set<String> extList = new HashSet<String>();
8532            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8533                if (app.pkgList != null) {
8534                    for (String pkg : app.pkgList) {
8535                        extList.add(pkg);
8536                    }
8537                }
8538            }
8539            IPackageManager pm = AppGlobals.getPackageManager();
8540            for (String pkg : extList) {
8541                try {
8542                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserId.getCallingUserId());
8543                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8544                        retList.add(info);
8545                    }
8546                } catch (RemoteException e) {
8547                }
8548            }
8549        }
8550        return retList;
8551    }
8552
8553    @Override
8554    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8555        enforceNotIsolatedCaller("getMyMemoryState");
8556        synchronized (this) {
8557            ProcessRecord proc;
8558            synchronized (mPidsSelfLocked) {
8559                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8560            }
8561            fillInProcMemInfo(proc, outInfo);
8562        }
8563    }
8564
8565    @Override
8566    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8567        if (checkCallingPermission(android.Manifest.permission.DUMP)
8568                != PackageManager.PERMISSION_GRANTED) {
8569            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8570                    + Binder.getCallingPid()
8571                    + ", uid=" + Binder.getCallingUid()
8572                    + " without permission "
8573                    + android.Manifest.permission.DUMP);
8574            return;
8575        }
8576
8577        boolean dumpAll = false;
8578        boolean dumpClient = false;
8579        String dumpPackage = null;
8580
8581        int opti = 0;
8582        while (opti < args.length) {
8583            String opt = args[opti];
8584            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8585                break;
8586            }
8587            opti++;
8588            if ("-a".equals(opt)) {
8589                dumpAll = true;
8590            } else if ("-c".equals(opt)) {
8591                dumpClient = true;
8592            } else if ("-h".equals(opt)) {
8593                pw.println("Activity manager dump options:");
8594                pw.println("  [-a] [-c] [-h] [cmd] ...");
8595                pw.println("  cmd may be one of:");
8596                pw.println("    a[ctivities]: activity stack state");
8597                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8598                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8599                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8600                pw.println("    o[om]: out of memory management");
8601                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8602                pw.println("    provider [COMP_SPEC]: provider client-side state");
8603                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8604                pw.println("    service [COMP_SPEC]: service client-side state");
8605                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8606                pw.println("    all: dump all activities");
8607                pw.println("    top: dump the top activity");
8608                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8609                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8610                pw.println("    a partial substring in a component name, a");
8611                pw.println("    hex object identifier.");
8612                pw.println("  -a: include all available server state.");
8613                pw.println("  -c: include client state.");
8614                return;
8615            } else {
8616                pw.println("Unknown argument: " + opt + "; use -h for help");
8617            }
8618        }
8619
8620        long origId = Binder.clearCallingIdentity();
8621        boolean more = false;
8622        // Is the caller requesting to dump a particular piece of data?
8623        if (opti < args.length) {
8624            String cmd = args[opti];
8625            opti++;
8626            if ("activities".equals(cmd) || "a".equals(cmd)) {
8627                synchronized (this) {
8628                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8629                }
8630            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8631                String[] newArgs;
8632                String name;
8633                if (opti >= args.length) {
8634                    name = null;
8635                    newArgs = EMPTY_STRING_ARRAY;
8636                } else {
8637                    name = args[opti];
8638                    opti++;
8639                    newArgs = new String[args.length - opti];
8640                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8641                            args.length - opti);
8642                }
8643                synchronized (this) {
8644                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8645                }
8646            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8647                String[] newArgs;
8648                String name;
8649                if (opti >= args.length) {
8650                    name = null;
8651                    newArgs = EMPTY_STRING_ARRAY;
8652                } else {
8653                    name = args[opti];
8654                    opti++;
8655                    newArgs = new String[args.length - opti];
8656                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8657                            args.length - opti);
8658                }
8659                synchronized (this) {
8660                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8661                }
8662            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8663                String[] newArgs;
8664                String name;
8665                if (opti >= args.length) {
8666                    name = null;
8667                    newArgs = EMPTY_STRING_ARRAY;
8668                } else {
8669                    name = args[opti];
8670                    opti++;
8671                    newArgs = new String[args.length - opti];
8672                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8673                            args.length - opti);
8674                }
8675                synchronized (this) {
8676                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8677                }
8678            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8679                synchronized (this) {
8680                    dumpOomLocked(fd, pw, args, opti, true);
8681                }
8682            } else if ("provider".equals(cmd)) {
8683                String[] newArgs;
8684                String name;
8685                if (opti >= args.length) {
8686                    name = null;
8687                    newArgs = EMPTY_STRING_ARRAY;
8688                } else {
8689                    name = args[opti];
8690                    opti++;
8691                    newArgs = new String[args.length - opti];
8692                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8693                }
8694                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8695                    pw.println("No providers match: " + name);
8696                    pw.println("Use -h for help.");
8697                }
8698            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8699                synchronized (this) {
8700                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8701                }
8702            } else if ("service".equals(cmd)) {
8703                String[] newArgs;
8704                String name;
8705                if (opti >= args.length) {
8706                    name = null;
8707                    newArgs = EMPTY_STRING_ARRAY;
8708                } else {
8709                    name = args[opti];
8710                    opti++;
8711                    newArgs = new String[args.length - opti];
8712                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8713                            args.length - opti);
8714                }
8715                if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8716                    pw.println("No services match: " + name);
8717                    pw.println("Use -h for help.");
8718                }
8719            } else if ("package".equals(cmd)) {
8720                String[] newArgs;
8721                if (opti >= args.length) {
8722                    pw.println("package: no package name specified");
8723                    pw.println("Use -h for help.");
8724                } else {
8725                    dumpPackage = args[opti];
8726                    opti++;
8727                    newArgs = new String[args.length - opti];
8728                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8729                            args.length - opti);
8730                    args = newArgs;
8731                    opti = 0;
8732                    more = true;
8733                }
8734            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8735                synchronized (this) {
8736                    dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8737                }
8738            } else {
8739                // Dumping a single activity?
8740                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8741                    pw.println("Bad activity command, or no activities match: " + cmd);
8742                    pw.println("Use -h for help.");
8743                }
8744            }
8745            if (!more) {
8746                Binder.restoreCallingIdentity(origId);
8747                return;
8748            }
8749        }
8750
8751        // No piece of data specified, dump everything.
8752        synchronized (this) {
8753            boolean needSep;
8754            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8755            if (needSep) {
8756                pw.println(" ");
8757            }
8758            if (dumpAll) {
8759                pw.println("-------------------------------------------------------------------------------");
8760            }
8761            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8762            if (needSep) {
8763                pw.println(" ");
8764            }
8765            if (dumpAll) {
8766                pw.println("-------------------------------------------------------------------------------");
8767            }
8768            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8769            if (needSep) {
8770                pw.println(" ");
8771            }
8772            if (dumpAll) {
8773                pw.println("-------------------------------------------------------------------------------");
8774            }
8775            needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8776            if (needSep) {
8777                pw.println(" ");
8778            }
8779            if (dumpAll) {
8780                pw.println("-------------------------------------------------------------------------------");
8781            }
8782            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8783            if (needSep) {
8784                pw.println(" ");
8785            }
8786            if (dumpAll) {
8787                pw.println("-------------------------------------------------------------------------------");
8788            }
8789            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8790        }
8791        Binder.restoreCallingIdentity(origId);
8792    }
8793
8794    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8795            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
8796        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8797        pw.println("  Main stack:");
8798        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
8799                dumpPackage);
8800        pw.println(" ");
8801        pw.println("  Running activities (most recent first):");
8802        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
8803                dumpPackage);
8804        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
8805            pw.println(" ");
8806            pw.println("  Activities waiting for another to become visible:");
8807            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
8808                    !dumpAll, false, dumpPackage);
8809        }
8810        if (mMainStack.mStoppingActivities.size() > 0) {
8811            pw.println(" ");
8812            pw.println("  Activities waiting to stop:");
8813            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
8814                    !dumpAll, false, dumpPackage);
8815        }
8816        if (mMainStack.mGoingToSleepActivities.size() > 0) {
8817            pw.println(" ");
8818            pw.println("  Activities waiting to sleep:");
8819            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
8820                    !dumpAll, false, dumpPackage);
8821        }
8822        if (mMainStack.mFinishingActivities.size() > 0) {
8823            pw.println(" ");
8824            pw.println("  Activities waiting to finish:");
8825            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
8826                    !dumpAll, false, dumpPackage);
8827        }
8828
8829        pw.println(" ");
8830        if (mMainStack.mPausingActivity != null) {
8831            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
8832        }
8833        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
8834        pw.println("  mFocusedActivity: " + mFocusedActivity);
8835        if (dumpAll) {
8836            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8837            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
8838            pw.println("  mDismissKeyguardOnNextActivity: "
8839                    + mMainStack.mDismissKeyguardOnNextActivity);
8840        }
8841
8842        if (mRecentTasks.size() > 0) {
8843            pw.println();
8844            pw.println("  Recent tasks:");
8845
8846            final int N = mRecentTasks.size();
8847            for (int i=0; i<N; i++) {
8848                TaskRecord tr = mRecentTasks.get(i);
8849                if (dumpPackage != null) {
8850                    if (tr.realActivity == null ||
8851                            !dumpPackage.equals(tr.realActivity)) {
8852                        continue;
8853                    }
8854                }
8855                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
8856                        pw.println(tr);
8857                if (dumpAll) {
8858                    mRecentTasks.get(i).dump(pw, "    ");
8859                }
8860            }
8861        }
8862
8863        if (dumpAll) {
8864            pw.println(" ");
8865            pw.println("  mCurTask: " + mCurTask);
8866        }
8867
8868        return true;
8869    }
8870
8871    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8872            int opti, boolean dumpAll, String dumpPackage) {
8873        boolean needSep = false;
8874        int numPers = 0;
8875
8876        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8877
8878        if (dumpAll) {
8879            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8880                final int NA = procs.size();
8881                for (int ia=0; ia<NA; ia++) {
8882                    ProcessRecord r = procs.valueAt(ia);
8883                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8884                        continue;
8885                    }
8886                    if (!needSep) {
8887                        pw.println("  All known processes:");
8888                        needSep = true;
8889                    }
8890                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
8891                        pw.print(" UID "); pw.print(procs.keyAt(ia));
8892                        pw.print(" "); pw.println(r);
8893                    r.dump(pw, "    ");
8894                    if (r.persistent) {
8895                        numPers++;
8896                    }
8897                }
8898            }
8899        }
8900
8901        if (mIsolatedProcesses.size() > 0) {
8902            if (needSep) pw.println(" ");
8903            needSep = true;
8904            pw.println("  Isolated process list (sorted by uid):");
8905            for (int i=0; i<mIsolatedProcesses.size(); i++) {
8906                ProcessRecord r = mIsolatedProcesses.valueAt(i);
8907                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8908                    continue;
8909                }
8910                pw.println(String.format("%sIsolated #%2d: %s",
8911                        "    ", i, r.toString()));
8912            }
8913        }
8914
8915        if (mLruProcesses.size() > 0) {
8916            if (needSep) pw.println(" ");
8917            needSep = true;
8918            pw.println("  Process LRU list (sorted by oom_adj):");
8919            dumpProcessOomList(pw, this, mLruProcesses, "    ",
8920                    "Proc", "PERS", false, dumpPackage);
8921            needSep = true;
8922        }
8923
8924        if (dumpAll) {
8925            synchronized (mPidsSelfLocked) {
8926                boolean printed = false;
8927                for (int i=0; i<mPidsSelfLocked.size(); i++) {
8928                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
8929                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8930                        continue;
8931                    }
8932                    if (!printed) {
8933                        if (needSep) pw.println(" ");
8934                        needSep = true;
8935                        pw.println("  PID mappings:");
8936                        printed = true;
8937                    }
8938                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8939                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
8940                }
8941            }
8942        }
8943
8944        if (mForegroundProcesses.size() > 0) {
8945            synchronized (mPidsSelfLocked) {
8946                boolean printed = false;
8947                for (int i=0; i<mForegroundProcesses.size(); i++) {
8948                    ProcessRecord r = mPidsSelfLocked.get(
8949                            mForegroundProcesses.valueAt(i).pid);
8950                    if (dumpPackage != null && (r == null
8951                            || !dumpPackage.equals(r.info.packageName))) {
8952                        continue;
8953                    }
8954                    if (!printed) {
8955                        if (needSep) pw.println(" ");
8956                        needSep = true;
8957                        pw.println("  Foreground Processes:");
8958                        printed = true;
8959                    }
8960                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
8961                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
8962                }
8963            }
8964        }
8965
8966        if (mPersistentStartingProcesses.size() > 0) {
8967            if (needSep) pw.println(" ");
8968            needSep = true;
8969            pw.println("  Persisent processes that are starting:");
8970            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
8971                    "Starting Norm", "Restarting PERS", dumpPackage);
8972        }
8973
8974        if (mRemovedProcesses.size() > 0) {
8975            if (needSep) pw.println(" ");
8976            needSep = true;
8977            pw.println("  Processes that are being removed:");
8978            dumpProcessList(pw, this, mRemovedProcesses, "    ",
8979                    "Removed Norm", "Removed PERS", dumpPackage);
8980        }
8981
8982        if (mProcessesOnHold.size() > 0) {
8983            if (needSep) pw.println(" ");
8984            needSep = true;
8985            pw.println("  Processes that are on old until the system is ready:");
8986            dumpProcessList(pw, this, mProcessesOnHold, "    ",
8987                    "OnHold Norm", "OnHold PERS", dumpPackage);
8988        }
8989
8990        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
8991
8992        if (mProcessCrashTimes.getMap().size() > 0) {
8993            boolean printed = false;
8994            long now = SystemClock.uptimeMillis();
8995            for (Map.Entry<String, SparseArray<Long>> procs
8996                    : mProcessCrashTimes.getMap().entrySet()) {
8997                String pname = procs.getKey();
8998                SparseArray<Long> uids = procs.getValue();
8999                final int N = uids.size();
9000                for (int i=0; i<N; i++) {
9001                    int puid = uids.keyAt(i);
9002                    ProcessRecord r = mProcessNames.get(pname, puid);
9003                    if (dumpPackage != null && (r == null
9004                            || !dumpPackage.equals(r.info.packageName))) {
9005                        continue;
9006                    }
9007                    if (!printed) {
9008                        if (needSep) pw.println(" ");
9009                        needSep = true;
9010                        pw.println("  Time since processes crashed:");
9011                        printed = true;
9012                    }
9013                    pw.print("    Process "); pw.print(pname);
9014                            pw.print(" uid "); pw.print(puid);
9015                            pw.print(": last crashed ");
9016                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9017                            pw.println(" ago");
9018                }
9019            }
9020        }
9021
9022        if (mBadProcesses.getMap().size() > 0) {
9023            boolean printed = false;
9024            for (Map.Entry<String, SparseArray<Long>> procs
9025                    : mBadProcesses.getMap().entrySet()) {
9026                String pname = procs.getKey();
9027                SparseArray<Long> uids = procs.getValue();
9028                final int N = uids.size();
9029                for (int i=0; i<N; i++) {
9030                    int puid = uids.keyAt(i);
9031                    ProcessRecord r = mProcessNames.get(pname, puid);
9032                    if (dumpPackage != null && (r == null
9033                            || !dumpPackage.equals(r.info.packageName))) {
9034                        continue;
9035                    }
9036                    if (!printed) {
9037                        if (needSep) pw.println(" ");
9038                        needSep = true;
9039                        pw.println("  Bad processes:");
9040                    }
9041                    pw.print("    Bad process "); pw.print(pname);
9042                            pw.print(" uid "); pw.print(puid);
9043                            pw.print(": crashed at time ");
9044                            pw.println(uids.valueAt(i));
9045                }
9046            }
9047        }
9048
9049        pw.println();
9050        pw.println("  mHomeProcess: " + mHomeProcess);
9051        pw.println("  mPreviousProcess: " + mPreviousProcess);
9052        if (dumpAll) {
9053            StringBuilder sb = new StringBuilder(128);
9054            sb.append("  mPreviousProcessVisibleTime: ");
9055            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9056            pw.println(sb);
9057        }
9058        if (mHeavyWeightProcess != null) {
9059            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9060        }
9061        pw.println("  mConfiguration: " + mConfiguration);
9062        if (dumpAll) {
9063            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9064            if (mCompatModePackages.getPackages().size() > 0) {
9065                boolean printed = false;
9066                for (Map.Entry<String, Integer> entry
9067                        : mCompatModePackages.getPackages().entrySet()) {
9068                    String pkg = entry.getKey();
9069                    int mode = entry.getValue();
9070                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9071                        continue;
9072                    }
9073                    if (!printed) {
9074                        pw.println("  mScreenCompatPackages:");
9075                        printed = true;
9076                    }
9077                    pw.print("    "); pw.print(pkg); pw.print(": ");
9078                            pw.print(mode); pw.println();
9079                }
9080            }
9081        }
9082        if (mSleeping || mWentToSleep || mLockScreenShown) {
9083            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9084                    + " mLockScreenShown " + mLockScreenShown);
9085        }
9086        if (mShuttingDown) {
9087            pw.println("  mShuttingDown=" + mShuttingDown);
9088        }
9089        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9090                || mOrigWaitForDebugger) {
9091            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9092                    + " mDebugTransient=" + mDebugTransient
9093                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9094        }
9095        if (mOpenGlTraceApp != null) {
9096            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9097        }
9098        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9099                || mProfileFd != null) {
9100            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9101            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9102            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9103                    + mAutoStopProfiler);
9104        }
9105        if (mAlwaysFinishActivities || mController != null) {
9106            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9107                    + " mController=" + mController);
9108        }
9109        if (dumpAll) {
9110            pw.println("  Total persistent processes: " + numPers);
9111            pw.println("  mStartRunning=" + mStartRunning
9112                    + " mProcessesReady=" + mProcessesReady
9113                    + " mSystemReady=" + mSystemReady);
9114            pw.println("  mBooting=" + mBooting
9115                    + " mBooted=" + mBooted
9116                    + " mFactoryTest=" + mFactoryTest);
9117            pw.print("  mLastPowerCheckRealtime=");
9118                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9119                    pw.println("");
9120            pw.print("  mLastPowerCheckUptime=");
9121                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9122                    pw.println("");
9123            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9124            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9125            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9126            pw.println("  mNumServiceProcs=" + mNumServiceProcs
9127                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9128        }
9129
9130        return true;
9131    }
9132
9133    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9134            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9135        if (mProcessesToGc.size() > 0) {
9136            boolean printed = false;
9137            long now = SystemClock.uptimeMillis();
9138            for (int i=0; i<mProcessesToGc.size(); i++) {
9139                ProcessRecord proc = mProcessesToGc.get(i);
9140                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9141                    continue;
9142                }
9143                if (!printed) {
9144                    if (needSep) pw.println(" ");
9145                    needSep = true;
9146                    pw.println("  Processes that are waiting to GC:");
9147                    printed = true;
9148                }
9149                pw.print("    Process "); pw.println(proc);
9150                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9151                        pw.print(", last gced=");
9152                        pw.print(now-proc.lastRequestedGc);
9153                        pw.print(" ms ago, last lowMem=");
9154                        pw.print(now-proc.lastLowMemory);
9155                        pw.println(" ms ago");
9156
9157            }
9158        }
9159        return needSep;
9160    }
9161
9162    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9163            int opti, boolean dumpAll) {
9164        boolean needSep = false;
9165
9166        if (mLruProcesses.size() > 0) {
9167            if (needSep) pw.println(" ");
9168            needSep = true;
9169            pw.println("  OOM levels:");
9170            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9171            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9172            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9173            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9174            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9175            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9176            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9177            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9178            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9179            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9180            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9181            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9182            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9183
9184            if (needSep) pw.println(" ");
9185            needSep = true;
9186            pw.println("  Process OOM control:");
9187            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9188                    "Proc", "PERS", true, null);
9189            needSep = true;
9190        }
9191
9192        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9193
9194        pw.println();
9195        pw.println("  mHomeProcess: " + mHomeProcess);
9196        pw.println("  mPreviousProcess: " + mPreviousProcess);
9197        if (mHeavyWeightProcess != null) {
9198            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9199        }
9200
9201        return true;
9202    }
9203
9204    /**
9205     * There are three ways to call this:
9206     *  - no service specified: dump all the services
9207     *  - a flattened component name that matched an existing service was specified as the
9208     *    first arg: dump that one service
9209     *  - the first arg isn't the flattened component name of an existing service:
9210     *    dump all services whose component contains the first arg as a substring
9211     */
9212    protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9213            int opti, boolean dumpAll) {
9214        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
9215
9216        if ("all".equals(name)) {
9217            synchronized (this) {
9218                try {
9219                    List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9220                    for (UserInfo user : users) {
9221                        for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) {
9222                            services.add(r1);
9223                        }
9224                    }
9225                } catch (RemoteException re) {
9226                }
9227            }
9228        } else {
9229            ComponentName componentName = name != null
9230                    ? ComponentName.unflattenFromString(name) : null;
9231            int objectId = 0;
9232            if (componentName == null) {
9233                // Not a '/' separated full component name; maybe an object ID?
9234                try {
9235                    objectId = Integer.parseInt(name, 16);
9236                    name = null;
9237                    componentName = null;
9238                } catch (RuntimeException e) {
9239                }
9240            }
9241
9242            synchronized (this) {
9243                try {
9244                    List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9245                    for (UserInfo user : users) {
9246                        for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) {
9247                            if (componentName != null) {
9248                                if (r1.name.equals(componentName)) {
9249                                    services.add(r1);
9250                                }
9251                            } else if (name != null) {
9252                                if (r1.name.flattenToString().contains(name)) {
9253                                    services.add(r1);
9254                                }
9255                            } else if (System.identityHashCode(r1) == objectId) {
9256                                services.add(r1);
9257                            }
9258                        }
9259                    }
9260                } catch (RemoteException re) {
9261                }
9262            }
9263        }
9264
9265        if (services.size() <= 0) {
9266            return false;
9267        }
9268
9269        boolean needSep = false;
9270        for (int i=0; i<services.size(); i++) {
9271            if (needSep) {
9272                pw.println();
9273            }
9274            needSep = true;
9275            dumpService("", fd, pw, services.get(i), args, dumpAll);
9276        }
9277        return true;
9278    }
9279
9280    /**
9281     * Invokes IApplicationThread.dumpService() on the thread of the specified service if
9282     * there is a thread associated with the service.
9283     */
9284    private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
9285            final ServiceRecord r, String[] args, boolean dumpAll) {
9286        String innerPrefix = prefix + "  ";
9287        synchronized (this) {
9288            pw.print(prefix); pw.print("SERVICE ");
9289                    pw.print(r.shortName); pw.print(" ");
9290                    pw.print(Integer.toHexString(System.identityHashCode(r)));
9291                    pw.print(" pid=");
9292                    if (r.app != null) pw.println(r.app.pid);
9293                    else pw.println("(not running)");
9294            if (dumpAll) {
9295                r.dump(pw, innerPrefix);
9296            }
9297        }
9298        if (r.app != null && r.app.thread != null) {
9299            pw.print(prefix); pw.println("  Client:");
9300            pw.flush();
9301            try {
9302                TransferPipe tp = new TransferPipe();
9303                try {
9304                    r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
9305                    tp.setBufferPrefix(prefix + "    ");
9306                    tp.go(fd);
9307                } finally {
9308                    tp.kill();
9309                }
9310            } catch (IOException e) {
9311                pw.println(prefix + "    Failure while dumping the service: " + e);
9312            } catch (RemoteException e) {
9313                pw.println(prefix + "    Got a RemoteException while dumping the service");
9314            }
9315        }
9316    }
9317
9318    /**
9319     * There are three ways to call this:
9320     *  - no provider specified: dump all the providers
9321     *  - a flattened component name that matched an existing provider was specified as the
9322     *    first arg: dump that one provider
9323     *  - the first arg isn't the flattened component name of an existing provider:
9324     *    dump all providers whose component contains the first arg as a substring
9325     */
9326    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9327            int opti, boolean dumpAll) {
9328        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9329    }
9330
9331    static class ItemMatcher {
9332        ArrayList<ComponentName> components;
9333        ArrayList<String> strings;
9334        ArrayList<Integer> objects;
9335        boolean all;
9336
9337        ItemMatcher() {
9338            all = true;
9339        }
9340
9341        void build(String name) {
9342            ComponentName componentName = ComponentName.unflattenFromString(name);
9343            if (componentName != null) {
9344                if (components == null) {
9345                    components = new ArrayList<ComponentName>();
9346                }
9347                components.add(componentName);
9348                all = false;
9349            } else {
9350                int objectId = 0;
9351                // Not a '/' separated full component name; maybe an object ID?
9352                try {
9353                    objectId = Integer.parseInt(name, 16);
9354                    if (objects == null) {
9355                        objects = new ArrayList<Integer>();
9356                    }
9357                    objects.add(objectId);
9358                    all = false;
9359                } catch (RuntimeException e) {
9360                    // Not an integer; just do string match.
9361                    if (strings == null) {
9362                        strings = new ArrayList<String>();
9363                    }
9364                    strings.add(name);
9365                    all = false;
9366                }
9367            }
9368        }
9369
9370        int build(String[] args, int opti) {
9371            for (; opti<args.length; opti++) {
9372                String name = args[opti];
9373                if ("--".equals(name)) {
9374                    return opti+1;
9375                }
9376                build(name);
9377            }
9378            return opti;
9379        }
9380
9381        boolean match(Object object, ComponentName comp) {
9382            if (all) {
9383                return true;
9384            }
9385            if (components != null) {
9386                for (int i=0; i<components.size(); i++) {
9387                    if (components.get(i).equals(comp)) {
9388                        return true;
9389                    }
9390                }
9391            }
9392            if (objects != null) {
9393                for (int i=0; i<objects.size(); i++) {
9394                    if (System.identityHashCode(object) == objects.get(i)) {
9395                        return true;
9396                    }
9397                }
9398            }
9399            if (strings != null) {
9400                String flat = comp.flattenToString();
9401                for (int i=0; i<strings.size(); i++) {
9402                    if (flat.contains(strings.get(i))) {
9403                        return true;
9404                    }
9405                }
9406            }
9407            return false;
9408        }
9409    }
9410
9411    /**
9412     * There are three things that cmd can be:
9413     *  - a flattened component name that matches an existing activity
9414     *  - the cmd arg isn't the flattened component name of an existing activity:
9415     *    dump all activity whose component contains the cmd as a substring
9416     *  - A hex number of the ActivityRecord object instance.
9417     */
9418    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9419            int opti, boolean dumpAll) {
9420        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9421
9422        if ("all".equals(name)) {
9423            synchronized (this) {
9424                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9425                    activities.add(r1);
9426                }
9427            }
9428        } else if ("top".equals(name)) {
9429            synchronized (this) {
9430                final int N = mMainStack.mHistory.size();
9431                if (N > 0) {
9432                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9433                }
9434            }
9435        } else {
9436            ItemMatcher matcher = new ItemMatcher();
9437            matcher.build(name);
9438
9439            synchronized (this) {
9440                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9441                    if (matcher.match(r1, r1.intent.getComponent())) {
9442                        activities.add(r1);
9443                    }
9444                }
9445            }
9446        }
9447
9448        if (activities.size() <= 0) {
9449            return false;
9450        }
9451
9452        String[] newArgs = new String[args.length - opti];
9453        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9454
9455        TaskRecord lastTask = null;
9456        boolean needSep = false;
9457        for (int i=activities.size()-1; i>=0; i--) {
9458            ActivityRecord r = (ActivityRecord)activities.get(i);
9459            if (needSep) {
9460                pw.println();
9461            }
9462            needSep = true;
9463            synchronized (this) {
9464                if (lastTask != r.task) {
9465                    lastTask = r.task;
9466                    pw.print("TASK "); pw.print(lastTask.affinity);
9467                            pw.print(" id="); pw.println(lastTask.taskId);
9468                    if (dumpAll) {
9469                        lastTask.dump(pw, "  ");
9470                    }
9471                }
9472            }
9473            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9474        }
9475        return true;
9476    }
9477
9478    /**
9479     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9480     * there is a thread associated with the activity.
9481     */
9482    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9483            final ActivityRecord r, String[] args, boolean dumpAll) {
9484        String innerPrefix = prefix + "  ";
9485        synchronized (this) {
9486            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9487                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9488                    pw.print(" pid=");
9489                    if (r.app != null) pw.println(r.app.pid);
9490                    else pw.println("(not running)");
9491            if (dumpAll) {
9492                r.dump(pw, innerPrefix);
9493            }
9494        }
9495        if (r.app != null && r.app.thread != null) {
9496            // flush anything that is already in the PrintWriter since the thread is going
9497            // to write to the file descriptor directly
9498            pw.flush();
9499            try {
9500                TransferPipe tp = new TransferPipe();
9501                try {
9502                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9503                            r.appToken, innerPrefix, args);
9504                    tp.go(fd);
9505                } finally {
9506                    tp.kill();
9507                }
9508            } catch (IOException e) {
9509                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9510            } catch (RemoteException e) {
9511                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9512            }
9513        }
9514    }
9515
9516    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9517            int opti, boolean dumpAll, String dumpPackage) {
9518        boolean needSep = false;
9519
9520        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9521        if (dumpAll) {
9522            if (mRegisteredReceivers.size() > 0) {
9523                boolean printed = false;
9524                Iterator it = mRegisteredReceivers.values().iterator();
9525                while (it.hasNext()) {
9526                    ReceiverList r = (ReceiverList)it.next();
9527                    if (dumpPackage != null && (r.app == null ||
9528                            !dumpPackage.equals(r.app.info.packageName))) {
9529                        continue;
9530                    }
9531                    if (!printed) {
9532                        pw.println("  Registered Receivers:");
9533                        needSep = true;
9534                        printed = true;
9535                    }
9536                    pw.print("  * "); pw.println(r);
9537                    r.dump(pw, "    ");
9538                }
9539            }
9540
9541            if (mReceiverResolver.dump(pw, needSep ?
9542                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9543                    "    ", dumpPackage, false)) {
9544                needSep = true;
9545            }
9546        }
9547
9548        for (BroadcastQueue q : mBroadcastQueues) {
9549            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9550        }
9551
9552        needSep = true;
9553
9554        if (mStickyBroadcasts != null && dumpPackage == null) {
9555            if (needSep) {
9556                pw.println();
9557            }
9558            needSep = true;
9559            pw.println("  Sticky broadcasts:");
9560            StringBuilder sb = new StringBuilder(128);
9561            for (Map.Entry<String, ArrayList<Intent>> ent
9562                    : mStickyBroadcasts.entrySet()) {
9563                pw.print("  * Sticky action "); pw.print(ent.getKey());
9564                if (dumpAll) {
9565                    pw.println(":");
9566                    ArrayList<Intent> intents = ent.getValue();
9567                    final int N = intents.size();
9568                    for (int i=0; i<N; i++) {
9569                        sb.setLength(0);
9570                        sb.append("    Intent: ");
9571                        intents.get(i).toShortString(sb, false, true, false, false);
9572                        pw.println(sb.toString());
9573                        Bundle bundle = intents.get(i).getExtras();
9574                        if (bundle != null) {
9575                            pw.print("      ");
9576                            pw.println(bundle.toString());
9577                        }
9578                    }
9579                } else {
9580                    pw.println("");
9581                }
9582            }
9583            needSep = true;
9584        }
9585
9586        if (dumpAll) {
9587            pw.println();
9588            for (BroadcastQueue queue : mBroadcastQueues) {
9589                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9590                        + queue.mBroadcastsScheduled);
9591            }
9592            pw.println("  mHandler:");
9593            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9594            needSep = true;
9595        }
9596
9597        return needSep;
9598    }
9599
9600    /**
9601     * Prints a list of ServiceRecords (dumpsys activity services)
9602     */
9603    boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9604            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
9605        boolean needSep = false;
9606
9607        ItemMatcher matcher = new ItemMatcher();
9608        matcher.build(args, opti);
9609
9610        pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
9611        try {
9612            List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9613            for (UserInfo user : users) {
9614                if (mServiceMap.getAllServices(user.id).size() > 0) {
9615                    boolean printed = false;
9616                    long nowReal = SystemClock.elapsedRealtime();
9617                    Iterator<ServiceRecord> it = mServiceMap.getAllServices(
9618                            user.id).iterator();
9619                    needSep = false;
9620                    while (it.hasNext()) {
9621                        ServiceRecord r = it.next();
9622                        if (!matcher.match(r, r.name)) {
9623                            continue;
9624                        }
9625                        if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9626                            continue;
9627                        }
9628                        if (!printed) {
9629                            pw.println("  Active services:");
9630                            printed = true;
9631                        }
9632                        if (needSep) {
9633                            pw.println();
9634                        }
9635                        pw.print("  * ");
9636                        pw.println(r);
9637                        if (dumpAll) {
9638                            r.dump(pw, "    ");
9639                            needSep = true;
9640                        } else {
9641                            pw.print("    app=");
9642                            pw.println(r.app);
9643                            pw.print("    created=");
9644                            TimeUtils.formatDuration(r.createTime, nowReal, pw);
9645                            pw.print(" started=");
9646                            pw.print(r.startRequested);
9647                            pw.print(" connections=");
9648                            pw.println(r.connections.size());
9649                            if (r.connections.size() > 0) {
9650                                pw.println("    Connections:");
9651                                for (ArrayList<ConnectionRecord> clist : r.connections.values()) {
9652                                    for (int i = 0; i < clist.size(); i++) {
9653                                        ConnectionRecord conn = clist.get(i);
9654                                        pw.print("      ");
9655                                        pw.print(conn.binding.intent.intent.getIntent()
9656                                                .toShortString(false, false, false, false));
9657                                        pw.print(" -> ");
9658                                        ProcessRecord proc = conn.binding.client;
9659                                        pw.println(proc != null ? proc.toShortString() : "null");
9660                                    }
9661                                }
9662                            }
9663                        }
9664                        if (dumpClient && r.app != null && r.app.thread != null) {
9665                            pw.println("    Client:");
9666                            pw.flush();
9667                            try {
9668                                TransferPipe tp = new TransferPipe();
9669                                try {
9670                                    r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(),
9671                                            r, args);
9672                                    tp.setBufferPrefix("      ");
9673                                    // Short timeout, since blocking here can
9674                                    // deadlock with the application.
9675                                    tp.go(fd, 2000);
9676                                } finally {
9677                                    tp.kill();
9678                                }
9679                            } catch (IOException e) {
9680                                pw.println("      Failure while dumping the service: " + e);
9681                            } catch (RemoteException e) {
9682                                pw.println("      Got a RemoteException while dumping the service");
9683                            }
9684                            needSep = true;
9685                        }
9686                    }
9687                    needSep = printed;
9688                }
9689            }
9690        } catch (RemoteException re) {
9691
9692        }
9693
9694        if (mPendingServices.size() > 0) {
9695            boolean printed = false;
9696            for (int i=0; i<mPendingServices.size(); i++) {
9697                ServiceRecord r = mPendingServices.get(i);
9698                if (!matcher.match(r, r.name)) {
9699                    continue;
9700                }
9701                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9702                    continue;
9703                }
9704                if (!printed) {
9705                    if (needSep) pw.println(" ");
9706                    needSep = true;
9707                    pw.println("  Pending services:");
9708                    printed = true;
9709                }
9710                pw.print("  * Pending "); pw.println(r);
9711                r.dump(pw, "    ");
9712            }
9713            needSep = true;
9714        }
9715
9716        if (mRestartingServices.size() > 0) {
9717            boolean printed = false;
9718            for (int i=0; i<mRestartingServices.size(); i++) {
9719                ServiceRecord r = mRestartingServices.get(i);
9720                if (!matcher.match(r, r.name)) {
9721                    continue;
9722                }
9723                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9724                    continue;
9725                }
9726                if (!printed) {
9727                    if (needSep) pw.println(" ");
9728                    needSep = true;
9729                    pw.println("  Restarting services:");
9730                    printed = true;
9731                }
9732                pw.print("  * Restarting "); pw.println(r);
9733                r.dump(pw, "    ");
9734            }
9735            needSep = true;
9736        }
9737
9738        if (mStoppingServices.size() > 0) {
9739            boolean printed = false;
9740            for (int i=0; i<mStoppingServices.size(); i++) {
9741                ServiceRecord r = mStoppingServices.get(i);
9742                if (!matcher.match(r, r.name)) {
9743                    continue;
9744                }
9745                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9746                    continue;
9747                }
9748                if (!printed) {
9749                    if (needSep) pw.println(" ");
9750                    needSep = true;
9751                    pw.println("  Stopping services:");
9752                    printed = true;
9753                }
9754                pw.print("  * Stopping "); pw.println(r);
9755                r.dump(pw, "    ");
9756            }
9757            needSep = true;
9758        }
9759
9760        if (dumpAll) {
9761            if (mServiceConnections.size() > 0) {
9762                boolean printed = false;
9763                Iterator<ArrayList<ConnectionRecord>> it
9764                        = mServiceConnections.values().iterator();
9765                while (it.hasNext()) {
9766                    ArrayList<ConnectionRecord> r = it.next();
9767                    for (int i=0; i<r.size(); i++) {
9768                        ConnectionRecord cr = r.get(i);
9769                        if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
9770                            continue;
9771                        }
9772                        if (dumpPackage != null && (cr.binding.client == null
9773                                || !dumpPackage.equals(cr.binding.client.info.packageName))) {
9774                            continue;
9775                        }
9776                        if (!printed) {
9777                            if (needSep) pw.println(" ");
9778                            needSep = true;
9779                            pw.println("  Connection bindings to services:");
9780                            printed = true;
9781                        }
9782                        pw.print("  * "); pw.println(cr);
9783                        cr.dump(pw, "    ");
9784                    }
9785                }
9786                needSep = true;
9787            }
9788        }
9789
9790        return needSep;
9791    }
9792
9793    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9794            int opti, boolean dumpAll, String dumpPackage) {
9795        boolean needSep = true;
9796
9797        ItemMatcher matcher = new ItemMatcher();
9798        matcher.build(args, opti);
9799
9800        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9801
9802        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9803
9804        if (mLaunchingProviders.size() > 0) {
9805            boolean printed = false;
9806            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9807                ContentProviderRecord r = mLaunchingProviders.get(i);
9808                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9809                    continue;
9810                }
9811                if (!printed) {
9812                    if (needSep) pw.println(" ");
9813                    needSep = true;
9814                    pw.println("  Launching content providers:");
9815                    printed = true;
9816                }
9817                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9818                        pw.println(r);
9819            }
9820        }
9821
9822        if (mGrantedUriPermissions.size() > 0) {
9823            if (needSep) pw.println();
9824            needSep = true;
9825            pw.println("Granted Uri Permissions:");
9826            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9827                int uid = mGrantedUriPermissions.keyAt(i);
9828                HashMap<Uri, UriPermission> perms
9829                        = mGrantedUriPermissions.valueAt(i);
9830                pw.print("  * UID "); pw.print(uid);
9831                        pw.println(" holds:");
9832                for (UriPermission perm : perms.values()) {
9833                    pw.print("    "); pw.println(perm);
9834                    if (dumpAll) {
9835                        perm.dump(pw, "      ");
9836                    }
9837                }
9838            }
9839            needSep = true;
9840        }
9841
9842        return needSep;
9843    }
9844
9845    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9846            int opti, boolean dumpAll, String dumpPackage) {
9847        boolean needSep = false;
9848
9849        if (mIntentSenderRecords.size() > 0) {
9850            boolean printed = false;
9851            Iterator<WeakReference<PendingIntentRecord>> it
9852                    = mIntentSenderRecords.values().iterator();
9853            while (it.hasNext()) {
9854                WeakReference<PendingIntentRecord> ref = it.next();
9855                PendingIntentRecord rec = ref != null ? ref.get(): null;
9856                if (dumpPackage != null && (rec == null
9857                        || !dumpPackage.equals(rec.key.packageName))) {
9858                    continue;
9859                }
9860                if (!printed) {
9861                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9862                    printed = true;
9863                }
9864                needSep = true;
9865                if (rec != null) {
9866                    pw.print("  * "); pw.println(rec);
9867                    if (dumpAll) {
9868                        rec.dump(pw, "    ");
9869                    }
9870                } else {
9871                    pw.print("  * "); pw.println(ref);
9872                }
9873            }
9874        }
9875
9876        return needSep;
9877    }
9878
9879    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9880            String prefix, String label, boolean complete, boolean brief, boolean client,
9881            String dumpPackage) {
9882        TaskRecord lastTask = null;
9883        boolean needNL = false;
9884        final String innerPrefix = prefix + "      ";
9885        final String[] args = new String[0];
9886        for (int i=list.size()-1; i>=0; i--) {
9887            final ActivityRecord r = (ActivityRecord)list.get(i);
9888            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9889                continue;
9890            }
9891            final boolean full = !brief && (complete || !r.isInHistory());
9892            if (needNL) {
9893                pw.println(" ");
9894                needNL = false;
9895            }
9896            if (lastTask != r.task) {
9897                lastTask = r.task;
9898                pw.print(prefix);
9899                pw.print(full ? "* " : "  ");
9900                pw.println(lastTask);
9901                if (full) {
9902                    lastTask.dump(pw, prefix + "  ");
9903                } else if (complete) {
9904                    // Complete + brief == give a summary.  Isn't that obvious?!?
9905                    if (lastTask.intent != null) {
9906                        pw.print(prefix); pw.print("  ");
9907                                pw.println(lastTask.intent.toInsecureStringWithClip());
9908                    }
9909                }
9910            }
9911            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9912            pw.print(" #"); pw.print(i); pw.print(": ");
9913            pw.println(r);
9914            if (full) {
9915                r.dump(pw, innerPrefix);
9916            } else if (complete) {
9917                // Complete + brief == give a summary.  Isn't that obvious?!?
9918                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9919                if (r.app != null) {
9920                    pw.print(innerPrefix); pw.println(r.app);
9921                }
9922            }
9923            if (client && r.app != null && r.app.thread != null) {
9924                // flush anything that is already in the PrintWriter since the thread is going
9925                // to write to the file descriptor directly
9926                pw.flush();
9927                try {
9928                    TransferPipe tp = new TransferPipe();
9929                    try {
9930                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9931                                r.appToken, innerPrefix, args);
9932                        // Short timeout, since blocking here can
9933                        // deadlock with the application.
9934                        tp.go(fd, 2000);
9935                    } finally {
9936                        tp.kill();
9937                    }
9938                } catch (IOException e) {
9939                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9940                } catch (RemoteException e) {
9941                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9942                }
9943                needNL = true;
9944            }
9945        }
9946    }
9947
9948    private static String buildOomTag(String prefix, String space, int val, int base) {
9949        if (val == base) {
9950            if (space == null) return prefix;
9951            return prefix + "  ";
9952        }
9953        return prefix + "+" + Integer.toString(val-base);
9954    }
9955
9956    private static final int dumpProcessList(PrintWriter pw,
9957            ActivityManagerService service, List list,
9958            String prefix, String normalLabel, String persistentLabel,
9959            String dumpPackage) {
9960        int numPers = 0;
9961        final int N = list.size()-1;
9962        for (int i=N; i>=0; i--) {
9963            ProcessRecord r = (ProcessRecord)list.get(i);
9964            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9965                continue;
9966            }
9967            pw.println(String.format("%s%s #%2d: %s",
9968                    prefix, (r.persistent ? persistentLabel : normalLabel),
9969                    i, r.toString()));
9970            if (r.persistent) {
9971                numPers++;
9972            }
9973        }
9974        return numPers;
9975    }
9976
9977    private static final boolean dumpProcessOomList(PrintWriter pw,
9978            ActivityManagerService service, List<ProcessRecord> origList,
9979            String prefix, String normalLabel, String persistentLabel,
9980            boolean inclDetails, String dumpPackage) {
9981
9982        ArrayList<Pair<ProcessRecord, Integer>> list
9983                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9984        for (int i=0; i<origList.size(); i++) {
9985            ProcessRecord r = origList.get(i);
9986            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9987                continue;
9988            }
9989            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9990        }
9991
9992        if (list.size() <= 0) {
9993            return false;
9994        }
9995
9996        Comparator<Pair<ProcessRecord, Integer>> comparator
9997                = new Comparator<Pair<ProcessRecord, Integer>>() {
9998            @Override
9999            public int compare(Pair<ProcessRecord, Integer> object1,
10000                    Pair<ProcessRecord, Integer> object2) {
10001                if (object1.first.setAdj != object2.first.setAdj) {
10002                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
10003                }
10004                if (object1.second.intValue() != object2.second.intValue()) {
10005                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
10006                }
10007                return 0;
10008            }
10009        };
10010
10011        Collections.sort(list, comparator);
10012
10013        final long curRealtime = SystemClock.elapsedRealtime();
10014        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
10015        final long curUptime = SystemClock.uptimeMillis();
10016        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
10017
10018        for (int i=list.size()-1; i>=0; i--) {
10019            ProcessRecord r = list.get(i).first;
10020            String oomAdj;
10021            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
10022                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
10023            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
10024                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
10025            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
10026                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
10027            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
10028                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
10029            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
10030                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
10031            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
10032                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
10033            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10034                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
10035            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10036                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
10037            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
10038                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
10039            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
10040                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
10041            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
10042                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
10043            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
10044                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
10045            } else {
10046                oomAdj = Integer.toString(r.setAdj);
10047            }
10048            String schedGroup;
10049            switch (r.setSchedGroup) {
10050                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
10051                    schedGroup = "B";
10052                    break;
10053                case Process.THREAD_GROUP_DEFAULT:
10054                    schedGroup = "F";
10055                    break;
10056                default:
10057                    schedGroup = Integer.toString(r.setSchedGroup);
10058                    break;
10059            }
10060            String foreground;
10061            if (r.foregroundActivities) {
10062                foreground = "A";
10063            } else if (r.foregroundServices) {
10064                foreground = "S";
10065            } else {
10066                foreground = " ";
10067            }
10068            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
10069                    prefix, (r.persistent ? persistentLabel : normalLabel),
10070                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
10071                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
10072            if (r.adjSource != null || r.adjTarget != null) {
10073                pw.print(prefix);
10074                pw.print("    ");
10075                if (r.adjTarget instanceof ComponentName) {
10076                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
10077                } else if (r.adjTarget != null) {
10078                    pw.print(r.adjTarget.toString());
10079                } else {
10080                    pw.print("{null}");
10081                }
10082                pw.print("<=");
10083                if (r.adjSource instanceof ProcessRecord) {
10084                    pw.print("Proc{");
10085                    pw.print(((ProcessRecord)r.adjSource).toShortString());
10086                    pw.println("}");
10087                } else if (r.adjSource != null) {
10088                    pw.println(r.adjSource.toString());
10089                } else {
10090                    pw.println("{null}");
10091                }
10092            }
10093            if (inclDetails) {
10094                pw.print(prefix);
10095                pw.print("    ");
10096                pw.print("oom: max="); pw.print(r.maxAdj);
10097                pw.print(" hidden="); pw.print(r.hiddenAdj);
10098                pw.print(" curRaw="); pw.print(r.curRawAdj);
10099                pw.print(" setRaw="); pw.print(r.setRawAdj);
10100                pw.print(" cur="); pw.print(r.curAdj);
10101                pw.print(" set="); pw.println(r.setAdj);
10102                pw.print(prefix);
10103                pw.print("    ");
10104                pw.print("keeping="); pw.print(r.keeping);
10105                pw.print(" hidden="); pw.print(r.hidden);
10106                pw.print(" empty="); pw.print(r.empty);
10107                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
10108
10109                if (!r.keeping) {
10110                    if (r.lastWakeTime != 0) {
10111                        long wtime;
10112                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10113                        synchronized (stats) {
10114                            wtime = stats.getProcessWakeTime(r.info.uid,
10115                                    r.pid, curRealtime);
10116                        }
10117                        long timeUsed = wtime - r.lastWakeTime;
10118                        pw.print(prefix);
10119                        pw.print("    ");
10120                        pw.print("keep awake over ");
10121                        TimeUtils.formatDuration(realtimeSince, pw);
10122                        pw.print(" used ");
10123                        TimeUtils.formatDuration(timeUsed, pw);
10124                        pw.print(" (");
10125                        pw.print((timeUsed*100)/realtimeSince);
10126                        pw.println("%)");
10127                    }
10128                    if (r.lastCpuTime != 0) {
10129                        long timeUsed = r.curCpuTime - r.lastCpuTime;
10130                        pw.print(prefix);
10131                        pw.print("    ");
10132                        pw.print("run cpu over ");
10133                        TimeUtils.formatDuration(uptimeSince, pw);
10134                        pw.print(" used ");
10135                        TimeUtils.formatDuration(timeUsed, pw);
10136                        pw.print(" (");
10137                        pw.print((timeUsed*100)/uptimeSince);
10138                        pw.println("%)");
10139                    }
10140                }
10141            }
10142        }
10143        return true;
10144    }
10145
10146    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
10147        ArrayList<ProcessRecord> procs;
10148        synchronized (this) {
10149            if (args != null && args.length > start
10150                    && args[start].charAt(0) != '-') {
10151                procs = new ArrayList<ProcessRecord>();
10152                int pid = -1;
10153                try {
10154                    pid = Integer.parseInt(args[start]);
10155                } catch (NumberFormatException e) {
10156
10157                }
10158                for (int i=mLruProcesses.size()-1; i>=0; i--) {
10159                    ProcessRecord proc = mLruProcesses.get(i);
10160                    if (proc.pid == pid) {
10161                        procs.add(proc);
10162                    } else if (proc.processName.equals(args[start])) {
10163                        procs.add(proc);
10164                    }
10165                }
10166                if (procs.size() <= 0) {
10167                    pw.println("No process found for: " + args[start]);
10168                    return null;
10169                }
10170            } else {
10171                procs = new ArrayList<ProcessRecord>(mLruProcesses);
10172            }
10173        }
10174        return procs;
10175    }
10176
10177    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10178            PrintWriter pw, String[] args) {
10179        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10180        if (procs == null) {
10181            return;
10182        }
10183
10184        long uptime = SystemClock.uptimeMillis();
10185        long realtime = SystemClock.elapsedRealtime();
10186        pw.println("Applications Graphics Acceleration Info:");
10187        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10188
10189        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10190            ProcessRecord r = procs.get(i);
10191            if (r.thread != null) {
10192                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10193                pw.flush();
10194                try {
10195                    TransferPipe tp = new TransferPipe();
10196                    try {
10197                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10198                        tp.go(fd);
10199                    } finally {
10200                        tp.kill();
10201                    }
10202                } catch (IOException e) {
10203                    pw.println("Failure while dumping the app: " + r);
10204                    pw.flush();
10205                } catch (RemoteException e) {
10206                    pw.println("Got a RemoteException while dumping the app " + r);
10207                    pw.flush();
10208                }
10209            }
10210        }
10211    }
10212
10213    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10214        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10215        if (procs == null) {
10216            return;
10217        }
10218
10219        pw.println("Applications Database Info:");
10220
10221        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10222            ProcessRecord r = procs.get(i);
10223            if (r.thread != null) {
10224                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10225                pw.flush();
10226                try {
10227                    TransferPipe tp = new TransferPipe();
10228                    try {
10229                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10230                        tp.go(fd);
10231                    } finally {
10232                        tp.kill();
10233                    }
10234                } catch (IOException e) {
10235                    pw.println("Failure while dumping the app: " + r);
10236                    pw.flush();
10237                } catch (RemoteException e) {
10238                    pw.println("Got a RemoteException while dumping the app " + r);
10239                    pw.flush();
10240                }
10241            }
10242        }
10243    }
10244
10245    final static class MemItem {
10246        final String label;
10247        final String shortLabel;
10248        final long pss;
10249        final int id;
10250        ArrayList<MemItem> subitems;
10251
10252        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10253            label = _label;
10254            shortLabel = _shortLabel;
10255            pss = _pss;
10256            id = _id;
10257        }
10258    }
10259
10260    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10261            boolean sort) {
10262        if (sort) {
10263            Collections.sort(items, new Comparator<MemItem>() {
10264                @Override
10265                public int compare(MemItem lhs, MemItem rhs) {
10266                    if (lhs.pss < rhs.pss) {
10267                        return 1;
10268                    } else if (lhs.pss > rhs.pss) {
10269                        return -1;
10270                    }
10271                    return 0;
10272                }
10273            });
10274        }
10275
10276        for (int i=0; i<items.size(); i++) {
10277            MemItem mi = items.get(i);
10278            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10279            if (mi.subitems != null) {
10280                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10281            }
10282        }
10283    }
10284
10285    // These are in KB.
10286    static final long[] DUMP_MEM_BUCKETS = new long[] {
10287        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10288        120*1024, 160*1024, 200*1024,
10289        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10290        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10291    };
10292
10293    static final void appendMemBucket(StringBuilder out, long memKB, String label,
10294            boolean stackLike) {
10295        int start = label.lastIndexOf('.');
10296        if (start >= 0) start++;
10297        else start = 0;
10298        int end = label.length();
10299        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10300            if (DUMP_MEM_BUCKETS[i] >= memKB) {
10301                long bucket = DUMP_MEM_BUCKETS[i]/1024;
10302                out.append(bucket);
10303                out.append(stackLike ? "MB." : "MB ");
10304                out.append(label, start, end);
10305                return;
10306            }
10307        }
10308        out.append(memKB/1024);
10309        out.append(stackLike ? "MB." : "MB ");
10310        out.append(label, start, end);
10311    }
10312
10313    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10314            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10315            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10316            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10317            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10318    };
10319    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10320            "System", "Persistent", "Foreground",
10321            "Visible", "Perceptible", "Heavy Weight",
10322            "Backup", "A Services", "Home", "Previous",
10323            "B Services", "Background"
10324    };
10325
10326    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10327            PrintWriter pw, String prefix, String[] args, boolean brief,
10328            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10329        boolean dumpAll = false;
10330        boolean oomOnly = false;
10331
10332        int opti = 0;
10333        while (opti < args.length) {
10334            String opt = args[opti];
10335            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10336                break;
10337            }
10338            opti++;
10339            if ("-a".equals(opt)) {
10340                dumpAll = true;
10341            } else if ("--oom".equals(opt)) {
10342                oomOnly = true;
10343            } else if ("-h".equals(opt)) {
10344                pw.println("meminfo dump options: [-a] [--oom] [process]");
10345                pw.println("  -a: include all available information for each process.");
10346                pw.println("  --oom: only show processes organized by oom adj.");
10347                pw.println("If [process] is specified it can be the name or ");
10348                pw.println("pid of a specific process to dump.");
10349                return;
10350            } else {
10351                pw.println("Unknown argument: " + opt + "; use -h for help");
10352            }
10353        }
10354
10355        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10356        if (procs == null) {
10357            return;
10358        }
10359
10360        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10361        long uptime = SystemClock.uptimeMillis();
10362        long realtime = SystemClock.elapsedRealtime();
10363
10364        if (procs.size() == 1 || isCheckinRequest) {
10365            dumpAll = true;
10366        }
10367
10368        if (isCheckinRequest) {
10369            // short checkin version
10370            pw.println(uptime + "," + realtime);
10371            pw.flush();
10372        } else {
10373            pw.println("Applications Memory Usage (kB):");
10374            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10375        }
10376
10377        String[] innerArgs = new String[args.length-opti];
10378        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10379
10380        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10381        long nativePss=0, dalvikPss=0, otherPss=0;
10382        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10383
10384        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10385        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10386                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10387
10388        long totalPss = 0;
10389
10390        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10391            ProcessRecord r = procs.get(i);
10392            if (r.thread != null) {
10393                if (!isCheckinRequest && dumpAll) {
10394                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10395                    pw.flush();
10396                }
10397                Debug.MemoryInfo mi = null;
10398                if (dumpAll) {
10399                    try {
10400                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10401                    } catch (RemoteException e) {
10402                        if (!isCheckinRequest) {
10403                            pw.println("Got RemoteException!");
10404                            pw.flush();
10405                        }
10406                    }
10407                } else {
10408                    mi = new Debug.MemoryInfo();
10409                    Debug.getMemoryInfo(r.pid, mi);
10410                }
10411
10412                if (!isCheckinRequest && mi != null) {
10413                    long myTotalPss = mi.getTotalPss();
10414                    totalPss += myTotalPss;
10415                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10416                            r.processName, myTotalPss, 0);
10417                    procMems.add(pssItem);
10418
10419                    nativePss += mi.nativePss;
10420                    dalvikPss += mi.dalvikPss;
10421                    otherPss += mi.otherPss;
10422                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10423                        long mem = mi.getOtherPss(j);
10424                        miscPss[j] += mem;
10425                        otherPss -= mem;
10426                    }
10427
10428                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10429                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10430                                || oomIndex == (oomPss.length-1)) {
10431                            oomPss[oomIndex] += myTotalPss;
10432                            if (oomProcs[oomIndex] == null) {
10433                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10434                            }
10435                            oomProcs[oomIndex].add(pssItem);
10436                            break;
10437                        }
10438                    }
10439                }
10440            }
10441        }
10442
10443        if (!isCheckinRequest && procs.size() > 1) {
10444            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10445
10446            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10447            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10448            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10449            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10450                String label = Debug.MemoryInfo.getOtherLabel(j);
10451                catMems.add(new MemItem(label, label, miscPss[j], j));
10452            }
10453
10454            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10455            for (int j=0; j<oomPss.length; j++) {
10456                if (oomPss[j] != 0) {
10457                    String label = DUMP_MEM_OOM_LABEL[j];
10458                    MemItem item = new MemItem(label, label, oomPss[j],
10459                            DUMP_MEM_OOM_ADJ[j]);
10460                    item.subitems = oomProcs[j];
10461                    oomMems.add(item);
10462                }
10463            }
10464
10465            if (outTag != null || outStack != null) {
10466                if (outTag != null) {
10467                    appendMemBucket(outTag, totalPss, "total", false);
10468                }
10469                if (outStack != null) {
10470                    appendMemBucket(outStack, totalPss, "total", true);
10471                }
10472                boolean firstLine = true;
10473                for (int i=0; i<oomMems.size(); i++) {
10474                    MemItem miCat = oomMems.get(i);
10475                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10476                        continue;
10477                    }
10478                    if (miCat.id < ProcessList.SERVICE_ADJ
10479                            || miCat.id == ProcessList.HOME_APP_ADJ
10480                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10481                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10482                            outTag.append(" / ");
10483                        }
10484                        if (outStack != null) {
10485                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10486                                if (firstLine) {
10487                                    outStack.append(":");
10488                                    firstLine = false;
10489                                }
10490                                outStack.append("\n\t at ");
10491                            } else {
10492                                outStack.append("$");
10493                            }
10494                        }
10495                        for (int j=0; j<miCat.subitems.size(); j++) {
10496                            MemItem mi = miCat.subitems.get(j);
10497                            if (j > 0) {
10498                                if (outTag != null) {
10499                                    outTag.append(" ");
10500                                }
10501                                if (outStack != null) {
10502                                    outStack.append("$");
10503                                }
10504                            }
10505                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10506                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10507                            }
10508                            if (outStack != null) {
10509                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10510                            }
10511                        }
10512                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10513                            outStack.append("(");
10514                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10515                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10516                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10517                                    outStack.append(":");
10518                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10519                                }
10520                            }
10521                            outStack.append(")");
10522                        }
10523                    }
10524                }
10525            }
10526
10527            if (!brief && !oomOnly) {
10528                pw.println();
10529                pw.println("Total PSS by process:");
10530                dumpMemItems(pw, "  ", procMems, true);
10531                pw.println();
10532            }
10533            pw.println("Total PSS by OOM adjustment:");
10534            dumpMemItems(pw, "  ", oomMems, false);
10535            if (!oomOnly) {
10536                PrintWriter out = categoryPw != null ? categoryPw : pw;
10537                out.println();
10538                out.println("Total PSS by category:");
10539                dumpMemItems(out, "  ", catMems, true);
10540            }
10541            pw.println();
10542            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10543            final int[] SINGLE_LONG_FORMAT = new int[] {
10544                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10545            };
10546            long[] longOut = new long[1];
10547            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10548                    SINGLE_LONG_FORMAT, null, longOut, null);
10549            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10550            longOut[0] = 0;
10551            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10552                    SINGLE_LONG_FORMAT, null, longOut, null);
10553            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10554            longOut[0] = 0;
10555            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10556                    SINGLE_LONG_FORMAT, null, longOut, null);
10557            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10558            longOut[0] = 0;
10559            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10560                    SINGLE_LONG_FORMAT, null, longOut, null);
10561            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10562            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10563                    pw.print(shared); pw.println(" kB");
10564            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10565                    pw.print(voltile); pw.println(" kB volatile");
10566        }
10567    }
10568
10569    /**
10570     * Searches array of arguments for the specified string
10571     * @param args array of argument strings
10572     * @param value value to search for
10573     * @return true if the value is contained in the array
10574     */
10575    private static boolean scanArgs(String[] args, String value) {
10576        if (args != null) {
10577            for (String arg : args) {
10578                if (value.equals(arg)) {
10579                    return true;
10580                }
10581            }
10582        }
10583        return false;
10584    }
10585
10586    private final void killServicesLocked(ProcessRecord app,
10587            boolean allowRestart) {
10588        // Report disconnected services.
10589        if (false) {
10590            // XXX we are letting the client link to the service for
10591            // death notifications.
10592            if (app.services.size() > 0) {
10593                Iterator<ServiceRecord> it = app.services.iterator();
10594                while (it.hasNext()) {
10595                    ServiceRecord r = it.next();
10596                    if (r.connections.size() > 0) {
10597                        Iterator<ArrayList<ConnectionRecord>> jt
10598                                = r.connections.values().iterator();
10599                        while (jt.hasNext()) {
10600                            ArrayList<ConnectionRecord> cl = jt.next();
10601                            for (int i=0; i<cl.size(); i++) {
10602                                ConnectionRecord c = cl.get(i);
10603                                if (c.binding.client != app) {
10604                                    try {
10605                                        //c.conn.connected(r.className, null);
10606                                    } catch (Exception e) {
10607                                        // todo: this should be asynchronous!
10608                                        Slog.w(TAG, "Exception thrown disconnected servce "
10609                                              + r.shortName
10610                                              + " from app " + app.processName, e);
10611                                    }
10612                                }
10613                            }
10614                        }
10615                    }
10616                }
10617            }
10618        }
10619
10620        // Clean up any connections this application has to other services.
10621        if (app.connections.size() > 0) {
10622            Iterator<ConnectionRecord> it = app.connections.iterator();
10623            while (it.hasNext()) {
10624                ConnectionRecord r = it.next();
10625                removeConnectionLocked(r, app, null);
10626            }
10627        }
10628        app.connections.clear();
10629
10630        if (app.services.size() != 0) {
10631            // Any services running in the application need to be placed
10632            // back in the pending list.
10633            Iterator<ServiceRecord> it = app.services.iterator();
10634            while (it.hasNext()) {
10635                ServiceRecord sr = it.next();
10636                synchronized (sr.stats.getBatteryStats()) {
10637                    sr.stats.stopLaunchedLocked();
10638                }
10639                sr.app = null;
10640                sr.isolatedProc = null;
10641                sr.executeNesting = 0;
10642                if (mStoppingServices.remove(sr)) {
10643                    if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
10644                }
10645
10646                boolean hasClients = sr.bindings.size() > 0;
10647                if (hasClients) {
10648                    Iterator<IntentBindRecord> bindings
10649                            = sr.bindings.values().iterator();
10650                    while (bindings.hasNext()) {
10651                        IntentBindRecord b = bindings.next();
10652                        if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
10653                                + ": shouldUnbind=" + b.hasBound);
10654                        b.binder = null;
10655                        b.requested = b.received = b.hasBound = false;
10656                    }
10657                }
10658
10659                if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
10660                        &ApplicationInfo.FLAG_PERSISTENT) == 0) {
10661                    Slog.w(TAG, "Service crashed " + sr.crashCount
10662                            + " times, stopping: " + sr);
10663                    EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
10664                            sr.crashCount, sr.shortName, app.pid);
10665                    bringDownServiceLocked(sr, true);
10666                } else if (!allowRestart) {
10667                    bringDownServiceLocked(sr, true);
10668                } else {
10669                    boolean canceled = scheduleServiceRestartLocked(sr, true);
10670
10671                    // Should the service remain running?  Note that in the
10672                    // extreme case of so many attempts to deliver a command
10673                    // that it failed we also will stop it here.
10674                    if (sr.startRequested && (sr.stopIfKilled || canceled)) {
10675                        if (sr.pendingStarts.size() == 0) {
10676                            sr.startRequested = false;
10677                            if (!hasClients) {
10678                                // Whoops, no reason to restart!
10679                                bringDownServiceLocked(sr, true);
10680                            }
10681                        }
10682                    }
10683                }
10684            }
10685
10686            if (!allowRestart) {
10687                app.services.clear();
10688            }
10689        }
10690
10691        // Make sure we have no more records on the stopping list.
10692        int i = mStoppingServices.size();
10693        while (i > 0) {
10694            i--;
10695            ServiceRecord sr = mStoppingServices.get(i);
10696            if (sr.app == app) {
10697                mStoppingServices.remove(i);
10698                if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
10699            }
10700        }
10701
10702        app.executingServices.clear();
10703    }
10704
10705    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10706            ContentProviderRecord cpr, boolean always) {
10707        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10708
10709        if (!inLaunching || always) {
10710            synchronized (cpr) {
10711                cpr.launchingApp = null;
10712                cpr.notifyAll();
10713            }
10714            mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid));
10715            String names[] = cpr.info.authority.split(";");
10716            for (int j = 0; j < names.length; j++) {
10717                mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid));
10718            }
10719        }
10720
10721        for (int i=0; i<cpr.connections.size(); i++) {
10722            ContentProviderConnection conn = cpr.connections.get(i);
10723            if (conn.waiting) {
10724                // If this connection is waiting for the provider, then we don't
10725                // need to mess with its process unless we are always removing
10726                // or for some reason the provider is not currently launching.
10727                if (inLaunching && !always) {
10728                    continue;
10729                }
10730            }
10731            ProcessRecord capp = conn.client;
10732            conn.dead = true;
10733            if (conn.stableCount > 0) {
10734                if (!capp.persistent && capp.thread != null
10735                        && capp.pid != 0
10736                        && capp.pid != MY_PID) {
10737                    Slog.i(TAG, "Kill " + capp.processName
10738                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10739                            + " in dying process " + (proc != null ? proc.processName : "??"));
10740                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10741                            capp.processName, capp.setAdj, "dying provider "
10742                                    + cpr.name.toShortString());
10743                    Process.killProcessQuiet(capp.pid);
10744                }
10745            } else if (capp.thread != null && conn.provider.provider != null) {
10746                try {
10747                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10748                } catch (RemoteException e) {
10749                }
10750                // In the protocol here, we don't expect the client to correctly
10751                // clean up this connection, we'll just remove it.
10752                cpr.connections.remove(i);
10753                conn.client.conProviders.remove(conn);
10754            }
10755        }
10756
10757        if (inLaunching && always) {
10758            mLaunchingProviders.remove(cpr);
10759        }
10760        return inLaunching;
10761    }
10762
10763    /**
10764     * Main code for cleaning up a process when it has gone away.  This is
10765     * called both as a result of the process dying, or directly when stopping
10766     * a process when running in single process mode.
10767     */
10768    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10769            boolean restarting, boolean allowRestart, int index) {
10770        if (index >= 0) {
10771            mLruProcesses.remove(index);
10772        }
10773
10774        mProcessesToGc.remove(app);
10775
10776        // Dismiss any open dialogs.
10777        if (app.crashDialog != null) {
10778            app.crashDialog.dismiss();
10779            app.crashDialog = null;
10780        }
10781        if (app.anrDialog != null) {
10782            app.anrDialog.dismiss();
10783            app.anrDialog = null;
10784        }
10785        if (app.waitDialog != null) {
10786            app.waitDialog.dismiss();
10787            app.waitDialog = null;
10788        }
10789
10790        app.crashing = false;
10791        app.notResponding = false;
10792
10793        app.resetPackageList();
10794        app.unlinkDeathRecipient();
10795        app.thread = null;
10796        app.forcingToForeground = null;
10797        app.foregroundServices = false;
10798        app.foregroundActivities = false;
10799        app.hasShownUi = false;
10800        app.hasAboveClient = false;
10801
10802        killServicesLocked(app, allowRestart);
10803
10804        boolean restart = false;
10805
10806        // Remove published content providers.
10807        if (!app.pubProviders.isEmpty()) {
10808            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10809            while (it.hasNext()) {
10810                ContentProviderRecord cpr = it.next();
10811
10812                final boolean always = app.bad || !allowRestart;
10813                if (removeDyingProviderLocked(app, cpr, always) || always) {
10814                    // We left the provider in the launching list, need to
10815                    // restart it.
10816                    restart = true;
10817                }
10818
10819                cpr.provider = null;
10820                cpr.proc = null;
10821            }
10822            app.pubProviders.clear();
10823        }
10824
10825        // Take care of any launching providers waiting for this process.
10826        if (checkAppInLaunchingProvidersLocked(app, false)) {
10827            restart = true;
10828        }
10829
10830        // Unregister from connected content providers.
10831        if (!app.conProviders.isEmpty()) {
10832            for (int i=0; i<app.conProviders.size(); i++) {
10833                ContentProviderConnection conn = app.conProviders.get(i);
10834                conn.provider.connections.remove(conn);
10835            }
10836            app.conProviders.clear();
10837        }
10838
10839        // At this point there may be remaining entries in mLaunchingProviders
10840        // where we were the only one waiting, so they are no longer of use.
10841        // Look for these and clean up if found.
10842        // XXX Commented out for now.  Trying to figure out a way to reproduce
10843        // the actual situation to identify what is actually going on.
10844        if (false) {
10845            for (int i=0; i<mLaunchingProviders.size(); i++) {
10846                ContentProviderRecord cpr = (ContentProviderRecord)
10847                        mLaunchingProviders.get(i);
10848                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10849                    synchronized (cpr) {
10850                        cpr.launchingApp = null;
10851                        cpr.notifyAll();
10852                    }
10853                }
10854            }
10855        }
10856
10857        skipCurrentReceiverLocked(app);
10858
10859        // Unregister any receivers.
10860        if (app.receivers.size() > 0) {
10861            Iterator<ReceiverList> it = app.receivers.iterator();
10862            while (it.hasNext()) {
10863                removeReceiverLocked(it.next());
10864            }
10865            app.receivers.clear();
10866        }
10867
10868        // If the app is undergoing backup, tell the backup manager about it
10869        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10870            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10871            try {
10872                IBackupManager bm = IBackupManager.Stub.asInterface(
10873                        ServiceManager.getService(Context.BACKUP_SERVICE));
10874                bm.agentDisconnected(app.info.packageName);
10875            } catch (RemoteException e) {
10876                // can't happen; backup manager is local
10877            }
10878        }
10879
10880        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10881            ProcessChangeItem item = mPendingProcessChanges.get(i);
10882            if (item.pid == app.pid) {
10883                mPendingProcessChanges.remove(i);
10884                mAvailProcessChanges.add(item);
10885            }
10886        }
10887        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10888
10889        // If the caller is restarting this app, then leave it in its
10890        // current lists and let the caller take care of it.
10891        if (restarting) {
10892            return;
10893        }
10894
10895        if (!app.persistent || app.isolated) {
10896            if (DEBUG_PROCESSES) Slog.v(TAG,
10897                    "Removing non-persistent process during cleanup: " + app);
10898            mProcessNames.remove(app.processName, app.uid);
10899            mIsolatedProcesses.remove(app.uid);
10900            if (mHeavyWeightProcess == app) {
10901                mHeavyWeightProcess = null;
10902                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
10903            }
10904        } else if (!app.removed) {
10905            // This app is persistent, so we need to keep its record around.
10906            // If it is not already on the pending app list, add it there
10907            // and start a new process for it.
10908            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10909                mPersistentStartingProcesses.add(app);
10910                restart = true;
10911            }
10912        }
10913        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10914                "Clean-up removing on hold: " + app);
10915        mProcessesOnHold.remove(app);
10916
10917        if (app == mHomeProcess) {
10918            mHomeProcess = null;
10919        }
10920        if (app == mPreviousProcess) {
10921            mPreviousProcess = null;
10922        }
10923
10924        if (restart && !app.isolated) {
10925            // We have components that still need to be running in the
10926            // process, so re-launch it.
10927            mProcessNames.put(app.processName, app.uid, app);
10928            startProcessLocked(app, "restart", app.processName);
10929        } else if (app.pid > 0 && app.pid != MY_PID) {
10930            // Goodbye!
10931            synchronized (mPidsSelfLocked) {
10932                mPidsSelfLocked.remove(app.pid);
10933                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10934            }
10935            app.setPid(0);
10936        }
10937    }
10938
10939    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10940        // Look through the content providers we are waiting to have launched,
10941        // and if any run in this process then either schedule a restart of
10942        // the process or kill the client waiting for it if this process has
10943        // gone bad.
10944        int NL = mLaunchingProviders.size();
10945        boolean restart = false;
10946        for (int i=0; i<NL; i++) {
10947            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10948            if (cpr.launchingApp == app) {
10949                if (!alwaysBad && !app.bad) {
10950                    restart = true;
10951                } else {
10952                    removeDyingProviderLocked(app, cpr, true);
10953                    NL = mLaunchingProviders.size();
10954                }
10955            }
10956        }
10957        return restart;
10958    }
10959
10960    // =========================================================
10961    // SERVICES
10962    // =========================================================
10963
10964    ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
10965        ActivityManager.RunningServiceInfo info =
10966            new ActivityManager.RunningServiceInfo();
10967        info.service = r.name;
10968        if (r.app != null) {
10969            info.pid = r.app.pid;
10970        }
10971        info.uid = r.appInfo.uid;
10972        info.process = r.processName;
10973        info.foreground = r.isForeground;
10974        info.activeSince = r.createTime;
10975        info.started = r.startRequested;
10976        info.clientCount = r.connections.size();
10977        info.crashCount = r.crashCount;
10978        info.lastActivityTime = r.lastActivity;
10979        if (r.isForeground) {
10980            info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
10981        }
10982        if (r.startRequested) {
10983            info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
10984        }
10985        if (r.app != null && r.app.pid == MY_PID) {
10986            info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
10987        }
10988        if (r.app != null && r.app.persistent) {
10989            info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
10990        }
10991
10992        for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
10993            for (int i=0; i<connl.size(); i++) {
10994                ConnectionRecord conn = connl.get(i);
10995                if (conn.clientLabel != 0) {
10996                    info.clientPackage = conn.binding.client.info.packageName;
10997                    info.clientLabel = conn.clientLabel;
10998                    return info;
10999                }
11000            }
11001        }
11002        return info;
11003    }
11004
11005    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
11006            int flags) {
11007        enforceNotIsolatedCaller("getServices");
11008        synchronized (this) {
11009            ArrayList<ActivityManager.RunningServiceInfo> res
11010                    = new ArrayList<ActivityManager.RunningServiceInfo>();
11011
11012            int userId = UserId.getUserId(Binder.getCallingUid());
11013            if (mServiceMap.getAllServices(userId).size() > 0) {
11014                Iterator<ServiceRecord> it
11015                        = mServiceMap.getAllServices(userId).iterator();
11016                while (it.hasNext() && res.size() < maxNum) {
11017                    res.add(makeRunningServiceInfoLocked(it.next()));
11018                }
11019            }
11020
11021            for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
11022                ServiceRecord r = mRestartingServices.get(i);
11023                ActivityManager.RunningServiceInfo info =
11024                        makeRunningServiceInfoLocked(r);
11025                info.restarting = r.nextRestartTime;
11026                res.add(info);
11027            }
11028
11029            return res;
11030        }
11031    }
11032
11033    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
11034        enforceNotIsolatedCaller("getRunningServiceControlPanel");
11035        synchronized (this) {
11036            int userId = UserId.getUserId(Binder.getCallingUid());
11037            ServiceRecord r = mServiceMap.getServiceByName(name, userId);
11038            if (r != null) {
11039                for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
11040                    for (int i=0; i<conn.size(); i++) {
11041                        if (conn.get(i).clientIntent != null) {
11042                            return conn.get(i).clientIntent;
11043                        }
11044                    }
11045                }
11046            }
11047        }
11048        return null;
11049    }
11050
11051    private final ServiceRecord findServiceLocked(ComponentName name,
11052            IBinder token) {
11053        ServiceRecord r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
11054        return r == token ? r : null;
11055    }
11056
11057    private final class ServiceLookupResult {
11058        final ServiceRecord record;
11059        final String permission;
11060
11061        ServiceLookupResult(ServiceRecord _record, String _permission) {
11062            record = _record;
11063            permission = _permission;
11064        }
11065    };
11066
11067    private ServiceLookupResult findServiceLocked(Intent service,
11068            String resolvedType, int userId) {
11069        ServiceRecord r = null;
11070        if (service.getComponent() != null) {
11071            r = mServiceMap.getServiceByName(service.getComponent(), userId);
11072        }
11073        if (r == null) {
11074            Intent.FilterComparison filter = new Intent.FilterComparison(service);
11075            r = mServiceMap.getServiceByIntent(filter, userId);
11076        }
11077
11078        if (r == null) {
11079            try {
11080                ResolveInfo rInfo =
11081                    AppGlobals.getPackageManager().resolveService(
11082                                service, resolvedType, 0, userId);
11083                ServiceInfo sInfo =
11084                    rInfo != null ? rInfo.serviceInfo : null;
11085                if (sInfo == null) {
11086                    return null;
11087                }
11088
11089                ComponentName name = new ComponentName(
11090                        sInfo.applicationInfo.packageName, sInfo.name);
11091                r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
11092            } catch (RemoteException ex) {
11093                // pm is in same process, this will never happen.
11094            }
11095        }
11096        if (r != null) {
11097            int callingPid = Binder.getCallingPid();
11098            int callingUid = Binder.getCallingUid();
11099            if (checkComponentPermission(r.permission,
11100                    callingPid, callingUid, r.appInfo.uid, r.exported)
11101                    != PackageManager.PERMISSION_GRANTED) {
11102                if (!r.exported) {
11103                    Slog.w(TAG, "Permission Denial: Accessing service " + r.name
11104                            + " from pid=" + callingPid
11105                            + ", uid=" + callingUid
11106                            + " that is not exported from uid " + r.appInfo.uid);
11107                    return new ServiceLookupResult(null, "not exported from uid "
11108                            + r.appInfo.uid);
11109                }
11110                Slog.w(TAG, "Permission Denial: Accessing service " + r.name
11111                        + " from pid=" + callingPid
11112                        + ", uid=" + callingUid
11113                        + " requires " + r.permission);
11114                return new ServiceLookupResult(null, r.permission);
11115            }
11116            return new ServiceLookupResult(r, null);
11117        }
11118        return null;
11119    }
11120
11121    private class ServiceRestarter implements Runnable {
11122        private ServiceRecord mService;
11123
11124        void setService(ServiceRecord service) {
11125            mService = service;
11126        }
11127
11128        public void run() {
11129            synchronized(ActivityManagerService.this) {
11130                performServiceRestartLocked(mService);
11131            }
11132        }
11133    }
11134
11135    private ServiceLookupResult retrieveServiceLocked(Intent service,
11136            String resolvedType, int callingPid, int callingUid, int userId) {
11137        ServiceRecord r = null;
11138        if (DEBUG_SERVICE)
11139            Slog.v(TAG, "retrieveServiceLocked: " + service + " type=" + resolvedType
11140                    + " callingUid=" + callingUid);
11141
11142        if (service.getComponent() != null) {
11143            r = mServiceMap.getServiceByName(service.getComponent(), userId);
11144        }
11145        if (r == null) {
11146            Intent.FilterComparison filter = new Intent.FilterComparison(service);
11147            r = mServiceMap.getServiceByIntent(filter, userId);
11148        }
11149        if (r == null) {
11150            try {
11151                ResolveInfo rInfo =
11152                    AppGlobals.getPackageManager().resolveService(
11153                                service, resolvedType, STOCK_PM_FLAGS, userId);
11154                ServiceInfo sInfo =
11155                    rInfo != null ? rInfo.serviceInfo : null;
11156                if (sInfo == null) {
11157                    Slog.w(TAG, "Unable to start service " + service +
11158                          ": not found");
11159                    return null;
11160                }
11161                if (userId > 0) {
11162                    if (isSingleton(sInfo.processName, sInfo.applicationInfo)) {
11163                        userId = 0;
11164                    }
11165                    sInfo.applicationInfo = getAppInfoForUser(sInfo.applicationInfo, userId);
11166                }
11167                ComponentName name = new ComponentName(
11168                        sInfo.applicationInfo.packageName, sInfo.name);
11169                r = mServiceMap.getServiceByName(name, userId);
11170                if (r == null) {
11171                    Intent.FilterComparison filter = new Intent.FilterComparison(
11172                            service.cloneFilter());
11173                    ServiceRestarter res = new ServiceRestarter();
11174                    BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11175                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11176                    synchronized (stats) {
11177                        ss = stats.getServiceStatsLocked(
11178                                sInfo.applicationInfo.uid, sInfo.packageName,
11179                                sInfo.name);
11180                    }
11181                    r = new ServiceRecord(this, ss, name, filter, sInfo, res);
11182                    res.setService(r);
11183                    mServiceMap.putServiceByName(name, UserId.getUserId(r.appInfo.uid), r);
11184                    mServiceMap.putServiceByIntent(filter, UserId.getUserId(r.appInfo.uid), r);
11185
11186                    // Make sure this component isn't in the pending list.
11187                    int N = mPendingServices.size();
11188                    for (int i=0; i<N; i++) {
11189                        ServiceRecord pr = mPendingServices.get(i);
11190                        if (pr.name.equals(name)) {
11191                            mPendingServices.remove(i);
11192                            i--;
11193                            N--;
11194                        }
11195                    }
11196                }
11197            } catch (RemoteException ex) {
11198                // pm is in same process, this will never happen.
11199            }
11200        }
11201        if (r != null) {
11202            if (checkComponentPermission(r.permission,
11203                    callingPid, callingUid, r.appInfo.uid, r.exported)
11204                    != PackageManager.PERMISSION_GRANTED) {
11205                if (!r.exported) {
11206                    Slog.w(TAG, "Permission Denial: Accessing service " + r.name
11207                            + " from pid=" + callingPid
11208                            + ", uid=" + callingUid
11209                            + " that is not exported from uid " + r.appInfo.uid);
11210                    return new ServiceLookupResult(null, "not exported from uid "
11211                            + r.appInfo.uid);
11212                }
11213                Slog.w(TAG, "Permission Denial: Accessing service " + r.name
11214                        + " from pid=" + callingPid
11215                        + ", uid=" + callingUid
11216                        + " requires " + r.permission);
11217                return new ServiceLookupResult(null, r.permission);
11218            }
11219            return new ServiceLookupResult(r, null);
11220        }
11221        return null;
11222    }
11223
11224    private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
11225        if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
11226                + why + " of " + r + " in app " + r.app);
11227        else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
11228                + why + " of " + r.shortName);
11229        long now = SystemClock.uptimeMillis();
11230        if (r.executeNesting == 0 && r.app != null) {
11231            if (r.app.executingServices.size() == 0) {
11232                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11233                msg.obj = r.app;
11234                mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
11235            }
11236            r.app.executingServices.add(r);
11237        }
11238        r.executeNesting++;
11239        r.executingStart = now;
11240    }
11241
11242    private final void sendServiceArgsLocked(ServiceRecord r,
11243            boolean oomAdjusted) {
11244        final int N = r.pendingStarts.size();
11245        if (N == 0) {
11246            return;
11247        }
11248
11249        while (r.pendingStarts.size() > 0) {
11250            try {
11251                ServiceRecord.StartItem si = r.pendingStarts.remove(0);
11252                if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
11253                        + r + " " + r.intent + " args=" + si.intent);
11254                if (si.intent == null && N > 1) {
11255                    // If somehow we got a dummy null intent in the middle,
11256                    // then skip it.  DO NOT skip a null intent when it is
11257                    // the only one in the list -- this is to support the
11258                    // onStartCommand(null) case.
11259                    continue;
11260                }
11261                si.deliveredTime = SystemClock.uptimeMillis();
11262                r.deliveredStarts.add(si);
11263                si.deliveryCount++;
11264                if (si.neededGrants != null) {
11265                    grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
11266                            si.getUriPermissionsLocked());
11267                }
11268                bumpServiceExecutingLocked(r, "start");
11269                if (!oomAdjusted) {
11270                    oomAdjusted = true;
11271                    updateOomAdjLocked(r.app);
11272                }
11273                int flags = 0;
11274                if (si.deliveryCount > 1) {
11275                    flags |= Service.START_FLAG_RETRY;
11276                }
11277                if (si.doneExecutingCount > 0) {
11278                    flags |= Service.START_FLAG_REDELIVERY;
11279                }
11280                r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
11281            } catch (RemoteException e) {
11282                // Remote process gone...  we'll let the normal cleanup take
11283                // care of this.
11284                if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
11285                break;
11286            } catch (Exception e) {
11287                Slog.w(TAG, "Unexpected exception", e);
11288                break;
11289            }
11290        }
11291    }
11292
11293    private final boolean requestServiceBindingLocked(ServiceRecord r,
11294            IntentBindRecord i, boolean rebind) {
11295        if (r.app == null || r.app.thread == null) {
11296            // If service is not currently running, can't yet bind.
11297            return false;
11298        }
11299        if ((!i.requested || rebind) && i.apps.size() > 0) {
11300            try {
11301                bumpServiceExecutingLocked(r, "bind");
11302                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
11303                if (!rebind) {
11304                    i.requested = true;
11305                }
11306                i.hasBound = true;
11307                i.doRebind = false;
11308            } catch (RemoteException e) {
11309                if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
11310                return false;
11311            }
11312        }
11313        return true;
11314    }
11315
11316    private final void requestServiceBindingsLocked(ServiceRecord r) {
11317        Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
11318        while (bindings.hasNext()) {
11319            IntentBindRecord i = bindings.next();
11320            if (!requestServiceBindingLocked(r, i, false)) {
11321                break;
11322            }
11323        }
11324    }
11325
11326    private final void realStartServiceLocked(ServiceRecord r,
11327            ProcessRecord app) throws RemoteException {
11328        if (app.thread == null) {
11329            throw new RemoteException();
11330        }
11331        if (DEBUG_MU)
11332            Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
11333                    + ", ProcessRecord.uid = " + app.uid);
11334        r.app = app;
11335        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
11336
11337        app.services.add(r);
11338        bumpServiceExecutingLocked(r, "create");
11339        updateLruProcessLocked(app, true, true);
11340
11341        boolean created = false;
11342        try {
11343            mStringBuilder.setLength(0);
11344            r.intent.getIntent().toShortString(mStringBuilder, true, false, true, false);
11345            EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
11346                    System.identityHashCode(r), r.shortName,
11347                    mStringBuilder.toString(), r.app.pid);
11348            synchronized (r.stats.getBatteryStats()) {
11349                r.stats.startLaunchedLocked();
11350            }
11351            ensurePackageDexOpt(r.serviceInfo.packageName);
11352            app.thread.scheduleCreateService(r, r.serviceInfo,
11353                    compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
11354            r.postNotification();
11355            created = true;
11356        } finally {
11357            if (!created) {
11358                app.services.remove(r);
11359                scheduleServiceRestartLocked(r, false);
11360            }
11361        }
11362
11363        requestServiceBindingsLocked(r);
11364
11365        // If the service is in the started state, and there are no
11366        // pending arguments, then fake up one so its onStartCommand() will
11367        // be called.
11368        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
11369            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
11370                    null, null));
11371        }
11372
11373        sendServiceArgsLocked(r, true);
11374    }
11375
11376    private final boolean scheduleServiceRestartLocked(ServiceRecord r,
11377            boolean allowCancel) {
11378        boolean canceled = false;
11379
11380        final long now = SystemClock.uptimeMillis();
11381        long minDuration = SERVICE_RESTART_DURATION;
11382        long resetTime = SERVICE_RESET_RUN_DURATION;
11383
11384        if ((r.serviceInfo.applicationInfo.flags
11385                &ApplicationInfo.FLAG_PERSISTENT) != 0) {
11386            minDuration /= 4;
11387        }
11388
11389        // Any delivered but not yet finished starts should be put back
11390        // on the pending list.
11391        final int N = r.deliveredStarts.size();
11392        if (N > 0) {
11393            for (int i=N-1; i>=0; i--) {
11394                ServiceRecord.StartItem si = r.deliveredStarts.get(i);
11395                si.removeUriPermissionsLocked();
11396                if (si.intent == null) {
11397                    // We'll generate this again if needed.
11398                } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
11399                        && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
11400                    r.pendingStarts.add(0, si);
11401                    long dur = SystemClock.uptimeMillis() - si.deliveredTime;
11402                    dur *= 2;
11403                    if (minDuration < dur) minDuration = dur;
11404                    if (resetTime < dur) resetTime = dur;
11405                } else {
11406                    Slog.w(TAG, "Canceling start item " + si.intent + " in service "
11407                            + r.name);
11408                    canceled = true;
11409                }
11410            }
11411            r.deliveredStarts.clear();
11412        }
11413
11414        r.totalRestartCount++;
11415        if (r.restartDelay == 0) {
11416            r.restartCount++;
11417            r.restartDelay = minDuration;
11418        } else {
11419            // If it has been a "reasonably long time" since the service
11420            // was started, then reset our restart duration back to
11421            // the beginning, so we don't infinitely increase the duration
11422            // on a service that just occasionally gets killed (which is
11423            // a normal case, due to process being killed to reclaim memory).
11424            if (now > (r.restartTime+resetTime)) {
11425                r.restartCount = 1;
11426                r.restartDelay = minDuration;
11427            } else {
11428                if ((r.serviceInfo.applicationInfo.flags
11429                        &ApplicationInfo.FLAG_PERSISTENT) != 0) {
11430                    // Services in peristent processes will restart much more
11431                    // quickly, since they are pretty important.  (Think SystemUI).
11432                    r.restartDelay += minDuration/2;
11433                } else {
11434                    r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
11435                    if (r.restartDelay < minDuration) {
11436                        r.restartDelay = minDuration;
11437                    }
11438                }
11439            }
11440        }
11441
11442        r.nextRestartTime = now + r.restartDelay;
11443
11444        // Make sure that we don't end up restarting a bunch of services
11445        // all at the same time.
11446        boolean repeat;
11447        do {
11448            repeat = false;
11449            for (int i=mRestartingServices.size()-1; i>=0; i--) {
11450                ServiceRecord r2 = mRestartingServices.get(i);
11451                if (r2 != r && r.nextRestartTime
11452                        >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
11453                        && r.nextRestartTime
11454                        < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
11455                    r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
11456                    r.restartDelay = r.nextRestartTime - now;
11457                    repeat = true;
11458                    break;
11459                }
11460            }
11461        } while (repeat);
11462
11463        if (!mRestartingServices.contains(r)) {
11464            mRestartingServices.add(r);
11465        }
11466
11467        r.cancelNotification();
11468
11469        mHandler.removeCallbacks(r.restarter);
11470        mHandler.postAtTime(r.restarter, r.nextRestartTime);
11471        r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
11472        Slog.w(TAG, "Scheduling restart of crashed service "
11473                + r.shortName + " in " + r.restartDelay + "ms");
11474        EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
11475                r.shortName, r.restartDelay);
11476
11477        return canceled;
11478    }
11479
11480    final void performServiceRestartLocked(ServiceRecord r) {
11481        if (!mRestartingServices.contains(r)) {
11482            return;
11483        }
11484        bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
11485    }
11486
11487    private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
11488        if (r.restartDelay == 0) {
11489            return false;
11490        }
11491        r.resetRestartCounter();
11492        mRestartingServices.remove(r);
11493        mHandler.removeCallbacks(r.restarter);
11494        return true;
11495    }
11496
11497    private final boolean bringUpServiceLocked(ServiceRecord r,
11498            int intentFlags, boolean whileRestarting) {
11499        //Slog.i(TAG, "Bring up service:");
11500        //r.dump("  ");
11501
11502        if (r.app != null && r.app.thread != null) {
11503            sendServiceArgsLocked(r, false);
11504            return true;
11505        }
11506
11507        if (!whileRestarting && r.restartDelay > 0) {
11508            // If waiting for a restart, then do nothing.
11509            return true;
11510        }
11511
11512        if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
11513
11514        // We are now bringing the service up, so no longer in the
11515        // restarting state.
11516        mRestartingServices.remove(r);
11517
11518        // Service is now being launched, its package can't be stopped.
11519        try {
11520            AppGlobals.getPackageManager().setPackageStoppedState(
11521                    r.packageName, false, r.userId);
11522        } catch (RemoteException e) {
11523        } catch (IllegalArgumentException e) {
11524            Slog.w(TAG, "Failed trying to unstop package "
11525                    + r.packageName + ": " + e);
11526        }
11527
11528        final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
11529        final String appName = r.processName;
11530        ProcessRecord app;
11531
11532        if (!isolated) {
11533            app = getProcessRecordLocked(appName, r.appInfo.uid);
11534            if (DEBUG_MU)
11535                Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + " app=" + app);
11536            if (app != null && app.thread != null) {
11537                try {
11538                    app.addPackage(r.appInfo.packageName);
11539                    realStartServiceLocked(r, app);
11540                    return true;
11541                } catch (RemoteException e) {
11542                    Slog.w(TAG, "Exception when starting service " + r.shortName, e);
11543                }
11544
11545                // If a dead object exception was thrown -- fall through to
11546                // restart the application.
11547            }
11548        } else {
11549            // If this service runs in an isolated process, then each time
11550            // we call startProcessLocked() we will get a new isolated
11551            // process, starting another process if we are currently waiting
11552            // for a previous process to come up.  To deal with this, we store
11553            // in the service any current isolated process it is running in or
11554            // waiting to have come up.
11555            app = r.isolatedProc;
11556        }
11557
11558        // Not running -- get it started, and enqueue this service record
11559        // to be executed when the app comes up.
11560        if (app == null) {
11561            if ((app=startProcessLocked(appName, r.appInfo, true, intentFlags,
11562                    "service", r.name, false, isolated)) == null) {
11563                Slog.w(TAG, "Unable to launch app "
11564                        + r.appInfo.packageName + "/"
11565                        + r.appInfo.uid + " for service "
11566                        + r.intent.getIntent() + ": process is bad");
11567                bringDownServiceLocked(r, true);
11568                return false;
11569            }
11570            if (isolated) {
11571                r.isolatedProc = app;
11572            }
11573        }
11574
11575        if (!mPendingServices.contains(r)) {
11576            mPendingServices.add(r);
11577        }
11578
11579        return true;
11580    }
11581
11582    private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
11583        //Slog.i(TAG, "Bring down service:");
11584        //r.dump("  ");
11585
11586        // Does it still need to run?
11587        if (!force && r.startRequested) {
11588            return;
11589        }
11590        if (r.connections.size() > 0) {
11591            if (!force) {
11592                // XXX should probably keep a count of the number of auto-create
11593                // connections directly in the service.
11594                Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
11595                while (it.hasNext()) {
11596                    ArrayList<ConnectionRecord> cr = it.next();
11597                    for (int i=0; i<cr.size(); i++) {
11598                        if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
11599                            return;
11600                        }
11601                    }
11602                }
11603            }
11604
11605            // Report to all of the connections that the service is no longer
11606            // available.
11607            Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
11608            while (it.hasNext()) {
11609                ArrayList<ConnectionRecord> c = it.next();
11610                for (int i=0; i<c.size(); i++) {
11611                    ConnectionRecord cr = c.get(i);
11612                    // There is still a connection to the service that is
11613                    // being brought down.  Mark it as dead.
11614                    cr.serviceDead = true;
11615                    try {
11616                        cr.conn.connected(r.name, null);
11617                    } catch (Exception e) {
11618                        Slog.w(TAG, "Failure disconnecting service " + r.name +
11619                              " to connection " + c.get(i).conn.asBinder() +
11620                              " (in " + c.get(i).binding.client.processName + ")", e);
11621                    }
11622                }
11623            }
11624        }
11625
11626        // Tell the service that it has been unbound.
11627        if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
11628            Iterator<IntentBindRecord> it = r.bindings.values().iterator();
11629            while (it.hasNext()) {
11630                IntentBindRecord ibr = it.next();
11631                if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
11632                        + ": hasBound=" + ibr.hasBound);
11633                if (r.app != null && r.app.thread != null && ibr.hasBound) {
11634                    try {
11635                        bumpServiceExecutingLocked(r, "bring down unbind");
11636                        updateOomAdjLocked(r.app);
11637                        ibr.hasBound = false;
11638                        r.app.thread.scheduleUnbindService(r,
11639                                ibr.intent.getIntent());
11640                    } catch (Exception e) {
11641                        Slog.w(TAG, "Exception when unbinding service "
11642                                + r.shortName, e);
11643                        serviceDoneExecutingLocked(r, true);
11644                    }
11645                }
11646            }
11647        }
11648
11649        if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
11650        EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
11651                System.identityHashCode(r), r.shortName,
11652                (r.app != null) ? r.app.pid : -1);
11653
11654        mServiceMap.removeServiceByName(r.name, r.userId);
11655        mServiceMap.removeServiceByIntent(r.intent, r.userId);
11656        r.totalRestartCount = 0;
11657        unscheduleServiceRestartLocked(r);
11658
11659        // Also make sure it is not on the pending list.
11660        int N = mPendingServices.size();
11661        for (int i=0; i<N; i++) {
11662            if (mPendingServices.get(i) == r) {
11663                mPendingServices.remove(i);
11664                if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
11665                i--;
11666                N--;
11667            }
11668        }
11669
11670        r.cancelNotification();
11671        r.isForeground = false;
11672        r.foregroundId = 0;
11673        r.foregroundNoti = null;
11674
11675        // Clear start entries.
11676        r.clearDeliveredStartsLocked();
11677        r.pendingStarts.clear();
11678
11679        if (r.app != null) {
11680            synchronized (r.stats.getBatteryStats()) {
11681                r.stats.stopLaunchedLocked();
11682            }
11683            r.app.services.remove(r);
11684            if (r.app.thread != null) {
11685                try {
11686                    bumpServiceExecutingLocked(r, "stop");
11687                    mStoppingServices.add(r);
11688                    updateOomAdjLocked(r.app);
11689                    r.app.thread.scheduleStopService(r);
11690                } catch (Exception e) {
11691                    Slog.w(TAG, "Exception when stopping service "
11692                            + r.shortName, e);
11693                    serviceDoneExecutingLocked(r, true);
11694                }
11695                updateServiceForegroundLocked(r.app, false);
11696            } else {
11697                if (DEBUG_SERVICE) Slog.v(
11698                    TAG, "Removed service that has no process: " + r);
11699            }
11700        } else {
11701            if (DEBUG_SERVICE) Slog.v(
11702                TAG, "Removed service that is not running: " + r);
11703        }
11704
11705        if (r.bindings.size() > 0) {
11706            r.bindings.clear();
11707        }
11708
11709        if (r.restarter instanceof ServiceRestarter) {
11710           ((ServiceRestarter)r.restarter).setService(null);
11711        }
11712    }
11713
11714    ComponentName startServiceLocked(IApplicationThread caller,
11715            Intent service, String resolvedType,
11716            int callingPid, int callingUid) {
11717        synchronized(this) {
11718            if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
11719                    + " type=" + resolvedType + " args=" + service.getExtras());
11720
11721            if (caller != null) {
11722                final ProcessRecord callerApp = getRecordForAppLocked(caller);
11723                if (callerApp == null) {
11724                    throw new SecurityException(
11725                            "Unable to find app for caller " + caller
11726                            + " (pid=" + Binder.getCallingPid()
11727                            + ") when starting service " + service);
11728                }
11729            }
11730
11731            ServiceLookupResult res =
11732                retrieveServiceLocked(service, resolvedType,
11733                        callingPid, callingUid, UserId.getUserId(callingUid));
11734            if (res == null) {
11735                return null;
11736            }
11737            if (res.record == null) {
11738                return new ComponentName("!", res.permission != null
11739                        ? res.permission : "private to package");
11740            }
11741            ServiceRecord r = res.record;
11742            NeededUriGrants neededGrants = checkGrantUriPermissionFromIntentLocked(
11743                    callingUid, r.packageName, service, service.getFlags(), null);
11744            if (unscheduleServiceRestartLocked(r)) {
11745                if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
11746            }
11747            r.startRequested = true;
11748            r.callStart = false;
11749            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
11750                    service, neededGrants));
11751            r.lastActivity = SystemClock.uptimeMillis();
11752            synchronized (r.stats.getBatteryStats()) {
11753                r.stats.startRunningLocked();
11754            }
11755            if (!bringUpServiceLocked(r, service.getFlags(), false)) {
11756                return new ComponentName("!", "Service process is bad");
11757            }
11758            return r.name;
11759        }
11760    }
11761
11762    public ComponentName startService(IApplicationThread caller, Intent service,
11763            String resolvedType) {
11764        enforceNotIsolatedCaller("startService");
11765        // Refuse possible leaked file descriptors
11766        if (service != null && service.hasFileDescriptors() == true) {
11767            throw new IllegalArgumentException("File descriptors passed in Intent");
11768        }
11769
11770        if (DEBUG_SERVICE)
11771            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
11772        synchronized(this) {
11773            final int callingPid = Binder.getCallingPid();
11774            final int callingUid = Binder.getCallingUid();
11775            final long origId = Binder.clearCallingIdentity();
11776            ComponentName res = startServiceLocked(caller, service,
11777                    resolvedType, callingPid, callingUid);
11778            Binder.restoreCallingIdentity(origId);
11779            return res;
11780        }
11781    }
11782
11783    ComponentName startServiceInPackage(int uid,
11784            Intent service, String resolvedType) {
11785        synchronized(this) {
11786            if (DEBUG_SERVICE)
11787                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
11788            final long origId = Binder.clearCallingIdentity();
11789            ComponentName res = startServiceLocked(null, service,
11790                    resolvedType, -1, uid);
11791            Binder.restoreCallingIdentity(origId);
11792            return res;
11793        }
11794    }
11795
11796    private void stopServiceLocked(ServiceRecord service) {
11797        synchronized (service.stats.getBatteryStats()) {
11798            service.stats.stopRunningLocked();
11799        }
11800        service.startRequested = false;
11801        service.callStart = false;
11802        bringDownServiceLocked(service, false);
11803    }
11804
11805    public int stopService(IApplicationThread caller, Intent service,
11806            String resolvedType) {
11807        enforceNotIsolatedCaller("stopService");
11808        // Refuse possible leaked file descriptors
11809        if (service != null && service.hasFileDescriptors() == true) {
11810            throw new IllegalArgumentException("File descriptors passed in Intent");
11811        }
11812
11813        synchronized(this) {
11814            if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
11815                    + " type=" + resolvedType);
11816
11817            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11818            if (caller != null && callerApp == null) {
11819                throw new SecurityException(
11820                        "Unable to find app for caller " + caller
11821                        + " (pid=" + Binder.getCallingPid()
11822                        + ") when stopping service " + service);
11823            }
11824
11825            // If this service is active, make sure it is stopped.
11826            ServiceLookupResult r = findServiceLocked(service, resolvedType,
11827                    callerApp == null ? UserId.getCallingUserId() : callerApp.userId);
11828            if (r != null) {
11829                if (r.record != null) {
11830                    final long origId = Binder.clearCallingIdentity();
11831                    try {
11832                        stopServiceLocked(r.record);
11833                    } finally {
11834                        Binder.restoreCallingIdentity(origId);
11835                    }
11836                    return 1;
11837                }
11838                return -1;
11839            }
11840        }
11841
11842        return 0;
11843    }
11844
11845    public IBinder peekService(Intent service, String resolvedType) {
11846        enforceNotIsolatedCaller("peekService");
11847        // Refuse possible leaked file descriptors
11848        if (service != null && service.hasFileDescriptors() == true) {
11849            throw new IllegalArgumentException("File descriptors passed in Intent");
11850        }
11851
11852        IBinder ret = null;
11853
11854        synchronized(this) {
11855            ServiceLookupResult r = findServiceLocked(service, resolvedType,
11856                    UserId.getCallingUserId());
11857
11858            if (r != null) {
11859                // r.record is null if findServiceLocked() failed the caller permission check
11860                if (r.record == null) {
11861                    throw new SecurityException(
11862                            "Permission Denial: Accessing service " + r.record.name
11863                            + " from pid=" + Binder.getCallingPid()
11864                            + ", uid=" + Binder.getCallingUid()
11865                            + " requires " + r.permission);
11866                }
11867                IntentBindRecord ib = r.record.bindings.get(r.record.intent);
11868                if (ib != null) {
11869                    ret = ib.binder;
11870                }
11871            }
11872        }
11873
11874        return ret;
11875    }
11876
11877    public boolean stopServiceToken(ComponentName className, IBinder token,
11878            int startId) {
11879        synchronized(this) {
11880            if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
11881                    + " " + token + " startId=" + startId);
11882            ServiceRecord r = findServiceLocked(className, token);
11883            if (r != null) {
11884                if (startId >= 0) {
11885                    // Asked to only stop if done with all work.  Note that
11886                    // to avoid leaks, we will take this as dropping all
11887                    // start items up to and including this one.
11888                    ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11889                    if (si != null) {
11890                        while (r.deliveredStarts.size() > 0) {
11891                            ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
11892                            cur.removeUriPermissionsLocked();
11893                            if (cur == si) {
11894                                break;
11895                            }
11896                        }
11897                    }
11898
11899                    if (r.getLastStartId() != startId) {
11900                        return false;
11901                    }
11902
11903                    if (r.deliveredStarts.size() > 0) {
11904                        Slog.w(TAG, "stopServiceToken startId " + startId
11905                                + " is last, but have " + r.deliveredStarts.size()
11906                                + " remaining args");
11907                    }
11908                }
11909
11910                synchronized (r.stats.getBatteryStats()) {
11911                    r.stats.stopRunningLocked();
11912                    r.startRequested = false;
11913                    r.callStart = false;
11914                }
11915                final long origId = Binder.clearCallingIdentity();
11916                bringDownServiceLocked(r, false);
11917                Binder.restoreCallingIdentity(origId);
11918                return true;
11919            }
11920        }
11921        return false;
11922    }
11923
11924    public void setServiceForeground(ComponentName className, IBinder token,
11925            int id, Notification notification, boolean removeNotification) {
11926        final long origId = Binder.clearCallingIdentity();
11927        try {
11928        synchronized(this) {
11929            ServiceRecord r = findServiceLocked(className, token);
11930            if (r != null) {
11931                if (id != 0) {
11932                    if (notification == null) {
11933                        throw new IllegalArgumentException("null notification");
11934                    }
11935                    if (r.foregroundId != id) {
11936                        r.cancelNotification();
11937                        r.foregroundId = id;
11938                    }
11939                    notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
11940                    r.foregroundNoti = notification;
11941                    r.isForeground = true;
11942                    r.postNotification();
11943                    if (r.app != null) {
11944                        updateServiceForegroundLocked(r.app, true);
11945                    }
11946                } else {
11947                    if (r.isForeground) {
11948                        r.isForeground = false;
11949                        if (r.app != null) {
11950                            updateLruProcessLocked(r.app, false, true);
11951                            updateServiceForegroundLocked(r.app, true);
11952                        }
11953                    }
11954                    if (removeNotification) {
11955                        r.cancelNotification();
11956                        r.foregroundId = 0;
11957                        r.foregroundNoti = null;
11958                    }
11959                }
11960            }
11961        }
11962        } finally {
11963            Binder.restoreCallingIdentity(origId);
11964        }
11965    }
11966
11967    public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
11968        boolean anyForeground = false;
11969        for (ServiceRecord sr : proc.services) {
11970            if (sr.isForeground) {
11971                anyForeground = true;
11972                break;
11973            }
11974        }
11975        if (anyForeground != proc.foregroundServices) {
11976            proc.foregroundServices = anyForeground;
11977            if (oomAdj) {
11978                updateOomAdjLocked();
11979            }
11980        }
11981    }
11982
11983    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo) {
11984        boolean result = false;
11985        if (UserId.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
11986            result = false;
11987        } else if (componentProcessName == aInfo.packageName) {
11988            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
11989        } else if ("system".equals(componentProcessName)) {
11990            result = true;
11991        }
11992        if (DEBUG_MU) {
11993            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo + ") = " + result);
11994        }
11995        return result;
11996    }
11997
11998    public int bindService(IApplicationThread caller, IBinder token,
11999            Intent service, String resolvedType,
12000            IServiceConnection connection, int flags, int userId) {
12001        enforceNotIsolatedCaller("bindService");
12002        // Refuse possible leaked file descriptors
12003        if (service != null && service.hasFileDescriptors() == true) {
12004            throw new IllegalArgumentException("File descriptors passed in Intent");
12005        }
12006
12007        checkValidCaller(Binder.getCallingUid(), userId);
12008
12009        synchronized(this) {
12010            if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
12011                    + " type=" + resolvedType + " conn=" + connection.asBinder()
12012                    + " flags=0x" + Integer.toHexString(flags));
12013            if (DEBUG_MU)
12014                Slog.i(TAG_MU, "bindService uid=" + Binder.getCallingUid() + " origUid="
12015                        + Binder.getOrigCallingUid());
12016            final ProcessRecord callerApp = getRecordForAppLocked(caller);
12017            if (callerApp == null) {
12018                throw new SecurityException(
12019                        "Unable to find app for caller " + caller
12020                        + " (pid=" + Binder.getCallingPid()
12021                        + ") when binding service " + service);
12022            }
12023
12024            ActivityRecord activity = null;
12025            if (token != null) {
12026                activity = mMainStack.isInStackLocked(token);
12027                if (activity == null) {
12028                    Slog.w(TAG, "Binding with unknown activity: " + token);
12029                    return 0;
12030                }
12031            }
12032
12033            int clientLabel = 0;
12034            PendingIntent clientIntent = null;
12035
12036            if (callerApp.info.uid == Process.SYSTEM_UID) {
12037                // Hacky kind of thing -- allow system stuff to tell us
12038                // what they are, so we can report this elsewhere for
12039                // others to know why certain services are running.
12040                try {
12041                    clientIntent = (PendingIntent)service.getParcelableExtra(
12042                            Intent.EXTRA_CLIENT_INTENT);
12043                } catch (RuntimeException e) {
12044                }
12045                if (clientIntent != null) {
12046                    clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
12047                    if (clientLabel != 0) {
12048                        // There are no useful extras in the intent, trash them.
12049                        // System code calling with this stuff just needs to know
12050                        // this will happen.
12051                        service = service.cloneFilter();
12052                    }
12053                }
12054            }
12055
12056            ServiceLookupResult res =
12057                retrieveServiceLocked(service, resolvedType,
12058                        Binder.getCallingPid(), Binder.getCallingUid(), userId);
12059            if (res == null) {
12060                return 0;
12061            }
12062            if (res.record == null) {
12063                return -1;
12064            }
12065            if (isSingleton(res.record.processName, res.record.appInfo)) {
12066                userId = 0;
12067                res = retrieveServiceLocked(service, resolvedType, Binder.getCallingPid(),
12068                        Binder.getCallingUid(), 0);
12069            }
12070            ServiceRecord s = res.record;
12071
12072            final long origId = Binder.clearCallingIdentity();
12073
12074            if (unscheduleServiceRestartLocked(s)) {
12075                if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
12076                        + s);
12077            }
12078
12079            AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
12080            ConnectionRecord c = new ConnectionRecord(b, activity,
12081                    connection, flags, clientLabel, clientIntent);
12082
12083            IBinder binder = connection.asBinder();
12084            ArrayList<ConnectionRecord> clist = s.connections.get(binder);
12085            if (clist == null) {
12086                clist = new ArrayList<ConnectionRecord>();
12087                s.connections.put(binder, clist);
12088            }
12089            clist.add(c);
12090            b.connections.add(c);
12091            if (activity != null) {
12092                if (activity.connections == null) {
12093                    activity.connections = new HashSet<ConnectionRecord>();
12094                }
12095                activity.connections.add(c);
12096            }
12097            b.client.connections.add(c);
12098            if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
12099                b.client.hasAboveClient = true;
12100            }
12101            clist = mServiceConnections.get(binder);
12102            if (clist == null) {
12103                clist = new ArrayList<ConnectionRecord>();
12104                mServiceConnections.put(binder, clist);
12105            }
12106            clist.add(c);
12107
12108            if ((flags&Context.BIND_AUTO_CREATE) != 0) {
12109                s.lastActivity = SystemClock.uptimeMillis();
12110                if (!bringUpServiceLocked(s, service.getFlags(), false)) {
12111                    return 0;
12112                }
12113            }
12114
12115            if (s.app != null) {
12116                // This could have made the service more important.
12117                updateOomAdjLocked(s.app);
12118            }
12119
12120            if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
12121                    + ": received=" + b.intent.received
12122                    + " apps=" + b.intent.apps.size()
12123                    + " doRebind=" + b.intent.doRebind);
12124
12125            if (s.app != null && b.intent.received) {
12126                // Service is already running, so we can immediately
12127                // publish the connection.
12128                try {
12129                    c.conn.connected(s.name, b.intent.binder);
12130                } catch (Exception e) {
12131                    Slog.w(TAG, "Failure sending service " + s.shortName
12132                            + " to connection " + c.conn.asBinder()
12133                            + " (in " + c.binding.client.processName + ")", e);
12134                }
12135
12136                // If this is the first app connected back to this binding,
12137                // and the service had previously asked to be told when
12138                // rebound, then do so.
12139                if (b.intent.apps.size() == 1 && b.intent.doRebind) {
12140                    requestServiceBindingLocked(s, b.intent, true);
12141                }
12142            } else if (!b.intent.requested) {
12143                requestServiceBindingLocked(s, b.intent, false);
12144            }
12145
12146            Binder.restoreCallingIdentity(origId);
12147        }
12148
12149        return 1;
12150    }
12151
12152    void removeConnectionLocked(
12153        ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
12154        IBinder binder = c.conn.asBinder();
12155        AppBindRecord b = c.binding;
12156        ServiceRecord s = b.service;
12157        ArrayList<ConnectionRecord> clist = s.connections.get(binder);
12158        if (clist != null) {
12159            clist.remove(c);
12160            if (clist.size() == 0) {
12161                s.connections.remove(binder);
12162            }
12163        }
12164        b.connections.remove(c);
12165        if (c.activity != null && c.activity != skipAct) {
12166            if (c.activity.connections != null) {
12167                c.activity.connections.remove(c);
12168            }
12169        }
12170        if (b.client != skipApp) {
12171            b.client.connections.remove(c);
12172            if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
12173                b.client.updateHasAboveClientLocked();
12174            }
12175        }
12176        clist = mServiceConnections.get(binder);
12177        if (clist != null) {
12178            clist.remove(c);
12179            if (clist.size() == 0) {
12180                mServiceConnections.remove(binder);
12181            }
12182        }
12183
12184        if (b.connections.size() == 0) {
12185            b.intent.apps.remove(b.client);
12186        }
12187
12188        if (!c.serviceDead) {
12189            if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
12190                    + ": shouldUnbind=" + b.intent.hasBound);
12191            if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
12192                    && b.intent.hasBound) {
12193                try {
12194                    bumpServiceExecutingLocked(s, "unbind");
12195                    updateOomAdjLocked(s.app);
12196                    b.intent.hasBound = false;
12197                    // Assume the client doesn't want to know about a rebind;
12198                    // we will deal with that later if it asks for one.
12199                    b.intent.doRebind = false;
12200                    s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
12201                } catch (Exception e) {
12202                    Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
12203                    serviceDoneExecutingLocked(s, true);
12204                }
12205            }
12206
12207            if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
12208                bringDownServiceLocked(s, false);
12209            }
12210        }
12211    }
12212
12213    public boolean unbindService(IServiceConnection connection) {
12214        synchronized (this) {
12215            IBinder binder = connection.asBinder();
12216            if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
12217            ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
12218            if (clist == null) {
12219                Slog.w(TAG, "Unbind failed: could not find connection for "
12220                      + connection.asBinder());
12221                return false;
12222            }
12223
12224            final long origId = Binder.clearCallingIdentity();
12225
12226            while (clist.size() > 0) {
12227                ConnectionRecord r = clist.get(0);
12228                removeConnectionLocked(r, null, null);
12229
12230                if (r.binding.service.app != null) {
12231                    // This could have made the service less important.
12232                    updateOomAdjLocked(r.binding.service.app);
12233                }
12234            }
12235
12236            Binder.restoreCallingIdentity(origId);
12237        }
12238
12239        return true;
12240    }
12241
12242    public void publishService(IBinder token, Intent intent, IBinder service) {
12243        // Refuse possible leaked file descriptors
12244        if (intent != null && intent.hasFileDescriptors() == true) {
12245            throw new IllegalArgumentException("File descriptors passed in Intent");
12246        }
12247
12248        synchronized(this) {
12249            if (!(token instanceof ServiceRecord)) {
12250                throw new IllegalArgumentException("Invalid service token");
12251            }
12252            ServiceRecord r = (ServiceRecord)token;
12253
12254            final long origId = Binder.clearCallingIdentity();
12255
12256            if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
12257                    + " " + intent + ": " + service);
12258            if (r != null) {
12259                Intent.FilterComparison filter
12260                        = new Intent.FilterComparison(intent);
12261                IntentBindRecord b = r.bindings.get(filter);
12262                if (b != null && !b.received) {
12263                    b.binder = service;
12264                    b.requested = true;
12265                    b.received = true;
12266                    if (r.connections.size() > 0) {
12267                        Iterator<ArrayList<ConnectionRecord>> it
12268                                = r.connections.values().iterator();
12269                        while (it.hasNext()) {
12270                            ArrayList<ConnectionRecord> clist = it.next();
12271                            for (int i=0; i<clist.size(); i++) {
12272                                ConnectionRecord c = clist.get(i);
12273                                if (!filter.equals(c.binding.intent.intent)) {
12274                                    if (DEBUG_SERVICE) Slog.v(
12275                                            TAG, "Not publishing to: " + c);
12276                                    if (DEBUG_SERVICE) Slog.v(
12277                                            TAG, "Bound intent: " + c.binding.intent.intent);
12278                                    if (DEBUG_SERVICE) Slog.v(
12279                                            TAG, "Published intent: " + intent);
12280                                    continue;
12281                                }
12282                                if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
12283                                try {
12284                                    c.conn.connected(r.name, service);
12285                                } catch (Exception e) {
12286                                    Slog.w(TAG, "Failure sending service " + r.name +
12287                                          " to connection " + c.conn.asBinder() +
12288                                          " (in " + c.binding.client.processName + ")", e);
12289                                }
12290                            }
12291                        }
12292                    }
12293                }
12294
12295                serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
12296
12297                Binder.restoreCallingIdentity(origId);
12298            }
12299        }
12300    }
12301
12302    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12303        // Refuse possible leaked file descriptors
12304        if (intent != null && intent.hasFileDescriptors() == true) {
12305            throw new IllegalArgumentException("File descriptors passed in Intent");
12306        }
12307
12308        synchronized(this) {
12309            if (!(token instanceof ServiceRecord)) {
12310                throw new IllegalArgumentException("Invalid service token");
12311            }
12312            ServiceRecord r = (ServiceRecord)token;
12313
12314            final long origId = Binder.clearCallingIdentity();
12315
12316            if (r != null) {
12317                Intent.FilterComparison filter
12318                        = new Intent.FilterComparison(intent);
12319                IntentBindRecord b = r.bindings.get(filter);
12320                if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
12321                        + " at " + b + ": apps="
12322                        + (b != null ? b.apps.size() : 0));
12323
12324                boolean inStopping = mStoppingServices.contains(r);
12325                if (b != null) {
12326                    if (b.apps.size() > 0 && !inStopping) {
12327                        // Applications have already bound since the last
12328                        // unbind, so just rebind right here.
12329                        requestServiceBindingLocked(r, b, true);
12330                    } else {
12331                        // Note to tell the service the next time there is
12332                        // a new client.
12333                        b.doRebind = true;
12334                    }
12335                }
12336
12337                serviceDoneExecutingLocked(r, inStopping);
12338
12339                Binder.restoreCallingIdentity(origId);
12340            }
12341        }
12342    }
12343
12344    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12345        synchronized(this) {
12346            if (!(token instanceof ServiceRecord)) {
12347                throw new IllegalArgumentException("Invalid service token");
12348            }
12349            ServiceRecord r = (ServiceRecord)token;
12350            boolean inStopping = mStoppingServices.contains(token);
12351            if (r != null) {
12352                if (r != token) {
12353                    Slog.w(TAG, "Done executing service " + r.name
12354                          + " with incorrect token: given " + token
12355                          + ", expected " + r);
12356                    return;
12357                }
12358
12359                if (type == 1) {
12360                    // This is a call from a service start...  take care of
12361                    // book-keeping.
12362                    r.callStart = true;
12363                    switch (res) {
12364                        case Service.START_STICKY_COMPATIBILITY:
12365                        case Service.START_STICKY: {
12366                            // We are done with the associated start arguments.
12367                            r.findDeliveredStart(startId, true);
12368                            // Don't stop if killed.
12369                            r.stopIfKilled = false;
12370                            break;
12371                        }
12372                        case Service.START_NOT_STICKY: {
12373                            // We are done with the associated start arguments.
12374                            r.findDeliveredStart(startId, true);
12375                            if (r.getLastStartId() == startId) {
12376                                // There is no more work, and this service
12377                                // doesn't want to hang around if killed.
12378                                r.stopIfKilled = true;
12379                            }
12380                            break;
12381                        }
12382                        case Service.START_REDELIVER_INTENT: {
12383                            // We'll keep this item until they explicitly
12384                            // call stop for it, but keep track of the fact
12385                            // that it was delivered.
12386                            ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
12387                            if (si != null) {
12388                                si.deliveryCount = 0;
12389                                si.doneExecutingCount++;
12390                                // Don't stop if killed.
12391                                r.stopIfKilled = true;
12392                            }
12393                            break;
12394                        }
12395                        case Service.START_TASK_REMOVED_COMPLETE: {
12396                            // Special processing for onTaskRemoved().  Don't
12397                            // impact normal onStartCommand() processing.
12398                            r.findDeliveredStart(startId, true);
12399                            break;
12400                        }
12401                        default:
12402                            throw new IllegalArgumentException(
12403                                    "Unknown service start result: " + res);
12404                    }
12405                    if (res == Service.START_STICKY_COMPATIBILITY) {
12406                        r.callStart = false;
12407                    }
12408                }
12409                if (DEBUG_MU)
12410                    Slog.v(TAG_MU, "before serviceDontExecutingLocked, uid="
12411                            + Binder.getOrigCallingUid());
12412                final long origId = Binder.clearCallingIdentity();
12413                serviceDoneExecutingLocked(r, inStopping);
12414                Binder.restoreCallingIdentity(origId);
12415            } else {
12416                Slog.w(TAG, "Done executing unknown service from pid "
12417                        + Binder.getCallingPid());
12418            }
12419        }
12420    }
12421
12422    public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
12423        if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
12424                + ": nesting=" + r.executeNesting
12425                + ", inStopping=" + inStopping + ", app=" + r.app);
12426        else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
12427        r.executeNesting--;
12428        if (r.executeNesting <= 0 && r.app != null) {
12429            if (DEBUG_SERVICE) Slog.v(TAG,
12430                    "Nesting at 0 of " + r.shortName);
12431            r.app.executingServices.remove(r);
12432            if (r.app.executingServices.size() == 0) {
12433                if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
12434                        "No more executingServices of " + r.shortName);
12435                mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
12436            }
12437            if (inStopping) {
12438                if (DEBUG_SERVICE) Slog.v(TAG,
12439                        "doneExecuting remove stopping " + r);
12440                mStoppingServices.remove(r);
12441                r.bindings.clear();
12442            }
12443            updateOomAdjLocked(r.app);
12444        }
12445    }
12446
12447    void serviceTimeout(ProcessRecord proc) {
12448        String anrMessage = null;
12449
12450        synchronized(this) {
12451            if (proc.executingServices.size() == 0 || proc.thread == null) {
12452                return;
12453            }
12454            long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
12455            Iterator<ServiceRecord> it = proc.executingServices.iterator();
12456            ServiceRecord timeout = null;
12457            long nextTime = 0;
12458            while (it.hasNext()) {
12459                ServiceRecord sr = it.next();
12460                if (sr.executingStart < maxTime) {
12461                    timeout = sr;
12462                    break;
12463                }
12464                if (sr.executingStart > nextTime) {
12465                    nextTime = sr.executingStart;
12466                }
12467            }
12468            if (timeout != null && mLruProcesses.contains(proc)) {
12469                Slog.w(TAG, "Timeout executing service: " + timeout);
12470                anrMessage = "Executing service " + timeout.shortName;
12471            } else {
12472                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
12473                msg.obj = proc;
12474                mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
12475            }
12476        }
12477
12478        if (anrMessage != null) {
12479            appNotResponding(proc, null, null, anrMessage);
12480        }
12481    }
12482
12483    // =========================================================
12484    // BACKUP AND RESTORE
12485    // =========================================================
12486
12487    // Cause the target app to be launched if necessary and its backup agent
12488    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12489    // activity manager to announce its creation.
12490    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12491        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
12492        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
12493
12494        synchronized(this) {
12495            // !!! TODO: currently no check here that we're already bound
12496            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12497            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12498            synchronized (stats) {
12499                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12500            }
12501
12502            // Backup agent is now in use, its package can't be stopped.
12503            try {
12504                AppGlobals.getPackageManager().setPackageStoppedState(
12505                        app.packageName, false, UserId.getUserId(app.uid));
12506            } catch (RemoteException e) {
12507            } catch (IllegalArgumentException e) {
12508                Slog.w(TAG, "Failed trying to unstop package "
12509                        + app.packageName + ": " + e);
12510            }
12511
12512            BackupRecord r = new BackupRecord(ss, app, backupMode);
12513            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12514                    ? new ComponentName(app.packageName, app.backupAgentName)
12515                    : new ComponentName("android", "FullBackupAgent");
12516            // startProcessLocked() returns existing proc's record if it's already running
12517            ProcessRecord proc = startProcessLocked(app.processName, app,
12518                    false, 0, "backup", hostingName, false, false);
12519            if (proc == null) {
12520                Slog.e(TAG, "Unable to start backup agent process " + r);
12521                return false;
12522            }
12523
12524            r.app = proc;
12525            mBackupTarget = r;
12526            mBackupAppName = app.packageName;
12527
12528            // Try not to kill the process during backup
12529            updateOomAdjLocked(proc);
12530
12531            // If the process is already attached, schedule the creation of the backup agent now.
12532            // If it is not yet live, this will be done when it attaches to the framework.
12533            if (proc.thread != null) {
12534                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12535                try {
12536                    proc.thread.scheduleCreateBackupAgent(app,
12537                            compatibilityInfoForPackageLocked(app), backupMode);
12538                } catch (RemoteException e) {
12539                    // Will time out on the backup manager side
12540                }
12541            } else {
12542                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
12543            }
12544            // Invariants: at this point, the target app process exists and the application
12545            // is either already running or in the process of coming up.  mBackupTarget and
12546            // mBackupAppName describe the app, so that when it binds back to the AM we
12547            // know that it's scheduled for a backup-agent operation.
12548        }
12549
12550        return true;
12551    }
12552
12553    // A backup agent has just come up
12554    public void backupAgentCreated(String agentPackageName, IBinder agent) {
12555        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
12556                + " = " + agent);
12557
12558        synchronized(this) {
12559            if (!agentPackageName.equals(mBackupAppName)) {
12560                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
12561                return;
12562            }
12563        }
12564
12565        long oldIdent = Binder.clearCallingIdentity();
12566        try {
12567            IBackupManager bm = IBackupManager.Stub.asInterface(
12568                    ServiceManager.getService(Context.BACKUP_SERVICE));
12569            bm.agentConnected(agentPackageName, agent);
12570        } catch (RemoteException e) {
12571            // can't happen; the backup manager service is local
12572        } catch (Exception e) {
12573            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12574            e.printStackTrace();
12575        } finally {
12576            Binder.restoreCallingIdentity(oldIdent);
12577        }
12578    }
12579
12580    // done with this agent
12581    public void unbindBackupAgent(ApplicationInfo appInfo) {
12582        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
12583        if (appInfo == null) {
12584            Slog.w(TAG, "unbind backup agent for null app");
12585            return;
12586        }
12587
12588        synchronized(this) {
12589            if (mBackupAppName == null) {
12590                Slog.w(TAG, "Unbinding backup agent with no active backup");
12591                return;
12592            }
12593
12594            if (!mBackupAppName.equals(appInfo.packageName)) {
12595                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
12596                return;
12597            }
12598
12599            ProcessRecord proc = mBackupTarget.app;
12600            mBackupTarget = null;
12601            mBackupAppName = null;
12602
12603            // Not backing this app up any more; reset its OOM adjustment
12604            updateOomAdjLocked(proc);
12605
12606            // If the app crashed during backup, 'thread' will be null here
12607            if (proc.thread != null) {
12608                try {
12609                    proc.thread.scheduleDestroyBackupAgent(appInfo,
12610                            compatibilityInfoForPackageLocked(appInfo));
12611                } catch (Exception e) {
12612                    Slog.e(TAG, "Exception when unbinding backup agent:");
12613                    e.printStackTrace();
12614                }
12615            }
12616        }
12617    }
12618    // =========================================================
12619    // BROADCASTS
12620    // =========================================================
12621
12622    private final List getStickiesLocked(String action, IntentFilter filter,
12623            List cur) {
12624        final ContentResolver resolver = mContext.getContentResolver();
12625        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
12626        if (list == null) {
12627            return cur;
12628        }
12629        int N = list.size();
12630        for (int i=0; i<N; i++) {
12631            Intent intent = list.get(i);
12632            if (filter.match(resolver, intent, true, TAG) >= 0) {
12633                if (cur == null) {
12634                    cur = new ArrayList<Intent>();
12635                }
12636                cur.add(intent);
12637            }
12638        }
12639        return cur;
12640    }
12641
12642    boolean isPendingBroadcastProcessLocked(int pid) {
12643        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12644                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12645    }
12646
12647    void skipPendingBroadcastLocked(int pid) {
12648            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12649            for (BroadcastQueue queue : mBroadcastQueues) {
12650                queue.skipPendingBroadcastLocked(pid);
12651            }
12652    }
12653
12654    // The app just attached; send any pending broadcasts that it should receive
12655    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12656        boolean didSomething = false;
12657        for (BroadcastQueue queue : mBroadcastQueues) {
12658            didSomething |= queue.sendPendingBroadcastsLocked(app);
12659        }
12660        return didSomething;
12661    }
12662
12663    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
12664            IIntentReceiver receiver, IntentFilter filter, String permission) {
12665        enforceNotIsolatedCaller("registerReceiver");
12666        synchronized(this) {
12667            ProcessRecord callerApp = null;
12668            if (caller != null) {
12669                callerApp = getRecordForAppLocked(caller);
12670                if (callerApp == null) {
12671                    throw new SecurityException(
12672                            "Unable to find app for caller " + caller
12673                            + " (pid=" + Binder.getCallingPid()
12674                            + ") when registering receiver " + receiver);
12675                }
12676                if (callerApp.info.uid != Process.SYSTEM_UID &&
12677                        !callerApp.pkgList.contains(callerPackage)) {
12678                    throw new SecurityException("Given caller package " + callerPackage
12679                            + " is not running in process " + callerApp);
12680                }
12681            } else {
12682                callerPackage = null;
12683            }
12684
12685            List allSticky = null;
12686
12687            // Look for any matching sticky broadcasts...
12688            Iterator actions = filter.actionsIterator();
12689            if (actions != null) {
12690                while (actions.hasNext()) {
12691                    String action = (String)actions.next();
12692                    allSticky = getStickiesLocked(action, filter, allSticky);
12693                }
12694            } else {
12695                allSticky = getStickiesLocked(null, filter, allSticky);
12696            }
12697
12698            // The first sticky in the list is returned directly back to
12699            // the client.
12700            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
12701
12702            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
12703                    + ": " + sticky);
12704
12705            if (receiver == null) {
12706                return sticky;
12707            }
12708
12709            ReceiverList rl
12710                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12711            if (rl == null) {
12712                rl = new ReceiverList(this, callerApp,
12713                        Binder.getCallingPid(),
12714                        Binder.getCallingUid(), receiver);
12715                if (rl.app != null) {
12716                    rl.app.receivers.add(rl);
12717                } else {
12718                    try {
12719                        receiver.asBinder().linkToDeath(rl, 0);
12720                    } catch (RemoteException e) {
12721                        return sticky;
12722                    }
12723                    rl.linkedToDeath = true;
12724                }
12725                mRegisteredReceivers.put(receiver.asBinder(), rl);
12726            }
12727            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
12728            rl.add(bf);
12729            if (!bf.debugCheck()) {
12730                Slog.w(TAG, "==> For Dynamic broadast");
12731            }
12732            mReceiverResolver.addFilter(bf);
12733
12734            // Enqueue broadcasts for all existing stickies that match
12735            // this filter.
12736            if (allSticky != null) {
12737                ArrayList receivers = new ArrayList();
12738                receivers.add(bf);
12739
12740                int N = allSticky.size();
12741                for (int i=0; i<N; i++) {
12742                    Intent intent = (Intent)allSticky.get(i);
12743                    BroadcastQueue queue = broadcastQueueForIntent(intent);
12744                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
12745                            null, -1, -1, null, receivers, null, 0, null, null,
12746                            false, true, true);
12747                    queue.enqueueParallelBroadcastLocked(r);
12748                    queue.scheduleBroadcastsLocked();
12749                }
12750            }
12751
12752            return sticky;
12753        }
12754    }
12755
12756    public void unregisterReceiver(IIntentReceiver receiver) {
12757        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
12758
12759        final long origId = Binder.clearCallingIdentity();
12760        try {
12761            boolean doTrim = false;
12762
12763            synchronized(this) {
12764                ReceiverList rl
12765                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12766                if (rl != null) {
12767                    if (rl.curBroadcast != null) {
12768                        BroadcastRecord r = rl.curBroadcast;
12769                        final boolean doNext = finishReceiverLocked(
12770                                receiver.asBinder(), r.resultCode, r.resultData,
12771                                r.resultExtras, r.resultAbort, true);
12772                        if (doNext) {
12773                            doTrim = true;
12774                            r.queue.processNextBroadcast(false);
12775                        }
12776                    }
12777
12778                    if (rl.app != null) {
12779                        rl.app.receivers.remove(rl);
12780                    }
12781                    removeReceiverLocked(rl);
12782                    if (rl.linkedToDeath) {
12783                        rl.linkedToDeath = false;
12784                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
12785                    }
12786                }
12787            }
12788
12789            // If we actually concluded any broadcasts, we might now be able
12790            // to trim the recipients' apps from our working set
12791            if (doTrim) {
12792                trimApplications();
12793                return;
12794            }
12795
12796        } finally {
12797            Binder.restoreCallingIdentity(origId);
12798        }
12799    }
12800
12801    void removeReceiverLocked(ReceiverList rl) {
12802        mRegisteredReceivers.remove(rl.receiver.asBinder());
12803        int N = rl.size();
12804        for (int i=0; i<N; i++) {
12805            mReceiverResolver.removeFilter(rl.get(i));
12806        }
12807    }
12808
12809    private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
12810        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12811            ProcessRecord r = mLruProcesses.get(i);
12812            if (r.thread != null) {
12813                try {
12814                    r.thread.dispatchPackageBroadcast(cmd, packages);
12815                } catch (RemoteException ex) {
12816                }
12817            }
12818        }
12819    }
12820
12821    private final int broadcastIntentLocked(ProcessRecord callerApp,
12822            String callerPackage, Intent intent, String resolvedType,
12823            IIntentReceiver resultTo, int resultCode, String resultData,
12824            Bundle map, String requiredPermission,
12825            boolean ordered, boolean sticky, int callingPid, int callingUid,
12826            int userId) {
12827        intent = new Intent(intent);
12828
12829        // By default broadcasts do not go to stopped apps.
12830        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
12831
12832        if (DEBUG_BROADCAST_LIGHT) Slog.v(
12833            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
12834            + " ordered=" + ordered + " userid=" + userId);
12835        if ((resultTo != null) && !ordered) {
12836            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
12837        }
12838
12839        // Handle special intents: if this broadcast is from the package
12840        // manager about a package being removed, we need to remove all of
12841        // its activities from the history stack.
12842        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
12843                intent.getAction());
12844        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
12845                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
12846                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
12847                || uidRemoved) {
12848            if (checkComponentPermission(
12849                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
12850                    callingPid, callingUid, -1, true)
12851                    == PackageManager.PERMISSION_GRANTED) {
12852                if (uidRemoved) {
12853                    final Bundle intentExtras = intent.getExtras();
12854                    final int uid = intentExtras != null
12855                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
12856                    if (uid >= 0) {
12857                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
12858                        synchronized (bs) {
12859                            bs.removeUidStatsLocked(uid);
12860                        }
12861                    }
12862                } else {
12863                    // If resources are unvailble just force stop all
12864                    // those packages and flush the attribute cache as well.
12865                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
12866                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
12867                        if (list != null && (list.length > 0)) {
12868                            for (String pkg : list) {
12869                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
12870                            }
12871                            sendPackageBroadcastLocked(
12872                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
12873                        }
12874                    } else {
12875                        Uri data = intent.getData();
12876                        String ssp;
12877                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12878                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
12879                                forceStopPackageLocked(ssp,
12880                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
12881                                        false, userId);
12882                            }
12883                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
12884                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
12885                                        new String[] {ssp});
12886                            }
12887                        }
12888                    }
12889                }
12890            } else {
12891                String msg = "Permission Denial: " + intent.getAction()
12892                        + " broadcast from " + callerPackage + " (pid=" + callingPid
12893                        + ", uid=" + callingUid + ")"
12894                        + " requires "
12895                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
12896                Slog.w(TAG, msg);
12897                throw new SecurityException(msg);
12898            }
12899
12900        // Special case for adding a package: by default turn on compatibility
12901        // mode.
12902        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
12903            Uri data = intent.getData();
12904            String ssp;
12905            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12906                mCompatModePackages.handlePackageAddedLocked(ssp,
12907                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
12908            }
12909        }
12910
12911        /*
12912         * If this is the time zone changed action, queue up a message that will reset the timezone
12913         * of all currently running processes. This message will get queued up before the broadcast
12914         * happens.
12915         */
12916        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
12917            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
12918        }
12919
12920        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
12921            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
12922        }
12923
12924        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
12925            ProxyProperties proxy = intent.getParcelableExtra("proxy");
12926            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
12927        }
12928
12929        /*
12930         * Prevent non-system code (defined here to be non-persistent
12931         * processes) from sending protected broadcasts.
12932         */
12933        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
12934            || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
12935            callingUid == 0) {
12936            // Always okay.
12937        } else if (callerApp == null || !callerApp.persistent) {
12938            try {
12939                if (AppGlobals.getPackageManager().isProtectedBroadcast(
12940                        intent.getAction())) {
12941                    String msg = "Permission Denial: not allowed to send broadcast "
12942                            + intent.getAction() + " from pid="
12943                            + callingPid + ", uid=" + callingUid;
12944                    Slog.w(TAG, msg);
12945                    throw new SecurityException(msg);
12946                }
12947            } catch (RemoteException e) {
12948                Slog.w(TAG, "Remote exception", e);
12949                return ActivityManager.BROADCAST_SUCCESS;
12950            }
12951        }
12952
12953        // Add to the sticky list if requested.
12954        if (sticky) {
12955            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
12956                    callingPid, callingUid)
12957                    != PackageManager.PERMISSION_GRANTED) {
12958                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
12959                        + callingPid + ", uid=" + callingUid
12960                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
12961                Slog.w(TAG, msg);
12962                throw new SecurityException(msg);
12963            }
12964            if (requiredPermission != null) {
12965                Slog.w(TAG, "Can't broadcast sticky intent " + intent
12966                        + " and enforce permission " + requiredPermission);
12967                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
12968            }
12969            if (intent.getComponent() != null) {
12970                throw new SecurityException(
12971                        "Sticky broadcasts can't target a specific component");
12972            }
12973            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12974            if (list == null) {
12975                list = new ArrayList<Intent>();
12976                mStickyBroadcasts.put(intent.getAction(), list);
12977            }
12978            int N = list.size();
12979            int i;
12980            for (i=0; i<N; i++) {
12981                if (intent.filterEquals(list.get(i))) {
12982                    // This sticky already exists, replace it.
12983                    list.set(i, new Intent(intent));
12984                    break;
12985                }
12986            }
12987            if (i >= N) {
12988                list.add(new Intent(intent));
12989            }
12990        }
12991
12992        // Figure out who all will receive this broadcast.
12993        List receivers = null;
12994        List<BroadcastFilter> registeredReceivers = null;
12995        try {
12996            if (intent.getComponent() != null) {
12997                // Broadcast is going to one specific receiver class...
12998                ActivityInfo ai = AppGlobals.getPackageManager().
12999                        getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS, userId);
13000                if (ai != null) {
13001                    receivers = new ArrayList();
13002                    ResolveInfo ri = new ResolveInfo();
13003                    if (isSingleton(ai.processName, ai.applicationInfo)) {
13004                        ri.activityInfo = getActivityInfoForUser(ai, 0);
13005                    } else {
13006                        ri.activityInfo = getActivityInfoForUser(ai, userId);
13007                    }
13008                    receivers.add(ri);
13009                }
13010            } else {
13011                // Need to resolve the intent to interested receivers...
13012                if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13013                         == 0) {
13014                    receivers =
13015                        AppGlobals.getPackageManager().queryIntentReceivers(
13016                                    intent, resolvedType, STOCK_PM_FLAGS, userId);
13017                }
13018                registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false,
13019                        userId);
13020            }
13021        } catch (RemoteException ex) {
13022            // pm is in same process, this will never happen.
13023        }
13024
13025        final boolean replacePending =
13026                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13027
13028        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13029                + " replacePending=" + replacePending);
13030
13031        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13032        if (!ordered && NR > 0) {
13033            // If we are not serializing this broadcast, then send the
13034            // registered receivers separately so they don't wait for the
13035            // components to be launched.
13036            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13037            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13038                    callerPackage, callingPid, callingUid, requiredPermission,
13039                    registeredReceivers, resultTo, resultCode, resultData, map,
13040                    ordered, sticky, false);
13041            if (DEBUG_BROADCAST) Slog.v(
13042                    TAG, "Enqueueing parallel broadcast " + r);
13043            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13044            if (!replaced) {
13045                queue.enqueueParallelBroadcastLocked(r);
13046                queue.scheduleBroadcastsLocked();
13047            }
13048            registeredReceivers = null;
13049            NR = 0;
13050        }
13051
13052        // Merge into one list.
13053        int ir = 0;
13054        if (receivers != null) {
13055            // A special case for PACKAGE_ADDED: do not allow the package
13056            // being added to see this broadcast.  This prevents them from
13057            // using this as a back door to get run as soon as they are
13058            // installed.  Maybe in the future we want to have a special install
13059            // broadcast or such for apps, but we'd like to deliberately make
13060            // this decision.
13061            String skipPackages[] = null;
13062            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13063                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13064                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13065                Uri data = intent.getData();
13066                if (data != null) {
13067                    String pkgName = data.getSchemeSpecificPart();
13068                    if (pkgName != null) {
13069                        skipPackages = new String[] { pkgName };
13070                    }
13071                }
13072            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13073                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13074            }
13075            if (skipPackages != null && (skipPackages.length > 0)) {
13076                for (String skipPackage : skipPackages) {
13077                    if (skipPackage != null) {
13078                        int NT = receivers.size();
13079                        for (int it=0; it<NT; it++) {
13080                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13081                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13082                                receivers.remove(it);
13083                                it--;
13084                                NT--;
13085                            }
13086                        }
13087                    }
13088                }
13089            }
13090
13091            int NT = receivers != null ? receivers.size() : 0;
13092            int it = 0;
13093            ResolveInfo curt = null;
13094            BroadcastFilter curr = null;
13095            while (it < NT && ir < NR) {
13096                if (curt == null) {
13097                    curt = (ResolveInfo)receivers.get(it);
13098                }
13099                if (curr == null) {
13100                    curr = registeredReceivers.get(ir);
13101                }
13102                if (curr.getPriority() >= curt.priority) {
13103                    // Insert this broadcast record into the final list.
13104                    receivers.add(it, curr);
13105                    ir++;
13106                    curr = null;
13107                    it++;
13108                    NT++;
13109                } else {
13110                    // Skip to the next ResolveInfo in the final list.
13111                    it++;
13112                    curt = null;
13113                }
13114            }
13115        }
13116        while (ir < NR) {
13117            if (receivers == null) {
13118                receivers = new ArrayList();
13119            }
13120            receivers.add(registeredReceivers.get(ir));
13121            ir++;
13122        }
13123
13124        if ((receivers != null && receivers.size() > 0)
13125                || resultTo != null) {
13126            BroadcastQueue queue = broadcastQueueForIntent(intent);
13127            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13128                    callerPackage, callingPid, callingUid, requiredPermission,
13129                    receivers, resultTo, resultCode, resultData, map, ordered,
13130                    sticky, false);
13131            if (DEBUG_BROADCAST) Slog.v(
13132                    TAG, "Enqueueing ordered broadcast " + r
13133                    + ": prev had " + queue.mOrderedBroadcasts.size());
13134            if (DEBUG_BROADCAST) {
13135                int seq = r.intent.getIntExtra("seq", -1);
13136                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13137            }
13138            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13139            if (!replaced) {
13140                queue.enqueueOrderedBroadcastLocked(r);
13141                queue.scheduleBroadcastsLocked();
13142            }
13143        }
13144
13145        return ActivityManager.BROADCAST_SUCCESS;
13146    }
13147
13148    final Intent verifyBroadcastLocked(Intent intent) {
13149        // Refuse possible leaked file descriptors
13150        if (intent != null && intent.hasFileDescriptors() == true) {
13151            throw new IllegalArgumentException("File descriptors passed in Intent");
13152        }
13153
13154        int flags = intent.getFlags();
13155
13156        if (!mProcessesReady) {
13157            // if the caller really truly claims to know what they're doing, go
13158            // ahead and allow the broadcast without launching any receivers
13159            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13160                intent = new Intent(intent);
13161                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13162            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13163                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13164                        + " before boot completion");
13165                throw new IllegalStateException("Cannot broadcast before boot completed");
13166            }
13167        }
13168
13169        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13170            throw new IllegalArgumentException(
13171                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13172        }
13173
13174        return intent;
13175    }
13176
13177    public final int broadcastIntent(IApplicationThread caller,
13178            Intent intent, String resolvedType, IIntentReceiver resultTo,
13179            int resultCode, String resultData, Bundle map,
13180            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13181        enforceNotIsolatedCaller("broadcastIntent");
13182        synchronized(this) {
13183            intent = verifyBroadcastLocked(intent);
13184
13185            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13186            final int callingPid = Binder.getCallingPid();
13187            final int callingUid = Binder.getCallingUid();
13188            final long origId = Binder.clearCallingIdentity();
13189            int res = broadcastIntentLocked(callerApp,
13190                    callerApp != null ? callerApp.info.packageName : null,
13191                    intent, resolvedType, resultTo,
13192                    resultCode, resultData, map, requiredPermission, serialized, sticky,
13193                    callingPid, callingUid, userId);
13194            Binder.restoreCallingIdentity(origId);
13195            return res;
13196        }
13197    }
13198
13199    int broadcastIntentInPackage(String packageName, int uid,
13200            Intent intent, String resolvedType, IIntentReceiver resultTo,
13201            int resultCode, String resultData, Bundle map,
13202            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13203        synchronized(this) {
13204            intent = verifyBroadcastLocked(intent);
13205
13206            final long origId = Binder.clearCallingIdentity();
13207            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13208                    resultTo, resultCode, resultData, map, requiredPermission,
13209                    serialized, sticky, -1, uid, userId);
13210            Binder.restoreCallingIdentity(origId);
13211            return res;
13212        }
13213    }
13214
13215    // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user.
13216    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13217        // Refuse possible leaked file descriptors
13218        if (intent != null && intent.hasFileDescriptors() == true) {
13219            throw new IllegalArgumentException("File descriptors passed in Intent");
13220        }
13221
13222        synchronized(this) {
13223            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13224                    != PackageManager.PERMISSION_GRANTED) {
13225                String msg = "Permission Denial: unbroadcastIntent() from pid="
13226                        + Binder.getCallingPid()
13227                        + ", uid=" + Binder.getCallingUid()
13228                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13229                Slog.w(TAG, msg);
13230                throw new SecurityException(msg);
13231            }
13232            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
13233            if (list != null) {
13234                int N = list.size();
13235                int i;
13236                for (i=0; i<N; i++) {
13237                    if (intent.filterEquals(list.get(i))) {
13238                        list.remove(i);
13239                        break;
13240                    }
13241                }
13242            }
13243        }
13244    }
13245
13246    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13247            String resultData, Bundle resultExtras, boolean resultAbort,
13248            boolean explicit) {
13249        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13250        if (r == null) {
13251            Slog.w(TAG, "finishReceiver called but not found on queue");
13252            return false;
13253        }
13254
13255        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
13256                explicit);
13257    }
13258
13259    public void finishReceiver(IBinder who, int resultCode, String resultData,
13260            Bundle resultExtras, boolean resultAbort) {
13261        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13262
13263        // Refuse possible leaked file descriptors
13264        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13265            throw new IllegalArgumentException("File descriptors passed in Bundle");
13266        }
13267
13268        final long origId = Binder.clearCallingIdentity();
13269        try {
13270            boolean doNext = false;
13271            BroadcastRecord r = null;
13272
13273            synchronized(this) {
13274                r = broadcastRecordForReceiverLocked(who);
13275                if (r != null) {
13276                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13277                        resultData, resultExtras, resultAbort, true);
13278                }
13279            }
13280
13281            if (doNext) {
13282                r.queue.processNextBroadcast(false);
13283            }
13284            trimApplications();
13285        } finally {
13286            Binder.restoreCallingIdentity(origId);
13287        }
13288    }
13289
13290    // =========================================================
13291    // INSTRUMENTATION
13292    // =========================================================
13293
13294    public boolean startInstrumentation(ComponentName className,
13295            String profileFile, int flags, Bundle arguments,
13296            IInstrumentationWatcher watcher) {
13297        enforceNotIsolatedCaller("startInstrumentation");
13298        // Refuse possible leaked file descriptors
13299        if (arguments != null && arguments.hasFileDescriptors()) {
13300            throw new IllegalArgumentException("File descriptors passed in Bundle");
13301        }
13302
13303        synchronized(this) {
13304            InstrumentationInfo ii = null;
13305            ApplicationInfo ai = null;
13306            try {
13307                ii = mContext.getPackageManager().getInstrumentationInfo(
13308                    className, STOCK_PM_FLAGS);
13309                ai = mContext.getPackageManager().getApplicationInfo(
13310                        ii.targetPackage, STOCK_PM_FLAGS);
13311            } catch (PackageManager.NameNotFoundException e) {
13312            }
13313            if (ii == null) {
13314                reportStartInstrumentationFailure(watcher, className,
13315                        "Unable to find instrumentation info for: " + className);
13316                return false;
13317            }
13318            if (ai == null) {
13319                reportStartInstrumentationFailure(watcher, className,
13320                        "Unable to find instrumentation target package: " + ii.targetPackage);
13321                return false;
13322            }
13323
13324            int match = mContext.getPackageManager().checkSignatures(
13325                    ii.targetPackage, ii.packageName);
13326            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13327                String msg = "Permission Denial: starting instrumentation "
13328                        + className + " from pid="
13329                        + Binder.getCallingPid()
13330                        + ", uid=" + Binder.getCallingPid()
13331                        + " not allowed because package " + ii.packageName
13332                        + " does not have a signature matching the target "
13333                        + ii.targetPackage;
13334                reportStartInstrumentationFailure(watcher, className, msg);
13335                throw new SecurityException(msg);
13336            }
13337
13338            int userId = UserId.getCallingUserId();
13339            final long origId = Binder.clearCallingIdentity();
13340            // Instrumentation can kill and relaunch even persistent processes
13341            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
13342            ProcessRecord app = addAppLocked(ai, false);
13343            app.instrumentationClass = className;
13344            app.instrumentationInfo = ai;
13345            app.instrumentationProfileFile = profileFile;
13346            app.instrumentationArguments = arguments;
13347            app.instrumentationWatcher = watcher;
13348            app.instrumentationResultClass = className;
13349            Binder.restoreCallingIdentity(origId);
13350        }
13351
13352        return true;
13353    }
13354
13355    /**
13356     * Report errors that occur while attempting to start Instrumentation.  Always writes the
13357     * error to the logs, but if somebody is watching, send the report there too.  This enables
13358     * the "am" command to report errors with more information.
13359     *
13360     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
13361     * @param cn The component name of the instrumentation.
13362     * @param report The error report.
13363     */
13364    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13365            ComponentName cn, String report) {
13366        Slog.w(TAG, report);
13367        try {
13368            if (watcher != null) {
13369                Bundle results = new Bundle();
13370                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13371                results.putString("Error", report);
13372                watcher.instrumentationStatus(cn, -1, results);
13373            }
13374        } catch (RemoteException e) {
13375            Slog.w(TAG, e);
13376        }
13377    }
13378
13379    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13380        if (app.instrumentationWatcher != null) {
13381            try {
13382                // NOTE:  IInstrumentationWatcher *must* be oneway here
13383                app.instrumentationWatcher.instrumentationFinished(
13384                    app.instrumentationClass,
13385                    resultCode,
13386                    results);
13387            } catch (RemoteException e) {
13388            }
13389        }
13390        app.instrumentationWatcher = null;
13391        app.instrumentationClass = null;
13392        app.instrumentationInfo = null;
13393        app.instrumentationProfileFile = null;
13394        app.instrumentationArguments = null;
13395
13396        forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId);
13397    }
13398
13399    public void finishInstrumentation(IApplicationThread target,
13400            int resultCode, Bundle results) {
13401        int userId = UserId.getCallingUserId();
13402        // Refuse possible leaked file descriptors
13403        if (results != null && results.hasFileDescriptors()) {
13404            throw new IllegalArgumentException("File descriptors passed in Intent");
13405        }
13406
13407        synchronized(this) {
13408            ProcessRecord app = getRecordForAppLocked(target);
13409            if (app == null) {
13410                Slog.w(TAG, "finishInstrumentation: no app for " + target);
13411                return;
13412            }
13413            final long origId = Binder.clearCallingIdentity();
13414            finishInstrumentationLocked(app, resultCode, results);
13415            Binder.restoreCallingIdentity(origId);
13416        }
13417    }
13418
13419    // =========================================================
13420    // CONFIGURATION
13421    // =========================================================
13422
13423    public ConfigurationInfo getDeviceConfigurationInfo() {
13424        ConfigurationInfo config = new ConfigurationInfo();
13425        synchronized (this) {
13426            config.reqTouchScreen = mConfiguration.touchscreen;
13427            config.reqKeyboardType = mConfiguration.keyboard;
13428            config.reqNavigation = mConfiguration.navigation;
13429            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13430                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
13431                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13432            }
13433            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13434                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
13435                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13436            }
13437            config.reqGlEsVersion = GL_ES_VERSION;
13438        }
13439        return config;
13440    }
13441
13442    public Configuration getConfiguration() {
13443        Configuration ci;
13444        synchronized(this) {
13445            ci = new Configuration(mConfiguration);
13446        }
13447        return ci;
13448    }
13449
13450    public void updatePersistentConfiguration(Configuration values) {
13451        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13452                "updateConfiguration()");
13453        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13454                "updateConfiguration()");
13455        if (values == null) {
13456            throw new NullPointerException("Configuration must not be null");
13457        }
13458
13459        synchronized(this) {
13460            final long origId = Binder.clearCallingIdentity();
13461            updateConfigurationLocked(values, null, true, false);
13462            Binder.restoreCallingIdentity(origId);
13463        }
13464    }
13465
13466    public void updateConfiguration(Configuration values) {
13467        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13468                "updateConfiguration()");
13469
13470        synchronized(this) {
13471            if (values == null && mWindowManager != null) {
13472                // sentinel: fetch the current configuration from the window manager
13473                values = mWindowManager.computeNewConfiguration();
13474            }
13475
13476            if (mWindowManager != null) {
13477                mProcessList.applyDisplaySize(mWindowManager);
13478            }
13479
13480            final long origId = Binder.clearCallingIdentity();
13481            if (values != null) {
13482                Settings.System.clearConfiguration(values);
13483            }
13484            updateConfigurationLocked(values, null, false, false);
13485            Binder.restoreCallingIdentity(origId);
13486        }
13487    }
13488
13489    /**
13490     * Do either or both things: (1) change the current configuration, and (2)
13491     * make sure the given activity is running with the (now) current
13492     * configuration.  Returns true if the activity has been left running, or
13493     * false if <var>starting</var> is being destroyed to match the new
13494     * configuration.
13495     * @param persistent TODO
13496     */
13497    boolean updateConfigurationLocked(Configuration values,
13498            ActivityRecord starting, boolean persistent, boolean initLocale) {
13499        // do nothing if we are headless
13500        if (mHeadless) return true;
13501
13502        int changes = 0;
13503
13504        boolean kept = true;
13505
13506        if (values != null) {
13507            Configuration newConfig = new Configuration(mConfiguration);
13508            changes = newConfig.updateFrom(values);
13509            if (changes != 0) {
13510                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
13511                    Slog.i(TAG, "Updating configuration to: " + values);
13512                }
13513
13514                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
13515
13516                if (values.locale != null && !initLocale) {
13517                    saveLocaleLocked(values.locale,
13518                                     !values.locale.equals(mConfiguration.locale),
13519                                     values.userSetLocale);
13520                }
13521
13522                mConfigurationSeq++;
13523                if (mConfigurationSeq <= 0) {
13524                    mConfigurationSeq = 1;
13525                }
13526                newConfig.seq = mConfigurationSeq;
13527                mConfiguration = newConfig;
13528                Slog.i(TAG, "Config changed: " + newConfig);
13529
13530                final Configuration configCopy = new Configuration(mConfiguration);
13531
13532                // TODO: If our config changes, should we auto dismiss any currently
13533                // showing dialogs?
13534                mShowDialogs = shouldShowDialogs(newConfig);
13535
13536                AttributeCache ac = AttributeCache.instance();
13537                if (ac != null) {
13538                    ac.updateConfiguration(configCopy);
13539                }
13540
13541                // Make sure all resources in our process are updated
13542                // right now, so that anyone who is going to retrieve
13543                // resource values after we return will be sure to get
13544                // the new ones.  This is especially important during
13545                // boot, where the first config change needs to guarantee
13546                // all resources have that config before following boot
13547                // code is executed.
13548                mSystemThread.applyConfigurationToResources(configCopy);
13549
13550                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
13551                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
13552                    msg.obj = new Configuration(configCopy);
13553                    mHandler.sendMessage(msg);
13554                }
13555
13556                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13557                    ProcessRecord app = mLruProcesses.get(i);
13558                    try {
13559                        if (app.thread != null) {
13560                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
13561                                    + app.processName + " new config " + mConfiguration);
13562                            app.thread.scheduleConfigurationChanged(configCopy);
13563                        }
13564                    } catch (Exception e) {
13565                    }
13566                }
13567                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
13568                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13569                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
13570                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
13571                        null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
13572                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
13573                    broadcastIntentLocked(null, null,
13574                            new Intent(Intent.ACTION_LOCALE_CHANGED),
13575                            null, null, 0, null, null,
13576                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
13577                }
13578            }
13579        }
13580
13581        if (changes != 0 && starting == null) {
13582            // If the configuration changed, and the caller is not already
13583            // in the process of starting an activity, then find the top
13584            // activity to check if its configuration needs to change.
13585            starting = mMainStack.topRunningActivityLocked(null);
13586        }
13587
13588        if (starting != null) {
13589            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
13590            // And we need to make sure at this point that all other activities
13591            // are made visible with the correct configuration.
13592            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
13593        }
13594
13595        if (values != null && mWindowManager != null) {
13596            mWindowManager.setNewConfiguration(mConfiguration);
13597        }
13598
13599        return kept;
13600    }
13601
13602    /**
13603     * Decide based on the configuration whether we should shouw the ANR,
13604     * crash, etc dialogs.  The idea is that if there is no affordnace to
13605     * press the on-screen buttons, we shouldn't show the dialog.
13606     *
13607     * A thought: SystemUI might also want to get told about this, the Power
13608     * dialog / global actions also might want different behaviors.
13609     */
13610    private static final boolean shouldShowDialogs(Configuration config) {
13611        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
13612                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
13613    }
13614
13615    /**
13616     * Save the locale.  You must be inside a synchronized (this) block.
13617     */
13618    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
13619        if(isDiff) {
13620            SystemProperties.set("user.language", l.getLanguage());
13621            SystemProperties.set("user.region", l.getCountry());
13622        }
13623
13624        if(isPersist) {
13625            SystemProperties.set("persist.sys.language", l.getLanguage());
13626            SystemProperties.set("persist.sys.country", l.getCountry());
13627            SystemProperties.set("persist.sys.localevar", l.getVariant());
13628        }
13629    }
13630
13631    @Override
13632    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
13633        ActivityRecord srec = ActivityRecord.forToken(token);
13634        return srec != null && srec.task.affinity != null &&
13635                srec.task.affinity.equals(destAffinity);
13636    }
13637
13638    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
13639            Intent resultData) {
13640        ComponentName dest = destIntent.getComponent();
13641
13642        synchronized (this) {
13643            ActivityRecord srec = ActivityRecord.forToken(token);
13644            if (srec == null) {
13645                return false;
13646            }
13647            ArrayList<ActivityRecord> history = srec.stack.mHistory;
13648            final int start = history.indexOf(srec);
13649            if (start < 0) {
13650                // Current activity is not in history stack; do nothing.
13651                return false;
13652            }
13653            int finishTo = start - 1;
13654            ActivityRecord parent = null;
13655            boolean foundParentInTask = false;
13656            if (dest != null) {
13657                TaskRecord tr = srec.task;
13658                for (int i = start - 1; i >= 0; i--) {
13659                    ActivityRecord r = history.get(i);
13660                    if (tr != r.task) {
13661                        // Couldn't find parent in the same task; stop at the one above this.
13662                        // (Root of current task; in-app "home" behavior)
13663                        // Always at least finish the current activity.
13664                        finishTo = Math.min(start - 1, i + 1);
13665                        parent = history.get(finishTo);
13666                        break;
13667                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
13668                            r.info.name.equals(dest.getClassName())) {
13669                        finishTo = i;
13670                        parent = r;
13671                        foundParentInTask = true;
13672                        break;
13673                    }
13674                }
13675            }
13676
13677            if (mController != null) {
13678                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
13679                if (next != null) {
13680                    // ask watcher if this is allowed
13681                    boolean resumeOK = true;
13682                    try {
13683                        resumeOK = mController.activityResuming(next.packageName);
13684                    } catch (RemoteException e) {
13685                        mController = null;
13686                    }
13687
13688                    if (!resumeOK) {
13689                        return false;
13690                    }
13691                }
13692            }
13693            final long origId = Binder.clearCallingIdentity();
13694            for (int i = start; i > finishTo; i--) {
13695                ActivityRecord r = history.get(i);
13696                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
13697                        "navigate-up");
13698                // Only return the supplied result for the first activity finished
13699                resultCode = Activity.RESULT_CANCELED;
13700                resultData = null;
13701            }
13702
13703            if (parent != null && foundParentInTask) {
13704                final int parentLaunchMode = parent.info.launchMode;
13705                final int destIntentFlags = destIntent.getFlags();
13706                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
13707                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
13708                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
13709                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
13710                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
13711                } else {
13712                    try {
13713                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
13714                                destIntent.getComponent(), 0, UserId.getCallingUserId());
13715                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
13716                                null, aInfo, parent.appToken, null,
13717                                0, -1, parent.launchedFromUid, 0, null, true, null);
13718                        foundParentInTask = res == ActivityManager.START_SUCCESS;
13719                    } catch (RemoteException e) {
13720                        foundParentInTask = false;
13721                    }
13722                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
13723                            resultData, "navigate-up");
13724                }
13725            }
13726            Binder.restoreCallingIdentity(origId);
13727            return foundParentInTask;
13728        }
13729    }
13730
13731    public int getLaunchedFromUid(IBinder activityToken) {
13732        ActivityRecord srec = ActivityRecord.forToken(activityToken);
13733        if (srec == null) {
13734            return -1;
13735        }
13736        return srec.launchedFromUid;
13737    }
13738
13739    // =========================================================
13740    // LIFETIME MANAGEMENT
13741    // =========================================================
13742
13743    // Returns which broadcast queue the app is the current [or imminent] receiver
13744    // on, or 'null' if the app is not an active broadcast recipient.
13745    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
13746        BroadcastRecord r = app.curReceiver;
13747        if (r != null) {
13748            return r.queue;
13749        }
13750
13751        // It's not the current receiver, but it might be starting up to become one
13752        synchronized (this) {
13753            for (BroadcastQueue queue : mBroadcastQueues) {
13754                r = queue.mPendingBroadcast;
13755                if (r != null && r.curApp == app) {
13756                    // found it; report which queue it's in
13757                    return queue;
13758                }
13759            }
13760        }
13761
13762        return null;
13763    }
13764
13765    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
13766            ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
13767        if (mAdjSeq == app.adjSeq) {
13768            // This adjustment has already been computed.  If we are calling
13769            // from the top, we may have already computed our adjustment with
13770            // an earlier hidden adjustment that isn't really for us... if
13771            // so, use the new hidden adjustment.
13772            if (!recursed && app.hidden) {
13773                app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
13774            }
13775            return app.curRawAdj;
13776        }
13777
13778        if (app.thread == null) {
13779            app.adjSeq = mAdjSeq;
13780            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13781            return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
13782        }
13783
13784        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
13785        app.adjSource = null;
13786        app.adjTarget = null;
13787        app.empty = false;
13788        app.hidden = false;
13789
13790        final int activitiesSize = app.activities.size();
13791
13792        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
13793            // The max adjustment doesn't allow this app to be anything
13794            // below foreground, so it is not worth doing work for it.
13795            app.adjType = "fixed";
13796            app.adjSeq = mAdjSeq;
13797            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
13798            app.foregroundActivities = false;
13799            app.keeping = true;
13800            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
13801            // System process can do UI, and when they do we want to have
13802            // them trim their memory after the user leaves the UI.  To
13803            // facilitate this, here we need to determine whether or not it
13804            // is currently showing UI.
13805            app.systemNoUi = true;
13806            if (app == TOP_APP) {
13807                app.systemNoUi = false;
13808            } else if (activitiesSize > 0) {
13809                for (int j = 0; j < activitiesSize; j++) {
13810                    final ActivityRecord r = app.activities.get(j);
13811                    if (r.visible) {
13812                        app.systemNoUi = false;
13813                        break;
13814                    }
13815                }
13816            }
13817            return (app.curAdj=app.maxAdj);
13818        }
13819
13820        app.keeping = false;
13821        app.systemNoUi = false;
13822
13823        // Determine the importance of the process, starting with most
13824        // important to least, and assign an appropriate OOM adjustment.
13825        int adj;
13826        int schedGroup;
13827        boolean foregroundActivities = false;
13828        boolean interesting = false;
13829        BroadcastQueue queue;
13830        if (app == TOP_APP) {
13831            // The last app on the list is the foreground app.
13832            adj = ProcessList.FOREGROUND_APP_ADJ;
13833            schedGroup = Process.THREAD_GROUP_DEFAULT;
13834            app.adjType = "top-activity";
13835            foregroundActivities = true;
13836            interesting = true;
13837        } else if (app.instrumentationClass != null) {
13838            // Don't want to kill running instrumentation.
13839            adj = ProcessList.FOREGROUND_APP_ADJ;
13840            schedGroup = Process.THREAD_GROUP_DEFAULT;
13841            app.adjType = "instrumentation";
13842            interesting = true;
13843        } else if ((queue = isReceivingBroadcast(app)) != null) {
13844            // An app that is currently receiving a broadcast also
13845            // counts as being in the foreground for OOM killer purposes.
13846            // It's placed in a sched group based on the nature of the
13847            // broadcast as reflected by which queue it's active in.
13848            adj = ProcessList.FOREGROUND_APP_ADJ;
13849            schedGroup = (queue == mFgBroadcastQueue)
13850                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
13851            app.adjType = "broadcast";
13852        } else if (app.executingServices.size() > 0) {
13853            // An app that is currently executing a service callback also
13854            // counts as being in the foreground.
13855            adj = ProcessList.FOREGROUND_APP_ADJ;
13856            schedGroup = Process.THREAD_GROUP_DEFAULT;
13857            app.adjType = "exec-service";
13858        } else if (activitiesSize > 0) {
13859            // This app is in the background with paused activities.
13860            // We inspect activities to potentially upgrade adjustment further below.
13861            adj = hiddenAdj;
13862            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13863            app.hidden = true;
13864            app.adjType = "bg-activities";
13865        } else {
13866            // A very not-needed process.  If this is lower in the lru list,
13867            // we will push it in to the empty bucket.
13868            adj = hiddenAdj;
13869            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13870            app.hidden = true;
13871            app.empty = true;
13872            app.adjType = "bg-empty";
13873        }
13874
13875        boolean hasStoppingActivities = false;
13876
13877        // Examine all activities if not already foreground.
13878        if (!foregroundActivities && activitiesSize > 0) {
13879            for (int j = 0; j < activitiesSize; j++) {
13880                final ActivityRecord r = app.activities.get(j);
13881                if (r.visible) {
13882                    // App has a visible activity; only upgrade adjustment.
13883                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
13884                        adj = ProcessList.VISIBLE_APP_ADJ;
13885                        app.adjType = "visible";
13886                    }
13887                    schedGroup = Process.THREAD_GROUP_DEFAULT;
13888                    app.hidden = false;
13889                    foregroundActivities = true;
13890                    break;
13891                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
13892                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13893                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13894                        app.adjType = "pausing";
13895                    }
13896                    app.hidden = false;
13897                    foregroundActivities = true;
13898                } else if (r.state == ActivityState.STOPPING) {
13899                    // We will apply the actual adjustment later, because
13900                    // we want to allow this process to immediately go through
13901                    // any memory trimming that is in effect.
13902                    app.hidden = false;
13903                    foregroundActivities = true;
13904                    hasStoppingActivities = true;
13905                }
13906            }
13907        }
13908
13909        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13910            if (app.foregroundServices) {
13911                // The user is aware of this app, so make it visible.
13912                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13913                app.hidden = false;
13914                app.adjType = "foreground-service";
13915                schedGroup = Process.THREAD_GROUP_DEFAULT;
13916            } else if (app.forcingToForeground != null) {
13917                // The user is aware of this app, so make it visible.
13918                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13919                app.hidden = false;
13920                app.adjType = "force-foreground";
13921                app.adjSource = app.forcingToForeground;
13922                schedGroup = Process.THREAD_GROUP_DEFAULT;
13923            }
13924        }
13925
13926        if (app.foregroundServices) {
13927            interesting = true;
13928        }
13929
13930        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
13931            // We don't want to kill the current heavy-weight process.
13932            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
13933            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13934            app.hidden = false;
13935            app.adjType = "heavy";
13936        }
13937
13938        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
13939            // This process is hosting what we currently consider to be the
13940            // home app, so we don't want to let it go into the background.
13941            adj = ProcessList.HOME_APP_ADJ;
13942            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13943            app.hidden = false;
13944            app.adjType = "home";
13945        }
13946
13947        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
13948                && app.activities.size() > 0) {
13949            // This was the previous process that showed UI to the user.
13950            // We want to try to keep it around more aggressively, to give
13951            // a good experience around switching between two apps.
13952            adj = ProcessList.PREVIOUS_APP_ADJ;
13953            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13954            app.hidden = false;
13955            app.adjType = "previous";
13956        }
13957
13958        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
13959                + " reason=" + app.adjType);
13960
13961        // By default, we use the computed adjustment.  It may be changed if
13962        // there are applications dependent on our services or providers, but
13963        // this gives us a baseline and makes sure we don't get into an
13964        // infinite recursion.
13965        app.adjSeq = mAdjSeq;
13966        app.curRawAdj = app.nonStoppingAdj = adj;
13967
13968        if (mBackupTarget != null && app == mBackupTarget.app) {
13969            // If possible we want to avoid killing apps while they're being backed up
13970            if (adj > ProcessList.BACKUP_APP_ADJ) {
13971                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
13972                adj = ProcessList.BACKUP_APP_ADJ;
13973                app.adjType = "backup";
13974                app.hidden = false;
13975            }
13976        }
13977
13978        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13979                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13980            final long now = SystemClock.uptimeMillis();
13981            // This process is more important if the top activity is
13982            // bound to the service.
13983            Iterator<ServiceRecord> jt = app.services.iterator();
13984            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
13985                ServiceRecord s = jt.next();
13986                if (s.startRequested) {
13987                    if (app.hasShownUi && app != mHomeProcess) {
13988                        // If this process has shown some UI, let it immediately
13989                        // go to the LRU list because it may be pretty heavy with
13990                        // UI stuff.  We'll tag it with a label just to help
13991                        // debug and understand what is going on.
13992                        if (adj > ProcessList.SERVICE_ADJ) {
13993                            app.adjType = "started-bg-ui-services";
13994                        }
13995                    } else {
13996                        if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13997                            // This service has seen some activity within
13998                            // recent memory, so we will keep its process ahead
13999                            // of the background processes.
14000                            if (adj > ProcessList.SERVICE_ADJ) {
14001                                adj = ProcessList.SERVICE_ADJ;
14002                                app.adjType = "started-services";
14003                                app.hidden = false;
14004                            }
14005                        }
14006                        // If we have let the service slide into the background
14007                        // state, still have some text describing what it is doing
14008                        // even though the service no longer has an impact.
14009                        if (adj > ProcessList.SERVICE_ADJ) {
14010                            app.adjType = "started-bg-services";
14011                        }
14012                    }
14013                    // Don't kill this process because it is doing work; it
14014                    // has said it is doing work.
14015                    app.keeping = true;
14016                }
14017                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14018                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
14019                    Iterator<ArrayList<ConnectionRecord>> kt
14020                            = s.connections.values().iterator();
14021                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
14022                        ArrayList<ConnectionRecord> clist = kt.next();
14023                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
14024                            // XXX should compute this based on the max of
14025                            // all connected clients.
14026                            ConnectionRecord cr = clist.get(i);
14027                            if (cr.binding.client == app) {
14028                                // Binding to ourself is not interesting.
14029                                continue;
14030                            }
14031                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14032                                ProcessRecord client = cr.binding.client;
14033                                int clientAdj = adj;
14034                                int myHiddenAdj = hiddenAdj;
14035                                if (myHiddenAdj > client.hiddenAdj) {
14036                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
14037                                        myHiddenAdj = client.hiddenAdj;
14038                                    } else {
14039                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
14040                                    }
14041                                }
14042                                clientAdj = computeOomAdjLocked(
14043                                    client, myHiddenAdj, TOP_APP, true, doingAll);
14044                                String adjType = null;
14045                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14046                                    // Not doing bind OOM management, so treat
14047                                    // this guy more like a started service.
14048                                    if (app.hasShownUi && app != mHomeProcess) {
14049                                        // If this process has shown some UI, let it immediately
14050                                        // go to the LRU list because it may be pretty heavy with
14051                                        // UI stuff.  We'll tag it with a label just to help
14052                                        // debug and understand what is going on.
14053                                        if (adj > clientAdj) {
14054                                            adjType = "bound-bg-ui-services";
14055                                        }
14056                                        app.hidden = false;
14057                                        clientAdj = adj;
14058                                    } else {
14059                                        if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
14060                                            // This service has not seen activity within
14061                                            // recent memory, so allow it to drop to the
14062                                            // LRU list if there is no other reason to keep
14063                                            // it around.  We'll also tag it with a label just
14064                                            // to help debug and undertand what is going on.
14065                                            if (adj > clientAdj) {
14066                                                adjType = "bound-bg-services";
14067                                            }
14068                                            clientAdj = adj;
14069                                        }
14070                                    }
14071                                }
14072                                if (adj > clientAdj) {
14073                                    // If this process has recently shown UI, and
14074                                    // the process that is binding to it is less
14075                                    // important than being visible, then we don't
14076                                    // care about the binding as much as we care
14077                                    // about letting this process get into the LRU
14078                                    // list to be killed and restarted if needed for
14079                                    // memory.
14080                                    if (app.hasShownUi && app != mHomeProcess
14081                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14082                                        adjType = "bound-bg-ui-services";
14083                                    } else {
14084                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14085                                                |Context.BIND_IMPORTANT)) != 0) {
14086                                            adj = clientAdj;
14087                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14088                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14089                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14090                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14091                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14092                                            adj = clientAdj;
14093                                        } else {
14094                                            app.pendingUiClean = true;
14095                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
14096                                                adj = ProcessList.VISIBLE_APP_ADJ;
14097                                            }
14098                                        }
14099                                        if (!client.hidden) {
14100                                            app.hidden = false;
14101                                        }
14102                                        if (client.keeping) {
14103                                            app.keeping = true;
14104                                        }
14105                                        adjType = "service";
14106                                    }
14107                                }
14108                                if (adjType != null) {
14109                                    app.adjType = adjType;
14110                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14111                                            .REASON_SERVICE_IN_USE;
14112                                    app.adjSource = cr.binding.client;
14113                                    app.adjSourceOom = clientAdj;
14114                                    app.adjTarget = s.name;
14115                                }
14116                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14117                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14118                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
14119                                    }
14120                                }
14121                            }
14122                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14123                                ActivityRecord a = cr.activity;
14124                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14125                                        (a.visible || a.state == ActivityState.RESUMED
14126                                         || a.state == ActivityState.PAUSING)) {
14127                                    adj = ProcessList.FOREGROUND_APP_ADJ;
14128                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14129                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
14130                                    }
14131                                    app.hidden = false;
14132                                    app.adjType = "service";
14133                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14134                                            .REASON_SERVICE_IN_USE;
14135                                    app.adjSource = a;
14136                                    app.adjSourceOom = adj;
14137                                    app.adjTarget = s.name;
14138                                }
14139                            }
14140                        }
14141                    }
14142                }
14143            }
14144
14145            // Finally, if this process has active services running in it, we
14146            // would like to avoid killing it unless it would prevent the current
14147            // application from running.  By default we put the process in
14148            // with the rest of the background processes; as we scan through
14149            // its services we may bump it up from there.
14150            if (adj > hiddenAdj) {
14151                adj = hiddenAdj;
14152                app.hidden = false;
14153                app.adjType = "bg-services";
14154            }
14155        }
14156
14157        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14158                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
14159            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
14160            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
14161                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
14162                ContentProviderRecord cpr = jt.next();
14163                for (int i = cpr.connections.size()-1;
14164                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14165                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
14166                        i--) {
14167                    ContentProviderConnection conn = cpr.connections.get(i);
14168                    ProcessRecord client = conn.client;
14169                    if (client == app) {
14170                        // Being our own client is not interesting.
14171                        continue;
14172                    }
14173                    int myHiddenAdj = hiddenAdj;
14174                    if (myHiddenAdj > client.hiddenAdj) {
14175                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
14176                            myHiddenAdj = client.hiddenAdj;
14177                        } else {
14178                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
14179                        }
14180                    }
14181                    int clientAdj = computeOomAdjLocked(
14182                        client, myHiddenAdj, TOP_APP, true, doingAll);
14183                    if (adj > clientAdj) {
14184                        if (app.hasShownUi && app != mHomeProcess
14185                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14186                            app.adjType = "bg-ui-provider";
14187                        } else {
14188                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14189                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14190                            app.adjType = "provider";
14191                        }
14192                        if (!client.hidden) {
14193                            app.hidden = false;
14194                        }
14195                        if (client.keeping) {
14196                            app.keeping = true;
14197                        }
14198                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14199                                .REASON_PROVIDER_IN_USE;
14200                        app.adjSource = client;
14201                        app.adjSourceOom = clientAdj;
14202                        app.adjTarget = cpr.name;
14203                    }
14204                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14205                        schedGroup = Process.THREAD_GROUP_DEFAULT;
14206                    }
14207                }
14208                // If the provider has external (non-framework) process
14209                // dependencies, ensure that its adjustment is at least
14210                // FOREGROUND_APP_ADJ.
14211                if (cpr.hasExternalProcessHandles()) {
14212                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14213                        adj = ProcessList.FOREGROUND_APP_ADJ;
14214                        schedGroup = Process.THREAD_GROUP_DEFAULT;
14215                        app.hidden = false;
14216                        app.keeping = true;
14217                        app.adjType = "provider";
14218                        app.adjTarget = cpr.name;
14219                    }
14220                }
14221            }
14222        }
14223
14224        if (adj == ProcessList.SERVICE_ADJ) {
14225            if (doingAll) {
14226                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
14227                mNewNumServiceProcs++;
14228            }
14229            if (app.serviceb) {
14230                adj = ProcessList.SERVICE_B_ADJ;
14231            }
14232        } else {
14233            app.serviceb = false;
14234        }
14235
14236        app.nonStoppingAdj = adj;
14237
14238        if (hasStoppingActivities) {
14239            // Only upgrade adjustment.
14240            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14241                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14242                app.adjType = "stopping";
14243            }
14244        }
14245
14246        app.curRawAdj = adj;
14247
14248        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
14249        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14250        if (adj > app.maxAdj) {
14251            adj = app.maxAdj;
14252            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
14253                schedGroup = Process.THREAD_GROUP_DEFAULT;
14254            }
14255        }
14256        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14257            app.keeping = true;
14258        }
14259
14260        if (app.hasAboveClient) {
14261            // If this process has bound to any services with BIND_ABOVE_CLIENT,
14262            // then we need to drop its adjustment to be lower than the service's
14263            // in order to honor the request.  We want to drop it by one adjustment
14264            // level...  but there is special meaning applied to various levels so
14265            // we will skip some of them.
14266            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
14267                // System process will not get dropped, ever
14268            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
14269                adj = ProcessList.VISIBLE_APP_ADJ;
14270            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
14271                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14272            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14273                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
14274            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
14275                adj++;
14276            }
14277        }
14278
14279        int importance = app.memImportance;
14280        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
14281            app.curAdj = adj;
14282            app.curSchedGroup = schedGroup;
14283            if (!interesting) {
14284                // For this reporting, if there is not something explicitly
14285                // interesting in this process then we will push it to the
14286                // background importance.
14287                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14288            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
14289                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14290            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
14291                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14292            } else if (adj >= ProcessList.HOME_APP_ADJ) {
14293                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14294            } else if (adj >= ProcessList.SERVICE_ADJ) {
14295                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14296            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14297                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
14298            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
14299                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
14300            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
14301                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
14302            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
14303                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
14304            } else {
14305                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
14306            }
14307        }
14308
14309        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
14310        if (foregroundActivities != app.foregroundActivities) {
14311            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
14312        }
14313        if (changes != 0) {
14314            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
14315            app.memImportance = importance;
14316            app.foregroundActivities = foregroundActivities;
14317            int i = mPendingProcessChanges.size()-1;
14318            ProcessChangeItem item = null;
14319            while (i >= 0) {
14320                item = mPendingProcessChanges.get(i);
14321                if (item.pid == app.pid) {
14322                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
14323                    break;
14324                }
14325                i--;
14326            }
14327            if (i < 0) {
14328                // No existing item in pending changes; need a new one.
14329                final int NA = mAvailProcessChanges.size();
14330                if (NA > 0) {
14331                    item = mAvailProcessChanges.remove(NA-1);
14332                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
14333                } else {
14334                    item = new ProcessChangeItem();
14335                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
14336                }
14337                item.changes = 0;
14338                item.pid = app.pid;
14339                item.uid = app.info.uid;
14340                if (mPendingProcessChanges.size() == 0) {
14341                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
14342                            "*** Enqueueing dispatch processes changed!");
14343                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
14344                }
14345                mPendingProcessChanges.add(item);
14346            }
14347            item.changes |= changes;
14348            item.importance = importance;
14349            item.foregroundActivities = foregroundActivities;
14350            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
14351                    + Integer.toHexString(System.identityHashCode(item))
14352                    + " " + app.toShortString() + ": changes=" + item.changes
14353                    + " importance=" + item.importance
14354                    + " foreground=" + item.foregroundActivities
14355                    + " type=" + app.adjType + " source=" + app.adjSource
14356                    + " target=" + app.adjTarget);
14357        }
14358
14359        return app.curRawAdj;
14360    }
14361
14362    /**
14363     * Ask a given process to GC right now.
14364     */
14365    final void performAppGcLocked(ProcessRecord app) {
14366        try {
14367            app.lastRequestedGc = SystemClock.uptimeMillis();
14368            if (app.thread != null) {
14369                if (app.reportLowMemory) {
14370                    app.reportLowMemory = false;
14371                    app.thread.scheduleLowMemory();
14372                } else {
14373                    app.thread.processInBackground();
14374                }
14375            }
14376        } catch (Exception e) {
14377            // whatever.
14378        }
14379    }
14380
14381    /**
14382     * Returns true if things are idle enough to perform GCs.
14383     */
14384    private final boolean canGcNowLocked() {
14385        boolean processingBroadcasts = false;
14386        for (BroadcastQueue q : mBroadcastQueues) {
14387            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
14388                processingBroadcasts = true;
14389            }
14390        }
14391        return !processingBroadcasts
14392                && (mSleeping || (mMainStack.mResumedActivity != null &&
14393                        mMainStack.mResumedActivity.idle));
14394    }
14395
14396    /**
14397     * Perform GCs on all processes that are waiting for it, but only
14398     * if things are idle.
14399     */
14400    final void performAppGcsLocked() {
14401        final int N = mProcessesToGc.size();
14402        if (N <= 0) {
14403            return;
14404        }
14405        if (canGcNowLocked()) {
14406            while (mProcessesToGc.size() > 0) {
14407                ProcessRecord proc = mProcessesToGc.remove(0);
14408                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
14409                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14410                            <= SystemClock.uptimeMillis()) {
14411                        // To avoid spamming the system, we will GC processes one
14412                        // at a time, waiting a few seconds between each.
14413                        performAppGcLocked(proc);
14414                        scheduleAppGcsLocked();
14415                        return;
14416                    } else {
14417                        // It hasn't been long enough since we last GCed this
14418                        // process...  put it in the list to wait for its time.
14419                        addProcessToGcListLocked(proc);
14420                        break;
14421                    }
14422                }
14423            }
14424
14425            scheduleAppGcsLocked();
14426        }
14427    }
14428
14429    /**
14430     * If all looks good, perform GCs on all processes waiting for them.
14431     */
14432    final void performAppGcsIfAppropriateLocked() {
14433        if (canGcNowLocked()) {
14434            performAppGcsLocked();
14435            return;
14436        }
14437        // Still not idle, wait some more.
14438        scheduleAppGcsLocked();
14439    }
14440
14441    /**
14442     * Schedule the execution of all pending app GCs.
14443     */
14444    final void scheduleAppGcsLocked() {
14445        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
14446
14447        if (mProcessesToGc.size() > 0) {
14448            // Schedule a GC for the time to the next process.
14449            ProcessRecord proc = mProcessesToGc.get(0);
14450            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
14451
14452            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
14453            long now = SystemClock.uptimeMillis();
14454            if (when < (now+GC_TIMEOUT)) {
14455                when = now + GC_TIMEOUT;
14456            }
14457            mHandler.sendMessageAtTime(msg, when);
14458        }
14459    }
14460
14461    /**
14462     * Add a process to the array of processes waiting to be GCed.  Keeps the
14463     * list in sorted order by the last GC time.  The process can't already be
14464     * on the list.
14465     */
14466    final void addProcessToGcListLocked(ProcessRecord proc) {
14467        boolean added = false;
14468        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
14469            if (mProcessesToGc.get(i).lastRequestedGc <
14470                    proc.lastRequestedGc) {
14471                added = true;
14472                mProcessesToGc.add(i+1, proc);
14473                break;
14474            }
14475        }
14476        if (!added) {
14477            mProcessesToGc.add(0, proc);
14478        }
14479    }
14480
14481    /**
14482     * Set up to ask a process to GC itself.  This will either do it
14483     * immediately, or put it on the list of processes to gc the next
14484     * time things are idle.
14485     */
14486    final void scheduleAppGcLocked(ProcessRecord app) {
14487        long now = SystemClock.uptimeMillis();
14488        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
14489            return;
14490        }
14491        if (!mProcessesToGc.contains(app)) {
14492            addProcessToGcListLocked(app);
14493            scheduleAppGcsLocked();
14494        }
14495    }
14496
14497    final void checkExcessivePowerUsageLocked(boolean doKills) {
14498        updateCpuStatsNow();
14499
14500        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14501        boolean doWakeKills = doKills;
14502        boolean doCpuKills = doKills;
14503        if (mLastPowerCheckRealtime == 0) {
14504            doWakeKills = false;
14505        }
14506        if (mLastPowerCheckUptime == 0) {
14507            doCpuKills = false;
14508        }
14509        if (stats.isScreenOn()) {
14510            doWakeKills = false;
14511        }
14512        final long curRealtime = SystemClock.elapsedRealtime();
14513        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
14514        final long curUptime = SystemClock.uptimeMillis();
14515        final long uptimeSince = curUptime - mLastPowerCheckUptime;
14516        mLastPowerCheckRealtime = curRealtime;
14517        mLastPowerCheckUptime = curUptime;
14518        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
14519            doWakeKills = false;
14520        }
14521        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
14522            doCpuKills = false;
14523        }
14524        int i = mLruProcesses.size();
14525        while (i > 0) {
14526            i--;
14527            ProcessRecord app = mLruProcesses.get(i);
14528            if (!app.keeping) {
14529                long wtime;
14530                synchronized (stats) {
14531                    wtime = stats.getProcessWakeTime(app.info.uid,
14532                            app.pid, curRealtime);
14533                }
14534                long wtimeUsed = wtime - app.lastWakeTime;
14535                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
14536                if (DEBUG_POWER) {
14537                    StringBuilder sb = new StringBuilder(128);
14538                    sb.append("Wake for ");
14539                    app.toShortString(sb);
14540                    sb.append(": over ");
14541                    TimeUtils.formatDuration(realtimeSince, sb);
14542                    sb.append(" used ");
14543                    TimeUtils.formatDuration(wtimeUsed, sb);
14544                    sb.append(" (");
14545                    sb.append((wtimeUsed*100)/realtimeSince);
14546                    sb.append("%)");
14547                    Slog.i(TAG, sb.toString());
14548                    sb.setLength(0);
14549                    sb.append("CPU for ");
14550                    app.toShortString(sb);
14551                    sb.append(": over ");
14552                    TimeUtils.formatDuration(uptimeSince, sb);
14553                    sb.append(" used ");
14554                    TimeUtils.formatDuration(cputimeUsed, sb);
14555                    sb.append(" (");
14556                    sb.append((cputimeUsed*100)/uptimeSince);
14557                    sb.append("%)");
14558                    Slog.i(TAG, sb.toString());
14559                }
14560                // If a process has held a wake lock for more
14561                // than 50% of the time during this period,
14562                // that sounds bad.  Kill!
14563                if (doWakeKills && realtimeSince > 0
14564                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
14565                    synchronized (stats) {
14566                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
14567                                realtimeSince, wtimeUsed);
14568                    }
14569                    Slog.w(TAG, "Excessive wake lock in " + app.processName
14570                            + " (pid " + app.pid + "): held " + wtimeUsed
14571                            + " during " + realtimeSince);
14572                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14573                            app.processName, app.setAdj, "excessive wake lock");
14574                    Process.killProcessQuiet(app.pid);
14575                } else if (doCpuKills && uptimeSince > 0
14576                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
14577                    synchronized (stats) {
14578                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
14579                                uptimeSince, cputimeUsed);
14580                    }
14581                    Slog.w(TAG, "Excessive CPU in " + app.processName
14582                            + " (pid " + app.pid + "): used " + cputimeUsed
14583                            + " during " + uptimeSince);
14584                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14585                            app.processName, app.setAdj, "excessive cpu");
14586                    Process.killProcessQuiet(app.pid);
14587                } else {
14588                    app.lastWakeTime = wtime;
14589                    app.lastCpuTime = app.curCpuTime;
14590                }
14591            }
14592        }
14593    }
14594
14595    private final boolean updateOomAdjLocked(
14596            ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
14597        app.hiddenAdj = hiddenAdj;
14598
14599        if (app.thread == null) {
14600            return false;
14601        }
14602
14603        final boolean wasKeeping = app.keeping;
14604
14605        boolean success = true;
14606
14607        computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
14608
14609        if (app.curRawAdj != app.setRawAdj) {
14610            if (wasKeeping && !app.keeping) {
14611                // This app is no longer something we want to keep.  Note
14612                // its current wake lock time to later know to kill it if
14613                // it is not behaving well.
14614                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14615                synchronized (stats) {
14616                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
14617                            app.pid, SystemClock.elapsedRealtime());
14618                }
14619                app.lastCpuTime = app.curCpuTime;
14620            }
14621
14622            app.setRawAdj = app.curRawAdj;
14623        }
14624
14625        if (app.curAdj != app.setAdj) {
14626            if (Process.setOomAdj(app.pid, app.curAdj)) {
14627                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
14628                    TAG, "Set " + app.pid + " " + app.processName +
14629                    " adj " + app.curAdj + ": " + app.adjType);
14630                app.setAdj = app.curAdj;
14631            } else {
14632                success = false;
14633                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
14634            }
14635        }
14636        if (app.setSchedGroup != app.curSchedGroup) {
14637            app.setSchedGroup = app.curSchedGroup;
14638            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
14639                    "Setting process group of " + app.processName
14640                    + " to " + app.curSchedGroup);
14641            if (app.waitingToKill != null &&
14642                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
14643                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
14644                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14645                        app.processName, app.setAdj, app.waitingToKill);
14646                app.killedBackground = true;
14647                Process.killProcessQuiet(app.pid);
14648                success = false;
14649            } else {
14650                if (true) {
14651                    long oldId = Binder.clearCallingIdentity();
14652                    try {
14653                        Process.setProcessGroup(app.pid, app.curSchedGroup);
14654                    } catch (Exception e) {
14655                        Slog.w(TAG, "Failed setting process group of " + app.pid
14656                                + " to " + app.curSchedGroup);
14657                        e.printStackTrace();
14658                    } finally {
14659                        Binder.restoreCallingIdentity(oldId);
14660                    }
14661                } else {
14662                    if (app.thread != null) {
14663                        try {
14664                            app.thread.setSchedulingGroup(app.curSchedGroup);
14665                        } catch (RemoteException e) {
14666                        }
14667                    }
14668                }
14669            }
14670        }
14671        return success;
14672    }
14673
14674    private final ActivityRecord resumedAppLocked() {
14675        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
14676        if (resumedActivity == null || resumedActivity.app == null) {
14677            resumedActivity = mMainStack.mPausingActivity;
14678            if (resumedActivity == null || resumedActivity.app == null) {
14679                resumedActivity = mMainStack.topRunningActivityLocked(null);
14680            }
14681        }
14682        return resumedActivity;
14683    }
14684
14685    private final boolean updateOomAdjLocked(ProcessRecord app) {
14686        final ActivityRecord TOP_ACT = resumedAppLocked();
14687        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14688        int curAdj = app.curAdj;
14689        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14690            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
14691
14692        mAdjSeq++;
14693
14694        boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
14695        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14696            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
14697        if (nowHidden != wasHidden) {
14698            // Changed to/from hidden state, so apps after it in the LRU
14699            // list may also be changed.
14700            updateOomAdjLocked();
14701        }
14702        return success;
14703    }
14704
14705    final void updateOomAdjLocked() {
14706        final ActivityRecord TOP_ACT = resumedAppLocked();
14707        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14708
14709        if (false) {
14710            RuntimeException e = new RuntimeException();
14711            e.fillInStackTrace();
14712            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
14713        }
14714
14715        mAdjSeq++;
14716        mNewNumServiceProcs = 0;
14717
14718        // Let's determine how many processes we have running vs.
14719        // how many slots we have for background processes; we may want
14720        // to put multiple processes in a slot of there are enough of
14721        // them.
14722        int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
14723        int factor = (mLruProcesses.size()-4)/numSlots;
14724        if (factor < 1) factor = 1;
14725        int step = 0;
14726        int numHidden = 0;
14727        int numTrimming = 0;
14728
14729        // First update the OOM adjustment for each of the
14730        // application processes based on their current state.
14731        int i = mLruProcesses.size();
14732        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
14733        while (i > 0) {
14734            i--;
14735            ProcessRecord app = mLruProcesses.get(i);
14736            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
14737            updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
14738            if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
14739                && app.curAdj == curHiddenAdj) {
14740                step++;
14741                if (step >= factor) {
14742                    step = 0;
14743                    curHiddenAdj++;
14744                }
14745            }
14746            if (!app.killedBackground) {
14747                if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
14748                    numHidden++;
14749                    if (numHidden > mProcessLimit) {
14750                        Slog.i(TAG, "No longer want " + app.processName
14751                                + " (pid " + app.pid + "): hidden #" + numHidden);
14752                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14753                                app.processName, app.setAdj, "too many background");
14754                        app.killedBackground = true;
14755                        Process.killProcessQuiet(app.pid);
14756                    }
14757                }
14758                if (!app.killedBackground && app.isolated && app.services.size() <= 0) {
14759                    // If this is an isolated process, and there are no
14760                    // services running in it, then the process is no longer
14761                    // needed.  We agressively kill these because we can by
14762                    // definition not re-use the same process again, and it is
14763                    // good to avoid having whatever code was running in them
14764                    // left sitting around after no longer needed.
14765                    Slog.i(TAG, "Isolated process " + app.processName
14766                            + " (pid " + app.pid + ") no longer needed");
14767                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14768                            app.processName, app.setAdj, "isolated not needed");
14769                    app.killedBackground = true;
14770                    Process.killProcessQuiet(app.pid);
14771                }
14772                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
14773                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
14774                        && !app.killedBackground) {
14775                    numTrimming++;
14776                }
14777            }
14778        }
14779
14780        mNumServiceProcs = mNewNumServiceProcs;
14781
14782        // Now determine the memory trimming level of background processes.
14783        // Unfortunately we need to start at the back of the list to do this
14784        // properly.  We only do this if the number of background apps we
14785        // are managing to keep around is less than half the maximum we desire;
14786        // if we are keeping a good number around, we'll let them use whatever
14787        // memory they want.
14788        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
14789            final int N = mLruProcesses.size();
14790            factor = numTrimming/3;
14791            int minFactor = 2;
14792            if (mHomeProcess != null) minFactor++;
14793            if (mPreviousProcess != null) minFactor++;
14794            if (factor < minFactor) factor = minFactor;
14795            step = 0;
14796            int fgTrimLevel;
14797            if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/5)) {
14798                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
14799            } else if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/3)) {
14800                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
14801            } else {
14802                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
14803            }
14804            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
14805            for (i=0; i<N; i++) {
14806                ProcessRecord app = mLruProcesses.get(i);
14807                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
14808                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
14809                        && !app.killedBackground) {
14810                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
14811                        try {
14812                            app.thread.scheduleTrimMemory(curLevel);
14813                        } catch (RemoteException e) {
14814                        }
14815                        if (false) {
14816                            // For now we won't do this; our memory trimming seems
14817                            // to be good enough at this point that destroying
14818                            // activities causes more harm than good.
14819                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
14820                                    && app != mHomeProcess && app != mPreviousProcess) {
14821                                // Need to do this on its own message because the stack may not
14822                                // be in a consistent state at this point.
14823                                // For these apps we will also finish their activities
14824                                // to help them free memory.
14825                                mMainStack.scheduleDestroyActivities(app, false, "trim");
14826                            }
14827                        }
14828                    }
14829                    app.trimMemoryLevel = curLevel;
14830                    step++;
14831                    if (step >= factor) {
14832                        step = 0;
14833                        switch (curLevel) {
14834                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
14835                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
14836                                break;
14837                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
14838                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
14839                                break;
14840                        }
14841                    }
14842                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14843                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
14844                            && app.thread != null) {
14845                        try {
14846                            app.thread.scheduleTrimMemory(
14847                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
14848                        } catch (RemoteException e) {
14849                        }
14850                    }
14851                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
14852                } else {
14853                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
14854                            && app.pendingUiClean) {
14855                        // If this application is now in the background and it
14856                        // had done UI, then give it the special trim level to
14857                        // have it free UI resources.
14858                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14859                        if (app.trimMemoryLevel < level && app.thread != null) {
14860                            try {
14861                                app.thread.scheduleTrimMemory(level);
14862                            } catch (RemoteException e) {
14863                            }
14864                        }
14865                        app.pendingUiClean = false;
14866                    }
14867                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
14868                        try {
14869                            app.thread.scheduleTrimMemory(fgTrimLevel);
14870                        } catch (RemoteException e) {
14871                        }
14872                    }
14873                    app.trimMemoryLevel = fgTrimLevel;
14874                }
14875            }
14876        } else {
14877            final int N = mLruProcesses.size();
14878            for (i=0; i<N; i++) {
14879                ProcessRecord app = mLruProcesses.get(i);
14880                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
14881                        && app.pendingUiClean) {
14882                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14883                            && app.thread != null) {
14884                        try {
14885                            app.thread.scheduleTrimMemory(
14886                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14887                        } catch (RemoteException e) {
14888                        }
14889                    }
14890                    app.pendingUiClean = false;
14891                }
14892                app.trimMemoryLevel = 0;
14893            }
14894        }
14895
14896        if (mAlwaysFinishActivities) {
14897            // Need to do this on its own message because the stack may not
14898            // be in a consistent state at this point.
14899            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
14900        }
14901    }
14902
14903    final void trimApplications() {
14904        synchronized (this) {
14905            int i;
14906
14907            // First remove any unused application processes whose package
14908            // has been removed.
14909            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
14910                final ProcessRecord app = mRemovedProcesses.get(i);
14911                if (app.activities.size() == 0
14912                        && app.curReceiver == null && app.services.size() == 0) {
14913                    Slog.i(
14914                        TAG, "Exiting empty application process "
14915                        + app.processName + " ("
14916                        + (app.thread != null ? app.thread.asBinder() : null)
14917                        + ")\n");
14918                    if (app.pid > 0 && app.pid != MY_PID) {
14919                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14920                                app.processName, app.setAdj, "empty");
14921                        Process.killProcessQuiet(app.pid);
14922                    } else {
14923                        try {
14924                            app.thread.scheduleExit();
14925                        } catch (Exception e) {
14926                            // Ignore exceptions.
14927                        }
14928                    }
14929                    cleanUpApplicationRecordLocked(app, false, true, -1);
14930                    mRemovedProcesses.remove(i);
14931
14932                    if (app.persistent) {
14933                        if (app.persistent) {
14934                            addAppLocked(app.info, false);
14935                        }
14936                    }
14937                }
14938            }
14939
14940            // Now update the oom adj for all processes.
14941            updateOomAdjLocked();
14942        }
14943    }
14944
14945    /** This method sends the specified signal to each of the persistent apps */
14946    public void signalPersistentProcesses(int sig) throws RemoteException {
14947        if (sig != Process.SIGNAL_USR1) {
14948            throw new SecurityException("Only SIGNAL_USR1 is allowed");
14949        }
14950
14951        synchronized (this) {
14952            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
14953                    != PackageManager.PERMISSION_GRANTED) {
14954                throw new SecurityException("Requires permission "
14955                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
14956            }
14957
14958            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14959                ProcessRecord r = mLruProcesses.get(i);
14960                if (r.thread != null && r.persistent) {
14961                    Process.sendSignal(r.pid, sig);
14962                }
14963            }
14964        }
14965    }
14966
14967    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
14968        if (proc == null || proc == mProfileProc) {
14969            proc = mProfileProc;
14970            path = mProfileFile;
14971            profileType = mProfileType;
14972            clearProfilerLocked();
14973        }
14974        if (proc == null) {
14975            return;
14976        }
14977        try {
14978            proc.thread.profilerControl(false, path, null, profileType);
14979        } catch (RemoteException e) {
14980            throw new IllegalStateException("Process disappeared");
14981        }
14982    }
14983
14984    private void clearProfilerLocked() {
14985        if (mProfileFd != null) {
14986            try {
14987                mProfileFd.close();
14988            } catch (IOException e) {
14989            }
14990        }
14991        mProfileApp = null;
14992        mProfileProc = null;
14993        mProfileFile = null;
14994        mProfileType = 0;
14995        mAutoStopProfiler = false;
14996    }
14997
14998    public boolean profileControl(String process, boolean start,
14999            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
15000
15001        try {
15002            synchronized (this) {
15003                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15004                // its own permission.
15005                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15006                        != PackageManager.PERMISSION_GRANTED) {
15007                    throw new SecurityException("Requires permission "
15008                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15009                }
15010
15011                if (start && fd == null) {
15012                    throw new IllegalArgumentException("null fd");
15013                }
15014
15015                ProcessRecord proc = null;
15016                if (process != null) {
15017                    try {
15018                        int pid = Integer.parseInt(process);
15019                        synchronized (mPidsSelfLocked) {
15020                            proc = mPidsSelfLocked.get(pid);
15021                        }
15022                    } catch (NumberFormatException e) {
15023                    }
15024
15025                    if (proc == null) {
15026                        HashMap<String, SparseArray<ProcessRecord>> all
15027                                = mProcessNames.getMap();
15028                        SparseArray<ProcessRecord> procs = all.get(process);
15029                        if (procs != null && procs.size() > 0) {
15030                            proc = procs.valueAt(0);
15031                        }
15032                    }
15033                }
15034
15035                if (start && (proc == null || proc.thread == null)) {
15036                    throw new IllegalArgumentException("Unknown process: " + process);
15037                }
15038
15039                if (start) {
15040                    stopProfilerLocked(null, null, 0);
15041                    setProfileApp(proc.info, proc.processName, path, fd, false);
15042                    mProfileProc = proc;
15043                    mProfileType = profileType;
15044                    try {
15045                        fd = fd.dup();
15046                    } catch (IOException e) {
15047                        fd = null;
15048                    }
15049                    proc.thread.profilerControl(start, path, fd, profileType);
15050                    fd = null;
15051                    mProfileFd = null;
15052                } else {
15053                    stopProfilerLocked(proc, path, profileType);
15054                    if (fd != null) {
15055                        try {
15056                            fd.close();
15057                        } catch (IOException e) {
15058                        }
15059                    }
15060                }
15061
15062                return true;
15063            }
15064        } catch (RemoteException e) {
15065            throw new IllegalStateException("Process disappeared");
15066        } finally {
15067            if (fd != null) {
15068                try {
15069                    fd.close();
15070                } catch (IOException e) {
15071                }
15072            }
15073        }
15074    }
15075
15076    public boolean dumpHeap(String process, boolean managed,
15077            String path, ParcelFileDescriptor fd) throws RemoteException {
15078
15079        try {
15080            synchronized (this) {
15081                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15082                // its own permission (same as profileControl).
15083                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15084                        != PackageManager.PERMISSION_GRANTED) {
15085                    throw new SecurityException("Requires permission "
15086                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15087                }
15088
15089                if (fd == null) {
15090                    throw new IllegalArgumentException("null fd");
15091                }
15092
15093                ProcessRecord proc = null;
15094                try {
15095                    int pid = Integer.parseInt(process);
15096                    synchronized (mPidsSelfLocked) {
15097                        proc = mPidsSelfLocked.get(pid);
15098                    }
15099                } catch (NumberFormatException e) {
15100                }
15101
15102                if (proc == null) {
15103                    HashMap<String, SparseArray<ProcessRecord>> all
15104                            = mProcessNames.getMap();
15105                    SparseArray<ProcessRecord> procs = all.get(process);
15106                    if (procs != null && procs.size() > 0) {
15107                        proc = procs.valueAt(0);
15108                    }
15109                }
15110
15111                if (proc == null || proc.thread == null) {
15112                    throw new IllegalArgumentException("Unknown process: " + process);
15113                }
15114
15115                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
15116                if (!isDebuggable) {
15117                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
15118                        throw new SecurityException("Process not debuggable: " + proc);
15119                    }
15120                }
15121
15122                proc.thread.dumpHeap(managed, path, fd);
15123                fd = null;
15124                return true;
15125            }
15126        } catch (RemoteException e) {
15127            throw new IllegalStateException("Process disappeared");
15128        } finally {
15129            if (fd != null) {
15130                try {
15131                    fd.close();
15132                } catch (IOException e) {
15133                }
15134            }
15135        }
15136    }
15137
15138    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
15139    public void monitor() {
15140        synchronized (this) { }
15141    }
15142
15143    void onCoreSettingsChange(Bundle settings) {
15144        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15145            ProcessRecord processRecord = mLruProcesses.get(i);
15146            try {
15147                if (processRecord.thread != null) {
15148                    processRecord.thread.setCoreSettings(settings);
15149                }
15150            } catch (RemoteException re) {
15151                /* ignore */
15152            }
15153        }
15154    }
15155
15156    // Multi-user methods
15157
15158    private int mCurrentUserId;
15159    private SparseIntArray mLoggedInUsers = new SparseIntArray(5);
15160
15161    public boolean switchUser(int userId) {
15162        final int callingUid = Binder.getCallingUid();
15163        if (callingUid != 0 && callingUid != Process.myUid()) {
15164            Slog.e(TAG, "Trying to switch user from unauthorized app");
15165            return false;
15166        }
15167        if (mCurrentUserId == userId)
15168            return true;
15169
15170        synchronized (this) {
15171            // Check if user is already logged in, otherwise check if user exists first before
15172            // adding to the list of logged in users.
15173            if (mLoggedInUsers.indexOfKey(userId) < 0) {
15174                if (!userExists(userId)) {
15175                    return false;
15176                }
15177                mLoggedInUsers.append(userId, userId);
15178            }
15179
15180            mCurrentUserId = userId;
15181            boolean haveActivities = mMainStack.switchUser(userId);
15182            if (!haveActivities) {
15183                startHomeActivityLocked(userId);
15184            }
15185
15186        }
15187
15188        // Inform of user switch
15189        Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
15190        addedIntent.putExtra(Intent.EXTRA_USERID, userId);
15191        mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS);
15192
15193        return true;
15194    }
15195
15196    @Override
15197    public UserInfo getCurrentUser() throws RemoteException {
15198        final int callingUid = Binder.getCallingUid();
15199        if (callingUid != 0 && callingUid != Process.myUid()) {
15200            Slog.e(TAG, "Trying to get user from unauthorized app");
15201            return null;
15202        }
15203        return AppGlobals.getPackageManager().getUser(mCurrentUserId);
15204    }
15205
15206    private void onUserRemoved(Intent intent) {
15207        int extraUserId = intent.getIntExtra(Intent.EXTRA_USERID, -1);
15208        if (extraUserId < 1) return;
15209
15210        // Kill all the processes for the user
15211        ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>();
15212        synchronized (this) {
15213            HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap();
15214            for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) {
15215                SparseArray<ProcessRecord> uids = uidMap.getValue();
15216                for (int i = 0; i < uids.size(); i++) {
15217                    if (UserId.getUserId(uids.keyAt(i)) == extraUserId) {
15218                        pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i)));
15219                    }
15220                }
15221            }
15222
15223            for (Pair<String,Integer> pkgAndUid : pkgAndUids) {
15224                forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second,
15225                        false, false, true, true, extraUserId);
15226            }
15227        }
15228    }
15229
15230    private boolean userExists(int userId) {
15231        try {
15232            UserInfo user = AppGlobals.getPackageManager().getUser(userId);
15233            return user != null;
15234        } catch (RemoteException re) {
15235            // Won't happen, in same process
15236        }
15237
15238        return false;
15239    }
15240
15241    private void checkValidCaller(int uid, int userId) {
15242        if (UserId.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
15243
15244        throw new SecurityException("Caller uid=" + uid
15245                + " is not privileged to communicate with user=" + userId);
15246    }
15247
15248    private int applyUserId(int uid, int userId) {
15249        return UserId.getUid(userId, uid);
15250    }
15251
15252    private ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
15253        if (info == null) return null;
15254        ApplicationInfo newInfo = new ApplicationInfo(info);
15255        newInfo.uid = applyUserId(info.uid, userId);
15256        newInfo.dataDir = USER_DATA_DIR + userId + "/"
15257                + info.packageName;
15258        return newInfo;
15259    }
15260
15261    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
15262        if (aInfo == null
15263                || (userId < 1 && aInfo.applicationInfo.uid < UserId.PER_USER_RANGE)) {
15264            return aInfo;
15265        }
15266
15267        ActivityInfo info = new ActivityInfo(aInfo);
15268        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
15269        return info;
15270    }
15271
15272    static class ServiceMap {
15273
15274        private final SparseArray<HashMap<ComponentName, ServiceRecord>> mServicesByNamePerUser
15275                = new SparseArray<HashMap<ComponentName, ServiceRecord>>();
15276        private final SparseArray<HashMap<Intent.FilterComparison, ServiceRecord>>
15277                mServicesByIntentPerUser = new SparseArray<
15278                    HashMap<Intent.FilterComparison, ServiceRecord>>();
15279
15280        ServiceRecord getServiceByName(ComponentName name, int callingUser) {
15281            // TODO: Deal with global services
15282            if (DEBUG_MU)
15283                Slog.v(TAG_MU, "getServiceByName(" + name + "), callingUser = " + callingUser);
15284            return getServices(callingUser).get(name);
15285        }
15286
15287        ServiceRecord getServiceByName(ComponentName name) {
15288            return getServiceByName(name, -1);
15289        }
15290
15291        ServiceRecord getServiceByIntent(Intent.FilterComparison filter, int callingUser) {
15292            // TODO: Deal with global services
15293            if (DEBUG_MU)
15294                Slog.v(TAG_MU, "getServiceByIntent(" + filter + "), callingUser = " + callingUser);
15295            return getServicesByIntent(callingUser).get(filter);
15296        }
15297
15298        ServiceRecord getServiceByIntent(Intent.FilterComparison filter) {
15299            return getServiceByIntent(filter, -1);
15300        }
15301
15302        void putServiceByName(ComponentName name, int callingUser, ServiceRecord value) {
15303            // TODO: Deal with global services
15304            getServices(callingUser).put(name, value);
15305        }
15306
15307        void putServiceByIntent(Intent.FilterComparison filter, int callingUser,
15308                ServiceRecord value) {
15309            // TODO: Deal with global services
15310            getServicesByIntent(callingUser).put(filter, value);
15311        }
15312
15313        void removeServiceByName(ComponentName name, int callingUser) {
15314            // TODO: Deal with global services
15315            ServiceRecord removed = getServices(callingUser).remove(name);
15316            if (DEBUG_MU)
15317                Slog.v(TAG, "removeServiceByName user=" + callingUser + " name=" + name
15318                        + " removed=" + removed);
15319        }
15320
15321        void removeServiceByIntent(Intent.FilterComparison filter, int callingUser) {
15322            // TODO: Deal with global services
15323            ServiceRecord removed = getServicesByIntent(callingUser).remove(filter);
15324            if (DEBUG_MU)
15325                Slog.v(TAG_MU, "removeServiceByIntent user=" + callingUser + " intent=" + filter
15326                        + " removed=" + removed);
15327        }
15328
15329        Collection<ServiceRecord> getAllServices(int callingUser) {
15330            // TODO: Deal with global services
15331            return getServices(callingUser).values();
15332        }
15333
15334        private HashMap<ComponentName, ServiceRecord> getServices(int callingUser) {
15335            HashMap map = mServicesByNamePerUser.get(callingUser);
15336            if (map == null) {
15337                map = new HashMap<ComponentName, ServiceRecord>();
15338                mServicesByNamePerUser.put(callingUser, map);
15339            }
15340            return map;
15341        }
15342
15343        private HashMap<Intent.FilterComparison, ServiceRecord> getServicesByIntent(
15344                int callingUser) {
15345            HashMap map = mServicesByIntentPerUser.get(callingUser);
15346            if (map == null) {
15347                map = new HashMap<Intent.FilterComparison, ServiceRecord>();
15348                mServicesByIntentPerUser.put(callingUser, map);
15349            }
15350            return map;
15351        }
15352    }
15353}
15354