ActivityManagerService.java revision 1927ae8a56a010919a7535231fa0f7db70f7e152
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, oomAdj,
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, oomAdj,
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);
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            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5708            SparseArray<ProcessRecord> appProcs
5709                    = mProcessNames.getMap().get(component.getPackageName());
5710            if (appProcs != null) {
5711                for (int i=0; i<appProcs.size(); i++) {
5712                    procs.add(appProcs.valueAt(i));
5713                }
5714            }
5715
5716            // Kill the running processes.
5717            for (int i=0; i<procs.size(); i++) {
5718                ProcessRecord pr = procs.get(i);
5719                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5720                    Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5721                    EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5722                            pr.processName, pr.setAdj, "remove task");
5723                    Process.killProcessQuiet(pr.pid);
5724                } else {
5725                    pr.waitingToKill = "remove task";
5726                }
5727            }
5728        }
5729    }
5730
5731    public boolean removeTask(int taskId, int flags) {
5732        synchronized (this) {
5733            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5734                    "removeTask()");
5735            long ident = Binder.clearCallingIdentity();
5736            try {
5737                ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5738                        false);
5739                if (r != null) {
5740                    mRecentTasks.remove(r.task);
5741                    cleanUpRemovedTaskLocked(r.task, flags);
5742                    return true;
5743                } else {
5744                    TaskRecord tr = null;
5745                    int i=0;
5746                    while (i < mRecentTasks.size()) {
5747                        TaskRecord t = mRecentTasks.get(i);
5748                        if (t.taskId == taskId) {
5749                            tr = t;
5750                            break;
5751                        }
5752                        i++;
5753                    }
5754                    if (tr != null) {
5755                        if (tr.numActivities <= 0) {
5756                            // Caller is just removing a recent task that is
5757                            // not actively running.  That is easy!
5758                            mRecentTasks.remove(i);
5759                            cleanUpRemovedTaskLocked(tr, flags);
5760                            return true;
5761                        } else {
5762                            Slog.w(TAG, "removeTask: task " + taskId
5763                                    + " does not have activities to remove, "
5764                                    + " but numActivities=" + tr.numActivities
5765                                    + ": " + tr);
5766                        }
5767                    }
5768                }
5769            } finally {
5770                Binder.restoreCallingIdentity(ident);
5771            }
5772        }
5773        return false;
5774    }
5775
5776    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5777        int j;
5778        TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5779        TaskRecord jt = startTask;
5780
5781        // First look backwards
5782        for (j=startIndex-1; j>=0; j--) {
5783            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5784            if (r.task != jt) {
5785                jt = r.task;
5786                if (affinity.equals(jt.affinity)) {
5787                    return j;
5788                }
5789            }
5790        }
5791
5792        // Now look forwards
5793        final int N = mMainStack.mHistory.size();
5794        jt = startTask;
5795        for (j=startIndex+1; j<N; j++) {
5796            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
5797            if (r.task != jt) {
5798                if (affinity.equals(jt.affinity)) {
5799                    return j;
5800                }
5801                jt = r.task;
5802            }
5803        }
5804
5805        // Might it be at the top?
5806        if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
5807            return N-1;
5808        }
5809
5810        return -1;
5811    }
5812
5813    /**
5814     * TODO: Add mController hook
5815     */
5816    public void moveTaskToFront(int task, int flags, Bundle options) {
5817        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5818                "moveTaskToFront()");
5819
5820        synchronized(this) {
5821            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5822                    Binder.getCallingUid(), "Task to front")) {
5823                ActivityOptions.abort(options);
5824                return;
5825            }
5826            final long origId = Binder.clearCallingIdentity();
5827            try {
5828                TaskRecord tr = taskForIdLocked(task);
5829                if (tr != null) {
5830                    if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5831                        mMainStack.mUserLeaving = true;
5832                    }
5833                    if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5834                        // Caller wants the home activity moved with it.  To accomplish this,
5835                        // we'll just move the home task to the top first.
5836                        mMainStack.moveHomeToFrontLocked();
5837                    }
5838                    mMainStack.moveTaskToFrontLocked(tr, null, options);
5839                    return;
5840                }
5841                for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5842                    ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
5843                    if (hr.task.taskId == task) {
5844                        if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5845                            mMainStack.mUserLeaving = true;
5846                        }
5847                        if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5848                            // Caller wants the home activity moved with it.  To accomplish this,
5849                            // we'll just move the home task to the top first.
5850                            mMainStack.moveHomeToFrontLocked();
5851                        }
5852                        mMainStack.moveTaskToFrontLocked(hr.task, null, options);
5853                        return;
5854                    }
5855                }
5856            } finally {
5857                Binder.restoreCallingIdentity(origId);
5858            }
5859            ActivityOptions.abort(options);
5860        }
5861    }
5862
5863    public void moveTaskToBack(int task) {
5864        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5865                "moveTaskToBack()");
5866
5867        synchronized(this) {
5868            if (mMainStack.mResumedActivity != null
5869                    && mMainStack.mResumedActivity.task.taskId == task) {
5870                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5871                        Binder.getCallingUid(), "Task to back")) {
5872                    return;
5873                }
5874            }
5875            final long origId = Binder.clearCallingIdentity();
5876            mMainStack.moveTaskToBackLocked(task, null);
5877            Binder.restoreCallingIdentity(origId);
5878        }
5879    }
5880
5881    /**
5882     * Moves an activity, and all of the other activities within the same task, to the bottom
5883     * of the history stack.  The activity's order within the task is unchanged.
5884     *
5885     * @param token A reference to the activity we wish to move
5886     * @param nonRoot If false then this only works if the activity is the root
5887     *                of a task; if true it will work for any activity in a task.
5888     * @return Returns true if the move completed, false if not.
5889     */
5890    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5891        enforceNotIsolatedCaller("moveActivityTaskToBack");
5892        synchronized(this) {
5893            final long origId = Binder.clearCallingIdentity();
5894            int taskId = getTaskForActivityLocked(token, !nonRoot);
5895            if (taskId >= 0) {
5896                return mMainStack.moveTaskToBackLocked(taskId, null);
5897            }
5898            Binder.restoreCallingIdentity(origId);
5899        }
5900        return false;
5901    }
5902
5903    public void moveTaskBackwards(int task) {
5904        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5905                "moveTaskBackwards()");
5906
5907        synchronized(this) {
5908            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5909                    Binder.getCallingUid(), "Task backwards")) {
5910                return;
5911            }
5912            final long origId = Binder.clearCallingIdentity();
5913            moveTaskBackwardsLocked(task);
5914            Binder.restoreCallingIdentity(origId);
5915        }
5916    }
5917
5918    private final void moveTaskBackwardsLocked(int task) {
5919        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
5920    }
5921
5922    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5923        synchronized(this) {
5924            return getTaskForActivityLocked(token, onlyRoot);
5925        }
5926    }
5927
5928    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
5929        final int N = mMainStack.mHistory.size();
5930        TaskRecord lastTask = null;
5931        for (int i=0; i<N; i++) {
5932            ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
5933            if (r.appToken == token) {
5934                if (!onlyRoot || lastTask != r.task) {
5935                    return r.task.taskId;
5936                }
5937                return -1;
5938            }
5939            lastTask = r.task;
5940        }
5941
5942        return -1;
5943    }
5944
5945    // =========================================================
5946    // THUMBNAILS
5947    // =========================================================
5948
5949    public void reportThumbnail(IBinder token,
5950            Bitmap thumbnail, CharSequence description) {
5951        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5952        final long origId = Binder.clearCallingIdentity();
5953        sendPendingThumbnail(null, token, thumbnail, description, true);
5954        Binder.restoreCallingIdentity(origId);
5955    }
5956
5957    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
5958            Bitmap thumbnail, CharSequence description, boolean always) {
5959        TaskRecord task = null;
5960        ArrayList receivers = null;
5961
5962        //System.out.println("Send pending thumbnail: " + r);
5963
5964        synchronized(this) {
5965            if (r == null) {
5966                r = mMainStack.isInStackLocked(token);
5967                if (r == null) {
5968                    return;
5969                }
5970            }
5971            if (thumbnail == null && r.thumbHolder != null) {
5972                thumbnail = r.thumbHolder.lastThumbnail;
5973                description = r.thumbHolder.lastDescription;
5974            }
5975            if (thumbnail == null && !always) {
5976                // If there is no thumbnail, and this entry is not actually
5977                // going away, then abort for now and pick up the next
5978                // thumbnail we get.
5979                return;
5980            }
5981            task = r.task;
5982
5983            int N = mPendingThumbnails.size();
5984            int i=0;
5985            while (i<N) {
5986                PendingThumbnailsRecord pr =
5987                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5988                //System.out.println("Looking in " + pr.pendingRecords);
5989                if (pr.pendingRecords.remove(r)) {
5990                    if (receivers == null) {
5991                        receivers = new ArrayList();
5992                    }
5993                    receivers.add(pr);
5994                    if (pr.pendingRecords.size() == 0) {
5995                        pr.finished = true;
5996                        mPendingThumbnails.remove(i);
5997                        N--;
5998                        continue;
5999                    }
6000                }
6001                i++;
6002            }
6003        }
6004
6005        if (receivers != null) {
6006            final int N = receivers.size();
6007            for (int i=0; i<N; i++) {
6008                try {
6009                    PendingThumbnailsRecord pr =
6010                        (PendingThumbnailsRecord)receivers.get(i);
6011                    pr.receiver.newThumbnail(
6012                        task != null ? task.taskId : -1, thumbnail, description);
6013                    if (pr.finished) {
6014                        pr.receiver.finished();
6015                    }
6016                } catch (Exception e) {
6017                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6018                }
6019            }
6020        }
6021    }
6022
6023    // =========================================================
6024    // CONTENT PROVIDERS
6025    // =========================================================
6026
6027    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6028        List<ProviderInfo> providers = null;
6029        try {
6030            providers = AppGlobals.getPackageManager().
6031                queryContentProviders(app.processName, app.uid,
6032                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6033        } catch (RemoteException ex) {
6034        }
6035        if (DEBUG_MU)
6036            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6037        int userId = app.userId;
6038        if (providers != null) {
6039            final int N = providers.size();
6040            for (int i=0; i<N; i++) {
6041                ProviderInfo cpi =
6042                    (ProviderInfo)providers.get(i);
6043
6044                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6045                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6046                if (cpr == null) {
6047                    cpr = new ContentProviderRecord(this, cpi, app.info, comp);
6048                    mProviderMap.putProviderByClass(comp, cpr);
6049                }
6050                if (DEBUG_MU)
6051                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6052                app.pubProviders.put(cpi.name, cpr);
6053                app.addPackage(cpi.applicationInfo.packageName);
6054                ensurePackageDexOpt(cpi.applicationInfo.packageName);
6055            }
6056        }
6057        return providers;
6058    }
6059
6060    /**
6061     * Check if {@link ProcessRecord} has a possible chance at accessing the
6062     * given {@link ProviderInfo}. Final permission checking is always done
6063     * in {@link ContentProvider}.
6064     */
6065    private final String checkContentProviderPermissionLocked(
6066            ProviderInfo cpi, ProcessRecord r) {
6067        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6068        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6069        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6070                cpi.applicationInfo.uid, cpi.exported)
6071                == PackageManager.PERMISSION_GRANTED) {
6072            return null;
6073        }
6074        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6075                cpi.applicationInfo.uid, cpi.exported)
6076                == PackageManager.PERMISSION_GRANTED) {
6077            return null;
6078        }
6079
6080        PathPermission[] pps = cpi.pathPermissions;
6081        if (pps != null) {
6082            int i = pps.length;
6083            while (i > 0) {
6084                i--;
6085                PathPermission pp = pps[i];
6086                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6087                        cpi.applicationInfo.uid, cpi.exported)
6088                        == PackageManager.PERMISSION_GRANTED) {
6089                    return null;
6090                }
6091                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6092                        cpi.applicationInfo.uid, cpi.exported)
6093                        == PackageManager.PERMISSION_GRANTED) {
6094                    return null;
6095                }
6096            }
6097        }
6098
6099        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6100        if (perms != null) {
6101            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6102                if (uri.getKey().getAuthority().equals(cpi.authority)) {
6103                    return null;
6104                }
6105            }
6106        }
6107
6108        String msg;
6109        if (!cpi.exported) {
6110            msg = "Permission Denial: opening provider " + cpi.name
6111                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6112                    + ", uid=" + callingUid + ") that is not exported from uid "
6113                    + cpi.applicationInfo.uid;
6114        } else {
6115            msg = "Permission Denial: opening provider " + cpi.name
6116                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6117                    + ", uid=" + callingUid + ") requires "
6118                    + cpi.readPermission + " or " + cpi.writePermission;
6119        }
6120        Slog.w(TAG, msg);
6121        return msg;
6122    }
6123
6124    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6125            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6126        if (r != null) {
6127            for (int i=0; i<r.conProviders.size(); i++) {
6128                ContentProviderConnection conn = r.conProviders.get(i);
6129                if (conn.provider == cpr) {
6130                    if (DEBUG_PROVIDER) Slog.v(TAG,
6131                            "Adding provider requested by "
6132                            + r.processName + " from process "
6133                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6134                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6135                    if (stable) {
6136                        conn.stableCount++;
6137                        conn.numStableIncs++;
6138                    } else {
6139                        conn.unstableCount++;
6140                        conn.numUnstableIncs++;
6141                    }
6142                    return conn;
6143                }
6144            }
6145            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6146            if (stable) {
6147                conn.stableCount = 1;
6148                conn.numStableIncs = 1;
6149            } else {
6150                conn.unstableCount = 1;
6151                conn.numUnstableIncs = 1;
6152            }
6153            cpr.connections.add(conn);
6154            r.conProviders.add(conn);
6155            return conn;
6156        }
6157        cpr.addExternalProcessHandleLocked(externalProcessToken);
6158        return null;
6159    }
6160
6161    boolean decProviderCountLocked(ContentProviderConnection conn,
6162            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6163        if (conn != null) {
6164            cpr = conn.provider;
6165            if (DEBUG_PROVIDER) Slog.v(TAG,
6166                    "Removing provider requested by "
6167                    + conn.client.processName + " from process "
6168                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6169                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6170            if (stable) {
6171                conn.stableCount--;
6172            } else {
6173                conn.unstableCount--;
6174            }
6175            if (conn.stableCount == 0 && conn.unstableCount == 0) {
6176                cpr.connections.remove(conn);
6177                conn.client.conProviders.remove(conn);
6178                return true;
6179            }
6180            return false;
6181        }
6182        cpr.removeExternalProcessHandleLocked(externalProcessToken);
6183        return false;
6184    }
6185
6186    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6187            String name, IBinder token, boolean stable) {
6188        ContentProviderRecord cpr;
6189        ContentProviderConnection conn = null;
6190        ProviderInfo cpi = null;
6191
6192        synchronized(this) {
6193            ProcessRecord r = null;
6194            if (caller != null) {
6195                r = getRecordForAppLocked(caller);
6196                if (r == null) {
6197                    throw new SecurityException(
6198                            "Unable to find app for caller " + caller
6199                          + " (pid=" + Binder.getCallingPid()
6200                          + ") when getting content provider " + name);
6201                }
6202            }
6203
6204            // First check if this content provider has been published...
6205            int userId = UserId.getUserId(r != null ? r.uid : Binder.getCallingUid());
6206            cpr = mProviderMap.getProviderByName(name, userId);
6207            boolean providerRunning = cpr != null;
6208            if (providerRunning) {
6209                cpi = cpr.info;
6210                String msg;
6211                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6212                    throw new SecurityException(msg);
6213                }
6214
6215                if (r != null && cpr.canRunHere(r)) {
6216                    // This provider has been published or is in the process
6217                    // of being published...  but it is also allowed to run
6218                    // in the caller's process, so don't make a connection
6219                    // and just let the caller instantiate its own instance.
6220                    ContentProviderHolder holder = cpr.newHolder(null);
6221                    // don't give caller the provider object, it needs
6222                    // to make its own.
6223                    holder.provider = null;
6224                    return holder;
6225                }
6226
6227                final long origId = Binder.clearCallingIdentity();
6228
6229                // In this case the provider instance already exists, so we can
6230                // return it right away.
6231                conn = incProviderCountLocked(r, cpr, token, stable);
6232                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6233                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6234                        // If this is a perceptible app accessing the provider,
6235                        // make sure to count it as being accessed and thus
6236                        // back up on the LRU list.  This is good because
6237                        // content providers are often expensive to start.
6238                        updateLruProcessLocked(cpr.proc, false, true);
6239                    }
6240                }
6241
6242                if (cpr.proc != null) {
6243                    if (false) {
6244                        if (cpr.name.flattenToShortString().equals(
6245                                "com.android.providers.calendar/.CalendarProvider2")) {
6246                            Slog.v(TAG, "****************** KILLING "
6247                                + cpr.name.flattenToShortString());
6248                            Process.killProcess(cpr.proc.pid);
6249                        }
6250                    }
6251                    boolean success = updateOomAdjLocked(cpr.proc);
6252                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6253                    // NOTE: there is still a race here where a signal could be
6254                    // pending on the process even though we managed to update its
6255                    // adj level.  Not sure what to do about this, but at least
6256                    // the race is now smaller.
6257                    if (!success) {
6258                        // Uh oh...  it looks like the provider's process
6259                        // has been killed on us.  We need to wait for a new
6260                        // process to be started, and make sure its death
6261                        // doesn't kill our process.
6262                        Slog.i(TAG,
6263                                "Existing provider " + cpr.name.flattenToShortString()
6264                                + " is crashing; detaching " + r);
6265                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6266                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6267                        if (!lastRef) {
6268                            // This wasn't the last ref our process had on
6269                            // the provider...  we have now been killed, bail.
6270                            return null;
6271                        }
6272                        providerRunning = false;
6273                        conn = null;
6274                    }
6275                }
6276
6277                Binder.restoreCallingIdentity(origId);
6278            }
6279
6280            if (!providerRunning) {
6281                try {
6282                    cpi = AppGlobals.getPackageManager().
6283                        resolveContentProvider(name,
6284                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6285                } catch (RemoteException ex) {
6286                }
6287                if (cpi == null) {
6288                    return null;
6289                }
6290                if (isSingleton(cpi.processName, cpi.applicationInfo)) {
6291                    userId = 0;
6292                }
6293                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6294
6295                String msg;
6296                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6297                    throw new SecurityException(msg);
6298                }
6299
6300                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6301                        && !cpi.processName.equals("system")) {
6302                    // If this content provider does not run in the system
6303                    // process, and the system is not yet ready to run other
6304                    // processes, then fail fast instead of hanging.
6305                    throw new IllegalArgumentException(
6306                            "Attempt to launch content provider before system ready");
6307                }
6308
6309                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6310                cpr = mProviderMap.getProviderByClass(comp, userId);
6311                final boolean firstClass = cpr == null;
6312                if (firstClass) {
6313                    try {
6314                        ApplicationInfo ai =
6315                            AppGlobals.getPackageManager().
6316                                getApplicationInfo(
6317                                        cpi.applicationInfo.packageName,
6318                                        STOCK_PM_FLAGS, userId);
6319                        if (ai == null) {
6320                            Slog.w(TAG, "No package info for content provider "
6321                                    + cpi.name);
6322                            return null;
6323                        }
6324                        ai = getAppInfoForUser(ai, userId);
6325                        cpr = new ContentProviderRecord(this, cpi, ai, comp);
6326                    } catch (RemoteException ex) {
6327                        // pm is in same process, this will never happen.
6328                    }
6329                }
6330
6331                if (r != null && cpr.canRunHere(r)) {
6332                    // If this is a multiprocess provider, then just return its
6333                    // info and allow the caller to instantiate it.  Only do
6334                    // this if the provider is the same user as the caller's
6335                    // process, or can run as root (so can be in any process).
6336                    return cpr.newHolder(null);
6337                }
6338
6339                if (DEBUG_PROVIDER) {
6340                    RuntimeException e = new RuntimeException("here");
6341                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6342                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6343                }
6344
6345                // This is single process, and our app is now connecting to it.
6346                // See if we are already in the process of launching this
6347                // provider.
6348                final int N = mLaunchingProviders.size();
6349                int i;
6350                for (i=0; i<N; i++) {
6351                    if (mLaunchingProviders.get(i) == cpr) {
6352                        break;
6353                    }
6354                }
6355
6356                // If the provider is not already being launched, then get it
6357                // started.
6358                if (i >= N) {
6359                    final long origId = Binder.clearCallingIdentity();
6360
6361                    try {
6362                        // Content provider is now in use, its package can't be stopped.
6363                        try {
6364                            AppGlobals.getPackageManager().setPackageStoppedState(
6365                                    cpr.appInfo.packageName, false, userId);
6366                        } catch (RemoteException e) {
6367                        } catch (IllegalArgumentException e) {
6368                            Slog.w(TAG, "Failed trying to unstop package "
6369                                    + cpr.appInfo.packageName + ": " + e);
6370                        }
6371
6372                        ProcessRecord proc = startProcessLocked(cpi.processName,
6373                                cpr.appInfo, false, 0, "content provider",
6374                                new ComponentName(cpi.applicationInfo.packageName,
6375                                        cpi.name), false, false);
6376                        if (proc == null) {
6377                            Slog.w(TAG, "Unable to launch app "
6378                                    + cpi.applicationInfo.packageName + "/"
6379                                    + cpi.applicationInfo.uid + " for provider "
6380                                    + name + ": process is bad");
6381                            return null;
6382                        }
6383                        cpr.launchingApp = proc;
6384                        mLaunchingProviders.add(cpr);
6385                    } finally {
6386                        Binder.restoreCallingIdentity(origId);
6387                    }
6388                }
6389
6390                // Make sure the provider is published (the same provider class
6391                // may be published under multiple names).
6392                if (firstClass) {
6393                    mProviderMap.putProviderByClass(comp, cpr);
6394                }
6395
6396                mProviderMap.putProviderByName(name, cpr);
6397                conn = incProviderCountLocked(r, cpr, token, stable);
6398                if (conn != null) {
6399                    conn.waiting = true;
6400                }
6401            }
6402        }
6403
6404        // Wait for the provider to be published...
6405        synchronized (cpr) {
6406            while (cpr.provider == null) {
6407                if (cpr.launchingApp == null) {
6408                    Slog.w(TAG, "Unable to launch app "
6409                            + cpi.applicationInfo.packageName + "/"
6410                            + cpi.applicationInfo.uid + " for provider "
6411                            + name + ": launching app became null");
6412                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6413                            cpi.applicationInfo.packageName,
6414                            cpi.applicationInfo.uid, name);
6415                    return null;
6416                }
6417                try {
6418                    if (DEBUG_MU) {
6419                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6420                                + cpr.launchingApp);
6421                    }
6422                    if (conn != null) {
6423                        conn.waiting = true;
6424                    }
6425                    cpr.wait();
6426                } catch (InterruptedException ex) {
6427                } finally {
6428                    if (conn != null) {
6429                        conn.waiting = false;
6430                    }
6431                }
6432            }
6433        }
6434        return cpr != null ? cpr.newHolder(conn) : null;
6435    }
6436
6437    public final ContentProviderHolder getContentProvider(
6438            IApplicationThread caller, String name, boolean stable) {
6439        enforceNotIsolatedCaller("getContentProvider");
6440        if (caller == null) {
6441            String msg = "null IApplicationThread when getting content provider "
6442                    + name;
6443            Slog.w(TAG, msg);
6444            throw new SecurityException(msg);
6445        }
6446
6447        return getContentProviderImpl(caller, name, null, stable);
6448    }
6449
6450    public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6451        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6452            "Do not have permission in call getContentProviderExternal()");
6453        return getContentProviderExternalUnchecked(name, token);
6454    }
6455
6456    private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) {
6457        return getContentProviderImpl(null, name, token, true);
6458    }
6459
6460    /**
6461     * Drop a content provider from a ProcessRecord's bookkeeping
6462     * @param cpr
6463     */
6464    public void removeContentProvider(IBinder connection, boolean stable) {
6465        enforceNotIsolatedCaller("removeContentProvider");
6466        synchronized (this) {
6467            ContentProviderConnection conn;
6468            try {
6469                conn = (ContentProviderConnection)connection;
6470            } catch (ClassCastException e) {
6471                String msg ="removeContentProvider: " + connection
6472                        + " not a ContentProviderConnection";
6473                Slog.w(TAG, msg);
6474                throw new IllegalArgumentException(msg);
6475            }
6476            if (conn == null) {
6477                throw new NullPointerException("connection is null");
6478            }
6479            if (decProviderCountLocked(conn, null, null, stable)) {
6480                updateOomAdjLocked();
6481            }
6482        }
6483    }
6484
6485    public void removeContentProviderExternal(String name, IBinder token) {
6486        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6487            "Do not have permission in call removeContentProviderExternal()");
6488        removeContentProviderExternalUnchecked(name, token);
6489    }
6490
6491    private void removeContentProviderExternalUnchecked(String name, IBinder token) {
6492        synchronized (this) {
6493            ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
6494                    Binder.getOrigCallingUser());
6495            if(cpr == null) {
6496                //remove from mProvidersByClass
6497                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6498                return;
6499            }
6500
6501            //update content provider record entry info
6502            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6503            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
6504                    Binder.getOrigCallingUser());
6505            if (localCpr.hasExternalProcessHandles()) {
6506                if (localCpr.removeExternalProcessHandleLocked(token)) {
6507                    updateOomAdjLocked();
6508                } else {
6509                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6510                            + " with no external reference for token: "
6511                            + token + ".");
6512                }
6513            } else {
6514                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6515                        + " with no external references.");
6516            }
6517        }
6518    }
6519
6520    public final void publishContentProviders(IApplicationThread caller,
6521            List<ContentProviderHolder> providers) {
6522        if (providers == null) {
6523            return;
6524        }
6525
6526        enforceNotIsolatedCaller("publishContentProviders");
6527        synchronized (this) {
6528            final ProcessRecord r = getRecordForAppLocked(caller);
6529            if (DEBUG_MU)
6530                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6531            if (r == null) {
6532                throw new SecurityException(
6533                        "Unable to find app for caller " + caller
6534                      + " (pid=" + Binder.getCallingPid()
6535                      + ") when publishing content providers");
6536            }
6537
6538            final long origId = Binder.clearCallingIdentity();
6539
6540            final int N = providers.size();
6541            for (int i=0; i<N; i++) {
6542                ContentProviderHolder src = providers.get(i);
6543                if (src == null || src.info == null || src.provider == null) {
6544                    continue;
6545                }
6546                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6547                if (DEBUG_MU)
6548                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6549                if (dst != null) {
6550                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6551                    mProviderMap.putProviderByClass(comp, dst);
6552                    String names[] = dst.info.authority.split(";");
6553                    for (int j = 0; j < names.length; j++) {
6554                        mProviderMap.putProviderByName(names[j], dst);
6555                    }
6556
6557                    int NL = mLaunchingProviders.size();
6558                    int j;
6559                    for (j=0; j<NL; j++) {
6560                        if (mLaunchingProviders.get(j) == dst) {
6561                            mLaunchingProviders.remove(j);
6562                            j--;
6563                            NL--;
6564                        }
6565                    }
6566                    synchronized (dst) {
6567                        dst.provider = src.provider;
6568                        dst.proc = r;
6569                        dst.notifyAll();
6570                    }
6571                    updateOomAdjLocked(r);
6572                }
6573            }
6574
6575            Binder.restoreCallingIdentity(origId);
6576        }
6577    }
6578
6579    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6580        ContentProviderConnection conn;
6581        try {
6582            conn = (ContentProviderConnection)connection;
6583        } catch (ClassCastException e) {
6584            String msg ="refContentProvider: " + connection
6585                    + " not a ContentProviderConnection";
6586            Slog.w(TAG, msg);
6587            throw new IllegalArgumentException(msg);
6588        }
6589        if (conn == null) {
6590            throw new NullPointerException("connection is null");
6591        }
6592
6593        synchronized (this) {
6594            if (stable > 0) {
6595                conn.numStableIncs += stable;
6596            }
6597            stable = conn.stableCount + stable;
6598            if (stable < 0) {
6599                throw new IllegalStateException("stableCount < 0: " + stable);
6600            }
6601
6602            if (unstable > 0) {
6603                conn.numUnstableIncs += unstable;
6604            }
6605            unstable = conn.unstableCount + unstable;
6606            if (unstable < 0) {
6607                throw new IllegalStateException("unstableCount < 0: " + unstable);
6608            }
6609
6610            if ((stable+unstable) <= 0) {
6611                throw new IllegalStateException("ref counts can't go to zero here: stable="
6612                        + stable + " unstable=" + unstable);
6613            }
6614            conn.stableCount = stable;
6615            conn.unstableCount = unstable;
6616            return !conn.dead;
6617        }
6618    }
6619
6620    public void unstableProviderDied(IBinder connection) {
6621        ContentProviderConnection conn;
6622        try {
6623            conn = (ContentProviderConnection)connection;
6624        } catch (ClassCastException e) {
6625            String msg ="refContentProvider: " + connection
6626                    + " not a ContentProviderConnection";
6627            Slog.w(TAG, msg);
6628            throw new IllegalArgumentException(msg);
6629        }
6630        if (conn == null) {
6631            throw new NullPointerException("connection is null");
6632        }
6633
6634        // Safely retrieve the content provider associated with the connection.
6635        IContentProvider provider;
6636        synchronized (this) {
6637            provider = conn.provider.provider;
6638        }
6639
6640        if (provider == null) {
6641            // Um, yeah, we're way ahead of you.
6642            return;
6643        }
6644
6645        // Make sure the caller is being honest with us.
6646        if (provider.asBinder().pingBinder()) {
6647            // Er, no, still looks good to us.
6648            synchronized (this) {
6649                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6650                        + " says " + conn + " died, but we don't agree");
6651                return;
6652            }
6653        }
6654
6655        // Well look at that!  It's dead!
6656        synchronized (this) {
6657            if (conn.provider.provider != provider) {
6658                // But something changed...  good enough.
6659                return;
6660            }
6661
6662            ProcessRecord proc = conn.provider.proc;
6663            if (proc == null || proc.thread == null) {
6664                // Seems like the process is already cleaned up.
6665                return;
6666            }
6667
6668            // As far as we're concerned, this is just like receiving a
6669            // death notification...  just a bit prematurely.
6670            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6671                    + ") early provider death");
6672            final long ident = Binder.clearCallingIdentity();
6673            try {
6674                appDiedLocked(proc, proc.pid, proc.thread);
6675            } finally {
6676                Binder.restoreCallingIdentity(ident);
6677            }
6678        }
6679    }
6680
6681    public static final void installSystemProviders() {
6682        List<ProviderInfo> providers;
6683        synchronized (mSelf) {
6684            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6685            providers = mSelf.generateApplicationProvidersLocked(app);
6686            if (providers != null) {
6687                for (int i=providers.size()-1; i>=0; i--) {
6688                    ProviderInfo pi = (ProviderInfo)providers.get(i);
6689                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6690                        Slog.w(TAG, "Not installing system proc provider " + pi.name
6691                                + ": not system .apk");
6692                        providers.remove(i);
6693                    }
6694                }
6695            }
6696        }
6697        if (providers != null) {
6698            mSystemThread.installSystemProviders(providers);
6699        }
6700
6701        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6702
6703        mSelf.mUsageStatsService.monitorPackages();
6704    }
6705
6706    /**
6707     * Allows app to retrieve the MIME type of a URI without having permission
6708     * to access its content provider.
6709     *
6710     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6711     *
6712     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6713     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6714     */
6715    public String getProviderMimeType(Uri uri) {
6716        enforceNotIsolatedCaller("getProviderMimeType");
6717        final String name = uri.getAuthority();
6718        final long ident = Binder.clearCallingIdentity();
6719        ContentProviderHolder holder = null;
6720
6721        try {
6722            holder = getContentProviderExternalUnchecked(name, null);
6723            if (holder != null) {
6724                return holder.provider.getType(uri);
6725            }
6726        } catch (RemoteException e) {
6727            Log.w(TAG, "Content provider dead retrieving " + uri, e);
6728            return null;
6729        } finally {
6730            if (holder != null) {
6731                removeContentProviderExternalUnchecked(name, null);
6732            }
6733            Binder.restoreCallingIdentity(ident);
6734        }
6735
6736        return null;
6737    }
6738
6739    // =========================================================
6740    // GLOBAL MANAGEMENT
6741    // =========================================================
6742
6743    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6744            ApplicationInfo info, String customProcess, boolean isolated) {
6745        String proc = customProcess != null ? customProcess : info.processName;
6746        BatteryStatsImpl.Uid.Proc ps = null;
6747        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6748        int uid = info.uid;
6749        if (isolated) {
6750            int userId = UserId.getUserId(uid);
6751            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6752            uid = 0;
6753            while (true) {
6754                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6755                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6756                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6757                }
6758                uid = UserId.getUid(userId, mNextIsolatedProcessUid);
6759                mNextIsolatedProcessUid++;
6760                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6761                    // No process for this uid, use it.
6762                    break;
6763                }
6764                stepsLeft--;
6765                if (stepsLeft <= 0) {
6766                    return null;
6767                }
6768            }
6769        }
6770        synchronized (stats) {
6771            ps = stats.getProcessStatsLocked(info.uid, proc);
6772        }
6773        return new ProcessRecord(ps, thread, info, proc, uid);
6774    }
6775
6776    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6777        ProcessRecord app;
6778        if (!isolated) {
6779            app = getProcessRecordLocked(info.processName, info.uid);
6780        } else {
6781            app = null;
6782        }
6783
6784        if (app == null) {
6785            app = newProcessRecordLocked(null, info, null, isolated);
6786            mProcessNames.put(info.processName, app.uid, app);
6787            if (isolated) {
6788                mIsolatedProcesses.put(app.uid, app);
6789            }
6790            updateLruProcessLocked(app, true, true);
6791        }
6792
6793        // This package really, really can not be stopped.
6794        try {
6795            AppGlobals.getPackageManager().setPackageStoppedState(
6796                    info.packageName, false, UserId.getUserId(app.uid));
6797        } catch (RemoteException e) {
6798        } catch (IllegalArgumentException e) {
6799            Slog.w(TAG, "Failed trying to unstop package "
6800                    + info.packageName + ": " + e);
6801        }
6802
6803        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6804                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6805            app.persistent = true;
6806            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
6807        }
6808        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6809            mPersistentStartingProcesses.add(app);
6810            startProcessLocked(app, "added application", app.processName);
6811        }
6812
6813        return app;
6814    }
6815
6816    public void unhandledBack() {
6817        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6818                "unhandledBack()");
6819
6820        synchronized(this) {
6821            int count = mMainStack.mHistory.size();
6822            if (DEBUG_SWITCH) Slog.d(
6823                TAG, "Performing unhandledBack(): stack size = " + count);
6824            if (count > 1) {
6825                final long origId = Binder.clearCallingIdentity();
6826                mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
6827                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6828                Binder.restoreCallingIdentity(origId);
6829            }
6830        }
6831    }
6832
6833    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6834        enforceNotIsolatedCaller("openContentUri");
6835        String name = uri.getAuthority();
6836        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null);
6837        ParcelFileDescriptor pfd = null;
6838        if (cph != null) {
6839            // We record the binder invoker's uid in thread-local storage before
6840            // going to the content provider to open the file.  Later, in the code
6841            // that handles all permissions checks, we look for this uid and use
6842            // that rather than the Activity Manager's own uid.  The effect is that
6843            // we do the check against the caller's permissions even though it looks
6844            // to the content provider like the Activity Manager itself is making
6845            // the request.
6846            sCallerIdentity.set(new Identity(
6847                    Binder.getCallingPid(), Binder.getCallingUid()));
6848            try {
6849                pfd = cph.provider.openFile(uri, "r");
6850            } catch (FileNotFoundException e) {
6851                // do nothing; pfd will be returned null
6852            } finally {
6853                // Ensure that whatever happens, we clean up the identity state
6854                sCallerIdentity.remove();
6855            }
6856
6857            // We've got the fd now, so we're done with the provider.
6858            removeContentProviderExternalUnchecked(name, null);
6859        } else {
6860            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
6861        }
6862        return pfd;
6863    }
6864
6865    // Actually is sleeping or shutting down or whatever else in the future
6866    // is an inactive state.
6867    public boolean isSleeping() {
6868        return mSleeping || mShuttingDown;
6869    }
6870
6871    public void goingToSleep() {
6872        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6873                != PackageManager.PERMISSION_GRANTED) {
6874            throw new SecurityException("Requires permission "
6875                    + android.Manifest.permission.DEVICE_POWER);
6876        }
6877
6878        synchronized(this) {
6879            mWentToSleep = true;
6880            updateEventDispatchingLocked();
6881
6882            if (!mSleeping) {
6883                mSleeping = true;
6884                mMainStack.stopIfSleepingLocked();
6885
6886                // Initialize the wake times of all processes.
6887                checkExcessivePowerUsageLocked(false);
6888                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6889                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6890                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6891            }
6892        }
6893    }
6894
6895    public boolean shutdown(int timeout) {
6896        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6897                != PackageManager.PERMISSION_GRANTED) {
6898            throw new SecurityException("Requires permission "
6899                    + android.Manifest.permission.SHUTDOWN);
6900        }
6901
6902        boolean timedout = false;
6903
6904        synchronized(this) {
6905            mShuttingDown = true;
6906            updateEventDispatchingLocked();
6907
6908            if (mMainStack.mResumedActivity != null) {
6909                mMainStack.stopIfSleepingLocked();
6910                final long endTime = System.currentTimeMillis() + timeout;
6911                while (mMainStack.mResumedActivity != null
6912                        || mMainStack.mPausingActivity != null) {
6913                    long delay = endTime - System.currentTimeMillis();
6914                    if (delay <= 0) {
6915                        Slog.w(TAG, "Activity manager shutdown timed out");
6916                        timedout = true;
6917                        break;
6918                    }
6919                    try {
6920                        this.wait();
6921                    } catch (InterruptedException e) {
6922                    }
6923                }
6924            }
6925        }
6926
6927        mUsageStatsService.shutdown();
6928        mBatteryStatsService.shutdown();
6929
6930        return timedout;
6931    }
6932
6933    public final void activitySlept(IBinder token) {
6934        if (localLOGV) Slog.v(
6935            TAG, "Activity slept: token=" + token);
6936
6937        ActivityRecord r = null;
6938
6939        final long origId = Binder.clearCallingIdentity();
6940
6941        synchronized (this) {
6942            r = mMainStack.isInStackLocked(token);
6943            if (r != null) {
6944                mMainStack.activitySleptLocked(r);
6945            }
6946        }
6947
6948        Binder.restoreCallingIdentity(origId);
6949    }
6950
6951    private void comeOutOfSleepIfNeededLocked() {
6952        if (!mWentToSleep && !mLockScreenShown) {
6953            if (mSleeping) {
6954                mSleeping = false;
6955                mMainStack.awakeFromSleepingLocked();
6956                mMainStack.resumeTopActivityLocked(null);
6957            }
6958        }
6959    }
6960
6961    public void wakingUp() {
6962        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6963                != PackageManager.PERMISSION_GRANTED) {
6964            throw new SecurityException("Requires permission "
6965                    + android.Manifest.permission.DEVICE_POWER);
6966        }
6967
6968        synchronized(this) {
6969            mWentToSleep = false;
6970            updateEventDispatchingLocked();
6971            comeOutOfSleepIfNeededLocked();
6972        }
6973    }
6974
6975    private void updateEventDispatchingLocked() {
6976        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
6977    }
6978
6979    public void setLockScreenShown(boolean shown) {
6980        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6981                != PackageManager.PERMISSION_GRANTED) {
6982            throw new SecurityException("Requires permission "
6983                    + android.Manifest.permission.DEVICE_POWER);
6984        }
6985
6986        synchronized(this) {
6987            mLockScreenShown = shown;
6988            comeOutOfSleepIfNeededLocked();
6989        }
6990    }
6991
6992    public void stopAppSwitches() {
6993        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6994                != PackageManager.PERMISSION_GRANTED) {
6995            throw new SecurityException("Requires permission "
6996                    + android.Manifest.permission.STOP_APP_SWITCHES);
6997        }
6998
6999        synchronized(this) {
7000            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7001                    + APP_SWITCH_DELAY_TIME;
7002            mDidAppSwitch = false;
7003            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7004            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7005            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7006        }
7007    }
7008
7009    public void resumeAppSwitches() {
7010        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7011                != PackageManager.PERMISSION_GRANTED) {
7012            throw new SecurityException("Requires permission "
7013                    + android.Manifest.permission.STOP_APP_SWITCHES);
7014        }
7015
7016        synchronized(this) {
7017            // Note that we don't execute any pending app switches... we will
7018            // let those wait until either the timeout, or the next start
7019            // activity request.
7020            mAppSwitchesAllowedTime = 0;
7021        }
7022    }
7023
7024    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7025            String name) {
7026        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7027            return true;
7028        }
7029
7030        final int perm = checkComponentPermission(
7031                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7032                callingUid, -1, true);
7033        if (perm == PackageManager.PERMISSION_GRANTED) {
7034            return true;
7035        }
7036
7037        Slog.w(TAG, name + " request from " + callingUid + " stopped");
7038        return false;
7039    }
7040
7041    public void setDebugApp(String packageName, boolean waitForDebugger,
7042            boolean persistent) {
7043        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7044                "setDebugApp()");
7045
7046        // Note that this is not really thread safe if there are multiple
7047        // callers into it at the same time, but that's not a situation we
7048        // care about.
7049        if (persistent) {
7050            final ContentResolver resolver = mContext.getContentResolver();
7051            Settings.System.putString(
7052                resolver, Settings.System.DEBUG_APP,
7053                packageName);
7054            Settings.System.putInt(
7055                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7056                waitForDebugger ? 1 : 0);
7057        }
7058
7059        synchronized (this) {
7060            if (!persistent) {
7061                mOrigDebugApp = mDebugApp;
7062                mOrigWaitForDebugger = mWaitForDebugger;
7063            }
7064            mDebugApp = packageName;
7065            mWaitForDebugger = waitForDebugger;
7066            mDebugTransient = !persistent;
7067            if (packageName != null) {
7068                final long origId = Binder.clearCallingIdentity();
7069                forceStopPackageLocked(packageName, -1, false, false, true, true, 0);
7070                Binder.restoreCallingIdentity(origId);
7071            }
7072        }
7073    }
7074
7075    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7076        synchronized (this) {
7077            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7078            if (!isDebuggable) {
7079                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7080                    throw new SecurityException("Process not debuggable: " + app.packageName);
7081                }
7082            }
7083
7084            mOpenGlTraceApp = processName;
7085        }
7086    }
7087
7088    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7089            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7090        synchronized (this) {
7091            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7092            if (!isDebuggable) {
7093                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7094                    throw new SecurityException("Process not debuggable: " + app.packageName);
7095                }
7096            }
7097            mProfileApp = processName;
7098            mProfileFile = profileFile;
7099            if (mProfileFd != null) {
7100                try {
7101                    mProfileFd.close();
7102                } catch (IOException e) {
7103                }
7104                mProfileFd = null;
7105            }
7106            mProfileFd = profileFd;
7107            mProfileType = 0;
7108            mAutoStopProfiler = autoStopProfiler;
7109        }
7110    }
7111
7112    public void setAlwaysFinish(boolean enabled) {
7113        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7114                "setAlwaysFinish()");
7115
7116        Settings.System.putInt(
7117                mContext.getContentResolver(),
7118                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7119
7120        synchronized (this) {
7121            mAlwaysFinishActivities = enabled;
7122        }
7123    }
7124
7125    public void setActivityController(IActivityController controller) {
7126        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7127                "setActivityController()");
7128        synchronized (this) {
7129            mController = controller;
7130        }
7131    }
7132
7133    public boolean isUserAMonkey() {
7134        // For now the fact that there is a controller implies
7135        // we have a monkey.
7136        synchronized (this) {
7137            return mController != null;
7138        }
7139    }
7140
7141    public void registerProcessObserver(IProcessObserver observer) {
7142        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7143                "registerProcessObserver()");
7144        synchronized (this) {
7145            mProcessObservers.register(observer);
7146        }
7147    }
7148
7149    public void unregisterProcessObserver(IProcessObserver observer) {
7150        synchronized (this) {
7151            mProcessObservers.unregister(observer);
7152        }
7153    }
7154
7155    public void setImmersive(IBinder token, boolean immersive) {
7156        synchronized(this) {
7157            ActivityRecord r = mMainStack.isInStackLocked(token);
7158            if (r == null) {
7159                throw new IllegalArgumentException();
7160            }
7161            r.immersive = immersive;
7162        }
7163    }
7164
7165    public boolean isImmersive(IBinder token) {
7166        synchronized (this) {
7167            ActivityRecord r = mMainStack.isInStackLocked(token);
7168            if (r == null) {
7169                throw new IllegalArgumentException();
7170            }
7171            return r.immersive;
7172        }
7173    }
7174
7175    public boolean isTopActivityImmersive() {
7176        enforceNotIsolatedCaller("startActivity");
7177        synchronized (this) {
7178            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7179            return (r != null) ? r.immersive : false;
7180        }
7181    }
7182
7183    public final void enterSafeMode() {
7184        synchronized(this) {
7185            // It only makes sense to do this before the system is ready
7186            // and started launching other packages.
7187            if (!mSystemReady) {
7188                try {
7189                    AppGlobals.getPackageManager().enterSafeMode();
7190                } catch (RemoteException e) {
7191                }
7192            }
7193        }
7194    }
7195
7196    public final void showSafeModeOverlay() {
7197        View v = LayoutInflater.from(mContext).inflate(
7198                com.android.internal.R.layout.safe_mode, null);
7199        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7200        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7201        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7202        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7203        lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
7204        lp.format = v.getBackground().getOpacity();
7205        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7206                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7207        ((WindowManager)mContext.getSystemService(
7208                Context.WINDOW_SERVICE)).addView(v, lp);
7209    }
7210
7211    public void noteWakeupAlarm(IIntentSender sender) {
7212        if (!(sender instanceof PendingIntentRecord)) {
7213            return;
7214        }
7215        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7216        synchronized (stats) {
7217            if (mBatteryStatsService.isOnBattery()) {
7218                mBatteryStatsService.enforceCallingPermission();
7219                PendingIntentRecord rec = (PendingIntentRecord)sender;
7220                int MY_UID = Binder.getCallingUid();
7221                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7222                BatteryStatsImpl.Uid.Pkg pkg =
7223                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7224                pkg.incWakeupsLocked();
7225            }
7226        }
7227    }
7228
7229    public boolean killPids(int[] pids, String pReason, boolean secure) {
7230        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7231            throw new SecurityException("killPids only available to the system");
7232        }
7233        String reason = (pReason == null) ? "Unknown" : pReason;
7234        // XXX Note: don't acquire main activity lock here, because the window
7235        // manager calls in with its locks held.
7236
7237        boolean killed = false;
7238        synchronized (mPidsSelfLocked) {
7239            int[] types = new int[pids.length];
7240            int worstType = 0;
7241            for (int i=0; i<pids.length; i++) {
7242                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7243                if (proc != null) {
7244                    int type = proc.setAdj;
7245                    types[i] = type;
7246                    if (type > worstType) {
7247                        worstType = type;
7248                    }
7249                }
7250            }
7251
7252            // If the worst oom_adj is somewhere in the hidden proc LRU range,
7253            // then constrain it so we will kill all hidden procs.
7254            if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7255                    && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7256                worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7257            }
7258
7259            // If this is not a secure call, don't let it kill processes that
7260            // are important.
7261            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7262                worstType = ProcessList.SERVICE_ADJ;
7263            }
7264
7265            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7266            for (int i=0; i<pids.length; i++) {
7267                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7268                if (proc == null) {
7269                    continue;
7270                }
7271                int adj = proc.setAdj;
7272                if (adj >= worstType && !proc.killedBackground) {
7273                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7274                    EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7275                            proc.processName, adj, reason);
7276                    killed = true;
7277                    proc.killedBackground = true;
7278                    Process.killProcessQuiet(pids[i]);
7279                }
7280            }
7281        }
7282        return killed;
7283    }
7284
7285    @Override
7286    public boolean killProcessesBelowForeground(String reason) {
7287        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7288            throw new SecurityException("killProcessesBelowForeground() only available to system");
7289        }
7290
7291        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7292    }
7293
7294    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7295        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7296            throw new SecurityException("killProcessesBelowAdj() only available to system");
7297        }
7298
7299        boolean killed = false;
7300        synchronized (mPidsSelfLocked) {
7301            final int size = mPidsSelfLocked.size();
7302            for (int i = 0; i < size; i++) {
7303                final int pid = mPidsSelfLocked.keyAt(i);
7304                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7305                if (proc == null) continue;
7306
7307                final int adj = proc.setAdj;
7308                if (adj > belowAdj && !proc.killedBackground) {
7309                    Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7310                    EventLog.writeEvent(
7311                            EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7312                    killed = true;
7313                    proc.killedBackground = true;
7314                    Process.killProcessQuiet(pid);
7315                }
7316            }
7317        }
7318        return killed;
7319    }
7320
7321    public final void startRunning(String pkg, String cls, String action,
7322            String data) {
7323        synchronized(this) {
7324            if (mStartRunning) {
7325                return;
7326            }
7327            mStartRunning = true;
7328            mTopComponent = pkg != null && cls != null
7329                    ? new ComponentName(pkg, cls) : null;
7330            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7331            mTopData = data;
7332            if (!mSystemReady) {
7333                return;
7334            }
7335        }
7336
7337        systemReady(null);
7338    }
7339
7340    private void retrieveSettings() {
7341        final ContentResolver resolver = mContext.getContentResolver();
7342        String debugApp = Settings.System.getString(
7343            resolver, Settings.System.DEBUG_APP);
7344        boolean waitForDebugger = Settings.System.getInt(
7345            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7346        boolean alwaysFinishActivities = Settings.System.getInt(
7347            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7348
7349        Configuration configuration = new Configuration();
7350        Settings.System.getConfiguration(resolver, configuration);
7351
7352        synchronized (this) {
7353            mDebugApp = mOrigDebugApp = debugApp;
7354            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7355            mAlwaysFinishActivities = alwaysFinishActivities;
7356            // This happens before any activities are started, so we can
7357            // change mConfiguration in-place.
7358            updateConfigurationLocked(configuration, null, false, true);
7359            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7360        }
7361    }
7362
7363    public boolean testIsSystemReady() {
7364        // no need to synchronize(this) just to read & return the value
7365        return mSystemReady;
7366    }
7367
7368    private static File getCalledPreBootReceiversFile() {
7369        File dataDir = Environment.getDataDirectory();
7370        File systemDir = new File(dataDir, "system");
7371        File fname = new File(systemDir, "called_pre_boots.dat");
7372        return fname;
7373    }
7374
7375    static final int LAST_DONE_VERSION = 10000;
7376
7377    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7378        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7379        File file = getCalledPreBootReceiversFile();
7380        FileInputStream fis = null;
7381        try {
7382            fis = new FileInputStream(file);
7383            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7384            int fvers = dis.readInt();
7385            if (fvers == LAST_DONE_VERSION) {
7386                String vers = dis.readUTF();
7387                String codename = dis.readUTF();
7388                String build = dis.readUTF();
7389                if (android.os.Build.VERSION.RELEASE.equals(vers)
7390                        && android.os.Build.VERSION.CODENAME.equals(codename)
7391                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7392                    int num = dis.readInt();
7393                    while (num > 0) {
7394                        num--;
7395                        String pkg = dis.readUTF();
7396                        String cls = dis.readUTF();
7397                        lastDoneReceivers.add(new ComponentName(pkg, cls));
7398                    }
7399                }
7400            }
7401        } catch (FileNotFoundException e) {
7402        } catch (IOException e) {
7403            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7404        } finally {
7405            if (fis != null) {
7406                try {
7407                    fis.close();
7408                } catch (IOException e) {
7409                }
7410            }
7411        }
7412        return lastDoneReceivers;
7413    }
7414
7415    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7416        File file = getCalledPreBootReceiversFile();
7417        FileOutputStream fos = null;
7418        DataOutputStream dos = null;
7419        try {
7420            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7421            fos = new FileOutputStream(file);
7422            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7423            dos.writeInt(LAST_DONE_VERSION);
7424            dos.writeUTF(android.os.Build.VERSION.RELEASE);
7425            dos.writeUTF(android.os.Build.VERSION.CODENAME);
7426            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7427            dos.writeInt(list.size());
7428            for (int i=0; i<list.size(); i++) {
7429                dos.writeUTF(list.get(i).getPackageName());
7430                dos.writeUTF(list.get(i).getClassName());
7431            }
7432        } catch (IOException e) {
7433            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7434            file.delete();
7435        } finally {
7436            FileUtils.sync(fos);
7437            if (dos != null) {
7438                try {
7439                    dos.close();
7440                } catch (IOException e) {
7441                    // TODO Auto-generated catch block
7442                    e.printStackTrace();
7443                }
7444            }
7445        }
7446    }
7447
7448    public void systemReady(final Runnable goingCallback) {
7449        synchronized(this) {
7450            if (mSystemReady) {
7451                if (goingCallback != null) goingCallback.run();
7452                return;
7453            }
7454
7455            // Check to see if there are any update receivers to run.
7456            if (!mDidUpdate) {
7457                if (mWaitingUpdate) {
7458                    return;
7459                }
7460                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7461                List<ResolveInfo> ris = null;
7462                try {
7463                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
7464                            intent, null, 0, 0);
7465                } catch (RemoteException e) {
7466                }
7467                if (ris != null) {
7468                    for (int i=ris.size()-1; i>=0; i--) {
7469                        if ((ris.get(i).activityInfo.applicationInfo.flags
7470                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
7471                            ris.remove(i);
7472                        }
7473                    }
7474                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7475
7476                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7477
7478                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7479                    for (int i=0; i<ris.size(); i++) {
7480                        ActivityInfo ai = ris.get(i).activityInfo;
7481                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7482                        if (lastDoneReceivers.contains(comp)) {
7483                            ris.remove(i);
7484                            i--;
7485                        }
7486                    }
7487
7488                    for (int i=0; i<ris.size(); i++) {
7489                        ActivityInfo ai = ris.get(i).activityInfo;
7490                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
7491                        doneReceivers.add(comp);
7492                        intent.setComponent(comp);
7493                        IIntentReceiver finisher = null;
7494                        if (i == ris.size()-1) {
7495                            finisher = new IIntentReceiver.Stub() {
7496                                public void performReceive(Intent intent, int resultCode,
7497                                        String data, Bundle extras, boolean ordered,
7498                                        boolean sticky) {
7499                                    // The raw IIntentReceiver interface is called
7500                                    // with the AM lock held, so redispatch to
7501                                    // execute our code without the lock.
7502                                    mHandler.post(new Runnable() {
7503                                        public void run() {
7504                                            synchronized (ActivityManagerService.this) {
7505                                                mDidUpdate = true;
7506                                            }
7507                                            writeLastDonePreBootReceivers(doneReceivers);
7508                                            showBootMessage(mContext.getText(
7509                                                    R.string.android_upgrading_complete),
7510                                                    false);
7511                                            systemReady(goingCallback);
7512                                        }
7513                                    });
7514                                }
7515                            };
7516                        }
7517                        Slog.i(TAG, "Sending system update to: " + intent.getComponent());
7518                        /* TODO: Send this to all users */
7519                        broadcastIntentLocked(null, null, intent, null, finisher,
7520                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7521                                0 /* UserId zero */);
7522                        if (finisher != null) {
7523                            mWaitingUpdate = true;
7524                        }
7525                    }
7526                }
7527                if (mWaitingUpdate) {
7528                    return;
7529                }
7530                mDidUpdate = true;
7531            }
7532
7533            mSystemReady = true;
7534            if (!mStartRunning) {
7535                return;
7536            }
7537        }
7538
7539        ArrayList<ProcessRecord> procsToKill = null;
7540        synchronized(mPidsSelfLocked) {
7541            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7542                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7543                if (!isAllowedWhileBooting(proc.info)){
7544                    if (procsToKill == null) {
7545                        procsToKill = new ArrayList<ProcessRecord>();
7546                    }
7547                    procsToKill.add(proc);
7548                }
7549            }
7550        }
7551
7552        synchronized(this) {
7553            if (procsToKill != null) {
7554                for (int i=procsToKill.size()-1; i>=0; i--) {
7555                    ProcessRecord proc = procsToKill.get(i);
7556                    Slog.i(TAG, "Removing system update proc: " + proc);
7557                    removeProcessLocked(proc, true, false, "system update done");
7558                }
7559            }
7560
7561            // Now that we have cleaned up any update processes, we
7562            // are ready to start launching real processes and know that
7563            // we won't trample on them any more.
7564            mProcessesReady = true;
7565        }
7566
7567        Slog.i(TAG, "System now ready");
7568        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7569            SystemClock.uptimeMillis());
7570
7571        synchronized(this) {
7572            // Make sure we have no pre-ready processes sitting around.
7573
7574            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7575                ResolveInfo ri = mContext.getPackageManager()
7576                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7577                                STOCK_PM_FLAGS);
7578                CharSequence errorMsg = null;
7579                if (ri != null) {
7580                    ActivityInfo ai = ri.activityInfo;
7581                    ApplicationInfo app = ai.applicationInfo;
7582                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7583                        mTopAction = Intent.ACTION_FACTORY_TEST;
7584                        mTopData = null;
7585                        mTopComponent = new ComponentName(app.packageName,
7586                                ai.name);
7587                    } else {
7588                        errorMsg = mContext.getResources().getText(
7589                                com.android.internal.R.string.factorytest_not_system);
7590                    }
7591                } else {
7592                    errorMsg = mContext.getResources().getText(
7593                            com.android.internal.R.string.factorytest_no_action);
7594                }
7595                if (errorMsg != null) {
7596                    mTopAction = null;
7597                    mTopData = null;
7598                    mTopComponent = null;
7599                    Message msg = Message.obtain();
7600                    msg.what = SHOW_FACTORY_ERROR_MSG;
7601                    msg.getData().putCharSequence("msg", errorMsg);
7602                    mHandler.sendMessage(msg);
7603                }
7604            }
7605        }
7606
7607        retrieveSettings();
7608
7609        if (goingCallback != null) goingCallback.run();
7610
7611        synchronized (this) {
7612            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7613                try {
7614                    List apps = AppGlobals.getPackageManager().
7615                        getPersistentApplications(STOCK_PM_FLAGS);
7616                    if (apps != null) {
7617                        int N = apps.size();
7618                        int i;
7619                        for (i=0; i<N; i++) {
7620                            ApplicationInfo info
7621                                = (ApplicationInfo)apps.get(i);
7622                            if (info != null &&
7623                                    !info.packageName.equals("android")) {
7624                                addAppLocked(info, false);
7625                            }
7626                        }
7627                    }
7628                } catch (RemoteException ex) {
7629                    // pm is in same process, this will never happen.
7630                }
7631            }
7632
7633            // Start up initial activity.
7634            mBooting = true;
7635
7636            try {
7637                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7638                    Message msg = Message.obtain();
7639                    msg.what = SHOW_UID_ERROR_MSG;
7640                    mHandler.sendMessage(msg);
7641                }
7642            } catch (RemoteException e) {
7643            }
7644
7645            mMainStack.resumeTopActivityLocked(null);
7646        }
7647    }
7648
7649    private boolean makeAppCrashingLocked(ProcessRecord app,
7650            String shortMsg, String longMsg, String stackTrace) {
7651        app.crashing = true;
7652        app.crashingReport = generateProcessError(app,
7653                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7654        startAppProblemLocked(app);
7655        app.stopFreezingAllLocked();
7656        return handleAppCrashLocked(app);
7657    }
7658
7659    private void makeAppNotRespondingLocked(ProcessRecord app,
7660            String activity, String shortMsg, String longMsg) {
7661        app.notResponding = true;
7662        app.notRespondingReport = generateProcessError(app,
7663                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7664                activity, shortMsg, longMsg, null);
7665        startAppProblemLocked(app);
7666        app.stopFreezingAllLocked();
7667    }
7668
7669    /**
7670     * Generate a process error record, suitable for attachment to a ProcessRecord.
7671     *
7672     * @param app The ProcessRecord in which the error occurred.
7673     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7674     *                      ActivityManager.AppErrorStateInfo
7675     * @param activity The activity associated with the crash, if known.
7676     * @param shortMsg Short message describing the crash.
7677     * @param longMsg Long message describing the crash.
7678     * @param stackTrace Full crash stack trace, may be null.
7679     *
7680     * @return Returns a fully-formed AppErrorStateInfo record.
7681     */
7682    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7683            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
7684        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7685
7686        report.condition = condition;
7687        report.processName = app.processName;
7688        report.pid = app.pid;
7689        report.uid = app.info.uid;
7690        report.tag = activity;
7691        report.shortMsg = shortMsg;
7692        report.longMsg = longMsg;
7693        report.stackTrace = stackTrace;
7694
7695        return report;
7696    }
7697
7698    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
7699        synchronized (this) {
7700            app.crashing = false;
7701            app.crashingReport = null;
7702            app.notResponding = false;
7703            app.notRespondingReport = null;
7704            if (app.anrDialog == fromDialog) {
7705                app.anrDialog = null;
7706            }
7707            if (app.waitDialog == fromDialog) {
7708                app.waitDialog = null;
7709            }
7710            if (app.pid > 0 && app.pid != MY_PID) {
7711                handleAppCrashLocked(app);
7712                Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
7713                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7714                        app.processName, app.setAdj, "user's request after error");
7715                Process.killProcessQuiet(app.pid);
7716            }
7717        }
7718    }
7719
7720    private boolean handleAppCrashLocked(ProcessRecord app) {
7721        if (mHeadless) {
7722            Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7723            return false;
7724        }
7725        long now = SystemClock.uptimeMillis();
7726
7727        Long crashTime;
7728        if (!app.isolated) {
7729            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7730        } else {
7731            crashTime = null;
7732        }
7733        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
7734            // This process loses!
7735            Slog.w(TAG, "Process " + app.info.processName
7736                    + " has crashed too many times: killing!");
7737            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
7738                    app.info.processName, app.uid);
7739            for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7740                ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
7741                if (r.app == app) {
7742                    Slog.w(TAG, "  Force finishing activity "
7743                        + r.intent.getComponent().flattenToShortString());
7744                    r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
7745                }
7746            }
7747            if (!app.persistent) {
7748                // We don't want to start this process again until the user
7749                // explicitly does so...  but for persistent process, we really
7750                // need to keep it running.  If a persistent process is actually
7751                // repeatedly crashing, then badness for everyone.
7752                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
7753                        app.info.processName);
7754                if (!app.isolated) {
7755                    // XXX We don't have a way to mark isolated processes
7756                    // as bad, since they don't have a peristent identity.
7757                    mBadProcesses.put(app.info.processName, app.uid, now);
7758                    mProcessCrashTimes.remove(app.info.processName, app.uid);
7759                }
7760                app.bad = true;
7761                app.removed = true;
7762                // Don't let services in this process be restarted and potentially
7763                // annoy the user repeatedly.  Unless it is persistent, since those
7764                // processes run critical code.
7765                removeProcessLocked(app, false, false, "crash");
7766                mMainStack.resumeTopActivityLocked(null);
7767                return false;
7768            }
7769            mMainStack.resumeTopActivityLocked(null);
7770        } else {
7771            ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7772            if (r != null && r.app == app) {
7773                // If the top running activity is from this crashing
7774                // process, then terminate it to avoid getting in a loop.
7775                Slog.w(TAG, "  Force finishing activity "
7776                        + r.intent.getComponent().flattenToShortString());
7777                int index = mMainStack.indexOfActivityLocked(r);
7778                r.stack.finishActivityLocked(r, index,
7779                        Activity.RESULT_CANCELED, null, "crashed");
7780                // Also terminate any activities below it that aren't yet
7781                // stopped, to avoid a situation where one will get
7782                // re-start our crashing activity once it gets resumed again.
7783                index--;
7784                if (index >= 0) {
7785                    r = (ActivityRecord)mMainStack.mHistory.get(index);
7786                    if (r.state == ActivityState.RESUMED
7787                            || r.state == ActivityState.PAUSING
7788                            || r.state == ActivityState.PAUSED) {
7789                        if (!r.isHomeActivity || mHomeProcess != r.app) {
7790                            Slog.w(TAG, "  Force finishing activity "
7791                                    + r.intent.getComponent().flattenToShortString());
7792                            r.stack.finishActivityLocked(r, index,
7793                                    Activity.RESULT_CANCELED, null, "crashed");
7794                        }
7795                    }
7796                }
7797            }
7798        }
7799
7800        // Bump up the crash count of any services currently running in the proc.
7801        if (app.services.size() != 0) {
7802            // Any services running in the application need to be placed
7803            // back in the pending list.
7804            Iterator<ServiceRecord> it = app.services.iterator();
7805            while (it.hasNext()) {
7806                ServiceRecord sr = it.next();
7807                sr.crashCount++;
7808            }
7809        }
7810
7811        // If the crashing process is what we consider to be the "home process" and it has been
7812        // replaced by a third-party app, clear the package preferred activities from packages
7813        // with a home activity running in the process to prevent a repeatedly crashing app
7814        // from blocking the user to manually clear the list.
7815        if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7816                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7817            Iterator it = mHomeProcess.activities.iterator();
7818            while (it.hasNext()) {
7819                ActivityRecord r = (ActivityRecord)it.next();
7820                if (r.isHomeActivity) {
7821                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7822                    try {
7823                        ActivityThread.getPackageManager()
7824                                .clearPackagePreferredActivities(r.packageName);
7825                    } catch (RemoteException c) {
7826                        // pm is in same process, this will never happen.
7827                    }
7828                }
7829            }
7830        }
7831
7832        if (!app.isolated) {
7833            // XXX Can't keep track of crash times for isolated processes,
7834            // because they don't have a perisistent identity.
7835            mProcessCrashTimes.put(app.info.processName, app.uid, now);
7836        }
7837
7838        return true;
7839    }
7840
7841    void startAppProblemLocked(ProcessRecord app) {
7842        app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7843                mContext, app.info.packageName, app.info.flags);
7844        skipCurrentReceiverLocked(app);
7845    }
7846
7847    void skipCurrentReceiverLocked(ProcessRecord app) {
7848        for (BroadcastQueue queue : mBroadcastQueues) {
7849            queue.skipCurrentReceiverLocked(app);
7850        }
7851    }
7852
7853    /**
7854     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7855     * The application process will exit immediately after this call returns.
7856     * @param app object of the crashing app, null for the system server
7857     * @param crashInfo describing the exception
7858     */
7859    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
7860        ProcessRecord r = findAppProcess(app, "Crash");
7861        final String processName = app == null ? "system_server"
7862                : (r == null ? "unknown" : r.processName);
7863
7864        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
7865                processName,
7866                r == null ? -1 : r.info.flags,
7867                crashInfo.exceptionClassName,
7868                crashInfo.exceptionMessage,
7869                crashInfo.throwFileName,
7870                crashInfo.throwLineNumber);
7871
7872        addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
7873
7874        crashApplication(r, crashInfo);
7875    }
7876
7877    public void handleApplicationStrictModeViolation(
7878            IBinder app,
7879            int violationMask,
7880            StrictMode.ViolationInfo info) {
7881        ProcessRecord r = findAppProcess(app, "StrictMode");
7882        if (r == null) {
7883            return;
7884        }
7885
7886        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
7887            Integer stackFingerprint = info.hashCode();
7888            boolean logIt = true;
7889            synchronized (mAlreadyLoggedViolatedStacks) {
7890                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7891                    logIt = false;
7892                    // TODO: sub-sample into EventLog for these, with
7893                    // the info.durationMillis?  Then we'd get
7894                    // the relative pain numbers, without logging all
7895                    // the stack traces repeatedly.  We'd want to do
7896                    // likewise in the client code, which also does
7897                    // dup suppression, before the Binder call.
7898                } else {
7899                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7900                        mAlreadyLoggedViolatedStacks.clear();
7901                    }
7902                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7903                }
7904            }
7905            if (logIt) {
7906                logStrictModeViolationToDropBox(r, info);
7907            }
7908        }
7909
7910        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7911            AppErrorResult result = new AppErrorResult();
7912            synchronized (this) {
7913                final long origId = Binder.clearCallingIdentity();
7914
7915                Message msg = Message.obtain();
7916                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7917                HashMap<String, Object> data = new HashMap<String, Object>();
7918                data.put("result", result);
7919                data.put("app", r);
7920                data.put("violationMask", violationMask);
7921                data.put("info", info);
7922                msg.obj = data;
7923                mHandler.sendMessage(msg);
7924
7925                Binder.restoreCallingIdentity(origId);
7926            }
7927            int res = result.get();
7928            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
7929        }
7930    }
7931
7932    // Depending on the policy in effect, there could be a bunch of
7933    // these in quick succession so we try to batch these together to
7934    // minimize disk writes, number of dropbox entries, and maximize
7935    // compression, by having more fewer, larger records.
7936    private void logStrictModeViolationToDropBox(
7937            ProcessRecord process,
7938            StrictMode.ViolationInfo info) {
7939        if (info == null) {
7940            return;
7941        }
7942        final boolean isSystemApp = process == null ||
7943                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7944                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7945        final String processName = process == null ? "unknown" : process.processName;
7946        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7947        final DropBoxManager dbox = (DropBoxManager)
7948                mContext.getSystemService(Context.DROPBOX_SERVICE);
7949
7950        // Exit early if the dropbox isn't configured to accept this report type.
7951        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7952
7953        boolean bufferWasEmpty;
7954        boolean needsFlush;
7955        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7956        synchronized (sb) {
7957            bufferWasEmpty = sb.length() == 0;
7958            appendDropBoxProcessHeaders(process, processName, sb);
7959            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7960            sb.append("System-App: ").append(isSystemApp).append("\n");
7961            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7962            if (info.violationNumThisLoop != 0) {
7963                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7964            }
7965            if (info.numAnimationsRunning != 0) {
7966                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7967            }
7968            if (info.broadcastIntentAction != null) {
7969                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7970            }
7971            if (info.durationMillis != -1) {
7972                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
7973            }
7974            if (info.numInstances != -1) {
7975                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7976            }
7977            if (info.tags != null) {
7978                for (String tag : info.tags) {
7979                    sb.append("Span-Tag: ").append(tag).append("\n");
7980                }
7981            }
7982            sb.append("\n");
7983            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7984                sb.append(info.crashInfo.stackTrace);
7985            }
7986            sb.append("\n");
7987
7988            // Only buffer up to ~64k.  Various logging bits truncate
7989            // things at 128k.
7990            needsFlush = (sb.length() > 64 * 1024);
7991        }
7992
7993        // Flush immediately if the buffer's grown too large, or this
7994        // is a non-system app.  Non-system apps are isolated with a
7995        // different tag & policy and not batched.
7996        //
7997        // Batching is useful during internal testing with
7998        // StrictMode settings turned up high.  Without batching,
7999        // thousands of separate files could be created on boot.
8000        if (!isSystemApp || needsFlush) {
8001            new Thread("Error dump: " + dropboxTag) {
8002                @Override
8003                public void run() {
8004                    String report;
8005                    synchronized (sb) {
8006                        report = sb.toString();
8007                        sb.delete(0, sb.length());
8008                        sb.trimToSize();
8009                    }
8010                    if (report.length() != 0) {
8011                        dbox.addText(dropboxTag, report);
8012                    }
8013                }
8014            }.start();
8015            return;
8016        }
8017
8018        // System app batching:
8019        if (!bufferWasEmpty) {
8020            // An existing dropbox-writing thread is outstanding, so
8021            // we don't need to start it up.  The existing thread will
8022            // catch the buffer appends we just did.
8023            return;
8024        }
8025
8026        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8027        // (After this point, we shouldn't access AMS internal data structures.)
8028        new Thread("Error dump: " + dropboxTag) {
8029            @Override
8030            public void run() {
8031                // 5 second sleep to let stacks arrive and be batched together
8032                try {
8033                    Thread.sleep(5000);  // 5 seconds
8034                } catch (InterruptedException e) {}
8035
8036                String errorReport;
8037                synchronized (mStrictModeBuffer) {
8038                    errorReport = mStrictModeBuffer.toString();
8039                    if (errorReport.length() == 0) {
8040                        return;
8041                    }
8042                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8043                    mStrictModeBuffer.trimToSize();
8044                }
8045                dbox.addText(dropboxTag, errorReport);
8046            }
8047        }.start();
8048    }
8049
8050    /**
8051     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8052     * @param app object of the crashing app, null for the system server
8053     * @param tag reported by the caller
8054     * @param crashInfo describing the context of the error
8055     * @return true if the process should exit immediately (WTF is fatal)
8056     */
8057    public boolean handleApplicationWtf(IBinder app, String tag,
8058            ApplicationErrorReport.CrashInfo crashInfo) {
8059        ProcessRecord r = findAppProcess(app, "WTF");
8060        final String processName = app == null ? "system_server"
8061                : (r == null ? "unknown" : r.processName);
8062
8063        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8064                processName,
8065                r == null ? -1 : r.info.flags,
8066                tag, crashInfo.exceptionMessage);
8067
8068        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8069
8070        if (r != null && r.pid != Process.myPid() &&
8071                Settings.Secure.getInt(mContext.getContentResolver(),
8072                        Settings.Secure.WTF_IS_FATAL, 0) != 0) {
8073            crashApplication(r, crashInfo);
8074            return true;
8075        } else {
8076            return false;
8077        }
8078    }
8079
8080    /**
8081     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8082     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8083     */
8084    private ProcessRecord findAppProcess(IBinder app, String reason) {
8085        if (app == null) {
8086            return null;
8087        }
8088
8089        synchronized (this) {
8090            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8091                final int NA = apps.size();
8092                for (int ia=0; ia<NA; ia++) {
8093                    ProcessRecord p = apps.valueAt(ia);
8094                    if (p.thread != null && p.thread.asBinder() == app) {
8095                        return p;
8096                    }
8097                }
8098            }
8099
8100            Slog.w(TAG, "Can't find mystery application for " + reason
8101                    + " from pid=" + Binder.getCallingPid()
8102                    + " uid=" + Binder.getCallingUid() + ": " + app);
8103            return null;
8104        }
8105    }
8106
8107    /**
8108     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8109     * to append various headers to the dropbox log text.
8110     */
8111    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8112            StringBuilder sb) {
8113        // Watchdog thread ends up invoking this function (with
8114        // a null ProcessRecord) to add the stack file to dropbox.
8115        // Do not acquire a lock on this (am) in such cases, as it
8116        // could cause a potential deadlock, if and when watchdog
8117        // is invoked due to unavailability of lock on am and it
8118        // would prevent watchdog from killing system_server.
8119        if (process == null) {
8120            sb.append("Process: ").append(processName).append("\n");
8121            return;
8122        }
8123        // Note: ProcessRecord 'process' is guarded by the service
8124        // instance.  (notably process.pkgList, which could otherwise change
8125        // concurrently during execution of this method)
8126        synchronized (this) {
8127            sb.append("Process: ").append(processName).append("\n");
8128            int flags = process.info.flags;
8129            IPackageManager pm = AppGlobals.getPackageManager();
8130            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8131            for (String pkg : process.pkgList) {
8132                sb.append("Package: ").append(pkg);
8133                try {
8134                    PackageInfo pi = pm.getPackageInfo(pkg, 0, 0);
8135                    if (pi != null) {
8136                        sb.append(" v").append(pi.versionCode);
8137                        if (pi.versionName != null) {
8138                            sb.append(" (").append(pi.versionName).append(")");
8139                        }
8140                    }
8141                } catch (RemoteException e) {
8142                    Slog.e(TAG, "Error getting package info: " + pkg, e);
8143                }
8144                sb.append("\n");
8145            }
8146        }
8147    }
8148
8149    private static String processClass(ProcessRecord process) {
8150        if (process == null || process.pid == MY_PID) {
8151            return "system_server";
8152        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8153            return "system_app";
8154        } else {
8155            return "data_app";
8156        }
8157    }
8158
8159    /**
8160     * Write a description of an error (crash, WTF, ANR) to the drop box.
8161     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8162     * @param process which caused the error, null means the system server
8163     * @param activity which triggered the error, null if unknown
8164     * @param parent activity related to the error, null if unknown
8165     * @param subject line related to the error, null if absent
8166     * @param report in long form describing the error, null if absent
8167     * @param logFile to include in the report, null if none
8168     * @param crashInfo giving an application stack trace, null if absent
8169     */
8170    public void addErrorToDropBox(String eventType,
8171            ProcessRecord process, String processName, ActivityRecord activity,
8172            ActivityRecord parent, String subject,
8173            final String report, final File logFile,
8174            final ApplicationErrorReport.CrashInfo crashInfo) {
8175        // NOTE -- this must never acquire the ActivityManagerService lock,
8176        // otherwise the watchdog may be prevented from resetting the system.
8177
8178        final String dropboxTag = processClass(process) + "_" + eventType;
8179        final DropBoxManager dbox = (DropBoxManager)
8180                mContext.getSystemService(Context.DROPBOX_SERVICE);
8181
8182        // Exit early if the dropbox isn't configured to accept this report type.
8183        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8184
8185        final StringBuilder sb = new StringBuilder(1024);
8186        appendDropBoxProcessHeaders(process, processName, sb);
8187        if (activity != null) {
8188            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8189        }
8190        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8191            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8192        }
8193        if (parent != null && parent != activity) {
8194            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8195        }
8196        if (subject != null) {
8197            sb.append("Subject: ").append(subject).append("\n");
8198        }
8199        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8200        if (Debug.isDebuggerConnected()) {
8201            sb.append("Debugger: Connected\n");
8202        }
8203        sb.append("\n");
8204
8205        // Do the rest in a worker thread to avoid blocking the caller on I/O
8206        // (After this point, we shouldn't access AMS internal data structures.)
8207        Thread worker = new Thread("Error dump: " + dropboxTag) {
8208            @Override
8209            public void run() {
8210                if (report != null) {
8211                    sb.append(report);
8212                }
8213                if (logFile != null) {
8214                    try {
8215                        sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8216                    } catch (IOException e) {
8217                        Slog.e(TAG, "Error reading " + logFile, e);
8218                    }
8219                }
8220                if (crashInfo != null && crashInfo.stackTrace != null) {
8221                    sb.append(crashInfo.stackTrace);
8222                }
8223
8224                String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8225                int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8226                if (lines > 0) {
8227                    sb.append("\n");
8228
8229                    // Merge several logcat streams, and take the last N lines
8230                    InputStreamReader input = null;
8231                    try {
8232                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8233                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8234                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8235
8236                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
8237                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
8238                        input = new InputStreamReader(logcat.getInputStream());
8239
8240                        int num;
8241                        char[] buf = new char[8192];
8242                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8243                    } catch (IOException e) {
8244                        Slog.e(TAG, "Error running logcat", e);
8245                    } finally {
8246                        if (input != null) try { input.close(); } catch (IOException e) {}
8247                    }
8248                }
8249
8250                dbox.addText(dropboxTag, sb.toString());
8251            }
8252        };
8253
8254        if (process == null) {
8255            // If process is null, we are being called from some internal code
8256            // and may be about to die -- run this synchronously.
8257            worker.run();
8258        } else {
8259            worker.start();
8260        }
8261    }
8262
8263    /**
8264     * Bring up the "unexpected error" dialog box for a crashing app.
8265     * Deal with edge cases (intercepts from instrumented applications,
8266     * ActivityController, error intent receivers, that sort of thing).
8267     * @param r the application crashing
8268     * @param crashInfo describing the failure
8269     */
8270    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8271        long timeMillis = System.currentTimeMillis();
8272        String shortMsg = crashInfo.exceptionClassName;
8273        String longMsg = crashInfo.exceptionMessage;
8274        String stackTrace = crashInfo.stackTrace;
8275        if (shortMsg != null && longMsg != null) {
8276            longMsg = shortMsg + ": " + longMsg;
8277        } else if (shortMsg != null) {
8278            longMsg = shortMsg;
8279        }
8280
8281        AppErrorResult result = new AppErrorResult();
8282        synchronized (this) {
8283            if (mController != null) {
8284                try {
8285                    String name = r != null ? r.processName : null;
8286                    int pid = r != null ? r.pid : Binder.getCallingPid();
8287                    if (!mController.appCrashed(name, pid,
8288                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8289                        Slog.w(TAG, "Force-killing crashed app " + name
8290                                + " at watcher's request");
8291                        Process.killProcess(pid);
8292                        return;
8293                    }
8294                } catch (RemoteException e) {
8295                    mController = null;
8296                }
8297            }
8298
8299            final long origId = Binder.clearCallingIdentity();
8300
8301            // If this process is running instrumentation, finish it.
8302            if (r != null && r.instrumentationClass != null) {
8303                Slog.w(TAG, "Error in app " + r.processName
8304                      + " running instrumentation " + r.instrumentationClass + ":");
8305                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
8306                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
8307                Bundle info = new Bundle();
8308                info.putString("shortMsg", shortMsg);
8309                info.putString("longMsg", longMsg);
8310                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8311                Binder.restoreCallingIdentity(origId);
8312                return;
8313            }
8314
8315            // If we can't identify the process or it's already exceeded its crash quota,
8316            // quit right away without showing a crash dialog.
8317            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8318                Binder.restoreCallingIdentity(origId);
8319                return;
8320            }
8321
8322            Message msg = Message.obtain();
8323            msg.what = SHOW_ERROR_MSG;
8324            HashMap data = new HashMap();
8325            data.put("result", result);
8326            data.put("app", r);
8327            msg.obj = data;
8328            mHandler.sendMessage(msg);
8329
8330            Binder.restoreCallingIdentity(origId);
8331        }
8332
8333        int res = result.get();
8334
8335        Intent appErrorIntent = null;
8336        synchronized (this) {
8337            if (r != null && !r.isolated) {
8338                // XXX Can't keep track of crash time for isolated processes,
8339                // since they don't have a persistent identity.
8340                mProcessCrashTimes.put(r.info.processName, r.uid,
8341                        SystemClock.uptimeMillis());
8342            }
8343            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8344                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8345            }
8346        }
8347
8348        if (appErrorIntent != null) {
8349            try {
8350                mContext.startActivity(appErrorIntent);
8351            } catch (ActivityNotFoundException e) {
8352                Slog.w(TAG, "bug report receiver dissappeared", e);
8353            }
8354        }
8355    }
8356
8357    Intent createAppErrorIntentLocked(ProcessRecord r,
8358            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8359        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8360        if (report == null) {
8361            return null;
8362        }
8363        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8364        result.setComponent(r.errorReportReceiver);
8365        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8366        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8367        return result;
8368    }
8369
8370    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8371            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8372        if (r.errorReportReceiver == null) {
8373            return null;
8374        }
8375
8376        if (!r.crashing && !r.notResponding) {
8377            return null;
8378        }
8379
8380        ApplicationErrorReport report = new ApplicationErrorReport();
8381        report.packageName = r.info.packageName;
8382        report.installerPackageName = r.errorReportReceiver.getPackageName();
8383        report.processName = r.processName;
8384        report.time = timeMillis;
8385        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8386
8387        if (r.crashing) {
8388            report.type = ApplicationErrorReport.TYPE_CRASH;
8389            report.crashInfo = crashInfo;
8390        } else if (r.notResponding) {
8391            report.type = ApplicationErrorReport.TYPE_ANR;
8392            report.anrInfo = new ApplicationErrorReport.AnrInfo();
8393
8394            report.anrInfo.activity = r.notRespondingReport.tag;
8395            report.anrInfo.cause = r.notRespondingReport.shortMsg;
8396            report.anrInfo.info = r.notRespondingReport.longMsg;
8397        }
8398
8399        return report;
8400    }
8401
8402    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8403        enforceNotIsolatedCaller("getProcessesInErrorState");
8404        // assume our apps are happy - lazy create the list
8405        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8406
8407        synchronized (this) {
8408
8409            // iterate across all processes
8410            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8411                ProcessRecord app = mLruProcesses.get(i);
8412                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8413                    // This one's in trouble, so we'll generate a report for it
8414                    // crashes are higher priority (in case there's a crash *and* an anr)
8415                    ActivityManager.ProcessErrorStateInfo report = null;
8416                    if (app.crashing) {
8417                        report = app.crashingReport;
8418                    } else if (app.notResponding) {
8419                        report = app.notRespondingReport;
8420                    }
8421
8422                    if (report != null) {
8423                        if (errList == null) {
8424                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8425                        }
8426                        errList.add(report);
8427                    } else {
8428                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
8429                                " crashing = " + app.crashing +
8430                                " notResponding = " + app.notResponding);
8431                    }
8432                }
8433            }
8434        }
8435
8436        return errList;
8437    }
8438
8439    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8440        if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8441            if (currApp != null) {
8442                currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8443            }
8444            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8445        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8446            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8447        } else if (adj >= ProcessList.HOME_APP_ADJ) {
8448            if (currApp != null) {
8449                currApp.lru = 0;
8450            }
8451            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8452        } else if (adj >= ProcessList.SERVICE_ADJ) {
8453            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8454        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8455            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8456        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8457            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8458        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8459            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8460        } else {
8461            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8462        }
8463    }
8464
8465    private void fillInProcMemInfo(ProcessRecord app,
8466            ActivityManager.RunningAppProcessInfo outInfo) {
8467        outInfo.pid = app.pid;
8468        outInfo.uid = app.info.uid;
8469        if (mHeavyWeightProcess == app) {
8470            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8471        }
8472        if (app.persistent) {
8473            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8474        }
8475        outInfo.lastTrimLevel = app.trimMemoryLevel;
8476        int adj = app.curAdj;
8477        outInfo.importance = oomAdjToImportance(adj, outInfo);
8478        outInfo.importanceReasonCode = app.adjTypeCode;
8479    }
8480
8481    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8482        enforceNotIsolatedCaller("getRunningAppProcesses");
8483        // Lazy instantiation of list
8484        List<ActivityManager.RunningAppProcessInfo> runList = null;
8485        synchronized (this) {
8486            // Iterate across all processes
8487            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8488                ProcessRecord app = mLruProcesses.get(i);
8489                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8490                    // Generate process state info for running application
8491                    ActivityManager.RunningAppProcessInfo currApp =
8492                        new ActivityManager.RunningAppProcessInfo(app.processName,
8493                                app.pid, app.getPackageList());
8494                    fillInProcMemInfo(app, currApp);
8495                    if (app.adjSource instanceof ProcessRecord) {
8496                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8497                        currApp.importanceReasonImportance = oomAdjToImportance(
8498                                app.adjSourceOom, null);
8499                    } else if (app.adjSource instanceof ActivityRecord) {
8500                        ActivityRecord r = (ActivityRecord)app.adjSource;
8501                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8502                    }
8503                    if (app.adjTarget instanceof ComponentName) {
8504                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8505                    }
8506                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8507                    //        + " lru=" + currApp.lru);
8508                    if (runList == null) {
8509                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8510                    }
8511                    runList.add(currApp);
8512                }
8513            }
8514        }
8515        return runList;
8516    }
8517
8518    public List<ApplicationInfo> getRunningExternalApplications() {
8519        enforceNotIsolatedCaller("getRunningExternalApplications");
8520        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8521        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8522        if (runningApps != null && runningApps.size() > 0) {
8523            Set<String> extList = new HashSet<String>();
8524            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8525                if (app.pkgList != null) {
8526                    for (String pkg : app.pkgList) {
8527                        extList.add(pkg);
8528                    }
8529                }
8530            }
8531            IPackageManager pm = AppGlobals.getPackageManager();
8532            for (String pkg : extList) {
8533                try {
8534                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserId.getCallingUserId());
8535                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8536                        retList.add(info);
8537                    }
8538                } catch (RemoteException e) {
8539                }
8540            }
8541        }
8542        return retList;
8543    }
8544
8545    @Override
8546    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8547        enforceNotIsolatedCaller("getMyMemoryState");
8548        synchronized (this) {
8549            ProcessRecord proc;
8550            synchronized (mPidsSelfLocked) {
8551                proc = mPidsSelfLocked.get(Binder.getCallingPid());
8552            }
8553            fillInProcMemInfo(proc, outInfo);
8554        }
8555    }
8556
8557    @Override
8558    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8559        if (checkCallingPermission(android.Manifest.permission.DUMP)
8560                != PackageManager.PERMISSION_GRANTED) {
8561            pw.println("Permission Denial: can't dump ActivityManager from from pid="
8562                    + Binder.getCallingPid()
8563                    + ", uid=" + Binder.getCallingUid()
8564                    + " without permission "
8565                    + android.Manifest.permission.DUMP);
8566            return;
8567        }
8568
8569        boolean dumpAll = false;
8570        boolean dumpClient = false;
8571        String dumpPackage = null;
8572
8573        int opti = 0;
8574        while (opti < args.length) {
8575            String opt = args[opti];
8576            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8577                break;
8578            }
8579            opti++;
8580            if ("-a".equals(opt)) {
8581                dumpAll = true;
8582            } else if ("-c".equals(opt)) {
8583                dumpClient = true;
8584            } else if ("-h".equals(opt)) {
8585                pw.println("Activity manager dump options:");
8586                pw.println("  [-a] [-c] [-h] [cmd] ...");
8587                pw.println("  cmd may be one of:");
8588                pw.println("    a[ctivities]: activity stack state");
8589                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
8590                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
8591                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
8592                pw.println("    o[om]: out of memory management");
8593                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
8594                pw.println("    provider [COMP_SPEC]: provider client-side state");
8595                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
8596                pw.println("    service [COMP_SPEC]: service client-side state");
8597                pw.println("    package [PACKAGE_NAME]: all state related to given package");
8598                pw.println("    all: dump all activities");
8599                pw.println("    top: dump the top activity");
8600                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
8601                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
8602                pw.println("    a partial substring in a component name, a");
8603                pw.println("    hex object identifier.");
8604                pw.println("  -a: include all available server state.");
8605                pw.println("  -c: include client state.");
8606                return;
8607            } else {
8608                pw.println("Unknown argument: " + opt + "; use -h for help");
8609            }
8610        }
8611
8612        long origId = Binder.clearCallingIdentity();
8613        boolean more = false;
8614        // Is the caller requesting to dump a particular piece of data?
8615        if (opti < args.length) {
8616            String cmd = args[opti];
8617            opti++;
8618            if ("activities".equals(cmd) || "a".equals(cmd)) {
8619                synchronized (this) {
8620                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8621                }
8622            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8623                String[] newArgs;
8624                String name;
8625                if (opti >= args.length) {
8626                    name = null;
8627                    newArgs = EMPTY_STRING_ARRAY;
8628                } else {
8629                    name = args[opti];
8630                    opti++;
8631                    newArgs = new String[args.length - opti];
8632                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8633                            args.length - opti);
8634                }
8635                synchronized (this) {
8636                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
8637                }
8638            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
8639                String[] newArgs;
8640                String name;
8641                if (opti >= args.length) {
8642                    name = null;
8643                    newArgs = EMPTY_STRING_ARRAY;
8644                } else {
8645                    name = args[opti];
8646                    opti++;
8647                    newArgs = new String[args.length - opti];
8648                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8649                            args.length - opti);
8650                }
8651                synchronized (this) {
8652                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
8653                }
8654            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
8655                String[] newArgs;
8656                String name;
8657                if (opti >= args.length) {
8658                    name = null;
8659                    newArgs = EMPTY_STRING_ARRAY;
8660                } else {
8661                    name = args[opti];
8662                    opti++;
8663                    newArgs = new String[args.length - opti];
8664                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8665                            args.length - opti);
8666                }
8667                synchronized (this) {
8668                    dumpProcessesLocked(fd, pw, args, opti, true, name);
8669                }
8670            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8671                synchronized (this) {
8672                    dumpOomLocked(fd, pw, args, opti, true);
8673                }
8674            } else if ("provider".equals(cmd)) {
8675                String[] newArgs;
8676                String name;
8677                if (opti >= args.length) {
8678                    name = null;
8679                    newArgs = EMPTY_STRING_ARRAY;
8680                } else {
8681                    name = args[opti];
8682                    opti++;
8683                    newArgs = new String[args.length - opti];
8684                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8685                }
8686                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8687                    pw.println("No providers match: " + name);
8688                    pw.println("Use -h for help.");
8689                }
8690            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8691                synchronized (this) {
8692                    dumpProvidersLocked(fd, pw, args, opti, true, null);
8693                }
8694            } else if ("service".equals(cmd)) {
8695                String[] newArgs;
8696                String name;
8697                if (opti >= args.length) {
8698                    name = null;
8699                    newArgs = EMPTY_STRING_ARRAY;
8700                } else {
8701                    name = args[opti];
8702                    opti++;
8703                    newArgs = new String[args.length - opti];
8704                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8705                            args.length - opti);
8706                }
8707                if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8708                    pw.println("No services match: " + name);
8709                    pw.println("Use -h for help.");
8710                }
8711            } else if ("package".equals(cmd)) {
8712                String[] newArgs;
8713                if (opti >= args.length) {
8714                    pw.println("package: no package name specified");
8715                    pw.println("Use -h for help.");
8716                } else {
8717                    dumpPackage = args[opti];
8718                    opti++;
8719                    newArgs = new String[args.length - opti];
8720                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8721                            args.length - opti);
8722                    args = newArgs;
8723                    opti = 0;
8724                    more = true;
8725                }
8726            } else if ("services".equals(cmd) || "s".equals(cmd)) {
8727                synchronized (this) {
8728                    dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
8729                }
8730            } else {
8731                // Dumping a single activity?
8732                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8733                    pw.println("Bad activity command, or no activities match: " + cmd);
8734                    pw.println("Use -h for help.");
8735                }
8736            }
8737            if (!more) {
8738                Binder.restoreCallingIdentity(origId);
8739                return;
8740            }
8741        }
8742
8743        // No piece of data specified, dump everything.
8744        synchronized (this) {
8745            boolean needSep;
8746            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8747            if (needSep) {
8748                pw.println(" ");
8749            }
8750            if (dumpAll) {
8751                pw.println("-------------------------------------------------------------------------------");
8752            }
8753            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8754            if (needSep) {
8755                pw.println(" ");
8756            }
8757            if (dumpAll) {
8758                pw.println("-------------------------------------------------------------------------------");
8759            }
8760            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8761            if (needSep) {
8762                pw.println(" ");
8763            }
8764            if (dumpAll) {
8765                pw.println("-------------------------------------------------------------------------------");
8766            }
8767            needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8768            if (needSep) {
8769                pw.println(" ");
8770            }
8771            if (dumpAll) {
8772                pw.println("-------------------------------------------------------------------------------");
8773            }
8774            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
8775            if (needSep) {
8776                pw.println(" ");
8777            }
8778            if (dumpAll) {
8779                pw.println("-------------------------------------------------------------------------------");
8780            }
8781            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
8782        }
8783        Binder.restoreCallingIdentity(origId);
8784    }
8785
8786    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8787            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
8788        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8789        pw.println("  Main stack:");
8790        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
8791                dumpPackage);
8792        pw.println(" ");
8793        pw.println("  Running activities (most recent first):");
8794        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
8795                dumpPackage);
8796        if (mMainStack.mWaitingVisibleActivities.size() > 0) {
8797            pw.println(" ");
8798            pw.println("  Activities waiting for another to become visible:");
8799            dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
8800                    !dumpAll, false, dumpPackage);
8801        }
8802        if (mMainStack.mStoppingActivities.size() > 0) {
8803            pw.println(" ");
8804            pw.println("  Activities waiting to stop:");
8805            dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
8806                    !dumpAll, false, dumpPackage);
8807        }
8808        if (mMainStack.mGoingToSleepActivities.size() > 0) {
8809            pw.println(" ");
8810            pw.println("  Activities waiting to sleep:");
8811            dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
8812                    !dumpAll, false, dumpPackage);
8813        }
8814        if (mMainStack.mFinishingActivities.size() > 0) {
8815            pw.println(" ");
8816            pw.println("  Activities waiting to finish:");
8817            dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
8818                    !dumpAll, false, dumpPackage);
8819        }
8820
8821        pw.println(" ");
8822        if (mMainStack.mPausingActivity != null) {
8823            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
8824        }
8825        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
8826        pw.println("  mFocusedActivity: " + mFocusedActivity);
8827        if (dumpAll) {
8828            pw.println("  mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8829            pw.println("  mSleepTimeout: " + mMainStack.mSleepTimeout);
8830            pw.println("  mDismissKeyguardOnNextActivity: "
8831                    + mMainStack.mDismissKeyguardOnNextActivity);
8832        }
8833
8834        if (mRecentTasks.size() > 0) {
8835            pw.println();
8836            pw.println("  Recent tasks:");
8837
8838            final int N = mRecentTasks.size();
8839            for (int i=0; i<N; i++) {
8840                TaskRecord tr = mRecentTasks.get(i);
8841                if (dumpPackage != null) {
8842                    if (tr.realActivity == null ||
8843                            !dumpPackage.equals(tr.realActivity)) {
8844                        continue;
8845                    }
8846                }
8847                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
8848                        pw.println(tr);
8849                if (dumpAll) {
8850                    mRecentTasks.get(i).dump(pw, "    ");
8851                }
8852            }
8853        }
8854
8855        if (dumpAll) {
8856            pw.println(" ");
8857            pw.println("  mCurTask: " + mCurTask);
8858        }
8859
8860        return true;
8861    }
8862
8863    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8864            int opti, boolean dumpAll, String dumpPackage) {
8865        boolean needSep = false;
8866        int numPers = 0;
8867
8868        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8869
8870        if (dumpAll) {
8871            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8872                final int NA = procs.size();
8873                for (int ia=0; ia<NA; ia++) {
8874                    ProcessRecord r = procs.valueAt(ia);
8875                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8876                        continue;
8877                    }
8878                    if (!needSep) {
8879                        pw.println("  All known processes:");
8880                        needSep = true;
8881                    }
8882                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
8883                        pw.print(" UID "); pw.print(procs.keyAt(ia));
8884                        pw.print(" "); pw.println(r);
8885                    r.dump(pw, "    ");
8886                    if (r.persistent) {
8887                        numPers++;
8888                    }
8889                }
8890            }
8891        }
8892
8893        if (mIsolatedProcesses.size() > 0) {
8894            if (needSep) pw.println(" ");
8895            needSep = true;
8896            pw.println("  Isolated process list (sorted by uid):");
8897            for (int i=0; i<mIsolatedProcesses.size(); i++) {
8898                ProcessRecord r = mIsolatedProcesses.valueAt(i);
8899                if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8900                    continue;
8901                }
8902                pw.println(String.format("%sIsolated #%2d: %s",
8903                        "    ", i, r.toString()));
8904            }
8905        }
8906
8907        if (mLruProcesses.size() > 0) {
8908            if (needSep) pw.println(" ");
8909            needSep = true;
8910            pw.println("  Process LRU list (sorted by oom_adj):");
8911            dumpProcessOomList(pw, this, mLruProcesses, "    ",
8912                    "Proc", "PERS", false, dumpPackage);
8913            needSep = true;
8914        }
8915
8916        if (dumpAll) {
8917            synchronized (mPidsSelfLocked) {
8918                boolean printed = false;
8919                for (int i=0; i<mPidsSelfLocked.size(); i++) {
8920                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
8921                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8922                        continue;
8923                    }
8924                    if (!printed) {
8925                        if (needSep) pw.println(" ");
8926                        needSep = true;
8927                        pw.println("  PID mappings:");
8928                        printed = true;
8929                    }
8930                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8931                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
8932                }
8933            }
8934        }
8935
8936        if (mForegroundProcesses.size() > 0) {
8937            synchronized (mPidsSelfLocked) {
8938                boolean printed = false;
8939                for (int i=0; i<mForegroundProcesses.size(); i++) {
8940                    ProcessRecord r = mPidsSelfLocked.get(
8941                            mForegroundProcesses.valueAt(i).pid);
8942                    if (dumpPackage != null && (r == null
8943                            || !dumpPackage.equals(r.info.packageName))) {
8944                        continue;
8945                    }
8946                    if (!printed) {
8947                        if (needSep) pw.println(" ");
8948                        needSep = true;
8949                        pw.println("  Foreground Processes:");
8950                        printed = true;
8951                    }
8952                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
8953                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
8954                }
8955            }
8956        }
8957
8958        if (mPersistentStartingProcesses.size() > 0) {
8959            if (needSep) pw.println(" ");
8960            needSep = true;
8961            pw.println("  Persisent processes that are starting:");
8962            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
8963                    "Starting Norm", "Restarting PERS", dumpPackage);
8964        }
8965
8966        if (mRemovedProcesses.size() > 0) {
8967            if (needSep) pw.println(" ");
8968            needSep = true;
8969            pw.println("  Processes that are being removed:");
8970            dumpProcessList(pw, this, mRemovedProcesses, "    ",
8971                    "Removed Norm", "Removed PERS", dumpPackage);
8972        }
8973
8974        if (mProcessesOnHold.size() > 0) {
8975            if (needSep) pw.println(" ");
8976            needSep = true;
8977            pw.println("  Processes that are on old until the system is ready:");
8978            dumpProcessList(pw, this, mProcessesOnHold, "    ",
8979                    "OnHold Norm", "OnHold PERS", dumpPackage);
8980        }
8981
8982        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
8983
8984        if (mProcessCrashTimes.getMap().size() > 0) {
8985            boolean printed = false;
8986            long now = SystemClock.uptimeMillis();
8987            for (Map.Entry<String, SparseArray<Long>> procs
8988                    : mProcessCrashTimes.getMap().entrySet()) {
8989                String pname = procs.getKey();
8990                SparseArray<Long> uids = procs.getValue();
8991                final int N = uids.size();
8992                for (int i=0; i<N; i++) {
8993                    int puid = uids.keyAt(i);
8994                    ProcessRecord r = mProcessNames.get(pname, puid);
8995                    if (dumpPackage != null && (r == null
8996                            || !dumpPackage.equals(r.info.packageName))) {
8997                        continue;
8998                    }
8999                    if (!printed) {
9000                        if (needSep) pw.println(" ");
9001                        needSep = true;
9002                        pw.println("  Time since processes crashed:");
9003                        printed = true;
9004                    }
9005                    pw.print("    Process "); pw.print(pname);
9006                            pw.print(" uid "); pw.print(puid);
9007                            pw.print(": last crashed ");
9008                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9009                            pw.println(" ago");
9010                }
9011            }
9012        }
9013
9014        if (mBadProcesses.getMap().size() > 0) {
9015            boolean printed = false;
9016            for (Map.Entry<String, SparseArray<Long>> procs
9017                    : mBadProcesses.getMap().entrySet()) {
9018                String pname = procs.getKey();
9019                SparseArray<Long> uids = procs.getValue();
9020                final int N = uids.size();
9021                for (int i=0; i<N; i++) {
9022                    int puid = uids.keyAt(i);
9023                    ProcessRecord r = mProcessNames.get(pname, puid);
9024                    if (dumpPackage != null && (r == null
9025                            || !dumpPackage.equals(r.info.packageName))) {
9026                        continue;
9027                    }
9028                    if (!printed) {
9029                        if (needSep) pw.println(" ");
9030                        needSep = true;
9031                        pw.println("  Bad processes:");
9032                    }
9033                    pw.print("    Bad process "); pw.print(pname);
9034                            pw.print(" uid "); pw.print(puid);
9035                            pw.print(": crashed at time ");
9036                            pw.println(uids.valueAt(i));
9037                }
9038            }
9039        }
9040
9041        pw.println();
9042        pw.println("  mHomeProcess: " + mHomeProcess);
9043        pw.println("  mPreviousProcess: " + mPreviousProcess);
9044        if (dumpAll) {
9045            StringBuilder sb = new StringBuilder(128);
9046            sb.append("  mPreviousProcessVisibleTime: ");
9047            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9048            pw.println(sb);
9049        }
9050        if (mHeavyWeightProcess != null) {
9051            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9052        }
9053        pw.println("  mConfiguration: " + mConfiguration);
9054        if (dumpAll) {
9055            pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
9056            if (mCompatModePackages.getPackages().size() > 0) {
9057                boolean printed = false;
9058                for (Map.Entry<String, Integer> entry
9059                        : mCompatModePackages.getPackages().entrySet()) {
9060                    String pkg = entry.getKey();
9061                    int mode = entry.getValue();
9062                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9063                        continue;
9064                    }
9065                    if (!printed) {
9066                        pw.println("  mScreenCompatPackages:");
9067                        printed = true;
9068                    }
9069                    pw.print("    "); pw.print(pkg); pw.print(": ");
9070                            pw.print(mode); pw.println();
9071                }
9072            }
9073        }
9074        if (mSleeping || mWentToSleep || mLockScreenShown) {
9075            pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9076                    + " mLockScreenShown " + mLockScreenShown);
9077        }
9078        if (mShuttingDown) {
9079            pw.println("  mShuttingDown=" + mShuttingDown);
9080        }
9081        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9082                || mOrigWaitForDebugger) {
9083            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9084                    + " mDebugTransient=" + mDebugTransient
9085                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9086        }
9087        if (mOpenGlTraceApp != null) {
9088            pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
9089        }
9090        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9091                || mProfileFd != null) {
9092            pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9093            pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9094            pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
9095                    + mAutoStopProfiler);
9096        }
9097        if (mAlwaysFinishActivities || mController != null) {
9098            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9099                    + " mController=" + mController);
9100        }
9101        if (dumpAll) {
9102            pw.println("  Total persistent processes: " + numPers);
9103            pw.println("  mStartRunning=" + mStartRunning
9104                    + " mProcessesReady=" + mProcessesReady
9105                    + " mSystemReady=" + mSystemReady);
9106            pw.println("  mBooting=" + mBooting
9107                    + " mBooted=" + mBooted
9108                    + " mFactoryTest=" + mFactoryTest);
9109            pw.print("  mLastPowerCheckRealtime=");
9110                    TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9111                    pw.println("");
9112            pw.print("  mLastPowerCheckUptime=");
9113                    TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9114                    pw.println("");
9115            pw.println("  mGoingToSleep=" + mMainStack.mGoingToSleep);
9116            pw.println("  mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9117            pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9118            pw.println("  mNumServiceProcs=" + mNumServiceProcs
9119                    + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9120        }
9121
9122        return true;
9123    }
9124
9125    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9126            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9127        if (mProcessesToGc.size() > 0) {
9128            boolean printed = false;
9129            long now = SystemClock.uptimeMillis();
9130            for (int i=0; i<mProcessesToGc.size(); i++) {
9131                ProcessRecord proc = mProcessesToGc.get(i);
9132                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9133                    continue;
9134                }
9135                if (!printed) {
9136                    if (needSep) pw.println(" ");
9137                    needSep = true;
9138                    pw.println("  Processes that are waiting to GC:");
9139                    printed = true;
9140                }
9141                pw.print("    Process "); pw.println(proc);
9142                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9143                        pw.print(", last gced=");
9144                        pw.print(now-proc.lastRequestedGc);
9145                        pw.print(" ms ago, last lowMem=");
9146                        pw.print(now-proc.lastLowMemory);
9147                        pw.println(" ms ago");
9148
9149            }
9150        }
9151        return needSep;
9152    }
9153
9154    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9155            int opti, boolean dumpAll) {
9156        boolean needSep = false;
9157
9158        if (mLruProcesses.size() > 0) {
9159            if (needSep) pw.println(" ");
9160            needSep = true;
9161            pw.println("  OOM levels:");
9162            pw.print("    SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9163            pw.print("    PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9164            pw.print("    FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9165            pw.print("    VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9166            pw.print("    PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9167            pw.print("    HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9168            pw.print("    BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9169            pw.print("    SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9170            pw.print("    HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9171            pw.print("    PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9172            pw.print("    SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9173            pw.print("    HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9174            pw.print("    HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9175
9176            if (needSep) pw.println(" ");
9177            needSep = true;
9178            pw.println("  Process OOM control:");
9179            dumpProcessOomList(pw, this, mLruProcesses, "    ",
9180                    "Proc", "PERS", true, null);
9181            needSep = true;
9182        }
9183
9184        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9185
9186        pw.println();
9187        pw.println("  mHomeProcess: " + mHomeProcess);
9188        pw.println("  mPreviousProcess: " + mPreviousProcess);
9189        if (mHeavyWeightProcess != null) {
9190            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
9191        }
9192
9193        return true;
9194    }
9195
9196    /**
9197     * There are three ways to call this:
9198     *  - no service specified: dump all the services
9199     *  - a flattened component name that matched an existing service was specified as the
9200     *    first arg: dump that one service
9201     *  - the first arg isn't the flattened component name of an existing service:
9202     *    dump all services whose component contains the first arg as a substring
9203     */
9204    protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9205            int opti, boolean dumpAll) {
9206        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
9207
9208        if ("all".equals(name)) {
9209            synchronized (this) {
9210                try {
9211                    List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9212                    for (UserInfo user : users) {
9213                        for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) {
9214                            services.add(r1);
9215                        }
9216                    }
9217                } catch (RemoteException re) {
9218                }
9219            }
9220        } else {
9221            ComponentName componentName = name != null
9222                    ? ComponentName.unflattenFromString(name) : null;
9223            int objectId = 0;
9224            if (componentName == null) {
9225                // Not a '/' separated full component name; maybe an object ID?
9226                try {
9227                    objectId = Integer.parseInt(name, 16);
9228                    name = null;
9229                    componentName = null;
9230                } catch (RuntimeException e) {
9231                }
9232            }
9233
9234            synchronized (this) {
9235                try {
9236                    List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9237                    for (UserInfo user : users) {
9238                        for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) {
9239                            if (componentName != null) {
9240                                if (r1.name.equals(componentName)) {
9241                                    services.add(r1);
9242                                }
9243                            } else if (name != null) {
9244                                if (r1.name.flattenToString().contains(name)) {
9245                                    services.add(r1);
9246                                }
9247                            } else if (System.identityHashCode(r1) == objectId) {
9248                                services.add(r1);
9249                            }
9250                        }
9251                    }
9252                } catch (RemoteException re) {
9253                }
9254            }
9255        }
9256
9257        if (services.size() <= 0) {
9258            return false;
9259        }
9260
9261        boolean needSep = false;
9262        for (int i=0; i<services.size(); i++) {
9263            if (needSep) {
9264                pw.println();
9265            }
9266            needSep = true;
9267            dumpService("", fd, pw, services.get(i), args, dumpAll);
9268        }
9269        return true;
9270    }
9271
9272    /**
9273     * Invokes IApplicationThread.dumpService() on the thread of the specified service if
9274     * there is a thread associated with the service.
9275     */
9276    private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
9277            final ServiceRecord r, String[] args, boolean dumpAll) {
9278        String innerPrefix = prefix + "  ";
9279        synchronized (this) {
9280            pw.print(prefix); pw.print("SERVICE ");
9281                    pw.print(r.shortName); pw.print(" ");
9282                    pw.print(Integer.toHexString(System.identityHashCode(r)));
9283                    pw.print(" pid=");
9284                    if (r.app != null) pw.println(r.app.pid);
9285                    else pw.println("(not running)");
9286            if (dumpAll) {
9287                r.dump(pw, innerPrefix);
9288            }
9289        }
9290        if (r.app != null && r.app.thread != null) {
9291            pw.print(prefix); pw.println("  Client:");
9292            pw.flush();
9293            try {
9294                TransferPipe tp = new TransferPipe();
9295                try {
9296                    r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
9297                    tp.setBufferPrefix(prefix + "    ");
9298                    tp.go(fd);
9299                } finally {
9300                    tp.kill();
9301                }
9302            } catch (IOException e) {
9303                pw.println(prefix + "    Failure while dumping the service: " + e);
9304            } catch (RemoteException e) {
9305                pw.println(prefix + "    Got a RemoteException while dumping the service");
9306            }
9307        }
9308    }
9309
9310    /**
9311     * There are three ways to call this:
9312     *  - no provider specified: dump all the providers
9313     *  - a flattened component name that matched an existing provider was specified as the
9314     *    first arg: dump that one provider
9315     *  - the first arg isn't the flattened component name of an existing provider:
9316     *    dump all providers whose component contains the first arg as a substring
9317     */
9318    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9319            int opti, boolean dumpAll) {
9320        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9321    }
9322
9323    static class ItemMatcher {
9324        ArrayList<ComponentName> components;
9325        ArrayList<String> strings;
9326        ArrayList<Integer> objects;
9327        boolean all;
9328
9329        ItemMatcher() {
9330            all = true;
9331        }
9332
9333        void build(String name) {
9334            ComponentName componentName = ComponentName.unflattenFromString(name);
9335            if (componentName != null) {
9336                if (components == null) {
9337                    components = new ArrayList<ComponentName>();
9338                }
9339                components.add(componentName);
9340                all = false;
9341            } else {
9342                int objectId = 0;
9343                // Not a '/' separated full component name; maybe an object ID?
9344                try {
9345                    objectId = Integer.parseInt(name, 16);
9346                    if (objects == null) {
9347                        objects = new ArrayList<Integer>();
9348                    }
9349                    objects.add(objectId);
9350                    all = false;
9351                } catch (RuntimeException e) {
9352                    // Not an integer; just do string match.
9353                    if (strings == null) {
9354                        strings = new ArrayList<String>();
9355                    }
9356                    strings.add(name);
9357                    all = false;
9358                }
9359            }
9360        }
9361
9362        int build(String[] args, int opti) {
9363            for (; opti<args.length; opti++) {
9364                String name = args[opti];
9365                if ("--".equals(name)) {
9366                    return opti+1;
9367                }
9368                build(name);
9369            }
9370            return opti;
9371        }
9372
9373        boolean match(Object object, ComponentName comp) {
9374            if (all) {
9375                return true;
9376            }
9377            if (components != null) {
9378                for (int i=0; i<components.size(); i++) {
9379                    if (components.get(i).equals(comp)) {
9380                        return true;
9381                    }
9382                }
9383            }
9384            if (objects != null) {
9385                for (int i=0; i<objects.size(); i++) {
9386                    if (System.identityHashCode(object) == objects.get(i)) {
9387                        return true;
9388                    }
9389                }
9390            }
9391            if (strings != null) {
9392                String flat = comp.flattenToString();
9393                for (int i=0; i<strings.size(); i++) {
9394                    if (flat.contains(strings.get(i))) {
9395                        return true;
9396                    }
9397                }
9398            }
9399            return false;
9400        }
9401    }
9402
9403    /**
9404     * There are three things that cmd can be:
9405     *  - a flattened component name that matches an existing activity
9406     *  - the cmd arg isn't the flattened component name of an existing activity:
9407     *    dump all activity whose component contains the cmd as a substring
9408     *  - A hex number of the ActivityRecord object instance.
9409     */
9410    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9411            int opti, boolean dumpAll) {
9412        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9413
9414        if ("all".equals(name)) {
9415            synchronized (this) {
9416                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9417                    activities.add(r1);
9418                }
9419            }
9420        } else if ("top".equals(name)) {
9421            synchronized (this) {
9422                final int N = mMainStack.mHistory.size();
9423                if (N > 0) {
9424                    activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9425                }
9426            }
9427        } else {
9428            ItemMatcher matcher = new ItemMatcher();
9429            matcher.build(name);
9430
9431            synchronized (this) {
9432                for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9433                    if (matcher.match(r1, r1.intent.getComponent())) {
9434                        activities.add(r1);
9435                    }
9436                }
9437            }
9438        }
9439
9440        if (activities.size() <= 0) {
9441            return false;
9442        }
9443
9444        String[] newArgs = new String[args.length - opti];
9445        if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9446
9447        TaskRecord lastTask = null;
9448        boolean needSep = false;
9449        for (int i=activities.size()-1; i>=0; i--) {
9450            ActivityRecord r = (ActivityRecord)activities.get(i);
9451            if (needSep) {
9452                pw.println();
9453            }
9454            needSep = true;
9455            synchronized (this) {
9456                if (lastTask != r.task) {
9457                    lastTask = r.task;
9458                    pw.print("TASK "); pw.print(lastTask.affinity);
9459                            pw.print(" id="); pw.println(lastTask.taskId);
9460                    if (dumpAll) {
9461                        lastTask.dump(pw, "  ");
9462                    }
9463                }
9464            }
9465            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
9466        }
9467        return true;
9468    }
9469
9470    /**
9471     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9472     * there is a thread associated with the activity.
9473     */
9474    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9475            final ActivityRecord r, String[] args, boolean dumpAll) {
9476        String innerPrefix = prefix + "  ";
9477        synchronized (this) {
9478            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9479                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9480                    pw.print(" pid=");
9481                    if (r.app != null) pw.println(r.app.pid);
9482                    else pw.println("(not running)");
9483            if (dumpAll) {
9484                r.dump(pw, innerPrefix);
9485            }
9486        }
9487        if (r.app != null && r.app.thread != null) {
9488            // flush anything that is already in the PrintWriter since the thread is going
9489            // to write to the file descriptor directly
9490            pw.flush();
9491            try {
9492                TransferPipe tp = new TransferPipe();
9493                try {
9494                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9495                            r.appToken, innerPrefix, args);
9496                    tp.go(fd);
9497                } finally {
9498                    tp.kill();
9499                }
9500            } catch (IOException e) {
9501                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9502            } catch (RemoteException e) {
9503                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9504            }
9505        }
9506    }
9507
9508    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9509            int opti, boolean dumpAll, String dumpPackage) {
9510        boolean needSep = false;
9511
9512        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9513        if (dumpAll) {
9514            if (mRegisteredReceivers.size() > 0) {
9515                boolean printed = false;
9516                Iterator it = mRegisteredReceivers.values().iterator();
9517                while (it.hasNext()) {
9518                    ReceiverList r = (ReceiverList)it.next();
9519                    if (dumpPackage != null && (r.app == null ||
9520                            !dumpPackage.equals(r.app.info.packageName))) {
9521                        continue;
9522                    }
9523                    if (!printed) {
9524                        pw.println("  Registered Receivers:");
9525                        needSep = true;
9526                        printed = true;
9527                    }
9528                    pw.print("  * "); pw.println(r);
9529                    r.dump(pw, "    ");
9530                }
9531            }
9532
9533            if (mReceiverResolver.dump(pw, needSep ?
9534                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
9535                    "    ", dumpPackage, false)) {
9536                needSep = true;
9537            }
9538        }
9539
9540        for (BroadcastQueue q : mBroadcastQueues) {
9541            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9542        }
9543
9544        needSep = true;
9545
9546        if (mStickyBroadcasts != null && dumpPackage == null) {
9547            if (needSep) {
9548                pw.println();
9549            }
9550            needSep = true;
9551            pw.println("  Sticky broadcasts:");
9552            StringBuilder sb = new StringBuilder(128);
9553            for (Map.Entry<String, ArrayList<Intent>> ent
9554                    : mStickyBroadcasts.entrySet()) {
9555                pw.print("  * Sticky action "); pw.print(ent.getKey());
9556                if (dumpAll) {
9557                    pw.println(":");
9558                    ArrayList<Intent> intents = ent.getValue();
9559                    final int N = intents.size();
9560                    for (int i=0; i<N; i++) {
9561                        sb.setLength(0);
9562                        sb.append("    Intent: ");
9563                        intents.get(i).toShortString(sb, false, true, false, false);
9564                        pw.println(sb.toString());
9565                        Bundle bundle = intents.get(i).getExtras();
9566                        if (bundle != null) {
9567                            pw.print("      ");
9568                            pw.println(bundle.toString());
9569                        }
9570                    }
9571                } else {
9572                    pw.println("");
9573                }
9574            }
9575            needSep = true;
9576        }
9577
9578        if (dumpAll) {
9579            pw.println();
9580            for (BroadcastQueue queue : mBroadcastQueues) {
9581                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
9582                        + queue.mBroadcastsScheduled);
9583            }
9584            pw.println("  mHandler:");
9585            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9586            needSep = true;
9587        }
9588
9589        return needSep;
9590    }
9591
9592    /**
9593     * Prints a list of ServiceRecords (dumpsys activity services)
9594     */
9595    boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9596            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
9597        boolean needSep = false;
9598
9599        ItemMatcher matcher = new ItemMatcher();
9600        matcher.build(args, opti);
9601
9602        pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
9603        try {
9604            List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9605            for (UserInfo user : users) {
9606                if (mServiceMap.getAllServices(user.id).size() > 0) {
9607                    boolean printed = false;
9608                    long nowReal = SystemClock.elapsedRealtime();
9609                    Iterator<ServiceRecord> it = mServiceMap.getAllServices(
9610                            user.id).iterator();
9611                    needSep = false;
9612                    while (it.hasNext()) {
9613                        ServiceRecord r = it.next();
9614                        if (!matcher.match(r, r.name)) {
9615                            continue;
9616                        }
9617                        if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9618                            continue;
9619                        }
9620                        if (!printed) {
9621                            pw.println("  Active services:");
9622                            printed = true;
9623                        }
9624                        if (needSep) {
9625                            pw.println();
9626                        }
9627                        pw.print("  * ");
9628                        pw.println(r);
9629                        if (dumpAll) {
9630                            r.dump(pw, "    ");
9631                            needSep = true;
9632                        } else {
9633                            pw.print("    app=");
9634                            pw.println(r.app);
9635                            pw.print("    created=");
9636                            TimeUtils.formatDuration(r.createTime, nowReal, pw);
9637                            pw.print(" started=");
9638                            pw.print(r.startRequested);
9639                            pw.print(" connections=");
9640                            pw.println(r.connections.size());
9641                            if (r.connections.size() > 0) {
9642                                pw.println("    Connections:");
9643                                for (ArrayList<ConnectionRecord> clist : r.connections.values()) {
9644                                    for (int i = 0; i < clist.size(); i++) {
9645                                        ConnectionRecord conn = clist.get(i);
9646                                        pw.print("      ");
9647                                        pw.print(conn.binding.intent.intent.getIntent()
9648                                                .toShortString(false, false, false, false));
9649                                        pw.print(" -> ");
9650                                        ProcessRecord proc = conn.binding.client;
9651                                        pw.println(proc != null ? proc.toShortString() : "null");
9652                                    }
9653                                }
9654                            }
9655                        }
9656                        if (dumpClient && r.app != null && r.app.thread != null) {
9657                            pw.println("    Client:");
9658                            pw.flush();
9659                            try {
9660                                TransferPipe tp = new TransferPipe();
9661                                try {
9662                                    r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(),
9663                                            r, args);
9664                                    tp.setBufferPrefix("      ");
9665                                    // Short timeout, since blocking here can
9666                                    // deadlock with the application.
9667                                    tp.go(fd, 2000);
9668                                } finally {
9669                                    tp.kill();
9670                                }
9671                            } catch (IOException e) {
9672                                pw.println("      Failure while dumping the service: " + e);
9673                            } catch (RemoteException e) {
9674                                pw.println("      Got a RemoteException while dumping the service");
9675                            }
9676                            needSep = true;
9677                        }
9678                    }
9679                    needSep = printed;
9680                }
9681            }
9682        } catch (RemoteException re) {
9683
9684        }
9685
9686        if (mPendingServices.size() > 0) {
9687            boolean printed = false;
9688            for (int i=0; i<mPendingServices.size(); i++) {
9689                ServiceRecord r = mPendingServices.get(i);
9690                if (!matcher.match(r, r.name)) {
9691                    continue;
9692                }
9693                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9694                    continue;
9695                }
9696                if (!printed) {
9697                    if (needSep) pw.println(" ");
9698                    needSep = true;
9699                    pw.println("  Pending services:");
9700                    printed = true;
9701                }
9702                pw.print("  * Pending "); pw.println(r);
9703                r.dump(pw, "    ");
9704            }
9705            needSep = true;
9706        }
9707
9708        if (mRestartingServices.size() > 0) {
9709            boolean printed = false;
9710            for (int i=0; i<mRestartingServices.size(); i++) {
9711                ServiceRecord r = mRestartingServices.get(i);
9712                if (!matcher.match(r, r.name)) {
9713                    continue;
9714                }
9715                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9716                    continue;
9717                }
9718                if (!printed) {
9719                    if (needSep) pw.println(" ");
9720                    needSep = true;
9721                    pw.println("  Restarting services:");
9722                    printed = true;
9723                }
9724                pw.print("  * Restarting "); pw.println(r);
9725                r.dump(pw, "    ");
9726            }
9727            needSep = true;
9728        }
9729
9730        if (mStoppingServices.size() > 0) {
9731            boolean printed = false;
9732            for (int i=0; i<mStoppingServices.size(); i++) {
9733                ServiceRecord r = mStoppingServices.get(i);
9734                if (!matcher.match(r, r.name)) {
9735                    continue;
9736                }
9737                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9738                    continue;
9739                }
9740                if (!printed) {
9741                    if (needSep) pw.println(" ");
9742                    needSep = true;
9743                    pw.println("  Stopping services:");
9744                    printed = true;
9745                }
9746                pw.print("  * Stopping "); pw.println(r);
9747                r.dump(pw, "    ");
9748            }
9749            needSep = true;
9750        }
9751
9752        if (dumpAll) {
9753            if (mServiceConnections.size() > 0) {
9754                boolean printed = false;
9755                Iterator<ArrayList<ConnectionRecord>> it
9756                        = mServiceConnections.values().iterator();
9757                while (it.hasNext()) {
9758                    ArrayList<ConnectionRecord> r = it.next();
9759                    for (int i=0; i<r.size(); i++) {
9760                        ConnectionRecord cr = r.get(i);
9761                        if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
9762                            continue;
9763                        }
9764                        if (dumpPackage != null && (cr.binding.client == null
9765                                || !dumpPackage.equals(cr.binding.client.info.packageName))) {
9766                            continue;
9767                        }
9768                        if (!printed) {
9769                            if (needSep) pw.println(" ");
9770                            needSep = true;
9771                            pw.println("  Connection bindings to services:");
9772                            printed = true;
9773                        }
9774                        pw.print("  * "); pw.println(cr);
9775                        cr.dump(pw, "    ");
9776                    }
9777                }
9778                needSep = true;
9779            }
9780        }
9781
9782        return needSep;
9783    }
9784
9785    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9786            int opti, boolean dumpAll, String dumpPackage) {
9787        boolean needSep = true;
9788
9789        ItemMatcher matcher = new ItemMatcher();
9790        matcher.build(args, opti);
9791
9792        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9793
9794        mProviderMap.dumpProvidersLocked(pw, dumpAll);
9795
9796        if (mLaunchingProviders.size() > 0) {
9797            boolean printed = false;
9798            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9799                ContentProviderRecord r = mLaunchingProviders.get(i);
9800                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9801                    continue;
9802                }
9803                if (!printed) {
9804                    if (needSep) pw.println(" ");
9805                    needSep = true;
9806                    pw.println("  Launching content providers:");
9807                    printed = true;
9808                }
9809                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9810                        pw.println(r);
9811            }
9812        }
9813
9814        if (mGrantedUriPermissions.size() > 0) {
9815            if (needSep) pw.println();
9816            needSep = true;
9817            pw.println("Granted Uri Permissions:");
9818            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9819                int uid = mGrantedUriPermissions.keyAt(i);
9820                HashMap<Uri, UriPermission> perms
9821                        = mGrantedUriPermissions.valueAt(i);
9822                pw.print("  * UID "); pw.print(uid);
9823                        pw.println(" holds:");
9824                for (UriPermission perm : perms.values()) {
9825                    pw.print("    "); pw.println(perm);
9826                    if (dumpAll) {
9827                        perm.dump(pw, "      ");
9828                    }
9829                }
9830            }
9831            needSep = true;
9832        }
9833
9834        return needSep;
9835    }
9836
9837    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9838            int opti, boolean dumpAll, String dumpPackage) {
9839        boolean needSep = false;
9840
9841        if (mIntentSenderRecords.size() > 0) {
9842            boolean printed = false;
9843            Iterator<WeakReference<PendingIntentRecord>> it
9844                    = mIntentSenderRecords.values().iterator();
9845            while (it.hasNext()) {
9846                WeakReference<PendingIntentRecord> ref = it.next();
9847                PendingIntentRecord rec = ref != null ? ref.get(): null;
9848                if (dumpPackage != null && (rec == null
9849                        || !dumpPackage.equals(rec.key.packageName))) {
9850                    continue;
9851                }
9852                if (!printed) {
9853                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9854                    printed = true;
9855                }
9856                needSep = true;
9857                if (rec != null) {
9858                    pw.print("  * "); pw.println(rec);
9859                    if (dumpAll) {
9860                        rec.dump(pw, "    ");
9861                    }
9862                } else {
9863                    pw.print("  * "); pw.println(ref);
9864                }
9865            }
9866        }
9867
9868        return needSep;
9869    }
9870
9871    private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9872            String prefix, String label, boolean complete, boolean brief, boolean client,
9873            String dumpPackage) {
9874        TaskRecord lastTask = null;
9875        boolean needNL = false;
9876        final String innerPrefix = prefix + "      ";
9877        final String[] args = new String[0];
9878        for (int i=list.size()-1; i>=0; i--) {
9879            final ActivityRecord r = (ActivityRecord)list.get(i);
9880            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9881                continue;
9882            }
9883            final boolean full = !brief && (complete || !r.isInHistory());
9884            if (needNL) {
9885                pw.println(" ");
9886                needNL = false;
9887            }
9888            if (lastTask != r.task) {
9889                lastTask = r.task;
9890                pw.print(prefix);
9891                pw.print(full ? "* " : "  ");
9892                pw.println(lastTask);
9893                if (full) {
9894                    lastTask.dump(pw, prefix + "  ");
9895                } else if (complete) {
9896                    // Complete + brief == give a summary.  Isn't that obvious?!?
9897                    if (lastTask.intent != null) {
9898                        pw.print(prefix); pw.print("  ");
9899                                pw.println(lastTask.intent.toInsecureStringWithClip());
9900                    }
9901                }
9902            }
9903            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9904            pw.print(" #"); pw.print(i); pw.print(": ");
9905            pw.println(r);
9906            if (full) {
9907                r.dump(pw, innerPrefix);
9908            } else if (complete) {
9909                // Complete + brief == give a summary.  Isn't that obvious?!?
9910                pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
9911                if (r.app != null) {
9912                    pw.print(innerPrefix); pw.println(r.app);
9913                }
9914            }
9915            if (client && r.app != null && r.app.thread != null) {
9916                // flush anything that is already in the PrintWriter since the thread is going
9917                // to write to the file descriptor directly
9918                pw.flush();
9919                try {
9920                    TransferPipe tp = new TransferPipe();
9921                    try {
9922                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9923                                r.appToken, innerPrefix, args);
9924                        // Short timeout, since blocking here can
9925                        // deadlock with the application.
9926                        tp.go(fd, 2000);
9927                    } finally {
9928                        tp.kill();
9929                    }
9930                } catch (IOException e) {
9931                    pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9932                } catch (RemoteException e) {
9933                    pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9934                }
9935                needNL = true;
9936            }
9937        }
9938    }
9939
9940    private static String buildOomTag(String prefix, String space, int val, int base) {
9941        if (val == base) {
9942            if (space == null) return prefix;
9943            return prefix + "  ";
9944        }
9945        return prefix + "+" + Integer.toString(val-base);
9946    }
9947
9948    private static final int dumpProcessList(PrintWriter pw,
9949            ActivityManagerService service, List list,
9950            String prefix, String normalLabel, String persistentLabel,
9951            String dumpPackage) {
9952        int numPers = 0;
9953        final int N = list.size()-1;
9954        for (int i=N; i>=0; i--) {
9955            ProcessRecord r = (ProcessRecord)list.get(i);
9956            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9957                continue;
9958            }
9959            pw.println(String.format("%s%s #%2d: %s",
9960                    prefix, (r.persistent ? persistentLabel : normalLabel),
9961                    i, r.toString()));
9962            if (r.persistent) {
9963                numPers++;
9964            }
9965        }
9966        return numPers;
9967    }
9968
9969    private static final boolean dumpProcessOomList(PrintWriter pw,
9970            ActivityManagerService service, List<ProcessRecord> origList,
9971            String prefix, String normalLabel, String persistentLabel,
9972            boolean inclDetails, String dumpPackage) {
9973
9974        ArrayList<Pair<ProcessRecord, Integer>> list
9975                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9976        for (int i=0; i<origList.size(); i++) {
9977            ProcessRecord r = origList.get(i);
9978            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9979                continue;
9980            }
9981            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9982        }
9983
9984        if (list.size() <= 0) {
9985            return false;
9986        }
9987
9988        Comparator<Pair<ProcessRecord, Integer>> comparator
9989                = new Comparator<Pair<ProcessRecord, Integer>>() {
9990            @Override
9991            public int compare(Pair<ProcessRecord, Integer> object1,
9992                    Pair<ProcessRecord, Integer> object2) {
9993                if (object1.first.setAdj != object2.first.setAdj) {
9994                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9995                }
9996                if (object1.second.intValue() != object2.second.intValue()) {
9997                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9998                }
9999                return 0;
10000            }
10001        };
10002
10003        Collections.sort(list, comparator);
10004
10005        final long curRealtime = SystemClock.elapsedRealtime();
10006        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
10007        final long curUptime = SystemClock.uptimeMillis();
10008        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
10009
10010        for (int i=list.size()-1; i>=0; i--) {
10011            ProcessRecord r = list.get(i).first;
10012            String oomAdj;
10013            if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
10014                oomAdj = buildOomTag("bak", "  ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
10015            } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
10016                oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
10017            } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
10018                oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
10019            } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
10020                oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
10021            } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
10022                oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
10023            } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
10024                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
10025            } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10026                oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
10027            } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10028                oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
10029            } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
10030                oomAdj = buildOomTag("vis  ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
10031            } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
10032                oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
10033            } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
10034                oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
10035            } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
10036                oomAdj = buildOomTag("sys  ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
10037            } else {
10038                oomAdj = Integer.toString(r.setAdj);
10039            }
10040            String schedGroup;
10041            switch (r.setSchedGroup) {
10042                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
10043                    schedGroup = "B";
10044                    break;
10045                case Process.THREAD_GROUP_DEFAULT:
10046                    schedGroup = "F";
10047                    break;
10048                default:
10049                    schedGroup = Integer.toString(r.setSchedGroup);
10050                    break;
10051            }
10052            String foreground;
10053            if (r.foregroundActivities) {
10054                foreground = "A";
10055            } else if (r.foregroundServices) {
10056                foreground = "S";
10057            } else {
10058                foreground = " ";
10059            }
10060            pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
10061                    prefix, (r.persistent ? persistentLabel : normalLabel),
10062                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
10063                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
10064            if (r.adjSource != null || r.adjTarget != null) {
10065                pw.print(prefix);
10066                pw.print("    ");
10067                if (r.adjTarget instanceof ComponentName) {
10068                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
10069                } else if (r.adjTarget != null) {
10070                    pw.print(r.adjTarget.toString());
10071                } else {
10072                    pw.print("{null}");
10073                }
10074                pw.print("<=");
10075                if (r.adjSource instanceof ProcessRecord) {
10076                    pw.print("Proc{");
10077                    pw.print(((ProcessRecord)r.adjSource).toShortString());
10078                    pw.println("}");
10079                } else if (r.adjSource != null) {
10080                    pw.println(r.adjSource.toString());
10081                } else {
10082                    pw.println("{null}");
10083                }
10084            }
10085            if (inclDetails) {
10086                pw.print(prefix);
10087                pw.print("    ");
10088                pw.print("oom: max="); pw.print(r.maxAdj);
10089                pw.print(" hidden="); pw.print(r.hiddenAdj);
10090                pw.print(" curRaw="); pw.print(r.curRawAdj);
10091                pw.print(" setRaw="); pw.print(r.setRawAdj);
10092                pw.print(" cur="); pw.print(r.curAdj);
10093                pw.print(" set="); pw.println(r.setAdj);
10094                pw.print(prefix);
10095                pw.print("    ");
10096                pw.print("keeping="); pw.print(r.keeping);
10097                pw.print(" hidden="); pw.print(r.hidden);
10098                pw.print(" empty="); pw.print(r.empty);
10099                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
10100
10101                if (!r.keeping) {
10102                    if (r.lastWakeTime != 0) {
10103                        long wtime;
10104                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10105                        synchronized (stats) {
10106                            wtime = stats.getProcessWakeTime(r.info.uid,
10107                                    r.pid, curRealtime);
10108                        }
10109                        long timeUsed = wtime - r.lastWakeTime;
10110                        pw.print(prefix);
10111                        pw.print("    ");
10112                        pw.print("keep awake over ");
10113                        TimeUtils.formatDuration(realtimeSince, pw);
10114                        pw.print(" used ");
10115                        TimeUtils.formatDuration(timeUsed, pw);
10116                        pw.print(" (");
10117                        pw.print((timeUsed*100)/realtimeSince);
10118                        pw.println("%)");
10119                    }
10120                    if (r.lastCpuTime != 0) {
10121                        long timeUsed = r.curCpuTime - r.lastCpuTime;
10122                        pw.print(prefix);
10123                        pw.print("    ");
10124                        pw.print("run cpu over ");
10125                        TimeUtils.formatDuration(uptimeSince, pw);
10126                        pw.print(" used ");
10127                        TimeUtils.formatDuration(timeUsed, pw);
10128                        pw.print(" (");
10129                        pw.print((timeUsed*100)/uptimeSince);
10130                        pw.println("%)");
10131                    }
10132                }
10133            }
10134        }
10135        return true;
10136    }
10137
10138    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
10139        ArrayList<ProcessRecord> procs;
10140        synchronized (this) {
10141            if (args != null && args.length > start
10142                    && args[start].charAt(0) != '-') {
10143                procs = new ArrayList<ProcessRecord>();
10144                int pid = -1;
10145                try {
10146                    pid = Integer.parseInt(args[start]);
10147                } catch (NumberFormatException e) {
10148
10149                }
10150                for (int i=mLruProcesses.size()-1; i>=0; i--) {
10151                    ProcessRecord proc = mLruProcesses.get(i);
10152                    if (proc.pid == pid) {
10153                        procs.add(proc);
10154                    } else if (proc.processName.equals(args[start])) {
10155                        procs.add(proc);
10156                    }
10157                }
10158                if (procs.size() <= 0) {
10159                    pw.println("No process found for: " + args[start]);
10160                    return null;
10161                }
10162            } else {
10163                procs = new ArrayList<ProcessRecord>(mLruProcesses);
10164            }
10165        }
10166        return procs;
10167    }
10168
10169    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10170            PrintWriter pw, String[] args) {
10171        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10172        if (procs == null) {
10173            return;
10174        }
10175
10176        long uptime = SystemClock.uptimeMillis();
10177        long realtime = SystemClock.elapsedRealtime();
10178        pw.println("Applications Graphics Acceleration Info:");
10179        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10180
10181        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10182            ProcessRecord r = procs.get(i);
10183            if (r.thread != null) {
10184                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10185                pw.flush();
10186                try {
10187                    TransferPipe tp = new TransferPipe();
10188                    try {
10189                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10190                        tp.go(fd);
10191                    } finally {
10192                        tp.kill();
10193                    }
10194                } catch (IOException e) {
10195                    pw.println("Failure while dumping the app: " + r);
10196                    pw.flush();
10197                } catch (RemoteException e) {
10198                    pw.println("Got a RemoteException while dumping the app " + r);
10199                    pw.flush();
10200                }
10201            }
10202        }
10203    }
10204
10205    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10206        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10207        if (procs == null) {
10208            return;
10209        }
10210
10211        pw.println("Applications Database Info:");
10212
10213        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10214            ProcessRecord r = procs.get(i);
10215            if (r.thread != null) {
10216                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10217                pw.flush();
10218                try {
10219                    TransferPipe tp = new TransferPipe();
10220                    try {
10221                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10222                        tp.go(fd);
10223                    } finally {
10224                        tp.kill();
10225                    }
10226                } catch (IOException e) {
10227                    pw.println("Failure while dumping the app: " + r);
10228                    pw.flush();
10229                } catch (RemoteException e) {
10230                    pw.println("Got a RemoteException while dumping the app " + r);
10231                    pw.flush();
10232                }
10233            }
10234        }
10235    }
10236
10237    final static class MemItem {
10238        final String label;
10239        final String shortLabel;
10240        final long pss;
10241        final int id;
10242        ArrayList<MemItem> subitems;
10243
10244        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10245            label = _label;
10246            shortLabel = _shortLabel;
10247            pss = _pss;
10248            id = _id;
10249        }
10250    }
10251
10252    static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10253            boolean sort) {
10254        if (sort) {
10255            Collections.sort(items, new Comparator<MemItem>() {
10256                @Override
10257                public int compare(MemItem lhs, MemItem rhs) {
10258                    if (lhs.pss < rhs.pss) {
10259                        return 1;
10260                    } else if (lhs.pss > rhs.pss) {
10261                        return -1;
10262                    }
10263                    return 0;
10264                }
10265            });
10266        }
10267
10268        for (int i=0; i<items.size(); i++) {
10269            MemItem mi = items.get(i);
10270            pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10271            if (mi.subitems != null) {
10272                dumpMemItems(pw, prefix + "           ", mi.subitems, true);
10273            }
10274        }
10275    }
10276
10277    // These are in KB.
10278    static final long[] DUMP_MEM_BUCKETS = new long[] {
10279        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10280        120*1024, 160*1024, 200*1024,
10281        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10282        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10283    };
10284
10285    static final void appendMemBucket(StringBuilder out, long memKB, String label,
10286            boolean stackLike) {
10287        int start = label.lastIndexOf('.');
10288        if (start >= 0) start++;
10289        else start = 0;
10290        int end = label.length();
10291        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10292            if (DUMP_MEM_BUCKETS[i] >= memKB) {
10293                long bucket = DUMP_MEM_BUCKETS[i]/1024;
10294                out.append(bucket);
10295                out.append(stackLike ? "MB." : "MB ");
10296                out.append(label, start, end);
10297                return;
10298            }
10299        }
10300        out.append(memKB/1024);
10301        out.append(stackLike ? "MB." : "MB ");
10302        out.append(label, start, end);
10303    }
10304
10305    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10306            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10307            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10308            ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10309            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10310    };
10311    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10312            "System", "Persistent", "Foreground",
10313            "Visible", "Perceptible", "Heavy Weight",
10314            "Backup", "A Services", "Home", "Previous",
10315            "B Services", "Background"
10316    };
10317
10318    final void dumpApplicationMemoryUsage(FileDescriptor fd,
10319            PrintWriter pw, String prefix, String[] args, boolean brief,
10320            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10321        boolean dumpAll = false;
10322        boolean oomOnly = false;
10323
10324        int opti = 0;
10325        while (opti < args.length) {
10326            String opt = args[opti];
10327            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10328                break;
10329            }
10330            opti++;
10331            if ("-a".equals(opt)) {
10332                dumpAll = true;
10333            } else if ("--oom".equals(opt)) {
10334                oomOnly = true;
10335            } else if ("-h".equals(opt)) {
10336                pw.println("meminfo dump options: [-a] [--oom] [process]");
10337                pw.println("  -a: include all available information for each process.");
10338                pw.println("  --oom: only show processes organized by oom adj.");
10339                pw.println("If [process] is specified it can be the name or ");
10340                pw.println("pid of a specific process to dump.");
10341                return;
10342            } else {
10343                pw.println("Unknown argument: " + opt + "; use -h for help");
10344            }
10345        }
10346
10347        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10348        if (procs == null) {
10349            return;
10350        }
10351
10352        final boolean isCheckinRequest = scanArgs(args, "--checkin");
10353        long uptime = SystemClock.uptimeMillis();
10354        long realtime = SystemClock.elapsedRealtime();
10355
10356        if (procs.size() == 1 || isCheckinRequest) {
10357            dumpAll = true;
10358        }
10359
10360        if (isCheckinRequest) {
10361            // short checkin version
10362            pw.println(uptime + "," + realtime);
10363            pw.flush();
10364        } else {
10365            pw.println("Applications Memory Usage (kB):");
10366            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10367        }
10368
10369        String[] innerArgs = new String[args.length-opti];
10370        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10371
10372        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10373        long nativePss=0, dalvikPss=0, otherPss=0;
10374        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10375
10376        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10377        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10378                new ArrayList[DUMP_MEM_OOM_LABEL.length];
10379
10380        long totalPss = 0;
10381
10382        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10383            ProcessRecord r = procs.get(i);
10384            if (r.thread != null) {
10385                if (!isCheckinRequest && dumpAll) {
10386                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10387                    pw.flush();
10388                }
10389                Debug.MemoryInfo mi = null;
10390                if (dumpAll) {
10391                    try {
10392                        mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10393                    } catch (RemoteException e) {
10394                        if (!isCheckinRequest) {
10395                            pw.println("Got RemoteException!");
10396                            pw.flush();
10397                        }
10398                    }
10399                } else {
10400                    mi = new Debug.MemoryInfo();
10401                    Debug.getMemoryInfo(r.pid, mi);
10402                }
10403
10404                if (!isCheckinRequest && mi != null) {
10405                    long myTotalPss = mi.getTotalPss();
10406                    totalPss += myTotalPss;
10407                    MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10408                            r.processName, myTotalPss, 0);
10409                    procMems.add(pssItem);
10410
10411                    nativePss += mi.nativePss;
10412                    dalvikPss += mi.dalvikPss;
10413                    otherPss += mi.otherPss;
10414                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10415                        long mem = mi.getOtherPss(j);
10416                        miscPss[j] += mem;
10417                        otherPss -= mem;
10418                    }
10419
10420                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10421                        if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10422                                || oomIndex == (oomPss.length-1)) {
10423                            oomPss[oomIndex] += myTotalPss;
10424                            if (oomProcs[oomIndex] == null) {
10425                                oomProcs[oomIndex] = new ArrayList<MemItem>();
10426                            }
10427                            oomProcs[oomIndex].add(pssItem);
10428                            break;
10429                        }
10430                    }
10431                }
10432            }
10433        }
10434
10435        if (!isCheckinRequest && procs.size() > 1) {
10436            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10437
10438            catMems.add(new MemItem("Native", "Native", nativePss, -1));
10439            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10440            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10441            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10442                String label = Debug.MemoryInfo.getOtherLabel(j);
10443                catMems.add(new MemItem(label, label, miscPss[j], j));
10444            }
10445
10446            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10447            for (int j=0; j<oomPss.length; j++) {
10448                if (oomPss[j] != 0) {
10449                    String label = DUMP_MEM_OOM_LABEL[j];
10450                    MemItem item = new MemItem(label, label, oomPss[j],
10451                            DUMP_MEM_OOM_ADJ[j]);
10452                    item.subitems = oomProcs[j];
10453                    oomMems.add(item);
10454                }
10455            }
10456
10457            if (outTag != null || outStack != null) {
10458                if (outTag != null) {
10459                    appendMemBucket(outTag, totalPss, "total", false);
10460                }
10461                if (outStack != null) {
10462                    appendMemBucket(outStack, totalPss, "total", true);
10463                }
10464                boolean firstLine = true;
10465                for (int i=0; i<oomMems.size(); i++) {
10466                    MemItem miCat = oomMems.get(i);
10467                    if (miCat.subitems == null || miCat.subitems.size() < 1) {
10468                        continue;
10469                    }
10470                    if (miCat.id < ProcessList.SERVICE_ADJ
10471                            || miCat.id == ProcessList.HOME_APP_ADJ
10472                            || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10473                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10474                            outTag.append(" / ");
10475                        }
10476                        if (outStack != null) {
10477                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10478                                if (firstLine) {
10479                                    outStack.append(":");
10480                                    firstLine = false;
10481                                }
10482                                outStack.append("\n\t at ");
10483                            } else {
10484                                outStack.append("$");
10485                            }
10486                        }
10487                        for (int j=0; j<miCat.subitems.size(); j++) {
10488                            MemItem mi = miCat.subitems.get(j);
10489                            if (j > 0) {
10490                                if (outTag != null) {
10491                                    outTag.append(" ");
10492                                }
10493                                if (outStack != null) {
10494                                    outStack.append("$");
10495                                }
10496                            }
10497                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10498                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10499                            }
10500                            if (outStack != null) {
10501                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10502                            }
10503                        }
10504                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10505                            outStack.append("(");
10506                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10507                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10508                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
10509                                    outStack.append(":");
10510                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
10511                                }
10512                            }
10513                            outStack.append(")");
10514                        }
10515                    }
10516                }
10517            }
10518
10519            if (!brief && !oomOnly) {
10520                pw.println();
10521                pw.println("Total PSS by process:");
10522                dumpMemItems(pw, "  ", procMems, true);
10523                pw.println();
10524            }
10525            pw.println("Total PSS by OOM adjustment:");
10526            dumpMemItems(pw, "  ", oomMems, false);
10527            if (!oomOnly) {
10528                PrintWriter out = categoryPw != null ? categoryPw : pw;
10529                out.println();
10530                out.println("Total PSS by category:");
10531                dumpMemItems(out, "  ", catMems, true);
10532            }
10533            pw.println();
10534            pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10535            final int[] SINGLE_LONG_FORMAT = new int[] {
10536                Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10537            };
10538            long[] longOut = new long[1];
10539            Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10540                    SINGLE_LONG_FORMAT, null, longOut, null);
10541            long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10542            longOut[0] = 0;
10543            Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10544                    SINGLE_LONG_FORMAT, null, longOut, null);
10545            long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10546            longOut[0] = 0;
10547            Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10548                    SINGLE_LONG_FORMAT, null, longOut, null);
10549            long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10550            longOut[0] = 0;
10551            Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10552                    SINGLE_LONG_FORMAT, null, longOut, null);
10553            long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10554            pw.print("      KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10555                    pw.print(shared); pw.println(" kB");
10556            pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
10557                    pw.print(voltile); pw.println(" kB volatile");
10558        }
10559    }
10560
10561    /**
10562     * Searches array of arguments for the specified string
10563     * @param args array of argument strings
10564     * @param value value to search for
10565     * @return true if the value is contained in the array
10566     */
10567    private static boolean scanArgs(String[] args, String value) {
10568        if (args != null) {
10569            for (String arg : args) {
10570                if (value.equals(arg)) {
10571                    return true;
10572                }
10573            }
10574        }
10575        return false;
10576    }
10577
10578    private final void killServicesLocked(ProcessRecord app,
10579            boolean allowRestart) {
10580        // Report disconnected services.
10581        if (false) {
10582            // XXX we are letting the client link to the service for
10583            // death notifications.
10584            if (app.services.size() > 0) {
10585                Iterator<ServiceRecord> it = app.services.iterator();
10586                while (it.hasNext()) {
10587                    ServiceRecord r = it.next();
10588                    if (r.connections.size() > 0) {
10589                        Iterator<ArrayList<ConnectionRecord>> jt
10590                                = r.connections.values().iterator();
10591                        while (jt.hasNext()) {
10592                            ArrayList<ConnectionRecord> cl = jt.next();
10593                            for (int i=0; i<cl.size(); i++) {
10594                                ConnectionRecord c = cl.get(i);
10595                                if (c.binding.client != app) {
10596                                    try {
10597                                        //c.conn.connected(r.className, null);
10598                                    } catch (Exception e) {
10599                                        // todo: this should be asynchronous!
10600                                        Slog.w(TAG, "Exception thrown disconnected servce "
10601                                              + r.shortName
10602                                              + " from app " + app.processName, e);
10603                                    }
10604                                }
10605                            }
10606                        }
10607                    }
10608                }
10609            }
10610        }
10611
10612        // Clean up any connections this application has to other services.
10613        if (app.connections.size() > 0) {
10614            Iterator<ConnectionRecord> it = app.connections.iterator();
10615            while (it.hasNext()) {
10616                ConnectionRecord r = it.next();
10617                removeConnectionLocked(r, app, null);
10618            }
10619        }
10620        app.connections.clear();
10621
10622        if (app.services.size() != 0) {
10623            // Any services running in the application need to be placed
10624            // back in the pending list.
10625            Iterator<ServiceRecord> it = app.services.iterator();
10626            while (it.hasNext()) {
10627                ServiceRecord sr = it.next();
10628                synchronized (sr.stats.getBatteryStats()) {
10629                    sr.stats.stopLaunchedLocked();
10630                }
10631                sr.app = null;
10632                sr.isolatedProc = null;
10633                sr.executeNesting = 0;
10634                if (mStoppingServices.remove(sr)) {
10635                    if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
10636                }
10637
10638                boolean hasClients = sr.bindings.size() > 0;
10639                if (hasClients) {
10640                    Iterator<IntentBindRecord> bindings
10641                            = sr.bindings.values().iterator();
10642                    while (bindings.hasNext()) {
10643                        IntentBindRecord b = bindings.next();
10644                        if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
10645                                + ": shouldUnbind=" + b.hasBound);
10646                        b.binder = null;
10647                        b.requested = b.received = b.hasBound = false;
10648                    }
10649                }
10650
10651                if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
10652                        &ApplicationInfo.FLAG_PERSISTENT) == 0) {
10653                    Slog.w(TAG, "Service crashed " + sr.crashCount
10654                            + " times, stopping: " + sr);
10655                    EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
10656                            sr.crashCount, sr.shortName, app.pid);
10657                    bringDownServiceLocked(sr, true);
10658                } else if (!allowRestart) {
10659                    bringDownServiceLocked(sr, true);
10660                } else {
10661                    boolean canceled = scheduleServiceRestartLocked(sr, true);
10662
10663                    // Should the service remain running?  Note that in the
10664                    // extreme case of so many attempts to deliver a command
10665                    // that it failed we also will stop it here.
10666                    if (sr.startRequested && (sr.stopIfKilled || canceled)) {
10667                        if (sr.pendingStarts.size() == 0) {
10668                            sr.startRequested = false;
10669                            if (!hasClients) {
10670                                // Whoops, no reason to restart!
10671                                bringDownServiceLocked(sr, true);
10672                            }
10673                        }
10674                    }
10675                }
10676            }
10677
10678            if (!allowRestart) {
10679                app.services.clear();
10680            }
10681        }
10682
10683        // Make sure we have no more records on the stopping list.
10684        int i = mStoppingServices.size();
10685        while (i > 0) {
10686            i--;
10687            ServiceRecord sr = mStoppingServices.get(i);
10688            if (sr.app == app) {
10689                mStoppingServices.remove(i);
10690                if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
10691            }
10692        }
10693
10694        app.executingServices.clear();
10695    }
10696
10697    private final boolean removeDyingProviderLocked(ProcessRecord proc,
10698            ContentProviderRecord cpr, boolean always) {
10699        final boolean inLaunching = mLaunchingProviders.contains(cpr);
10700
10701        if (!inLaunching || always) {
10702            synchronized (cpr) {
10703                cpr.launchingApp = null;
10704                cpr.notifyAll();
10705            }
10706            mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid));
10707            String names[] = cpr.info.authority.split(";");
10708            for (int j = 0; j < names.length; j++) {
10709                mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid));
10710            }
10711        }
10712
10713        for (int i=0; i<cpr.connections.size(); i++) {
10714            ContentProviderConnection conn = cpr.connections.get(i);
10715            if (conn.waiting) {
10716                // If this connection is waiting for the provider, then we don't
10717                // need to mess with its process unless we are always removing
10718                // or for some reason the provider is not currently launching.
10719                if (inLaunching && !always) {
10720                    continue;
10721                }
10722            }
10723            ProcessRecord capp = conn.client;
10724            conn.dead = true;
10725            if (conn.stableCount > 0) {
10726                if (!capp.persistent && capp.thread != null
10727                        && capp.pid != 0
10728                        && capp.pid != MY_PID) {
10729                    Slog.i(TAG, "Kill " + capp.processName
10730                            + " (pid " + capp.pid + "): provider " + cpr.info.name
10731                            + " in dying process " + (proc != null ? proc.processName : "??"));
10732                    EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10733                            capp.processName, capp.setAdj, "dying provider "
10734                                    + cpr.name.toShortString());
10735                    Process.killProcessQuiet(capp.pid);
10736                }
10737            } else if (capp.thread != null && conn.provider.provider != null) {
10738                try {
10739                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10740                } catch (RemoteException e) {
10741                }
10742                // In the protocol here, we don't expect the client to correctly
10743                // clean up this connection, we'll just remove it.
10744                cpr.connections.remove(i);
10745                conn.client.conProviders.remove(conn);
10746            }
10747        }
10748
10749        if (inLaunching && always) {
10750            mLaunchingProviders.remove(cpr);
10751        }
10752        return inLaunching;
10753    }
10754
10755    /**
10756     * Main code for cleaning up a process when it has gone away.  This is
10757     * called both as a result of the process dying, or directly when stopping
10758     * a process when running in single process mode.
10759     */
10760    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10761            boolean restarting, boolean allowRestart, int index) {
10762        if (index >= 0) {
10763            mLruProcesses.remove(index);
10764        }
10765
10766        mProcessesToGc.remove(app);
10767
10768        // Dismiss any open dialogs.
10769        if (app.crashDialog != null) {
10770            app.crashDialog.dismiss();
10771            app.crashDialog = null;
10772        }
10773        if (app.anrDialog != null) {
10774            app.anrDialog.dismiss();
10775            app.anrDialog = null;
10776        }
10777        if (app.waitDialog != null) {
10778            app.waitDialog.dismiss();
10779            app.waitDialog = null;
10780        }
10781
10782        app.crashing = false;
10783        app.notResponding = false;
10784
10785        app.resetPackageList();
10786        app.unlinkDeathRecipient();
10787        app.thread = null;
10788        app.forcingToForeground = null;
10789        app.foregroundServices = false;
10790        app.foregroundActivities = false;
10791        app.hasShownUi = false;
10792        app.hasAboveClient = false;
10793
10794        killServicesLocked(app, allowRestart);
10795
10796        boolean restart = false;
10797
10798        // Remove published content providers.
10799        if (!app.pubProviders.isEmpty()) {
10800            Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10801            while (it.hasNext()) {
10802                ContentProviderRecord cpr = it.next();
10803
10804                final boolean always = app.bad || !allowRestart;
10805                if (removeDyingProviderLocked(app, cpr, always) || always) {
10806                    // We left the provider in the launching list, need to
10807                    // restart it.
10808                    restart = true;
10809                }
10810
10811                cpr.provider = null;
10812                cpr.proc = null;
10813            }
10814            app.pubProviders.clear();
10815        }
10816
10817        // Take care of any launching providers waiting for this process.
10818        if (checkAppInLaunchingProvidersLocked(app, false)) {
10819            restart = true;
10820        }
10821
10822        // Unregister from connected content providers.
10823        if (!app.conProviders.isEmpty()) {
10824            for (int i=0; i<app.conProviders.size(); i++) {
10825                ContentProviderConnection conn = app.conProviders.get(i);
10826                conn.provider.connections.remove(conn);
10827            }
10828            app.conProviders.clear();
10829        }
10830
10831        // At this point there may be remaining entries in mLaunchingProviders
10832        // where we were the only one waiting, so they are no longer of use.
10833        // Look for these and clean up if found.
10834        // XXX Commented out for now.  Trying to figure out a way to reproduce
10835        // the actual situation to identify what is actually going on.
10836        if (false) {
10837            for (int i=0; i<mLaunchingProviders.size(); i++) {
10838                ContentProviderRecord cpr = (ContentProviderRecord)
10839                        mLaunchingProviders.get(i);
10840                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10841                    synchronized (cpr) {
10842                        cpr.launchingApp = null;
10843                        cpr.notifyAll();
10844                    }
10845                }
10846            }
10847        }
10848
10849        skipCurrentReceiverLocked(app);
10850
10851        // Unregister any receivers.
10852        if (app.receivers.size() > 0) {
10853            Iterator<ReceiverList> it = app.receivers.iterator();
10854            while (it.hasNext()) {
10855                removeReceiverLocked(it.next());
10856            }
10857            app.receivers.clear();
10858        }
10859
10860        // If the app is undergoing backup, tell the backup manager about it
10861        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10862            if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10863            try {
10864                IBackupManager bm = IBackupManager.Stub.asInterface(
10865                        ServiceManager.getService(Context.BACKUP_SERVICE));
10866                bm.agentDisconnected(app.info.packageName);
10867            } catch (RemoteException e) {
10868                // can't happen; backup manager is local
10869            }
10870        }
10871
10872        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10873            ProcessChangeItem item = mPendingProcessChanges.get(i);
10874            if (item.pid == app.pid) {
10875                mPendingProcessChanges.remove(i);
10876                mAvailProcessChanges.add(item);
10877            }
10878        }
10879        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10880
10881        // If the caller is restarting this app, then leave it in its
10882        // current lists and let the caller take care of it.
10883        if (restarting) {
10884            return;
10885        }
10886
10887        if (!app.persistent || app.isolated) {
10888            if (DEBUG_PROCESSES) Slog.v(TAG,
10889                    "Removing non-persistent process during cleanup: " + app);
10890            mProcessNames.remove(app.processName, app.uid);
10891            mIsolatedProcesses.remove(app.uid);
10892            if (mHeavyWeightProcess == app) {
10893                mHeavyWeightProcess = null;
10894                mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
10895            }
10896        } else if (!app.removed) {
10897            // This app is persistent, so we need to keep its record around.
10898            // If it is not already on the pending app list, add it there
10899            // and start a new process for it.
10900            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10901                mPersistentStartingProcesses.add(app);
10902                restart = true;
10903            }
10904        }
10905        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10906                "Clean-up removing on hold: " + app);
10907        mProcessesOnHold.remove(app);
10908
10909        if (app == mHomeProcess) {
10910            mHomeProcess = null;
10911        }
10912        if (app == mPreviousProcess) {
10913            mPreviousProcess = null;
10914        }
10915
10916        if (restart && !app.isolated) {
10917            // We have components that still need to be running in the
10918            // process, so re-launch it.
10919            mProcessNames.put(app.processName, app.uid, app);
10920            startProcessLocked(app, "restart", app.processName);
10921        } else if (app.pid > 0 && app.pid != MY_PID) {
10922            // Goodbye!
10923            synchronized (mPidsSelfLocked) {
10924                mPidsSelfLocked.remove(app.pid);
10925                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10926            }
10927            app.setPid(0);
10928        }
10929    }
10930
10931    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10932        // Look through the content providers we are waiting to have launched,
10933        // and if any run in this process then either schedule a restart of
10934        // the process or kill the client waiting for it if this process has
10935        // gone bad.
10936        int NL = mLaunchingProviders.size();
10937        boolean restart = false;
10938        for (int i=0; i<NL; i++) {
10939            ContentProviderRecord cpr = mLaunchingProviders.get(i);
10940            if (cpr.launchingApp == app) {
10941                if (!alwaysBad && !app.bad) {
10942                    restart = true;
10943                } else {
10944                    removeDyingProviderLocked(app, cpr, true);
10945                    NL = mLaunchingProviders.size();
10946                }
10947            }
10948        }
10949        return restart;
10950    }
10951
10952    // =========================================================
10953    // SERVICES
10954    // =========================================================
10955
10956    ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
10957        ActivityManager.RunningServiceInfo info =
10958            new ActivityManager.RunningServiceInfo();
10959        info.service = r.name;
10960        if (r.app != null) {
10961            info.pid = r.app.pid;
10962        }
10963        info.uid = r.appInfo.uid;
10964        info.process = r.processName;
10965        info.foreground = r.isForeground;
10966        info.activeSince = r.createTime;
10967        info.started = r.startRequested;
10968        info.clientCount = r.connections.size();
10969        info.crashCount = r.crashCount;
10970        info.lastActivityTime = r.lastActivity;
10971        if (r.isForeground) {
10972            info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
10973        }
10974        if (r.startRequested) {
10975            info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
10976        }
10977        if (r.app != null && r.app.pid == MY_PID) {
10978            info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
10979        }
10980        if (r.app != null && r.app.persistent) {
10981            info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
10982        }
10983
10984        for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
10985            for (int i=0; i<connl.size(); i++) {
10986                ConnectionRecord conn = connl.get(i);
10987                if (conn.clientLabel != 0) {
10988                    info.clientPackage = conn.binding.client.info.packageName;
10989                    info.clientLabel = conn.clientLabel;
10990                    return info;
10991                }
10992            }
10993        }
10994        return info;
10995    }
10996
10997    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10998            int flags) {
10999        enforceNotIsolatedCaller("getServices");
11000        synchronized (this) {
11001            ArrayList<ActivityManager.RunningServiceInfo> res
11002                    = new ArrayList<ActivityManager.RunningServiceInfo>();
11003
11004            int userId = UserId.getUserId(Binder.getCallingUid());
11005            if (mServiceMap.getAllServices(userId).size() > 0) {
11006                Iterator<ServiceRecord> it
11007                        = mServiceMap.getAllServices(userId).iterator();
11008                while (it.hasNext() && res.size() < maxNum) {
11009                    res.add(makeRunningServiceInfoLocked(it.next()));
11010                }
11011            }
11012
11013            for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
11014                ServiceRecord r = mRestartingServices.get(i);
11015                ActivityManager.RunningServiceInfo info =
11016                        makeRunningServiceInfoLocked(r);
11017                info.restarting = r.nextRestartTime;
11018                res.add(info);
11019            }
11020
11021            return res;
11022        }
11023    }
11024
11025    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
11026        enforceNotIsolatedCaller("getRunningServiceControlPanel");
11027        synchronized (this) {
11028            int userId = UserId.getUserId(Binder.getCallingUid());
11029            ServiceRecord r = mServiceMap.getServiceByName(name, userId);
11030            if (r != null) {
11031                for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
11032                    for (int i=0; i<conn.size(); i++) {
11033                        if (conn.get(i).clientIntent != null) {
11034                            return conn.get(i).clientIntent;
11035                        }
11036                    }
11037                }
11038            }
11039        }
11040        return null;
11041    }
11042
11043    private final ServiceRecord findServiceLocked(ComponentName name,
11044            IBinder token) {
11045        ServiceRecord r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
11046        return r == token ? r : null;
11047    }
11048
11049    private final class ServiceLookupResult {
11050        final ServiceRecord record;
11051        final String permission;
11052
11053        ServiceLookupResult(ServiceRecord _record, String _permission) {
11054            record = _record;
11055            permission = _permission;
11056        }
11057    };
11058
11059    private ServiceLookupResult findServiceLocked(Intent service,
11060            String resolvedType, int userId) {
11061        ServiceRecord r = null;
11062        if (service.getComponent() != null) {
11063            r = mServiceMap.getServiceByName(service.getComponent(), userId);
11064        }
11065        if (r == null) {
11066            Intent.FilterComparison filter = new Intent.FilterComparison(service);
11067            r = mServiceMap.getServiceByIntent(filter, userId);
11068        }
11069
11070        if (r == null) {
11071            try {
11072                ResolveInfo rInfo =
11073                    AppGlobals.getPackageManager().resolveService(
11074                                service, resolvedType, 0, userId);
11075                ServiceInfo sInfo =
11076                    rInfo != null ? rInfo.serviceInfo : null;
11077                if (sInfo == null) {
11078                    return null;
11079                }
11080
11081                ComponentName name = new ComponentName(
11082                        sInfo.applicationInfo.packageName, sInfo.name);
11083                r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
11084            } catch (RemoteException ex) {
11085                // pm is in same process, this will never happen.
11086            }
11087        }
11088        if (r != null) {
11089            int callingPid = Binder.getCallingPid();
11090            int callingUid = Binder.getCallingUid();
11091            if (checkComponentPermission(r.permission,
11092                    callingPid, callingUid, r.appInfo.uid, r.exported)
11093                    != PackageManager.PERMISSION_GRANTED) {
11094                if (!r.exported) {
11095                    Slog.w(TAG, "Permission Denial: Accessing service " + r.name
11096                            + " from pid=" + callingPid
11097                            + ", uid=" + callingUid
11098                            + " that is not exported from uid " + r.appInfo.uid);
11099                    return new ServiceLookupResult(null, "not exported from uid "
11100                            + r.appInfo.uid);
11101                }
11102                Slog.w(TAG, "Permission Denial: Accessing service " + r.name
11103                        + " from pid=" + callingPid
11104                        + ", uid=" + callingUid
11105                        + " requires " + r.permission);
11106                return new ServiceLookupResult(null, r.permission);
11107            }
11108            return new ServiceLookupResult(r, null);
11109        }
11110        return null;
11111    }
11112
11113    private class ServiceRestarter implements Runnable {
11114        private ServiceRecord mService;
11115
11116        void setService(ServiceRecord service) {
11117            mService = service;
11118        }
11119
11120        public void run() {
11121            synchronized(ActivityManagerService.this) {
11122                performServiceRestartLocked(mService);
11123            }
11124        }
11125    }
11126
11127    private ServiceLookupResult retrieveServiceLocked(Intent service,
11128            String resolvedType, int callingPid, int callingUid, int userId) {
11129        ServiceRecord r = null;
11130        if (DEBUG_SERVICE)
11131            Slog.v(TAG, "retrieveServiceLocked: " + service + " type=" + resolvedType
11132                    + " callingUid=" + callingUid);
11133
11134        if (service.getComponent() != null) {
11135            r = mServiceMap.getServiceByName(service.getComponent(), userId);
11136        }
11137        if (r == null) {
11138            Intent.FilterComparison filter = new Intent.FilterComparison(service);
11139            r = mServiceMap.getServiceByIntent(filter, userId);
11140        }
11141        if (r == null) {
11142            try {
11143                ResolveInfo rInfo =
11144                    AppGlobals.getPackageManager().resolveService(
11145                                service, resolvedType, STOCK_PM_FLAGS, userId);
11146                ServiceInfo sInfo =
11147                    rInfo != null ? rInfo.serviceInfo : null;
11148                if (sInfo == null) {
11149                    Slog.w(TAG, "Unable to start service " + service +
11150                          ": not found");
11151                    return null;
11152                }
11153                if (userId > 0) {
11154                    if (isSingleton(sInfo.processName, sInfo.applicationInfo)) {
11155                        userId = 0;
11156                    }
11157                    sInfo.applicationInfo = getAppInfoForUser(sInfo.applicationInfo, userId);
11158                }
11159                ComponentName name = new ComponentName(
11160                        sInfo.applicationInfo.packageName, sInfo.name);
11161                r = mServiceMap.getServiceByName(name, userId);
11162                if (r == null) {
11163                    Intent.FilterComparison filter = new Intent.FilterComparison(
11164                            service.cloneFilter());
11165                    ServiceRestarter res = new ServiceRestarter();
11166                    BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11167                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11168                    synchronized (stats) {
11169                        ss = stats.getServiceStatsLocked(
11170                                sInfo.applicationInfo.uid, sInfo.packageName,
11171                                sInfo.name);
11172                    }
11173                    r = new ServiceRecord(this, ss, name, filter, sInfo, res);
11174                    res.setService(r);
11175                    mServiceMap.putServiceByName(name, UserId.getUserId(r.appInfo.uid), r);
11176                    mServiceMap.putServiceByIntent(filter, UserId.getUserId(r.appInfo.uid), r);
11177
11178                    // Make sure this component isn't in the pending list.
11179                    int N = mPendingServices.size();
11180                    for (int i=0; i<N; i++) {
11181                        ServiceRecord pr = mPendingServices.get(i);
11182                        if (pr.name.equals(name)) {
11183                            mPendingServices.remove(i);
11184                            i--;
11185                            N--;
11186                        }
11187                    }
11188                }
11189            } catch (RemoteException ex) {
11190                // pm is in same process, this will never happen.
11191            }
11192        }
11193        if (r != null) {
11194            if (checkComponentPermission(r.permission,
11195                    callingPid, callingUid, r.appInfo.uid, r.exported)
11196                    != PackageManager.PERMISSION_GRANTED) {
11197                if (!r.exported) {
11198                    Slog.w(TAG, "Permission Denial: Accessing service " + r.name
11199                            + " from pid=" + callingPid
11200                            + ", uid=" + callingUid
11201                            + " that is not exported from uid " + r.appInfo.uid);
11202                    return new ServiceLookupResult(null, "not exported from uid "
11203                            + r.appInfo.uid);
11204                }
11205                Slog.w(TAG, "Permission Denial: Accessing service " + r.name
11206                        + " from pid=" + callingPid
11207                        + ", uid=" + callingUid
11208                        + " requires " + r.permission);
11209                return new ServiceLookupResult(null, r.permission);
11210            }
11211            return new ServiceLookupResult(r, null);
11212        }
11213        return null;
11214    }
11215
11216    private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
11217        if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
11218                + why + " of " + r + " in app " + r.app);
11219        else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
11220                + why + " of " + r.shortName);
11221        long now = SystemClock.uptimeMillis();
11222        if (r.executeNesting == 0 && r.app != null) {
11223            if (r.app.executingServices.size() == 0) {
11224                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11225                msg.obj = r.app;
11226                mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
11227            }
11228            r.app.executingServices.add(r);
11229        }
11230        r.executeNesting++;
11231        r.executingStart = now;
11232    }
11233
11234    private final void sendServiceArgsLocked(ServiceRecord r,
11235            boolean oomAdjusted) {
11236        final int N = r.pendingStarts.size();
11237        if (N == 0) {
11238            return;
11239        }
11240
11241        while (r.pendingStarts.size() > 0) {
11242            try {
11243                ServiceRecord.StartItem si = r.pendingStarts.remove(0);
11244                if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
11245                        + r + " " + r.intent + " args=" + si.intent);
11246                if (si.intent == null && N > 1) {
11247                    // If somehow we got a dummy null intent in the middle,
11248                    // then skip it.  DO NOT skip a null intent when it is
11249                    // the only one in the list -- this is to support the
11250                    // onStartCommand(null) case.
11251                    continue;
11252                }
11253                si.deliveredTime = SystemClock.uptimeMillis();
11254                r.deliveredStarts.add(si);
11255                si.deliveryCount++;
11256                if (si.neededGrants != null) {
11257                    grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
11258                            si.getUriPermissionsLocked());
11259                }
11260                bumpServiceExecutingLocked(r, "start");
11261                if (!oomAdjusted) {
11262                    oomAdjusted = true;
11263                    updateOomAdjLocked(r.app);
11264                }
11265                int flags = 0;
11266                if (si.deliveryCount > 1) {
11267                    flags |= Service.START_FLAG_RETRY;
11268                }
11269                if (si.doneExecutingCount > 0) {
11270                    flags |= Service.START_FLAG_REDELIVERY;
11271                }
11272                r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
11273            } catch (RemoteException e) {
11274                // Remote process gone...  we'll let the normal cleanup take
11275                // care of this.
11276                if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
11277                break;
11278            } catch (Exception e) {
11279                Slog.w(TAG, "Unexpected exception", e);
11280                break;
11281            }
11282        }
11283    }
11284
11285    private final boolean requestServiceBindingLocked(ServiceRecord r,
11286            IntentBindRecord i, boolean rebind) {
11287        if (r.app == null || r.app.thread == null) {
11288            // If service is not currently running, can't yet bind.
11289            return false;
11290        }
11291        if ((!i.requested || rebind) && i.apps.size() > 0) {
11292            try {
11293                bumpServiceExecutingLocked(r, "bind");
11294                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
11295                if (!rebind) {
11296                    i.requested = true;
11297                }
11298                i.hasBound = true;
11299                i.doRebind = false;
11300            } catch (RemoteException e) {
11301                if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
11302                return false;
11303            }
11304        }
11305        return true;
11306    }
11307
11308    private final void requestServiceBindingsLocked(ServiceRecord r) {
11309        Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
11310        while (bindings.hasNext()) {
11311            IntentBindRecord i = bindings.next();
11312            if (!requestServiceBindingLocked(r, i, false)) {
11313                break;
11314            }
11315        }
11316    }
11317
11318    private final void realStartServiceLocked(ServiceRecord r,
11319            ProcessRecord app) throws RemoteException {
11320        if (app.thread == null) {
11321            throw new RemoteException();
11322        }
11323        if (DEBUG_MU)
11324            Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
11325                    + ", ProcessRecord.uid = " + app.uid);
11326        r.app = app;
11327        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
11328
11329        app.services.add(r);
11330        bumpServiceExecutingLocked(r, "create");
11331        updateLruProcessLocked(app, true, true);
11332
11333        boolean created = false;
11334        try {
11335            mStringBuilder.setLength(0);
11336            r.intent.getIntent().toShortString(mStringBuilder, true, false, true, false);
11337            EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
11338                    System.identityHashCode(r), r.shortName,
11339                    mStringBuilder.toString(), r.app.pid);
11340            synchronized (r.stats.getBatteryStats()) {
11341                r.stats.startLaunchedLocked();
11342            }
11343            ensurePackageDexOpt(r.serviceInfo.packageName);
11344            app.thread.scheduleCreateService(r, r.serviceInfo,
11345                    compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
11346            r.postNotification();
11347            created = true;
11348        } finally {
11349            if (!created) {
11350                app.services.remove(r);
11351                scheduleServiceRestartLocked(r, false);
11352            }
11353        }
11354
11355        requestServiceBindingsLocked(r);
11356
11357        // If the service is in the started state, and there are no
11358        // pending arguments, then fake up one so its onStartCommand() will
11359        // be called.
11360        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
11361            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
11362                    null, null));
11363        }
11364
11365        sendServiceArgsLocked(r, true);
11366    }
11367
11368    private final boolean scheduleServiceRestartLocked(ServiceRecord r,
11369            boolean allowCancel) {
11370        boolean canceled = false;
11371
11372        final long now = SystemClock.uptimeMillis();
11373        long minDuration = SERVICE_RESTART_DURATION;
11374        long resetTime = SERVICE_RESET_RUN_DURATION;
11375
11376        if ((r.serviceInfo.applicationInfo.flags
11377                &ApplicationInfo.FLAG_PERSISTENT) != 0) {
11378            minDuration /= 4;
11379        }
11380
11381        // Any delivered but not yet finished starts should be put back
11382        // on the pending list.
11383        final int N = r.deliveredStarts.size();
11384        if (N > 0) {
11385            for (int i=N-1; i>=0; i--) {
11386                ServiceRecord.StartItem si = r.deliveredStarts.get(i);
11387                si.removeUriPermissionsLocked();
11388                if (si.intent == null) {
11389                    // We'll generate this again if needed.
11390                } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
11391                        && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
11392                    r.pendingStarts.add(0, si);
11393                    long dur = SystemClock.uptimeMillis() - si.deliveredTime;
11394                    dur *= 2;
11395                    if (minDuration < dur) minDuration = dur;
11396                    if (resetTime < dur) resetTime = dur;
11397                } else {
11398                    Slog.w(TAG, "Canceling start item " + si.intent + " in service "
11399                            + r.name);
11400                    canceled = true;
11401                }
11402            }
11403            r.deliveredStarts.clear();
11404        }
11405
11406        r.totalRestartCount++;
11407        if (r.restartDelay == 0) {
11408            r.restartCount++;
11409            r.restartDelay = minDuration;
11410        } else {
11411            // If it has been a "reasonably long time" since the service
11412            // was started, then reset our restart duration back to
11413            // the beginning, so we don't infinitely increase the duration
11414            // on a service that just occasionally gets killed (which is
11415            // a normal case, due to process being killed to reclaim memory).
11416            if (now > (r.restartTime+resetTime)) {
11417                r.restartCount = 1;
11418                r.restartDelay = minDuration;
11419            } else {
11420                if ((r.serviceInfo.applicationInfo.flags
11421                        &ApplicationInfo.FLAG_PERSISTENT) != 0) {
11422                    // Services in peristent processes will restart much more
11423                    // quickly, since they are pretty important.  (Think SystemUI).
11424                    r.restartDelay += minDuration/2;
11425                } else {
11426                    r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
11427                    if (r.restartDelay < minDuration) {
11428                        r.restartDelay = minDuration;
11429                    }
11430                }
11431            }
11432        }
11433
11434        r.nextRestartTime = now + r.restartDelay;
11435
11436        // Make sure that we don't end up restarting a bunch of services
11437        // all at the same time.
11438        boolean repeat;
11439        do {
11440            repeat = false;
11441            for (int i=mRestartingServices.size()-1; i>=0; i--) {
11442                ServiceRecord r2 = mRestartingServices.get(i);
11443                if (r2 != r && r.nextRestartTime
11444                        >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
11445                        && r.nextRestartTime
11446                        < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
11447                    r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
11448                    r.restartDelay = r.nextRestartTime - now;
11449                    repeat = true;
11450                    break;
11451                }
11452            }
11453        } while (repeat);
11454
11455        if (!mRestartingServices.contains(r)) {
11456            mRestartingServices.add(r);
11457        }
11458
11459        r.cancelNotification();
11460
11461        mHandler.removeCallbacks(r.restarter);
11462        mHandler.postAtTime(r.restarter, r.nextRestartTime);
11463        r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
11464        Slog.w(TAG, "Scheduling restart of crashed service "
11465                + r.shortName + " in " + r.restartDelay + "ms");
11466        EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
11467                r.shortName, r.restartDelay);
11468
11469        return canceled;
11470    }
11471
11472    final void performServiceRestartLocked(ServiceRecord r) {
11473        if (!mRestartingServices.contains(r)) {
11474            return;
11475        }
11476        bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
11477    }
11478
11479    private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
11480        if (r.restartDelay == 0) {
11481            return false;
11482        }
11483        r.resetRestartCounter();
11484        mRestartingServices.remove(r);
11485        mHandler.removeCallbacks(r.restarter);
11486        return true;
11487    }
11488
11489    private final boolean bringUpServiceLocked(ServiceRecord r,
11490            int intentFlags, boolean whileRestarting) {
11491        //Slog.i(TAG, "Bring up service:");
11492        //r.dump("  ");
11493
11494        if (r.app != null && r.app.thread != null) {
11495            sendServiceArgsLocked(r, false);
11496            return true;
11497        }
11498
11499        if (!whileRestarting && r.restartDelay > 0) {
11500            // If waiting for a restart, then do nothing.
11501            return true;
11502        }
11503
11504        if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
11505
11506        // We are now bringing the service up, so no longer in the
11507        // restarting state.
11508        mRestartingServices.remove(r);
11509
11510        // Service is now being launched, its package can't be stopped.
11511        try {
11512            AppGlobals.getPackageManager().setPackageStoppedState(
11513                    r.packageName, false, r.userId);
11514        } catch (RemoteException e) {
11515        } catch (IllegalArgumentException e) {
11516            Slog.w(TAG, "Failed trying to unstop package "
11517                    + r.packageName + ": " + e);
11518        }
11519
11520        final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
11521        final String appName = r.processName;
11522        ProcessRecord app;
11523
11524        if (!isolated) {
11525            app = getProcessRecordLocked(appName, r.appInfo.uid);
11526            if (DEBUG_MU)
11527                Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + " app=" + app);
11528            if (app != null && app.thread != null) {
11529                try {
11530                    app.addPackage(r.appInfo.packageName);
11531                    realStartServiceLocked(r, app);
11532                    return true;
11533                } catch (RemoteException e) {
11534                    Slog.w(TAG, "Exception when starting service " + r.shortName, e);
11535                }
11536
11537                // If a dead object exception was thrown -- fall through to
11538                // restart the application.
11539            }
11540        } else {
11541            // If this service runs in an isolated process, then each time
11542            // we call startProcessLocked() we will get a new isolated
11543            // process, starting another process if we are currently waiting
11544            // for a previous process to come up.  To deal with this, we store
11545            // in the service any current isolated process it is running in or
11546            // waiting to have come up.
11547            app = r.isolatedProc;
11548        }
11549
11550        // Not running -- get it started, and enqueue this service record
11551        // to be executed when the app comes up.
11552        if (app == null) {
11553            if ((app=startProcessLocked(appName, r.appInfo, true, intentFlags,
11554                    "service", r.name, false, isolated)) == null) {
11555                Slog.w(TAG, "Unable to launch app "
11556                        + r.appInfo.packageName + "/"
11557                        + r.appInfo.uid + " for service "
11558                        + r.intent.getIntent() + ": process is bad");
11559                bringDownServiceLocked(r, true);
11560                return false;
11561            }
11562            if (isolated) {
11563                r.isolatedProc = app;
11564            }
11565        }
11566
11567        if (!mPendingServices.contains(r)) {
11568            mPendingServices.add(r);
11569        }
11570
11571        return true;
11572    }
11573
11574    private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
11575        //Slog.i(TAG, "Bring down service:");
11576        //r.dump("  ");
11577
11578        // Does it still need to run?
11579        if (!force && r.startRequested) {
11580            return;
11581        }
11582        if (r.connections.size() > 0) {
11583            if (!force) {
11584                // XXX should probably keep a count of the number of auto-create
11585                // connections directly in the service.
11586                Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
11587                while (it.hasNext()) {
11588                    ArrayList<ConnectionRecord> cr = it.next();
11589                    for (int i=0; i<cr.size(); i++) {
11590                        if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
11591                            return;
11592                        }
11593                    }
11594                }
11595            }
11596
11597            // Report to all of the connections that the service is no longer
11598            // available.
11599            Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
11600            while (it.hasNext()) {
11601                ArrayList<ConnectionRecord> c = it.next();
11602                for (int i=0; i<c.size(); i++) {
11603                    ConnectionRecord cr = c.get(i);
11604                    // There is still a connection to the service that is
11605                    // being brought down.  Mark it as dead.
11606                    cr.serviceDead = true;
11607                    try {
11608                        cr.conn.connected(r.name, null);
11609                    } catch (Exception e) {
11610                        Slog.w(TAG, "Failure disconnecting service " + r.name +
11611                              " to connection " + c.get(i).conn.asBinder() +
11612                              " (in " + c.get(i).binding.client.processName + ")", e);
11613                    }
11614                }
11615            }
11616        }
11617
11618        // Tell the service that it has been unbound.
11619        if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
11620            Iterator<IntentBindRecord> it = r.bindings.values().iterator();
11621            while (it.hasNext()) {
11622                IntentBindRecord ibr = it.next();
11623                if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
11624                        + ": hasBound=" + ibr.hasBound);
11625                if (r.app != null && r.app.thread != null && ibr.hasBound) {
11626                    try {
11627                        bumpServiceExecutingLocked(r, "bring down unbind");
11628                        updateOomAdjLocked(r.app);
11629                        ibr.hasBound = false;
11630                        r.app.thread.scheduleUnbindService(r,
11631                                ibr.intent.getIntent());
11632                    } catch (Exception e) {
11633                        Slog.w(TAG, "Exception when unbinding service "
11634                                + r.shortName, e);
11635                        serviceDoneExecutingLocked(r, true);
11636                    }
11637                }
11638            }
11639        }
11640
11641        if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
11642        EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
11643                System.identityHashCode(r), r.shortName,
11644                (r.app != null) ? r.app.pid : -1);
11645
11646        mServiceMap.removeServiceByName(r.name, r.userId);
11647        mServiceMap.removeServiceByIntent(r.intent, r.userId);
11648        r.totalRestartCount = 0;
11649        unscheduleServiceRestartLocked(r);
11650
11651        // Also make sure it is not on the pending list.
11652        int N = mPendingServices.size();
11653        for (int i=0; i<N; i++) {
11654            if (mPendingServices.get(i) == r) {
11655                mPendingServices.remove(i);
11656                if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
11657                i--;
11658                N--;
11659            }
11660        }
11661
11662        r.cancelNotification();
11663        r.isForeground = false;
11664        r.foregroundId = 0;
11665        r.foregroundNoti = null;
11666
11667        // Clear start entries.
11668        r.clearDeliveredStartsLocked();
11669        r.pendingStarts.clear();
11670
11671        if (r.app != null) {
11672            synchronized (r.stats.getBatteryStats()) {
11673                r.stats.stopLaunchedLocked();
11674            }
11675            r.app.services.remove(r);
11676            if (r.app.thread != null) {
11677                try {
11678                    bumpServiceExecutingLocked(r, "stop");
11679                    mStoppingServices.add(r);
11680                    updateOomAdjLocked(r.app);
11681                    r.app.thread.scheduleStopService(r);
11682                } catch (Exception e) {
11683                    Slog.w(TAG, "Exception when stopping service "
11684                            + r.shortName, e);
11685                    serviceDoneExecutingLocked(r, true);
11686                }
11687                updateServiceForegroundLocked(r.app, false);
11688            } else {
11689                if (DEBUG_SERVICE) Slog.v(
11690                    TAG, "Removed service that has no process: " + r);
11691            }
11692        } else {
11693            if (DEBUG_SERVICE) Slog.v(
11694                TAG, "Removed service that is not running: " + r);
11695        }
11696
11697        if (r.bindings.size() > 0) {
11698            r.bindings.clear();
11699        }
11700
11701        if (r.restarter instanceof ServiceRestarter) {
11702           ((ServiceRestarter)r.restarter).setService(null);
11703        }
11704    }
11705
11706    ComponentName startServiceLocked(IApplicationThread caller,
11707            Intent service, String resolvedType,
11708            int callingPid, int callingUid) {
11709        synchronized(this) {
11710            if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
11711                    + " type=" + resolvedType + " args=" + service.getExtras());
11712
11713            if (caller != null) {
11714                final ProcessRecord callerApp = getRecordForAppLocked(caller);
11715                if (callerApp == null) {
11716                    throw new SecurityException(
11717                            "Unable to find app for caller " + caller
11718                            + " (pid=" + Binder.getCallingPid()
11719                            + ") when starting service " + service);
11720                }
11721            }
11722
11723            ServiceLookupResult res =
11724                retrieveServiceLocked(service, resolvedType,
11725                        callingPid, callingUid, UserId.getUserId(callingUid));
11726            if (res == null) {
11727                return null;
11728            }
11729            if (res.record == null) {
11730                return new ComponentName("!", res.permission != null
11731                        ? res.permission : "private to package");
11732            }
11733            ServiceRecord r = res.record;
11734            NeededUriGrants neededGrants = checkGrantUriPermissionFromIntentLocked(
11735                    callingUid, r.packageName, service, service.getFlags(), null);
11736            if (unscheduleServiceRestartLocked(r)) {
11737                if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
11738            }
11739            r.startRequested = true;
11740            r.callStart = false;
11741            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
11742                    service, neededGrants));
11743            r.lastActivity = SystemClock.uptimeMillis();
11744            synchronized (r.stats.getBatteryStats()) {
11745                r.stats.startRunningLocked();
11746            }
11747            if (!bringUpServiceLocked(r, service.getFlags(), false)) {
11748                return new ComponentName("!", "Service process is bad");
11749            }
11750            return r.name;
11751        }
11752    }
11753
11754    public ComponentName startService(IApplicationThread caller, Intent service,
11755            String resolvedType) {
11756        enforceNotIsolatedCaller("startService");
11757        // Refuse possible leaked file descriptors
11758        if (service != null && service.hasFileDescriptors() == true) {
11759            throw new IllegalArgumentException("File descriptors passed in Intent");
11760        }
11761
11762        if (DEBUG_SERVICE)
11763            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
11764        synchronized(this) {
11765            final int callingPid = Binder.getCallingPid();
11766            final int callingUid = Binder.getCallingUid();
11767            final long origId = Binder.clearCallingIdentity();
11768            ComponentName res = startServiceLocked(caller, service,
11769                    resolvedType, callingPid, callingUid);
11770            Binder.restoreCallingIdentity(origId);
11771            return res;
11772        }
11773    }
11774
11775    ComponentName startServiceInPackage(int uid,
11776            Intent service, String resolvedType) {
11777        synchronized(this) {
11778            if (DEBUG_SERVICE)
11779                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
11780            final long origId = Binder.clearCallingIdentity();
11781            ComponentName res = startServiceLocked(null, service,
11782                    resolvedType, -1, uid);
11783            Binder.restoreCallingIdentity(origId);
11784            return res;
11785        }
11786    }
11787
11788    private void stopServiceLocked(ServiceRecord service) {
11789        synchronized (service.stats.getBatteryStats()) {
11790            service.stats.stopRunningLocked();
11791        }
11792        service.startRequested = false;
11793        service.callStart = false;
11794        bringDownServiceLocked(service, false);
11795    }
11796
11797    public int stopService(IApplicationThread caller, Intent service,
11798            String resolvedType) {
11799        enforceNotIsolatedCaller("stopService");
11800        // Refuse possible leaked file descriptors
11801        if (service != null && service.hasFileDescriptors() == true) {
11802            throw new IllegalArgumentException("File descriptors passed in Intent");
11803        }
11804
11805        synchronized(this) {
11806            if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
11807                    + " type=" + resolvedType);
11808
11809            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11810            if (caller != null && callerApp == null) {
11811                throw new SecurityException(
11812                        "Unable to find app for caller " + caller
11813                        + " (pid=" + Binder.getCallingPid()
11814                        + ") when stopping service " + service);
11815            }
11816
11817            // If this service is active, make sure it is stopped.
11818            ServiceLookupResult r = findServiceLocked(service, resolvedType,
11819                    callerApp == null ? UserId.getCallingUserId() : callerApp.userId);
11820            if (r != null) {
11821                if (r.record != null) {
11822                    final long origId = Binder.clearCallingIdentity();
11823                    try {
11824                        stopServiceLocked(r.record);
11825                    } finally {
11826                        Binder.restoreCallingIdentity(origId);
11827                    }
11828                    return 1;
11829                }
11830                return -1;
11831            }
11832        }
11833
11834        return 0;
11835    }
11836
11837    public IBinder peekService(Intent service, String resolvedType) {
11838        enforceNotIsolatedCaller("peekService");
11839        // Refuse possible leaked file descriptors
11840        if (service != null && service.hasFileDescriptors() == true) {
11841            throw new IllegalArgumentException("File descriptors passed in Intent");
11842        }
11843
11844        IBinder ret = null;
11845
11846        synchronized(this) {
11847            ServiceLookupResult r = findServiceLocked(service, resolvedType,
11848                    UserId.getCallingUserId());
11849
11850            if (r != null) {
11851                // r.record is null if findServiceLocked() failed the caller permission check
11852                if (r.record == null) {
11853                    throw new SecurityException(
11854                            "Permission Denial: Accessing service " + r.record.name
11855                            + " from pid=" + Binder.getCallingPid()
11856                            + ", uid=" + Binder.getCallingUid()
11857                            + " requires " + r.permission);
11858                }
11859                IntentBindRecord ib = r.record.bindings.get(r.record.intent);
11860                if (ib != null) {
11861                    ret = ib.binder;
11862                }
11863            }
11864        }
11865
11866        return ret;
11867    }
11868
11869    public boolean stopServiceToken(ComponentName className, IBinder token,
11870            int startId) {
11871        synchronized(this) {
11872            if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
11873                    + " " + token + " startId=" + startId);
11874            ServiceRecord r = findServiceLocked(className, token);
11875            if (r != null) {
11876                if (startId >= 0) {
11877                    // Asked to only stop if done with all work.  Note that
11878                    // to avoid leaks, we will take this as dropping all
11879                    // start items up to and including this one.
11880                    ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11881                    if (si != null) {
11882                        while (r.deliveredStarts.size() > 0) {
11883                            ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
11884                            cur.removeUriPermissionsLocked();
11885                            if (cur == si) {
11886                                break;
11887                            }
11888                        }
11889                    }
11890
11891                    if (r.getLastStartId() != startId) {
11892                        return false;
11893                    }
11894
11895                    if (r.deliveredStarts.size() > 0) {
11896                        Slog.w(TAG, "stopServiceToken startId " + startId
11897                                + " is last, but have " + r.deliveredStarts.size()
11898                                + " remaining args");
11899                    }
11900                }
11901
11902                synchronized (r.stats.getBatteryStats()) {
11903                    r.stats.stopRunningLocked();
11904                    r.startRequested = false;
11905                    r.callStart = false;
11906                }
11907                final long origId = Binder.clearCallingIdentity();
11908                bringDownServiceLocked(r, false);
11909                Binder.restoreCallingIdentity(origId);
11910                return true;
11911            }
11912        }
11913        return false;
11914    }
11915
11916    public void setServiceForeground(ComponentName className, IBinder token,
11917            int id, Notification notification, boolean removeNotification) {
11918        final long origId = Binder.clearCallingIdentity();
11919        try {
11920        synchronized(this) {
11921            ServiceRecord r = findServiceLocked(className, token);
11922            if (r != null) {
11923                if (id != 0) {
11924                    if (notification == null) {
11925                        throw new IllegalArgumentException("null notification");
11926                    }
11927                    if (r.foregroundId != id) {
11928                        r.cancelNotification();
11929                        r.foregroundId = id;
11930                    }
11931                    notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
11932                    r.foregroundNoti = notification;
11933                    r.isForeground = true;
11934                    r.postNotification();
11935                    if (r.app != null) {
11936                        updateServiceForegroundLocked(r.app, true);
11937                    }
11938                } else {
11939                    if (r.isForeground) {
11940                        r.isForeground = false;
11941                        if (r.app != null) {
11942                            updateLruProcessLocked(r.app, false, true);
11943                            updateServiceForegroundLocked(r.app, true);
11944                        }
11945                    }
11946                    if (removeNotification) {
11947                        r.cancelNotification();
11948                        r.foregroundId = 0;
11949                        r.foregroundNoti = null;
11950                    }
11951                }
11952            }
11953        }
11954        } finally {
11955            Binder.restoreCallingIdentity(origId);
11956        }
11957    }
11958
11959    public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
11960        boolean anyForeground = false;
11961        for (ServiceRecord sr : proc.services) {
11962            if (sr.isForeground) {
11963                anyForeground = true;
11964                break;
11965            }
11966        }
11967        if (anyForeground != proc.foregroundServices) {
11968            proc.foregroundServices = anyForeground;
11969            if (oomAdj) {
11970                updateOomAdjLocked();
11971            }
11972        }
11973    }
11974
11975    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo) {
11976        boolean result = false;
11977        if (UserId.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
11978            result = false;
11979        } else if (componentProcessName == aInfo.packageName) {
11980            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
11981        } else if ("system".equals(componentProcessName)) {
11982            result = true;
11983        }
11984        if (DEBUG_MU) {
11985            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo + ") = " + result);
11986        }
11987        return result;
11988    }
11989
11990    public int bindService(IApplicationThread caller, IBinder token,
11991            Intent service, String resolvedType,
11992            IServiceConnection connection, int flags, int userId) {
11993        enforceNotIsolatedCaller("bindService");
11994        // Refuse possible leaked file descriptors
11995        if (service != null && service.hasFileDescriptors() == true) {
11996            throw new IllegalArgumentException("File descriptors passed in Intent");
11997        }
11998
11999        checkValidCaller(Binder.getCallingUid(), userId);
12000
12001        synchronized(this) {
12002            if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
12003                    + " type=" + resolvedType + " conn=" + connection.asBinder()
12004                    + " flags=0x" + Integer.toHexString(flags));
12005            if (DEBUG_MU)
12006                Slog.i(TAG_MU, "bindService uid=" + Binder.getCallingUid() + " origUid="
12007                        + Binder.getOrigCallingUid());
12008            final ProcessRecord callerApp = getRecordForAppLocked(caller);
12009            if (callerApp == null) {
12010                throw new SecurityException(
12011                        "Unable to find app for caller " + caller
12012                        + " (pid=" + Binder.getCallingPid()
12013                        + ") when binding service " + service);
12014            }
12015
12016            ActivityRecord activity = null;
12017            if (token != null) {
12018                activity = mMainStack.isInStackLocked(token);
12019                if (activity == null) {
12020                    Slog.w(TAG, "Binding with unknown activity: " + token);
12021                    return 0;
12022                }
12023            }
12024
12025            int clientLabel = 0;
12026            PendingIntent clientIntent = null;
12027
12028            if (callerApp.info.uid == Process.SYSTEM_UID) {
12029                // Hacky kind of thing -- allow system stuff to tell us
12030                // what they are, so we can report this elsewhere for
12031                // others to know why certain services are running.
12032                try {
12033                    clientIntent = (PendingIntent)service.getParcelableExtra(
12034                            Intent.EXTRA_CLIENT_INTENT);
12035                } catch (RuntimeException e) {
12036                }
12037                if (clientIntent != null) {
12038                    clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
12039                    if (clientLabel != 0) {
12040                        // There are no useful extras in the intent, trash them.
12041                        // System code calling with this stuff just needs to know
12042                        // this will happen.
12043                        service = service.cloneFilter();
12044                    }
12045                }
12046            }
12047
12048            ServiceLookupResult res =
12049                retrieveServiceLocked(service, resolvedType,
12050                        Binder.getCallingPid(), Binder.getCallingUid(), userId);
12051            if (res == null) {
12052                return 0;
12053            }
12054            if (res.record == null) {
12055                return -1;
12056            }
12057            if (isSingleton(res.record.processName, res.record.appInfo)) {
12058                userId = 0;
12059                res = retrieveServiceLocked(service, resolvedType, Binder.getCallingPid(),
12060                        Binder.getCallingUid(), 0);
12061            }
12062            ServiceRecord s = res.record;
12063
12064            final long origId = Binder.clearCallingIdentity();
12065
12066            if (unscheduleServiceRestartLocked(s)) {
12067                if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
12068                        + s);
12069            }
12070
12071            AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
12072            ConnectionRecord c = new ConnectionRecord(b, activity,
12073                    connection, flags, clientLabel, clientIntent);
12074
12075            IBinder binder = connection.asBinder();
12076            ArrayList<ConnectionRecord> clist = s.connections.get(binder);
12077            if (clist == null) {
12078                clist = new ArrayList<ConnectionRecord>();
12079                s.connections.put(binder, clist);
12080            }
12081            clist.add(c);
12082            b.connections.add(c);
12083            if (activity != null) {
12084                if (activity.connections == null) {
12085                    activity.connections = new HashSet<ConnectionRecord>();
12086                }
12087                activity.connections.add(c);
12088            }
12089            b.client.connections.add(c);
12090            if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
12091                b.client.hasAboveClient = true;
12092            }
12093            clist = mServiceConnections.get(binder);
12094            if (clist == null) {
12095                clist = new ArrayList<ConnectionRecord>();
12096                mServiceConnections.put(binder, clist);
12097            }
12098            clist.add(c);
12099
12100            if ((flags&Context.BIND_AUTO_CREATE) != 0) {
12101                s.lastActivity = SystemClock.uptimeMillis();
12102                if (!bringUpServiceLocked(s, service.getFlags(), false)) {
12103                    return 0;
12104                }
12105            }
12106
12107            if (s.app != null) {
12108                // This could have made the service more important.
12109                updateOomAdjLocked(s.app);
12110            }
12111
12112            if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
12113                    + ": received=" + b.intent.received
12114                    + " apps=" + b.intent.apps.size()
12115                    + " doRebind=" + b.intent.doRebind);
12116
12117            if (s.app != null && b.intent.received) {
12118                // Service is already running, so we can immediately
12119                // publish the connection.
12120                try {
12121                    c.conn.connected(s.name, b.intent.binder);
12122                } catch (Exception e) {
12123                    Slog.w(TAG, "Failure sending service " + s.shortName
12124                            + " to connection " + c.conn.asBinder()
12125                            + " (in " + c.binding.client.processName + ")", e);
12126                }
12127
12128                // If this is the first app connected back to this binding,
12129                // and the service had previously asked to be told when
12130                // rebound, then do so.
12131                if (b.intent.apps.size() == 1 && b.intent.doRebind) {
12132                    requestServiceBindingLocked(s, b.intent, true);
12133                }
12134            } else if (!b.intent.requested) {
12135                requestServiceBindingLocked(s, b.intent, false);
12136            }
12137
12138            Binder.restoreCallingIdentity(origId);
12139        }
12140
12141        return 1;
12142    }
12143
12144    void removeConnectionLocked(
12145        ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
12146        IBinder binder = c.conn.asBinder();
12147        AppBindRecord b = c.binding;
12148        ServiceRecord s = b.service;
12149        ArrayList<ConnectionRecord> clist = s.connections.get(binder);
12150        if (clist != null) {
12151            clist.remove(c);
12152            if (clist.size() == 0) {
12153                s.connections.remove(binder);
12154            }
12155        }
12156        b.connections.remove(c);
12157        if (c.activity != null && c.activity != skipAct) {
12158            if (c.activity.connections != null) {
12159                c.activity.connections.remove(c);
12160            }
12161        }
12162        if (b.client != skipApp) {
12163            b.client.connections.remove(c);
12164            if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
12165                b.client.updateHasAboveClientLocked();
12166            }
12167        }
12168        clist = mServiceConnections.get(binder);
12169        if (clist != null) {
12170            clist.remove(c);
12171            if (clist.size() == 0) {
12172                mServiceConnections.remove(binder);
12173            }
12174        }
12175
12176        if (b.connections.size() == 0) {
12177            b.intent.apps.remove(b.client);
12178        }
12179
12180        if (!c.serviceDead) {
12181            if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
12182                    + ": shouldUnbind=" + b.intent.hasBound);
12183            if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
12184                    && b.intent.hasBound) {
12185                try {
12186                    bumpServiceExecutingLocked(s, "unbind");
12187                    updateOomAdjLocked(s.app);
12188                    b.intent.hasBound = false;
12189                    // Assume the client doesn't want to know about a rebind;
12190                    // we will deal with that later if it asks for one.
12191                    b.intent.doRebind = false;
12192                    s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
12193                } catch (Exception e) {
12194                    Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
12195                    serviceDoneExecutingLocked(s, true);
12196                }
12197            }
12198
12199            if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
12200                bringDownServiceLocked(s, false);
12201            }
12202        }
12203    }
12204
12205    public boolean unbindService(IServiceConnection connection) {
12206        synchronized (this) {
12207            IBinder binder = connection.asBinder();
12208            if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
12209            ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
12210            if (clist == null) {
12211                Slog.w(TAG, "Unbind failed: could not find connection for "
12212                      + connection.asBinder());
12213                return false;
12214            }
12215
12216            final long origId = Binder.clearCallingIdentity();
12217
12218            while (clist.size() > 0) {
12219                ConnectionRecord r = clist.get(0);
12220                removeConnectionLocked(r, null, null);
12221
12222                if (r.binding.service.app != null) {
12223                    // This could have made the service less important.
12224                    updateOomAdjLocked(r.binding.service.app);
12225                }
12226            }
12227
12228            Binder.restoreCallingIdentity(origId);
12229        }
12230
12231        return true;
12232    }
12233
12234    public void publishService(IBinder token, Intent intent, IBinder service) {
12235        // Refuse possible leaked file descriptors
12236        if (intent != null && intent.hasFileDescriptors() == true) {
12237            throw new IllegalArgumentException("File descriptors passed in Intent");
12238        }
12239
12240        synchronized(this) {
12241            if (!(token instanceof ServiceRecord)) {
12242                throw new IllegalArgumentException("Invalid service token");
12243            }
12244            ServiceRecord r = (ServiceRecord)token;
12245
12246            final long origId = Binder.clearCallingIdentity();
12247
12248            if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
12249                    + " " + intent + ": " + service);
12250            if (r != null) {
12251                Intent.FilterComparison filter
12252                        = new Intent.FilterComparison(intent);
12253                IntentBindRecord b = r.bindings.get(filter);
12254                if (b != null && !b.received) {
12255                    b.binder = service;
12256                    b.requested = true;
12257                    b.received = true;
12258                    if (r.connections.size() > 0) {
12259                        Iterator<ArrayList<ConnectionRecord>> it
12260                                = r.connections.values().iterator();
12261                        while (it.hasNext()) {
12262                            ArrayList<ConnectionRecord> clist = it.next();
12263                            for (int i=0; i<clist.size(); i++) {
12264                                ConnectionRecord c = clist.get(i);
12265                                if (!filter.equals(c.binding.intent.intent)) {
12266                                    if (DEBUG_SERVICE) Slog.v(
12267                                            TAG, "Not publishing to: " + c);
12268                                    if (DEBUG_SERVICE) Slog.v(
12269                                            TAG, "Bound intent: " + c.binding.intent.intent);
12270                                    if (DEBUG_SERVICE) Slog.v(
12271                                            TAG, "Published intent: " + intent);
12272                                    continue;
12273                                }
12274                                if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
12275                                try {
12276                                    c.conn.connected(r.name, service);
12277                                } catch (Exception e) {
12278                                    Slog.w(TAG, "Failure sending service " + r.name +
12279                                          " to connection " + c.conn.asBinder() +
12280                                          " (in " + c.binding.client.processName + ")", e);
12281                                }
12282                            }
12283                        }
12284                    }
12285                }
12286
12287                serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
12288
12289                Binder.restoreCallingIdentity(origId);
12290            }
12291        }
12292    }
12293
12294    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12295        // Refuse possible leaked file descriptors
12296        if (intent != null && intent.hasFileDescriptors() == true) {
12297            throw new IllegalArgumentException("File descriptors passed in Intent");
12298        }
12299
12300        synchronized(this) {
12301            if (!(token instanceof ServiceRecord)) {
12302                throw new IllegalArgumentException("Invalid service token");
12303            }
12304            ServiceRecord r = (ServiceRecord)token;
12305
12306            final long origId = Binder.clearCallingIdentity();
12307
12308            if (r != null) {
12309                Intent.FilterComparison filter
12310                        = new Intent.FilterComparison(intent);
12311                IntentBindRecord b = r.bindings.get(filter);
12312                if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
12313                        + " at " + b + ": apps="
12314                        + (b != null ? b.apps.size() : 0));
12315
12316                boolean inStopping = mStoppingServices.contains(r);
12317                if (b != null) {
12318                    if (b.apps.size() > 0 && !inStopping) {
12319                        // Applications have already bound since the last
12320                        // unbind, so just rebind right here.
12321                        requestServiceBindingLocked(r, b, true);
12322                    } else {
12323                        // Note to tell the service the next time there is
12324                        // a new client.
12325                        b.doRebind = true;
12326                    }
12327                }
12328
12329                serviceDoneExecutingLocked(r, inStopping);
12330
12331                Binder.restoreCallingIdentity(origId);
12332            }
12333        }
12334    }
12335
12336    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12337        synchronized(this) {
12338            if (!(token instanceof ServiceRecord)) {
12339                throw new IllegalArgumentException("Invalid service token");
12340            }
12341            ServiceRecord r = (ServiceRecord)token;
12342            boolean inStopping = mStoppingServices.contains(token);
12343            if (r != null) {
12344                if (r != token) {
12345                    Slog.w(TAG, "Done executing service " + r.name
12346                          + " with incorrect token: given " + token
12347                          + ", expected " + r);
12348                    return;
12349                }
12350
12351                if (type == 1) {
12352                    // This is a call from a service start...  take care of
12353                    // book-keeping.
12354                    r.callStart = true;
12355                    switch (res) {
12356                        case Service.START_STICKY_COMPATIBILITY:
12357                        case Service.START_STICKY: {
12358                            // We are done with the associated start arguments.
12359                            r.findDeliveredStart(startId, true);
12360                            // Don't stop if killed.
12361                            r.stopIfKilled = false;
12362                            break;
12363                        }
12364                        case Service.START_NOT_STICKY: {
12365                            // We are done with the associated start arguments.
12366                            r.findDeliveredStart(startId, true);
12367                            if (r.getLastStartId() == startId) {
12368                                // There is no more work, and this service
12369                                // doesn't want to hang around if killed.
12370                                r.stopIfKilled = true;
12371                            }
12372                            break;
12373                        }
12374                        case Service.START_REDELIVER_INTENT: {
12375                            // We'll keep this item until they explicitly
12376                            // call stop for it, but keep track of the fact
12377                            // that it was delivered.
12378                            ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
12379                            if (si != null) {
12380                                si.deliveryCount = 0;
12381                                si.doneExecutingCount++;
12382                                // Don't stop if killed.
12383                                r.stopIfKilled = true;
12384                            }
12385                            break;
12386                        }
12387                        case Service.START_TASK_REMOVED_COMPLETE: {
12388                            // Special processing for onTaskRemoved().  Don't
12389                            // impact normal onStartCommand() processing.
12390                            r.findDeliveredStart(startId, true);
12391                            break;
12392                        }
12393                        default:
12394                            throw new IllegalArgumentException(
12395                                    "Unknown service start result: " + res);
12396                    }
12397                    if (res == Service.START_STICKY_COMPATIBILITY) {
12398                        r.callStart = false;
12399                    }
12400                }
12401                if (DEBUG_MU)
12402                    Slog.v(TAG_MU, "before serviceDontExecutingLocked, uid="
12403                            + Binder.getOrigCallingUid());
12404                final long origId = Binder.clearCallingIdentity();
12405                serviceDoneExecutingLocked(r, inStopping);
12406                Binder.restoreCallingIdentity(origId);
12407            } else {
12408                Slog.w(TAG, "Done executing unknown service from pid "
12409                        + Binder.getCallingPid());
12410            }
12411        }
12412    }
12413
12414    public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
12415        if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
12416                + ": nesting=" + r.executeNesting
12417                + ", inStopping=" + inStopping + ", app=" + r.app);
12418        else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
12419        r.executeNesting--;
12420        if (r.executeNesting <= 0 && r.app != null) {
12421            if (DEBUG_SERVICE) Slog.v(TAG,
12422                    "Nesting at 0 of " + r.shortName);
12423            r.app.executingServices.remove(r);
12424            if (r.app.executingServices.size() == 0) {
12425                if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
12426                        "No more executingServices of " + r.shortName);
12427                mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
12428            }
12429            if (inStopping) {
12430                if (DEBUG_SERVICE) Slog.v(TAG,
12431                        "doneExecuting remove stopping " + r);
12432                mStoppingServices.remove(r);
12433                r.bindings.clear();
12434            }
12435            updateOomAdjLocked(r.app);
12436        }
12437    }
12438
12439    void serviceTimeout(ProcessRecord proc) {
12440        String anrMessage = null;
12441
12442        synchronized(this) {
12443            if (proc.executingServices.size() == 0 || proc.thread == null) {
12444                return;
12445            }
12446            long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
12447            Iterator<ServiceRecord> it = proc.executingServices.iterator();
12448            ServiceRecord timeout = null;
12449            long nextTime = 0;
12450            while (it.hasNext()) {
12451                ServiceRecord sr = it.next();
12452                if (sr.executingStart < maxTime) {
12453                    timeout = sr;
12454                    break;
12455                }
12456                if (sr.executingStart > nextTime) {
12457                    nextTime = sr.executingStart;
12458                }
12459            }
12460            if (timeout != null && mLruProcesses.contains(proc)) {
12461                Slog.w(TAG, "Timeout executing service: " + timeout);
12462                anrMessage = "Executing service " + timeout.shortName;
12463            } else {
12464                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
12465                msg.obj = proc;
12466                mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
12467            }
12468        }
12469
12470        if (anrMessage != null) {
12471            appNotResponding(proc, null, null, anrMessage);
12472        }
12473    }
12474
12475    // =========================================================
12476    // BACKUP AND RESTORE
12477    // =========================================================
12478
12479    // Cause the target app to be launched if necessary and its backup agent
12480    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12481    // activity manager to announce its creation.
12482    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12483        if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
12484        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
12485
12486        synchronized(this) {
12487            // !!! TODO: currently no check here that we're already bound
12488            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12489            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12490            synchronized (stats) {
12491                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12492            }
12493
12494            // Backup agent is now in use, its package can't be stopped.
12495            try {
12496                AppGlobals.getPackageManager().setPackageStoppedState(
12497                        app.packageName, false, UserId.getUserId(app.uid));
12498            } catch (RemoteException e) {
12499            } catch (IllegalArgumentException e) {
12500                Slog.w(TAG, "Failed trying to unstop package "
12501                        + app.packageName + ": " + e);
12502            }
12503
12504            BackupRecord r = new BackupRecord(ss, app, backupMode);
12505            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12506                    ? new ComponentName(app.packageName, app.backupAgentName)
12507                    : new ComponentName("android", "FullBackupAgent");
12508            // startProcessLocked() returns existing proc's record if it's already running
12509            ProcessRecord proc = startProcessLocked(app.processName, app,
12510                    false, 0, "backup", hostingName, false, false);
12511            if (proc == null) {
12512                Slog.e(TAG, "Unable to start backup agent process " + r);
12513                return false;
12514            }
12515
12516            r.app = proc;
12517            mBackupTarget = r;
12518            mBackupAppName = app.packageName;
12519
12520            // Try not to kill the process during backup
12521            updateOomAdjLocked(proc);
12522
12523            // If the process is already attached, schedule the creation of the backup agent now.
12524            // If it is not yet live, this will be done when it attaches to the framework.
12525            if (proc.thread != null) {
12526                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12527                try {
12528                    proc.thread.scheduleCreateBackupAgent(app,
12529                            compatibilityInfoForPackageLocked(app), backupMode);
12530                } catch (RemoteException e) {
12531                    // Will time out on the backup manager side
12532                }
12533            } else {
12534                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
12535            }
12536            // Invariants: at this point, the target app process exists and the application
12537            // is either already running or in the process of coming up.  mBackupTarget and
12538            // mBackupAppName describe the app, so that when it binds back to the AM we
12539            // know that it's scheduled for a backup-agent operation.
12540        }
12541
12542        return true;
12543    }
12544
12545    // A backup agent has just come up
12546    public void backupAgentCreated(String agentPackageName, IBinder agent) {
12547        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
12548                + " = " + agent);
12549
12550        synchronized(this) {
12551            if (!agentPackageName.equals(mBackupAppName)) {
12552                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
12553                return;
12554            }
12555        }
12556
12557        long oldIdent = Binder.clearCallingIdentity();
12558        try {
12559            IBackupManager bm = IBackupManager.Stub.asInterface(
12560                    ServiceManager.getService(Context.BACKUP_SERVICE));
12561            bm.agentConnected(agentPackageName, agent);
12562        } catch (RemoteException e) {
12563            // can't happen; the backup manager service is local
12564        } catch (Exception e) {
12565            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12566            e.printStackTrace();
12567        } finally {
12568            Binder.restoreCallingIdentity(oldIdent);
12569        }
12570    }
12571
12572    // done with this agent
12573    public void unbindBackupAgent(ApplicationInfo appInfo) {
12574        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
12575        if (appInfo == null) {
12576            Slog.w(TAG, "unbind backup agent for null app");
12577            return;
12578        }
12579
12580        synchronized(this) {
12581            if (mBackupAppName == null) {
12582                Slog.w(TAG, "Unbinding backup agent with no active backup");
12583                return;
12584            }
12585
12586            if (!mBackupAppName.equals(appInfo.packageName)) {
12587                Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
12588                return;
12589            }
12590
12591            ProcessRecord proc = mBackupTarget.app;
12592            mBackupTarget = null;
12593            mBackupAppName = null;
12594
12595            // Not backing this app up any more; reset its OOM adjustment
12596            updateOomAdjLocked(proc);
12597
12598            // If the app crashed during backup, 'thread' will be null here
12599            if (proc.thread != null) {
12600                try {
12601                    proc.thread.scheduleDestroyBackupAgent(appInfo,
12602                            compatibilityInfoForPackageLocked(appInfo));
12603                } catch (Exception e) {
12604                    Slog.e(TAG, "Exception when unbinding backup agent:");
12605                    e.printStackTrace();
12606                }
12607            }
12608        }
12609    }
12610    // =========================================================
12611    // BROADCASTS
12612    // =========================================================
12613
12614    private final List getStickiesLocked(String action, IntentFilter filter,
12615            List cur) {
12616        final ContentResolver resolver = mContext.getContentResolver();
12617        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
12618        if (list == null) {
12619            return cur;
12620        }
12621        int N = list.size();
12622        for (int i=0; i<N; i++) {
12623            Intent intent = list.get(i);
12624            if (filter.match(resolver, intent, true, TAG) >= 0) {
12625                if (cur == null) {
12626                    cur = new ArrayList<Intent>();
12627                }
12628                cur.add(intent);
12629            }
12630        }
12631        return cur;
12632    }
12633
12634    boolean isPendingBroadcastProcessLocked(int pid) {
12635        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12636                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12637    }
12638
12639    void skipPendingBroadcastLocked(int pid) {
12640            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12641            for (BroadcastQueue queue : mBroadcastQueues) {
12642                queue.skipPendingBroadcastLocked(pid);
12643            }
12644    }
12645
12646    // The app just attached; send any pending broadcasts that it should receive
12647    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12648        boolean didSomething = false;
12649        for (BroadcastQueue queue : mBroadcastQueues) {
12650            didSomething |= queue.sendPendingBroadcastsLocked(app);
12651        }
12652        return didSomething;
12653    }
12654
12655    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
12656            IIntentReceiver receiver, IntentFilter filter, String permission) {
12657        enforceNotIsolatedCaller("registerReceiver");
12658        synchronized(this) {
12659            ProcessRecord callerApp = null;
12660            if (caller != null) {
12661                callerApp = getRecordForAppLocked(caller);
12662                if (callerApp == null) {
12663                    throw new SecurityException(
12664                            "Unable to find app for caller " + caller
12665                            + " (pid=" + Binder.getCallingPid()
12666                            + ") when registering receiver " + receiver);
12667                }
12668                if (callerApp.info.uid != Process.SYSTEM_UID &&
12669                        !callerApp.pkgList.contains(callerPackage)) {
12670                    throw new SecurityException("Given caller package " + callerPackage
12671                            + " is not running in process " + callerApp);
12672                }
12673            } else {
12674                callerPackage = null;
12675            }
12676
12677            List allSticky = null;
12678
12679            // Look for any matching sticky broadcasts...
12680            Iterator actions = filter.actionsIterator();
12681            if (actions != null) {
12682                while (actions.hasNext()) {
12683                    String action = (String)actions.next();
12684                    allSticky = getStickiesLocked(action, filter, allSticky);
12685                }
12686            } else {
12687                allSticky = getStickiesLocked(null, filter, allSticky);
12688            }
12689
12690            // The first sticky in the list is returned directly back to
12691            // the client.
12692            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
12693
12694            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
12695                    + ": " + sticky);
12696
12697            if (receiver == null) {
12698                return sticky;
12699            }
12700
12701            ReceiverList rl
12702                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12703            if (rl == null) {
12704                rl = new ReceiverList(this, callerApp,
12705                        Binder.getCallingPid(),
12706                        Binder.getCallingUid(), receiver);
12707                if (rl.app != null) {
12708                    rl.app.receivers.add(rl);
12709                } else {
12710                    try {
12711                        receiver.asBinder().linkToDeath(rl, 0);
12712                    } catch (RemoteException e) {
12713                        return sticky;
12714                    }
12715                    rl.linkedToDeath = true;
12716                }
12717                mRegisteredReceivers.put(receiver.asBinder(), rl);
12718            }
12719            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
12720            rl.add(bf);
12721            if (!bf.debugCheck()) {
12722                Slog.w(TAG, "==> For Dynamic broadast");
12723            }
12724            mReceiverResolver.addFilter(bf);
12725
12726            // Enqueue broadcasts for all existing stickies that match
12727            // this filter.
12728            if (allSticky != null) {
12729                ArrayList receivers = new ArrayList();
12730                receivers.add(bf);
12731
12732                int N = allSticky.size();
12733                for (int i=0; i<N; i++) {
12734                    Intent intent = (Intent)allSticky.get(i);
12735                    BroadcastQueue queue = broadcastQueueForIntent(intent);
12736                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
12737                            null, -1, -1, null, receivers, null, 0, null, null,
12738                            false, true, true);
12739                    queue.enqueueParallelBroadcastLocked(r);
12740                    queue.scheduleBroadcastsLocked();
12741                }
12742            }
12743
12744            return sticky;
12745        }
12746    }
12747
12748    public void unregisterReceiver(IIntentReceiver receiver) {
12749        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
12750
12751        final long origId = Binder.clearCallingIdentity();
12752        try {
12753            boolean doTrim = false;
12754
12755            synchronized(this) {
12756                ReceiverList rl
12757                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12758                if (rl != null) {
12759                    if (rl.curBroadcast != null) {
12760                        BroadcastRecord r = rl.curBroadcast;
12761                        final boolean doNext = finishReceiverLocked(
12762                                receiver.asBinder(), r.resultCode, r.resultData,
12763                                r.resultExtras, r.resultAbort, true);
12764                        if (doNext) {
12765                            doTrim = true;
12766                            r.queue.processNextBroadcast(false);
12767                        }
12768                    }
12769
12770                    if (rl.app != null) {
12771                        rl.app.receivers.remove(rl);
12772                    }
12773                    removeReceiverLocked(rl);
12774                    if (rl.linkedToDeath) {
12775                        rl.linkedToDeath = false;
12776                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
12777                    }
12778                }
12779            }
12780
12781            // If we actually concluded any broadcasts, we might now be able
12782            // to trim the recipients' apps from our working set
12783            if (doTrim) {
12784                trimApplications();
12785                return;
12786            }
12787
12788        } finally {
12789            Binder.restoreCallingIdentity(origId);
12790        }
12791    }
12792
12793    void removeReceiverLocked(ReceiverList rl) {
12794        mRegisteredReceivers.remove(rl.receiver.asBinder());
12795        int N = rl.size();
12796        for (int i=0; i<N; i++) {
12797            mReceiverResolver.removeFilter(rl.get(i));
12798        }
12799    }
12800
12801    private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
12802        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12803            ProcessRecord r = mLruProcesses.get(i);
12804            if (r.thread != null) {
12805                try {
12806                    r.thread.dispatchPackageBroadcast(cmd, packages);
12807                } catch (RemoteException ex) {
12808                }
12809            }
12810        }
12811    }
12812
12813    private final int broadcastIntentLocked(ProcessRecord callerApp,
12814            String callerPackage, Intent intent, String resolvedType,
12815            IIntentReceiver resultTo, int resultCode, String resultData,
12816            Bundle map, String requiredPermission,
12817            boolean ordered, boolean sticky, int callingPid, int callingUid,
12818            int userId) {
12819        intent = new Intent(intent);
12820
12821        // By default broadcasts do not go to stopped apps.
12822        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
12823
12824        if (DEBUG_BROADCAST_LIGHT) Slog.v(
12825            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
12826            + " ordered=" + ordered + " userid=" + userId);
12827        if ((resultTo != null) && !ordered) {
12828            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
12829        }
12830
12831        // Handle special intents: if this broadcast is from the package
12832        // manager about a package being removed, we need to remove all of
12833        // its activities from the history stack.
12834        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
12835                intent.getAction());
12836        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
12837                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
12838                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
12839                || uidRemoved) {
12840            if (checkComponentPermission(
12841                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
12842                    callingPid, callingUid, -1, true)
12843                    == PackageManager.PERMISSION_GRANTED) {
12844                if (uidRemoved) {
12845                    final Bundle intentExtras = intent.getExtras();
12846                    final int uid = intentExtras != null
12847                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
12848                    if (uid >= 0) {
12849                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
12850                        synchronized (bs) {
12851                            bs.removeUidStatsLocked(uid);
12852                        }
12853                    }
12854                } else {
12855                    // If resources are unvailble just force stop all
12856                    // those packages and flush the attribute cache as well.
12857                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
12858                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
12859                        if (list != null && (list.length > 0)) {
12860                            for (String pkg : list) {
12861                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
12862                            }
12863                            sendPackageBroadcastLocked(
12864                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
12865                        }
12866                    } else {
12867                        Uri data = intent.getData();
12868                        String ssp;
12869                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12870                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
12871                                forceStopPackageLocked(ssp,
12872                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
12873                                        false, userId);
12874                            }
12875                            if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
12876                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
12877                                        new String[] {ssp});
12878                            }
12879                        }
12880                    }
12881                }
12882            } else {
12883                String msg = "Permission Denial: " + intent.getAction()
12884                        + " broadcast from " + callerPackage + " (pid=" + callingPid
12885                        + ", uid=" + callingUid + ")"
12886                        + " requires "
12887                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
12888                Slog.w(TAG, msg);
12889                throw new SecurityException(msg);
12890            }
12891
12892        // Special case for adding a package: by default turn on compatibility
12893        // mode.
12894        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
12895            Uri data = intent.getData();
12896            String ssp;
12897            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12898                mCompatModePackages.handlePackageAddedLocked(ssp,
12899                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
12900            }
12901        }
12902
12903        /*
12904         * If this is the time zone changed action, queue up a message that will reset the timezone
12905         * of all currently running processes. This message will get queued up before the broadcast
12906         * happens.
12907         */
12908        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
12909            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
12910        }
12911
12912        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
12913            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
12914        }
12915
12916        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
12917            ProxyProperties proxy = intent.getParcelableExtra("proxy");
12918            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
12919        }
12920
12921        /*
12922         * Prevent non-system code (defined here to be non-persistent
12923         * processes) from sending protected broadcasts.
12924         */
12925        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
12926                || callingUid == Process.SHELL_UID || callingUid == 0) {
12927            // Always okay.
12928        } else if (callerApp == null || !callerApp.persistent) {
12929            try {
12930                if (AppGlobals.getPackageManager().isProtectedBroadcast(
12931                        intent.getAction())) {
12932                    String msg = "Permission Denial: not allowed to send broadcast "
12933                            + intent.getAction() + " from pid="
12934                            + callingPid + ", uid=" + callingUid;
12935                    Slog.w(TAG, msg);
12936                    throw new SecurityException(msg);
12937                }
12938            } catch (RemoteException e) {
12939                Slog.w(TAG, "Remote exception", e);
12940                return ActivityManager.BROADCAST_SUCCESS;
12941            }
12942        }
12943
12944        // Add to the sticky list if requested.
12945        if (sticky) {
12946            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
12947                    callingPid, callingUid)
12948                    != PackageManager.PERMISSION_GRANTED) {
12949                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
12950                        + callingPid + ", uid=" + callingUid
12951                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
12952                Slog.w(TAG, msg);
12953                throw new SecurityException(msg);
12954            }
12955            if (requiredPermission != null) {
12956                Slog.w(TAG, "Can't broadcast sticky intent " + intent
12957                        + " and enforce permission " + requiredPermission);
12958                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
12959            }
12960            if (intent.getComponent() != null) {
12961                throw new SecurityException(
12962                        "Sticky broadcasts can't target a specific component");
12963            }
12964            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12965            if (list == null) {
12966                list = new ArrayList<Intent>();
12967                mStickyBroadcasts.put(intent.getAction(), list);
12968            }
12969            int N = list.size();
12970            int i;
12971            for (i=0; i<N; i++) {
12972                if (intent.filterEquals(list.get(i))) {
12973                    // This sticky already exists, replace it.
12974                    list.set(i, new Intent(intent));
12975                    break;
12976                }
12977            }
12978            if (i >= N) {
12979                list.add(new Intent(intent));
12980            }
12981        }
12982
12983        // Figure out who all will receive this broadcast.
12984        List receivers = null;
12985        List<BroadcastFilter> registeredReceivers = null;
12986        try {
12987            if (intent.getComponent() != null) {
12988                // Broadcast is going to one specific receiver class...
12989                ActivityInfo ai = AppGlobals.getPackageManager().
12990                        getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS, userId);
12991                if (ai != null) {
12992                    receivers = new ArrayList();
12993                    ResolveInfo ri = new ResolveInfo();
12994                    if (isSingleton(ai.processName, ai.applicationInfo)) {
12995                        ri.activityInfo = getActivityInfoForUser(ai, 0);
12996                    } else {
12997                        ri.activityInfo = getActivityInfoForUser(ai, userId);
12998                    }
12999                    receivers.add(ri);
13000                }
13001            } else {
13002                // Need to resolve the intent to interested receivers...
13003                if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13004                         == 0) {
13005                    receivers =
13006                        AppGlobals.getPackageManager().queryIntentReceivers(
13007                                    intent, resolvedType, STOCK_PM_FLAGS, userId);
13008                }
13009                registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false,
13010                        userId);
13011            }
13012        } catch (RemoteException ex) {
13013            // pm is in same process, this will never happen.
13014        }
13015
13016        final boolean replacePending =
13017                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13018
13019        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13020                + " replacePending=" + replacePending);
13021
13022        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13023        if (!ordered && NR > 0) {
13024            // If we are not serializing this broadcast, then send the
13025            // registered receivers separately so they don't wait for the
13026            // components to be launched.
13027            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13028            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13029                    callerPackage, callingPid, callingUid, requiredPermission,
13030                    registeredReceivers, resultTo, resultCode, resultData, map,
13031                    ordered, sticky, false);
13032            if (DEBUG_BROADCAST) Slog.v(
13033                    TAG, "Enqueueing parallel broadcast " + r);
13034            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13035            if (!replaced) {
13036                queue.enqueueParallelBroadcastLocked(r);
13037                queue.scheduleBroadcastsLocked();
13038            }
13039            registeredReceivers = null;
13040            NR = 0;
13041        }
13042
13043        // Merge into one list.
13044        int ir = 0;
13045        if (receivers != null) {
13046            // A special case for PACKAGE_ADDED: do not allow the package
13047            // being added to see this broadcast.  This prevents them from
13048            // using this as a back door to get run as soon as they are
13049            // installed.  Maybe in the future we want to have a special install
13050            // broadcast or such for apps, but we'd like to deliberately make
13051            // this decision.
13052            String skipPackages[] = null;
13053            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13054                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13055                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13056                Uri data = intent.getData();
13057                if (data != null) {
13058                    String pkgName = data.getSchemeSpecificPart();
13059                    if (pkgName != null) {
13060                        skipPackages = new String[] { pkgName };
13061                    }
13062                }
13063            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13064                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13065            }
13066            if (skipPackages != null && (skipPackages.length > 0)) {
13067                for (String skipPackage : skipPackages) {
13068                    if (skipPackage != null) {
13069                        int NT = receivers.size();
13070                        for (int it=0; it<NT; it++) {
13071                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13072                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13073                                receivers.remove(it);
13074                                it--;
13075                                NT--;
13076                            }
13077                        }
13078                    }
13079                }
13080            }
13081
13082            int NT = receivers != null ? receivers.size() : 0;
13083            int it = 0;
13084            ResolveInfo curt = null;
13085            BroadcastFilter curr = null;
13086            while (it < NT && ir < NR) {
13087                if (curt == null) {
13088                    curt = (ResolveInfo)receivers.get(it);
13089                }
13090                if (curr == null) {
13091                    curr = registeredReceivers.get(ir);
13092                }
13093                if (curr.getPriority() >= curt.priority) {
13094                    // Insert this broadcast record into the final list.
13095                    receivers.add(it, curr);
13096                    ir++;
13097                    curr = null;
13098                    it++;
13099                    NT++;
13100                } else {
13101                    // Skip to the next ResolveInfo in the final list.
13102                    it++;
13103                    curt = null;
13104                }
13105            }
13106        }
13107        while (ir < NR) {
13108            if (receivers == null) {
13109                receivers = new ArrayList();
13110            }
13111            receivers.add(registeredReceivers.get(ir));
13112            ir++;
13113        }
13114
13115        if ((receivers != null && receivers.size() > 0)
13116                || resultTo != null) {
13117            BroadcastQueue queue = broadcastQueueForIntent(intent);
13118            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13119                    callerPackage, callingPid, callingUid, requiredPermission,
13120                    receivers, resultTo, resultCode, resultData, map, ordered,
13121                    sticky, false);
13122            if (DEBUG_BROADCAST) Slog.v(
13123                    TAG, "Enqueueing ordered broadcast " + r
13124                    + ": prev had " + queue.mOrderedBroadcasts.size());
13125            if (DEBUG_BROADCAST) {
13126                int seq = r.intent.getIntExtra("seq", -1);
13127                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13128            }
13129            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13130            if (!replaced) {
13131                queue.enqueueOrderedBroadcastLocked(r);
13132                queue.scheduleBroadcastsLocked();
13133            }
13134        }
13135
13136        return ActivityManager.BROADCAST_SUCCESS;
13137    }
13138
13139    final Intent verifyBroadcastLocked(Intent intent) {
13140        // Refuse possible leaked file descriptors
13141        if (intent != null && intent.hasFileDescriptors() == true) {
13142            throw new IllegalArgumentException("File descriptors passed in Intent");
13143        }
13144
13145        int flags = intent.getFlags();
13146
13147        if (!mProcessesReady) {
13148            // if the caller really truly claims to know what they're doing, go
13149            // ahead and allow the broadcast without launching any receivers
13150            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13151                intent = new Intent(intent);
13152                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13153            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13154                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13155                        + " before boot completion");
13156                throw new IllegalStateException("Cannot broadcast before boot completed");
13157            }
13158        }
13159
13160        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13161            throw new IllegalArgumentException(
13162                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13163        }
13164
13165        return intent;
13166    }
13167
13168    public final int broadcastIntent(IApplicationThread caller,
13169            Intent intent, String resolvedType, IIntentReceiver resultTo,
13170            int resultCode, String resultData, Bundle map,
13171            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13172        enforceNotIsolatedCaller("broadcastIntent");
13173        synchronized(this) {
13174            intent = verifyBroadcastLocked(intent);
13175
13176            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13177            final int callingPid = Binder.getCallingPid();
13178            final int callingUid = Binder.getCallingUid();
13179            final long origId = Binder.clearCallingIdentity();
13180            int res = broadcastIntentLocked(callerApp,
13181                    callerApp != null ? callerApp.info.packageName : null,
13182                    intent, resolvedType, resultTo,
13183                    resultCode, resultData, map, requiredPermission, serialized, sticky,
13184                    callingPid, callingUid, userId);
13185            Binder.restoreCallingIdentity(origId);
13186            return res;
13187        }
13188    }
13189
13190    int broadcastIntentInPackage(String packageName, int uid,
13191            Intent intent, String resolvedType, IIntentReceiver resultTo,
13192            int resultCode, String resultData, Bundle map,
13193            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13194        synchronized(this) {
13195            intent = verifyBroadcastLocked(intent);
13196
13197            final long origId = Binder.clearCallingIdentity();
13198            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13199                    resultTo, resultCode, resultData, map, requiredPermission,
13200                    serialized, sticky, -1, uid, userId);
13201            Binder.restoreCallingIdentity(origId);
13202            return res;
13203        }
13204    }
13205
13206    // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user.
13207    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13208        // Refuse possible leaked file descriptors
13209        if (intent != null && intent.hasFileDescriptors() == true) {
13210            throw new IllegalArgumentException("File descriptors passed in Intent");
13211        }
13212
13213        synchronized(this) {
13214            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13215                    != PackageManager.PERMISSION_GRANTED) {
13216                String msg = "Permission Denial: unbroadcastIntent() from pid="
13217                        + Binder.getCallingPid()
13218                        + ", uid=" + Binder.getCallingUid()
13219                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13220                Slog.w(TAG, msg);
13221                throw new SecurityException(msg);
13222            }
13223            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
13224            if (list != null) {
13225                int N = list.size();
13226                int i;
13227                for (i=0; i<N; i++) {
13228                    if (intent.filterEquals(list.get(i))) {
13229                        list.remove(i);
13230                        break;
13231                    }
13232                }
13233            }
13234        }
13235    }
13236
13237    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13238            String resultData, Bundle resultExtras, boolean resultAbort,
13239            boolean explicit) {
13240        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13241        if (r == null) {
13242            Slog.w(TAG, "finishReceiver called but not found on queue");
13243            return false;
13244        }
13245
13246        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
13247                explicit);
13248    }
13249
13250    public void finishReceiver(IBinder who, int resultCode, String resultData,
13251            Bundle resultExtras, boolean resultAbort) {
13252        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13253
13254        // Refuse possible leaked file descriptors
13255        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13256            throw new IllegalArgumentException("File descriptors passed in Bundle");
13257        }
13258
13259        final long origId = Binder.clearCallingIdentity();
13260        try {
13261            boolean doNext = false;
13262            BroadcastRecord r = null;
13263
13264            synchronized(this) {
13265                r = broadcastRecordForReceiverLocked(who);
13266                if (r != null) {
13267                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13268                        resultData, resultExtras, resultAbort, true);
13269                }
13270            }
13271
13272            if (doNext) {
13273                r.queue.processNextBroadcast(false);
13274            }
13275            trimApplications();
13276        } finally {
13277            Binder.restoreCallingIdentity(origId);
13278        }
13279    }
13280
13281    // =========================================================
13282    // INSTRUMENTATION
13283    // =========================================================
13284
13285    public boolean startInstrumentation(ComponentName className,
13286            String profileFile, int flags, Bundle arguments,
13287            IInstrumentationWatcher watcher) {
13288        enforceNotIsolatedCaller("startInstrumentation");
13289        // Refuse possible leaked file descriptors
13290        if (arguments != null && arguments.hasFileDescriptors()) {
13291            throw new IllegalArgumentException("File descriptors passed in Bundle");
13292        }
13293
13294        synchronized(this) {
13295            InstrumentationInfo ii = null;
13296            ApplicationInfo ai = null;
13297            try {
13298                ii = mContext.getPackageManager().getInstrumentationInfo(
13299                    className, STOCK_PM_FLAGS);
13300                ai = mContext.getPackageManager().getApplicationInfo(
13301                        ii.targetPackage, STOCK_PM_FLAGS);
13302            } catch (PackageManager.NameNotFoundException e) {
13303            }
13304            if (ii == null) {
13305                reportStartInstrumentationFailure(watcher, className,
13306                        "Unable to find instrumentation info for: " + className);
13307                return false;
13308            }
13309            if (ai == null) {
13310                reportStartInstrumentationFailure(watcher, className,
13311                        "Unable to find instrumentation target package: " + ii.targetPackage);
13312                return false;
13313            }
13314
13315            int match = mContext.getPackageManager().checkSignatures(
13316                    ii.targetPackage, ii.packageName);
13317            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13318                String msg = "Permission Denial: starting instrumentation "
13319                        + className + " from pid="
13320                        + Binder.getCallingPid()
13321                        + ", uid=" + Binder.getCallingPid()
13322                        + " not allowed because package " + ii.packageName
13323                        + " does not have a signature matching the target "
13324                        + ii.targetPackage;
13325                reportStartInstrumentationFailure(watcher, className, msg);
13326                throw new SecurityException(msg);
13327            }
13328
13329            int userId = UserId.getCallingUserId();
13330            final long origId = Binder.clearCallingIdentity();
13331            // Instrumentation can kill and relaunch even persistent processes
13332            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
13333            ProcessRecord app = addAppLocked(ai, false);
13334            app.instrumentationClass = className;
13335            app.instrumentationInfo = ai;
13336            app.instrumentationProfileFile = profileFile;
13337            app.instrumentationArguments = arguments;
13338            app.instrumentationWatcher = watcher;
13339            app.instrumentationResultClass = className;
13340            Binder.restoreCallingIdentity(origId);
13341        }
13342
13343        return true;
13344    }
13345
13346    /**
13347     * Report errors that occur while attempting to start Instrumentation.  Always writes the
13348     * error to the logs, but if somebody is watching, send the report there too.  This enables
13349     * the "am" command to report errors with more information.
13350     *
13351     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
13352     * @param cn The component name of the instrumentation.
13353     * @param report The error report.
13354     */
13355    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13356            ComponentName cn, String report) {
13357        Slog.w(TAG, report);
13358        try {
13359            if (watcher != null) {
13360                Bundle results = new Bundle();
13361                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13362                results.putString("Error", report);
13363                watcher.instrumentationStatus(cn, -1, results);
13364            }
13365        } catch (RemoteException e) {
13366            Slog.w(TAG, e);
13367        }
13368    }
13369
13370    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13371        if (app.instrumentationWatcher != null) {
13372            try {
13373                // NOTE:  IInstrumentationWatcher *must* be oneway here
13374                app.instrumentationWatcher.instrumentationFinished(
13375                    app.instrumentationClass,
13376                    resultCode,
13377                    results);
13378            } catch (RemoteException e) {
13379            }
13380        }
13381        app.instrumentationWatcher = null;
13382        app.instrumentationClass = null;
13383        app.instrumentationInfo = null;
13384        app.instrumentationProfileFile = null;
13385        app.instrumentationArguments = null;
13386
13387        forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId);
13388    }
13389
13390    public void finishInstrumentation(IApplicationThread target,
13391            int resultCode, Bundle results) {
13392        int userId = UserId.getCallingUserId();
13393        // Refuse possible leaked file descriptors
13394        if (results != null && results.hasFileDescriptors()) {
13395            throw new IllegalArgumentException("File descriptors passed in Intent");
13396        }
13397
13398        synchronized(this) {
13399            ProcessRecord app = getRecordForAppLocked(target);
13400            if (app == null) {
13401                Slog.w(TAG, "finishInstrumentation: no app for " + target);
13402                return;
13403            }
13404            final long origId = Binder.clearCallingIdentity();
13405            finishInstrumentationLocked(app, resultCode, results);
13406            Binder.restoreCallingIdentity(origId);
13407        }
13408    }
13409
13410    // =========================================================
13411    // CONFIGURATION
13412    // =========================================================
13413
13414    public ConfigurationInfo getDeviceConfigurationInfo() {
13415        ConfigurationInfo config = new ConfigurationInfo();
13416        synchronized (this) {
13417            config.reqTouchScreen = mConfiguration.touchscreen;
13418            config.reqKeyboardType = mConfiguration.keyboard;
13419            config.reqNavigation = mConfiguration.navigation;
13420            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13421                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
13422                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13423            }
13424            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13425                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
13426                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13427            }
13428            config.reqGlEsVersion = GL_ES_VERSION;
13429        }
13430        return config;
13431    }
13432
13433    public Configuration getConfiguration() {
13434        Configuration ci;
13435        synchronized(this) {
13436            ci = new Configuration(mConfiguration);
13437        }
13438        return ci;
13439    }
13440
13441    public void updatePersistentConfiguration(Configuration values) {
13442        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13443                "updateConfiguration()");
13444        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13445                "updateConfiguration()");
13446        if (values == null) {
13447            throw new NullPointerException("Configuration must not be null");
13448        }
13449
13450        synchronized(this) {
13451            final long origId = Binder.clearCallingIdentity();
13452            updateConfigurationLocked(values, null, true, false);
13453            Binder.restoreCallingIdentity(origId);
13454        }
13455    }
13456
13457    public void updateConfiguration(Configuration values) {
13458        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13459                "updateConfiguration()");
13460
13461        synchronized(this) {
13462            if (values == null && mWindowManager != null) {
13463                // sentinel: fetch the current configuration from the window manager
13464                values = mWindowManager.computeNewConfiguration();
13465            }
13466
13467            if (mWindowManager != null) {
13468                mProcessList.applyDisplaySize(mWindowManager);
13469            }
13470
13471            final long origId = Binder.clearCallingIdentity();
13472            if (values != null) {
13473                Settings.System.clearConfiguration(values);
13474            }
13475            updateConfigurationLocked(values, null, false, false);
13476            Binder.restoreCallingIdentity(origId);
13477        }
13478    }
13479
13480    /**
13481     * Do either or both things: (1) change the current configuration, and (2)
13482     * make sure the given activity is running with the (now) current
13483     * configuration.  Returns true if the activity has been left running, or
13484     * false if <var>starting</var> is being destroyed to match the new
13485     * configuration.
13486     * @param persistent TODO
13487     */
13488    boolean updateConfigurationLocked(Configuration values,
13489            ActivityRecord starting, boolean persistent, boolean initLocale) {
13490        // do nothing if we are headless
13491        if (mHeadless) return true;
13492
13493        int changes = 0;
13494
13495        boolean kept = true;
13496
13497        if (values != null) {
13498            Configuration newConfig = new Configuration(mConfiguration);
13499            changes = newConfig.updateFrom(values);
13500            if (changes != 0) {
13501                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
13502                    Slog.i(TAG, "Updating configuration to: " + values);
13503                }
13504
13505                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
13506
13507                if (values.locale != null && !initLocale) {
13508                    saveLocaleLocked(values.locale,
13509                                     !values.locale.equals(mConfiguration.locale),
13510                                     values.userSetLocale);
13511                }
13512
13513                mConfigurationSeq++;
13514                if (mConfigurationSeq <= 0) {
13515                    mConfigurationSeq = 1;
13516                }
13517                newConfig.seq = mConfigurationSeq;
13518                mConfiguration = newConfig;
13519                Slog.i(TAG, "Config changed: " + newConfig);
13520
13521                final Configuration configCopy = new Configuration(mConfiguration);
13522
13523                // TODO: If our config changes, should we auto dismiss any currently
13524                // showing dialogs?
13525                mShowDialogs = shouldShowDialogs(newConfig);
13526
13527                AttributeCache ac = AttributeCache.instance();
13528                if (ac != null) {
13529                    ac.updateConfiguration(configCopy);
13530                }
13531
13532                // Make sure all resources in our process are updated
13533                // right now, so that anyone who is going to retrieve
13534                // resource values after we return will be sure to get
13535                // the new ones.  This is especially important during
13536                // boot, where the first config change needs to guarantee
13537                // all resources have that config before following boot
13538                // code is executed.
13539                mSystemThread.applyConfigurationToResources(configCopy);
13540
13541                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
13542                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
13543                    msg.obj = new Configuration(configCopy);
13544                    mHandler.sendMessage(msg);
13545                }
13546
13547                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13548                    ProcessRecord app = mLruProcesses.get(i);
13549                    try {
13550                        if (app.thread != null) {
13551                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
13552                                    + app.processName + " new config " + mConfiguration);
13553                            app.thread.scheduleConfigurationChanged(configCopy);
13554                        }
13555                    } catch (Exception e) {
13556                    }
13557                }
13558                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
13559                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13560                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
13561                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
13562                        null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
13563                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
13564                    broadcastIntentLocked(null, null,
13565                            new Intent(Intent.ACTION_LOCALE_CHANGED),
13566                            null, null, 0, null, null,
13567                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
13568                }
13569            }
13570        }
13571
13572        if (changes != 0 && starting == null) {
13573            // If the configuration changed, and the caller is not already
13574            // in the process of starting an activity, then find the top
13575            // activity to check if its configuration needs to change.
13576            starting = mMainStack.topRunningActivityLocked(null);
13577        }
13578
13579        if (starting != null) {
13580            kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
13581            // And we need to make sure at this point that all other activities
13582            // are made visible with the correct configuration.
13583            mMainStack.ensureActivitiesVisibleLocked(starting, changes);
13584        }
13585
13586        if (values != null && mWindowManager != null) {
13587            mWindowManager.setNewConfiguration(mConfiguration);
13588        }
13589
13590        return kept;
13591    }
13592
13593    /**
13594     * Decide based on the configuration whether we should shouw the ANR,
13595     * crash, etc dialogs.  The idea is that if there is no affordnace to
13596     * press the on-screen buttons, we shouldn't show the dialog.
13597     *
13598     * A thought: SystemUI might also want to get told about this, the Power
13599     * dialog / global actions also might want different behaviors.
13600     */
13601    private static final boolean shouldShowDialogs(Configuration config) {
13602        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
13603                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
13604    }
13605
13606    /**
13607     * Save the locale.  You must be inside a synchronized (this) block.
13608     */
13609    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
13610        if(isDiff) {
13611            SystemProperties.set("user.language", l.getLanguage());
13612            SystemProperties.set("user.region", l.getCountry());
13613        }
13614
13615        if(isPersist) {
13616            SystemProperties.set("persist.sys.language", l.getLanguage());
13617            SystemProperties.set("persist.sys.country", l.getCountry());
13618            SystemProperties.set("persist.sys.localevar", l.getVariant());
13619        }
13620    }
13621
13622    @Override
13623    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
13624        ActivityRecord srec = ActivityRecord.forToken(token);
13625        return srec != null && srec.task.affinity != null &&
13626                srec.task.affinity.equals(destAffinity);
13627    }
13628
13629    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
13630            Intent resultData) {
13631        ComponentName dest = destIntent.getComponent();
13632
13633        synchronized (this) {
13634            ActivityRecord srec = ActivityRecord.forToken(token);
13635            if (srec == null) {
13636                return false;
13637            }
13638            ArrayList<ActivityRecord> history = srec.stack.mHistory;
13639            final int start = history.indexOf(srec);
13640            if (start < 0) {
13641                // Current activity is not in history stack; do nothing.
13642                return false;
13643            }
13644            int finishTo = start - 1;
13645            ActivityRecord parent = null;
13646            boolean foundParentInTask = false;
13647            if (dest != null) {
13648                TaskRecord tr = srec.task;
13649                for (int i = start - 1; i >= 0; i--) {
13650                    ActivityRecord r = history.get(i);
13651                    if (tr != r.task) {
13652                        // Couldn't find parent in the same task; stop at the one above this.
13653                        // (Root of current task; in-app "home" behavior)
13654                        // Always at least finish the current activity.
13655                        finishTo = Math.min(start - 1, i + 1);
13656                        parent = history.get(finishTo);
13657                        break;
13658                    } else if (r.info.packageName.equals(dest.getPackageName()) &&
13659                            r.info.name.equals(dest.getClassName())) {
13660                        finishTo = i;
13661                        parent = r;
13662                        foundParentInTask = true;
13663                        break;
13664                    }
13665                }
13666            }
13667
13668            if (mController != null) {
13669                ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
13670                if (next != null) {
13671                    // ask watcher if this is allowed
13672                    boolean resumeOK = true;
13673                    try {
13674                        resumeOK = mController.activityResuming(next.packageName);
13675                    } catch (RemoteException e) {
13676                        mController = null;
13677                    }
13678
13679                    if (!resumeOK) {
13680                        return false;
13681                    }
13682                }
13683            }
13684            final long origId = Binder.clearCallingIdentity();
13685            for (int i = start; i > finishTo; i--) {
13686                ActivityRecord r = history.get(i);
13687                mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
13688                        "navigate-up");
13689                // Only return the supplied result for the first activity finished
13690                resultCode = Activity.RESULT_CANCELED;
13691                resultData = null;
13692            }
13693
13694            if (parent != null && foundParentInTask) {
13695                final int parentLaunchMode = parent.info.launchMode;
13696                final int destIntentFlags = destIntent.getFlags();
13697                if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
13698                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
13699                        parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
13700                        (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
13701                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
13702                } else {
13703                    try {
13704                        ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
13705                                destIntent.getComponent(), 0, UserId.getCallingUserId());
13706                        int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
13707                                null, aInfo, parent.appToken, null,
13708                                0, -1, parent.launchedFromUid, 0, null, true, null);
13709                        foundParentInTask = res == ActivityManager.START_SUCCESS;
13710                    } catch (RemoteException e) {
13711                        foundParentInTask = false;
13712                    }
13713                    mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
13714                            resultData, "navigate-up");
13715                }
13716            }
13717            Binder.restoreCallingIdentity(origId);
13718            return foundParentInTask;
13719        }
13720    }
13721
13722    public int getLaunchedFromUid(IBinder activityToken) {
13723        ActivityRecord srec = ActivityRecord.forToken(activityToken);
13724        if (srec == null) {
13725            return -1;
13726        }
13727        return srec.launchedFromUid;
13728    }
13729
13730    // =========================================================
13731    // LIFETIME MANAGEMENT
13732    // =========================================================
13733
13734    // Returns which broadcast queue the app is the current [or imminent] receiver
13735    // on, or 'null' if the app is not an active broadcast recipient.
13736    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
13737        BroadcastRecord r = app.curReceiver;
13738        if (r != null) {
13739            return r.queue;
13740        }
13741
13742        // It's not the current receiver, but it might be starting up to become one
13743        synchronized (this) {
13744            for (BroadcastQueue queue : mBroadcastQueues) {
13745                r = queue.mPendingBroadcast;
13746                if (r != null && r.curApp == app) {
13747                    // found it; report which queue it's in
13748                    return queue;
13749                }
13750            }
13751        }
13752
13753        return null;
13754    }
13755
13756    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
13757            ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
13758        if (mAdjSeq == app.adjSeq) {
13759            // This adjustment has already been computed.  If we are calling
13760            // from the top, we may have already computed our adjustment with
13761            // an earlier hidden adjustment that isn't really for us... if
13762            // so, use the new hidden adjustment.
13763            if (!recursed && app.hidden) {
13764                app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
13765            }
13766            return app.curRawAdj;
13767        }
13768
13769        if (app.thread == null) {
13770            app.adjSeq = mAdjSeq;
13771            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13772            return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
13773        }
13774
13775        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
13776        app.adjSource = null;
13777        app.adjTarget = null;
13778        app.empty = false;
13779        app.hidden = false;
13780
13781        final int activitiesSize = app.activities.size();
13782
13783        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
13784            // The max adjustment doesn't allow this app to be anything
13785            // below foreground, so it is not worth doing work for it.
13786            app.adjType = "fixed";
13787            app.adjSeq = mAdjSeq;
13788            app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
13789            app.foregroundActivities = false;
13790            app.keeping = true;
13791            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
13792            // System process can do UI, and when they do we want to have
13793            // them trim their memory after the user leaves the UI.  To
13794            // facilitate this, here we need to determine whether or not it
13795            // is currently showing UI.
13796            app.systemNoUi = true;
13797            if (app == TOP_APP) {
13798                app.systemNoUi = false;
13799            } else if (activitiesSize > 0) {
13800                for (int j = 0; j < activitiesSize; j++) {
13801                    final ActivityRecord r = app.activities.get(j);
13802                    if (r.visible) {
13803                        app.systemNoUi = false;
13804                        break;
13805                    }
13806                }
13807            }
13808            return (app.curAdj=app.maxAdj);
13809        }
13810
13811        app.keeping = false;
13812        app.systemNoUi = false;
13813
13814        // Determine the importance of the process, starting with most
13815        // important to least, and assign an appropriate OOM adjustment.
13816        int adj;
13817        int schedGroup;
13818        boolean foregroundActivities = false;
13819        boolean interesting = false;
13820        BroadcastQueue queue;
13821        if (app == TOP_APP) {
13822            // The last app on the list is the foreground app.
13823            adj = ProcessList.FOREGROUND_APP_ADJ;
13824            schedGroup = Process.THREAD_GROUP_DEFAULT;
13825            app.adjType = "top-activity";
13826            foregroundActivities = true;
13827            interesting = true;
13828        } else if (app.instrumentationClass != null) {
13829            // Don't want to kill running instrumentation.
13830            adj = ProcessList.FOREGROUND_APP_ADJ;
13831            schedGroup = Process.THREAD_GROUP_DEFAULT;
13832            app.adjType = "instrumentation";
13833            interesting = true;
13834        } else if ((queue = isReceivingBroadcast(app)) != null) {
13835            // An app that is currently receiving a broadcast also
13836            // counts as being in the foreground for OOM killer purposes.
13837            // It's placed in a sched group based on the nature of the
13838            // broadcast as reflected by which queue it's active in.
13839            adj = ProcessList.FOREGROUND_APP_ADJ;
13840            schedGroup = (queue == mFgBroadcastQueue)
13841                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
13842            app.adjType = "broadcast";
13843        } else if (app.executingServices.size() > 0) {
13844            // An app that is currently executing a service callback also
13845            // counts as being in the foreground.
13846            adj = ProcessList.FOREGROUND_APP_ADJ;
13847            schedGroup = Process.THREAD_GROUP_DEFAULT;
13848            app.adjType = "exec-service";
13849        } else if (activitiesSize > 0) {
13850            // This app is in the background with paused activities.
13851            // We inspect activities to potentially upgrade adjustment further below.
13852            adj = hiddenAdj;
13853            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13854            app.hidden = true;
13855            app.adjType = "bg-activities";
13856        } else {
13857            // A very not-needed process.  If this is lower in the lru list,
13858            // we will push it in to the empty bucket.
13859            adj = hiddenAdj;
13860            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13861            app.hidden = true;
13862            app.empty = true;
13863            app.adjType = "bg-empty";
13864        }
13865
13866        boolean hasStoppingActivities = false;
13867
13868        // Examine all activities if not already foreground.
13869        if (!foregroundActivities && activitiesSize > 0) {
13870            for (int j = 0; j < activitiesSize; j++) {
13871                final ActivityRecord r = app.activities.get(j);
13872                if (r.visible) {
13873                    // App has a visible activity; only upgrade adjustment.
13874                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
13875                        adj = ProcessList.VISIBLE_APP_ADJ;
13876                        app.adjType = "visible";
13877                    }
13878                    schedGroup = Process.THREAD_GROUP_DEFAULT;
13879                    app.hidden = false;
13880                    foregroundActivities = true;
13881                    break;
13882                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
13883                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13884                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13885                        app.adjType = "pausing";
13886                    }
13887                    app.hidden = false;
13888                    foregroundActivities = true;
13889                } else if (r.state == ActivityState.STOPPING) {
13890                    // We will apply the actual adjustment later, because
13891                    // we want to allow this process to immediately go through
13892                    // any memory trimming that is in effect.
13893                    app.hidden = false;
13894                    foregroundActivities = true;
13895                    hasStoppingActivities = true;
13896                }
13897            }
13898        }
13899
13900        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13901            if (app.foregroundServices) {
13902                // The user is aware of this app, so make it visible.
13903                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13904                app.hidden = false;
13905                app.adjType = "foreground-service";
13906                schedGroup = Process.THREAD_GROUP_DEFAULT;
13907            } else if (app.forcingToForeground != null) {
13908                // The user is aware of this app, so make it visible.
13909                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13910                app.hidden = false;
13911                app.adjType = "force-foreground";
13912                app.adjSource = app.forcingToForeground;
13913                schedGroup = Process.THREAD_GROUP_DEFAULT;
13914            }
13915        }
13916
13917        if (app.foregroundServices) {
13918            interesting = true;
13919        }
13920
13921        if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
13922            // We don't want to kill the current heavy-weight process.
13923            adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
13924            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13925            app.hidden = false;
13926            app.adjType = "heavy";
13927        }
13928
13929        if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
13930            // This process is hosting what we currently consider to be the
13931            // home app, so we don't want to let it go into the background.
13932            adj = ProcessList.HOME_APP_ADJ;
13933            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13934            app.hidden = false;
13935            app.adjType = "home";
13936        }
13937
13938        if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
13939                && app.activities.size() > 0) {
13940            // This was the previous process that showed UI to the user.
13941            // We want to try to keep it around more aggressively, to give
13942            // a good experience around switching between two apps.
13943            adj = ProcessList.PREVIOUS_APP_ADJ;
13944            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13945            app.hidden = false;
13946            app.adjType = "previous";
13947        }
13948
13949        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
13950                + " reason=" + app.adjType);
13951
13952        // By default, we use the computed adjustment.  It may be changed if
13953        // there are applications dependent on our services or providers, but
13954        // this gives us a baseline and makes sure we don't get into an
13955        // infinite recursion.
13956        app.adjSeq = mAdjSeq;
13957        app.curRawAdj = app.nonStoppingAdj = adj;
13958
13959        if (mBackupTarget != null && app == mBackupTarget.app) {
13960            // If possible we want to avoid killing apps while they're being backed up
13961            if (adj > ProcessList.BACKUP_APP_ADJ) {
13962                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
13963                adj = ProcessList.BACKUP_APP_ADJ;
13964                app.adjType = "backup";
13965                app.hidden = false;
13966            }
13967        }
13968
13969        if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13970                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13971            final long now = SystemClock.uptimeMillis();
13972            // This process is more important if the top activity is
13973            // bound to the service.
13974            Iterator<ServiceRecord> jt = app.services.iterator();
13975            while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
13976                ServiceRecord s = jt.next();
13977                if (s.startRequested) {
13978                    if (app.hasShownUi && app != mHomeProcess) {
13979                        // If this process has shown some UI, let it immediately
13980                        // go to the LRU list because it may be pretty heavy with
13981                        // UI stuff.  We'll tag it with a label just to help
13982                        // debug and understand what is going on.
13983                        if (adj > ProcessList.SERVICE_ADJ) {
13984                            app.adjType = "started-bg-ui-services";
13985                        }
13986                    } else {
13987                        if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13988                            // This service has seen some activity within
13989                            // recent memory, so we will keep its process ahead
13990                            // of the background processes.
13991                            if (adj > ProcessList.SERVICE_ADJ) {
13992                                adj = ProcessList.SERVICE_ADJ;
13993                                app.adjType = "started-services";
13994                                app.hidden = false;
13995                            }
13996                        }
13997                        // If we have let the service slide into the background
13998                        // state, still have some text describing what it is doing
13999                        // even though the service no longer has an impact.
14000                        if (adj > ProcessList.SERVICE_ADJ) {
14001                            app.adjType = "started-bg-services";
14002                        }
14003                    }
14004                    // Don't kill this process because it is doing work; it
14005                    // has said it is doing work.
14006                    app.keeping = true;
14007                }
14008                if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14009                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
14010                    Iterator<ArrayList<ConnectionRecord>> kt
14011                            = s.connections.values().iterator();
14012                    while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
14013                        ArrayList<ConnectionRecord> clist = kt.next();
14014                        for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
14015                            // XXX should compute this based on the max of
14016                            // all connected clients.
14017                            ConnectionRecord cr = clist.get(i);
14018                            if (cr.binding.client == app) {
14019                                // Binding to ourself is not interesting.
14020                                continue;
14021                            }
14022                            if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14023                                ProcessRecord client = cr.binding.client;
14024                                int clientAdj = adj;
14025                                int myHiddenAdj = hiddenAdj;
14026                                if (myHiddenAdj > client.hiddenAdj) {
14027                                    if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
14028                                        myHiddenAdj = client.hiddenAdj;
14029                                    } else {
14030                                        myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
14031                                    }
14032                                }
14033                                clientAdj = computeOomAdjLocked(
14034                                    client, myHiddenAdj, TOP_APP, true, doingAll);
14035                                String adjType = null;
14036                                if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14037                                    // Not doing bind OOM management, so treat
14038                                    // this guy more like a started service.
14039                                    if (app.hasShownUi && app != mHomeProcess) {
14040                                        // If this process has shown some UI, let it immediately
14041                                        // go to the LRU list because it may be pretty heavy with
14042                                        // UI stuff.  We'll tag it with a label just to help
14043                                        // debug and understand what is going on.
14044                                        if (adj > clientAdj) {
14045                                            adjType = "bound-bg-ui-services";
14046                                        }
14047                                        app.hidden = false;
14048                                        clientAdj = adj;
14049                                    } else {
14050                                        if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
14051                                            // This service has not seen activity within
14052                                            // recent memory, so allow it to drop to the
14053                                            // LRU list if there is no other reason to keep
14054                                            // it around.  We'll also tag it with a label just
14055                                            // to help debug and undertand what is going on.
14056                                            if (adj > clientAdj) {
14057                                                adjType = "bound-bg-services";
14058                                            }
14059                                            clientAdj = adj;
14060                                        }
14061                                    }
14062                                }
14063                                if (adj > clientAdj) {
14064                                    // If this process has recently shown UI, and
14065                                    // the process that is binding to it is less
14066                                    // important than being visible, then we don't
14067                                    // care about the binding as much as we care
14068                                    // about letting this process get into the LRU
14069                                    // list to be killed and restarted if needed for
14070                                    // memory.
14071                                    if (app.hasShownUi && app != mHomeProcess
14072                                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14073                                        adjType = "bound-bg-ui-services";
14074                                    } else {
14075                                        if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14076                                                |Context.BIND_IMPORTANT)) != 0) {
14077                                            adj = clientAdj;
14078                                        } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14079                                                && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14080                                                && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14081                                            adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14082                                        } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14083                                            adj = clientAdj;
14084                                        } else {
14085                                            app.pendingUiClean = true;
14086                                            if (adj > ProcessList.VISIBLE_APP_ADJ) {
14087                                                adj = ProcessList.VISIBLE_APP_ADJ;
14088                                            }
14089                                        }
14090                                        if (!client.hidden) {
14091                                            app.hidden = false;
14092                                        }
14093                                        if (client.keeping) {
14094                                            app.keeping = true;
14095                                        }
14096                                        adjType = "service";
14097                                    }
14098                                }
14099                                if (adjType != null) {
14100                                    app.adjType = adjType;
14101                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14102                                            .REASON_SERVICE_IN_USE;
14103                                    app.adjSource = cr.binding.client;
14104                                    app.adjSourceOom = clientAdj;
14105                                    app.adjTarget = s.name;
14106                                }
14107                                if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14108                                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14109                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
14110                                    }
14111                                }
14112                            }
14113                            if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14114                                ActivityRecord a = cr.activity;
14115                                if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14116                                        (a.visible || a.state == ActivityState.RESUMED
14117                                         || a.state == ActivityState.PAUSING)) {
14118                                    adj = ProcessList.FOREGROUND_APP_ADJ;
14119                                    if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14120                                        schedGroup = Process.THREAD_GROUP_DEFAULT;
14121                                    }
14122                                    app.hidden = false;
14123                                    app.adjType = "service";
14124                                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14125                                            .REASON_SERVICE_IN_USE;
14126                                    app.adjSource = a;
14127                                    app.adjSourceOom = adj;
14128                                    app.adjTarget = s.name;
14129                                }
14130                            }
14131                        }
14132                    }
14133                }
14134            }
14135
14136            // Finally, if this process has active services running in it, we
14137            // would like to avoid killing it unless it would prevent the current
14138            // application from running.  By default we put the process in
14139            // with the rest of the background processes; as we scan through
14140            // its services we may bump it up from there.
14141            if (adj > hiddenAdj) {
14142                adj = hiddenAdj;
14143                app.hidden = false;
14144                app.adjType = "bg-services";
14145            }
14146        }
14147
14148        if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14149                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
14150            Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
14151            while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
14152                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
14153                ContentProviderRecord cpr = jt.next();
14154                for (int i = cpr.connections.size()-1;
14155                        i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14156                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
14157                        i--) {
14158                    ContentProviderConnection conn = cpr.connections.get(i);
14159                    ProcessRecord client = conn.client;
14160                    if (client == app) {
14161                        // Being our own client is not interesting.
14162                        continue;
14163                    }
14164                    int myHiddenAdj = hiddenAdj;
14165                    if (myHiddenAdj > client.hiddenAdj) {
14166                        if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
14167                            myHiddenAdj = client.hiddenAdj;
14168                        } else {
14169                            myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
14170                        }
14171                    }
14172                    int clientAdj = computeOomAdjLocked(
14173                        client, myHiddenAdj, TOP_APP, true, doingAll);
14174                    if (adj > clientAdj) {
14175                        if (app.hasShownUi && app != mHomeProcess
14176                                && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14177                            app.adjType = "bg-ui-provider";
14178                        } else {
14179                            adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14180                                    ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14181                            app.adjType = "provider";
14182                        }
14183                        if (!client.hidden) {
14184                            app.hidden = false;
14185                        }
14186                        if (client.keeping) {
14187                            app.keeping = true;
14188                        }
14189                        app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14190                                .REASON_PROVIDER_IN_USE;
14191                        app.adjSource = client;
14192                        app.adjSourceOom = clientAdj;
14193                        app.adjTarget = cpr.name;
14194                    }
14195                    if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14196                        schedGroup = Process.THREAD_GROUP_DEFAULT;
14197                    }
14198                }
14199                // If the provider has external (non-framework) process
14200                // dependencies, ensure that its adjustment is at least
14201                // FOREGROUND_APP_ADJ.
14202                if (cpr.hasExternalProcessHandles()) {
14203                    if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14204                        adj = ProcessList.FOREGROUND_APP_ADJ;
14205                        schedGroup = Process.THREAD_GROUP_DEFAULT;
14206                        app.hidden = false;
14207                        app.keeping = true;
14208                        app.adjType = "provider";
14209                        app.adjTarget = cpr.name;
14210                    }
14211                }
14212            }
14213        }
14214
14215        if (adj == ProcessList.SERVICE_ADJ) {
14216            if (doingAll) {
14217                app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
14218                mNewNumServiceProcs++;
14219            }
14220            if (app.serviceb) {
14221                adj = ProcessList.SERVICE_B_ADJ;
14222            }
14223        } else {
14224            app.serviceb = false;
14225        }
14226
14227        app.nonStoppingAdj = adj;
14228
14229        if (hasStoppingActivities) {
14230            // Only upgrade adjustment.
14231            if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14232                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14233                app.adjType = "stopping";
14234            }
14235        }
14236
14237        app.curRawAdj = adj;
14238
14239        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
14240        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14241        if (adj > app.maxAdj) {
14242            adj = app.maxAdj;
14243            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
14244                schedGroup = Process.THREAD_GROUP_DEFAULT;
14245            }
14246        }
14247        if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14248            app.keeping = true;
14249        }
14250
14251        if (app.hasAboveClient) {
14252            // If this process has bound to any services with BIND_ABOVE_CLIENT,
14253            // then we need to drop its adjustment to be lower than the service's
14254            // in order to honor the request.  We want to drop it by one adjustment
14255            // level...  but there is special meaning applied to various levels so
14256            // we will skip some of them.
14257            if (adj < ProcessList.FOREGROUND_APP_ADJ) {
14258                // System process will not get dropped, ever
14259            } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
14260                adj = ProcessList.VISIBLE_APP_ADJ;
14261            } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
14262                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14263            } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14264                adj = ProcessList.HIDDEN_APP_MIN_ADJ;
14265            } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
14266                adj++;
14267            }
14268        }
14269
14270        int importance = app.memImportance;
14271        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
14272            app.curAdj = adj;
14273            app.curSchedGroup = schedGroup;
14274            if (!interesting) {
14275                // For this reporting, if there is not something explicitly
14276                // interesting in this process then we will push it to the
14277                // background importance.
14278                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14279            } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
14280                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14281            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
14282                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14283            } else if (adj >= ProcessList.HOME_APP_ADJ) {
14284                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14285            } else if (adj >= ProcessList.SERVICE_ADJ) {
14286                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14287            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14288                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
14289            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
14290                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
14291            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
14292                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
14293            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
14294                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
14295            } else {
14296                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
14297            }
14298        }
14299
14300        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
14301        if (foregroundActivities != app.foregroundActivities) {
14302            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
14303        }
14304        if (changes != 0) {
14305            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
14306            app.memImportance = importance;
14307            app.foregroundActivities = foregroundActivities;
14308            int i = mPendingProcessChanges.size()-1;
14309            ProcessChangeItem item = null;
14310            while (i >= 0) {
14311                item = mPendingProcessChanges.get(i);
14312                if (item.pid == app.pid) {
14313                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
14314                    break;
14315                }
14316                i--;
14317            }
14318            if (i < 0) {
14319                // No existing item in pending changes; need a new one.
14320                final int NA = mAvailProcessChanges.size();
14321                if (NA > 0) {
14322                    item = mAvailProcessChanges.remove(NA-1);
14323                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
14324                } else {
14325                    item = new ProcessChangeItem();
14326                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
14327                }
14328                item.changes = 0;
14329                item.pid = app.pid;
14330                item.uid = app.info.uid;
14331                if (mPendingProcessChanges.size() == 0) {
14332                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
14333                            "*** Enqueueing dispatch processes changed!");
14334                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
14335                }
14336                mPendingProcessChanges.add(item);
14337            }
14338            item.changes |= changes;
14339            item.importance = importance;
14340            item.foregroundActivities = foregroundActivities;
14341            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
14342                    + Integer.toHexString(System.identityHashCode(item))
14343                    + " " + app.toShortString() + ": changes=" + item.changes
14344                    + " importance=" + item.importance
14345                    + " foreground=" + item.foregroundActivities
14346                    + " type=" + app.adjType + " source=" + app.adjSource
14347                    + " target=" + app.adjTarget);
14348        }
14349
14350        return app.curRawAdj;
14351    }
14352
14353    /**
14354     * Ask a given process to GC right now.
14355     */
14356    final void performAppGcLocked(ProcessRecord app) {
14357        try {
14358            app.lastRequestedGc = SystemClock.uptimeMillis();
14359            if (app.thread != null) {
14360                if (app.reportLowMemory) {
14361                    app.reportLowMemory = false;
14362                    app.thread.scheduleLowMemory();
14363                } else {
14364                    app.thread.processInBackground();
14365                }
14366            }
14367        } catch (Exception e) {
14368            // whatever.
14369        }
14370    }
14371
14372    /**
14373     * Returns true if things are idle enough to perform GCs.
14374     */
14375    private final boolean canGcNowLocked() {
14376        boolean processingBroadcasts = false;
14377        for (BroadcastQueue q : mBroadcastQueues) {
14378            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
14379                processingBroadcasts = true;
14380            }
14381        }
14382        return !processingBroadcasts
14383                && (mSleeping || (mMainStack.mResumedActivity != null &&
14384                        mMainStack.mResumedActivity.idle));
14385    }
14386
14387    /**
14388     * Perform GCs on all processes that are waiting for it, but only
14389     * if things are idle.
14390     */
14391    final void performAppGcsLocked() {
14392        final int N = mProcessesToGc.size();
14393        if (N <= 0) {
14394            return;
14395        }
14396        if (canGcNowLocked()) {
14397            while (mProcessesToGc.size() > 0) {
14398                ProcessRecord proc = mProcessesToGc.remove(0);
14399                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
14400                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14401                            <= SystemClock.uptimeMillis()) {
14402                        // To avoid spamming the system, we will GC processes one
14403                        // at a time, waiting a few seconds between each.
14404                        performAppGcLocked(proc);
14405                        scheduleAppGcsLocked();
14406                        return;
14407                    } else {
14408                        // It hasn't been long enough since we last GCed this
14409                        // process...  put it in the list to wait for its time.
14410                        addProcessToGcListLocked(proc);
14411                        break;
14412                    }
14413                }
14414            }
14415
14416            scheduleAppGcsLocked();
14417        }
14418    }
14419
14420    /**
14421     * If all looks good, perform GCs on all processes waiting for them.
14422     */
14423    final void performAppGcsIfAppropriateLocked() {
14424        if (canGcNowLocked()) {
14425            performAppGcsLocked();
14426            return;
14427        }
14428        // Still not idle, wait some more.
14429        scheduleAppGcsLocked();
14430    }
14431
14432    /**
14433     * Schedule the execution of all pending app GCs.
14434     */
14435    final void scheduleAppGcsLocked() {
14436        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
14437
14438        if (mProcessesToGc.size() > 0) {
14439            // Schedule a GC for the time to the next process.
14440            ProcessRecord proc = mProcessesToGc.get(0);
14441            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
14442
14443            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
14444            long now = SystemClock.uptimeMillis();
14445            if (when < (now+GC_TIMEOUT)) {
14446                when = now + GC_TIMEOUT;
14447            }
14448            mHandler.sendMessageAtTime(msg, when);
14449        }
14450    }
14451
14452    /**
14453     * Add a process to the array of processes waiting to be GCed.  Keeps the
14454     * list in sorted order by the last GC time.  The process can't already be
14455     * on the list.
14456     */
14457    final void addProcessToGcListLocked(ProcessRecord proc) {
14458        boolean added = false;
14459        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
14460            if (mProcessesToGc.get(i).lastRequestedGc <
14461                    proc.lastRequestedGc) {
14462                added = true;
14463                mProcessesToGc.add(i+1, proc);
14464                break;
14465            }
14466        }
14467        if (!added) {
14468            mProcessesToGc.add(0, proc);
14469        }
14470    }
14471
14472    /**
14473     * Set up to ask a process to GC itself.  This will either do it
14474     * immediately, or put it on the list of processes to gc the next
14475     * time things are idle.
14476     */
14477    final void scheduleAppGcLocked(ProcessRecord app) {
14478        long now = SystemClock.uptimeMillis();
14479        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
14480            return;
14481        }
14482        if (!mProcessesToGc.contains(app)) {
14483            addProcessToGcListLocked(app);
14484            scheduleAppGcsLocked();
14485        }
14486    }
14487
14488    final void checkExcessivePowerUsageLocked(boolean doKills) {
14489        updateCpuStatsNow();
14490
14491        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14492        boolean doWakeKills = doKills;
14493        boolean doCpuKills = doKills;
14494        if (mLastPowerCheckRealtime == 0) {
14495            doWakeKills = false;
14496        }
14497        if (mLastPowerCheckUptime == 0) {
14498            doCpuKills = false;
14499        }
14500        if (stats.isScreenOn()) {
14501            doWakeKills = false;
14502        }
14503        final long curRealtime = SystemClock.elapsedRealtime();
14504        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
14505        final long curUptime = SystemClock.uptimeMillis();
14506        final long uptimeSince = curUptime - mLastPowerCheckUptime;
14507        mLastPowerCheckRealtime = curRealtime;
14508        mLastPowerCheckUptime = curUptime;
14509        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
14510            doWakeKills = false;
14511        }
14512        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
14513            doCpuKills = false;
14514        }
14515        int i = mLruProcesses.size();
14516        while (i > 0) {
14517            i--;
14518            ProcessRecord app = mLruProcesses.get(i);
14519            if (!app.keeping) {
14520                long wtime;
14521                synchronized (stats) {
14522                    wtime = stats.getProcessWakeTime(app.info.uid,
14523                            app.pid, curRealtime);
14524                }
14525                long wtimeUsed = wtime - app.lastWakeTime;
14526                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
14527                if (DEBUG_POWER) {
14528                    StringBuilder sb = new StringBuilder(128);
14529                    sb.append("Wake for ");
14530                    app.toShortString(sb);
14531                    sb.append(": over ");
14532                    TimeUtils.formatDuration(realtimeSince, sb);
14533                    sb.append(" used ");
14534                    TimeUtils.formatDuration(wtimeUsed, sb);
14535                    sb.append(" (");
14536                    sb.append((wtimeUsed*100)/realtimeSince);
14537                    sb.append("%)");
14538                    Slog.i(TAG, sb.toString());
14539                    sb.setLength(0);
14540                    sb.append("CPU for ");
14541                    app.toShortString(sb);
14542                    sb.append(": over ");
14543                    TimeUtils.formatDuration(uptimeSince, sb);
14544                    sb.append(" used ");
14545                    TimeUtils.formatDuration(cputimeUsed, sb);
14546                    sb.append(" (");
14547                    sb.append((cputimeUsed*100)/uptimeSince);
14548                    sb.append("%)");
14549                    Slog.i(TAG, sb.toString());
14550                }
14551                // If a process has held a wake lock for more
14552                // than 50% of the time during this period,
14553                // that sounds bad.  Kill!
14554                if (doWakeKills && realtimeSince > 0
14555                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
14556                    synchronized (stats) {
14557                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
14558                                realtimeSince, wtimeUsed);
14559                    }
14560                    Slog.w(TAG, "Excessive wake lock in " + app.processName
14561                            + " (pid " + app.pid + "): held " + wtimeUsed
14562                            + " during " + realtimeSince);
14563                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14564                            app.processName, app.setAdj, "excessive wake lock");
14565                    Process.killProcessQuiet(app.pid);
14566                } else if (doCpuKills && uptimeSince > 0
14567                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
14568                    synchronized (stats) {
14569                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
14570                                uptimeSince, cputimeUsed);
14571                    }
14572                    Slog.w(TAG, "Excessive CPU in " + app.processName
14573                            + " (pid " + app.pid + "): used " + cputimeUsed
14574                            + " during " + uptimeSince);
14575                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14576                            app.processName, app.setAdj, "excessive cpu");
14577                    Process.killProcessQuiet(app.pid);
14578                } else {
14579                    app.lastWakeTime = wtime;
14580                    app.lastCpuTime = app.curCpuTime;
14581                }
14582            }
14583        }
14584    }
14585
14586    private final boolean updateOomAdjLocked(
14587            ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
14588        app.hiddenAdj = hiddenAdj;
14589
14590        if (app.thread == null) {
14591            return false;
14592        }
14593
14594        final boolean wasKeeping = app.keeping;
14595
14596        boolean success = true;
14597
14598        computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
14599
14600        if (app.curRawAdj != app.setRawAdj) {
14601            if (wasKeeping && !app.keeping) {
14602                // This app is no longer something we want to keep.  Note
14603                // its current wake lock time to later know to kill it if
14604                // it is not behaving well.
14605                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14606                synchronized (stats) {
14607                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
14608                            app.pid, SystemClock.elapsedRealtime());
14609                }
14610                app.lastCpuTime = app.curCpuTime;
14611            }
14612
14613            app.setRawAdj = app.curRawAdj;
14614        }
14615
14616        if (app.curAdj != app.setAdj) {
14617            if (Process.setOomAdj(app.pid, app.curAdj)) {
14618                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
14619                    TAG, "Set " + app.pid + " " + app.processName +
14620                    " adj " + app.curAdj + ": " + app.adjType);
14621                app.setAdj = app.curAdj;
14622            } else {
14623                success = false;
14624                Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
14625            }
14626        }
14627        if (app.setSchedGroup != app.curSchedGroup) {
14628            app.setSchedGroup = app.curSchedGroup;
14629            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
14630                    "Setting process group of " + app.processName
14631                    + " to " + app.curSchedGroup);
14632            if (app.waitingToKill != null &&
14633                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
14634                Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
14635                EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14636                        app.processName, app.setAdj, app.waitingToKill);
14637                Process.killProcessQuiet(app.pid);
14638                success = false;
14639            } else {
14640                if (true) {
14641                    long oldId = Binder.clearCallingIdentity();
14642                    try {
14643                        Process.setProcessGroup(app.pid, app.curSchedGroup);
14644                    } catch (Exception e) {
14645                        Slog.w(TAG, "Failed setting process group of " + app.pid
14646                                + " to " + app.curSchedGroup);
14647                        e.printStackTrace();
14648                    } finally {
14649                        Binder.restoreCallingIdentity(oldId);
14650                    }
14651                } else {
14652                    if (app.thread != null) {
14653                        try {
14654                            app.thread.setSchedulingGroup(app.curSchedGroup);
14655                        } catch (RemoteException e) {
14656                        }
14657                    }
14658                }
14659            }
14660        }
14661        return success;
14662    }
14663
14664    private final ActivityRecord resumedAppLocked() {
14665        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
14666        if (resumedActivity == null || resumedActivity.app == null) {
14667            resumedActivity = mMainStack.mPausingActivity;
14668            if (resumedActivity == null || resumedActivity.app == null) {
14669                resumedActivity = mMainStack.topRunningActivityLocked(null);
14670            }
14671        }
14672        return resumedActivity;
14673    }
14674
14675    private final boolean updateOomAdjLocked(ProcessRecord app) {
14676        final ActivityRecord TOP_ACT = resumedAppLocked();
14677        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14678        int curAdj = app.curAdj;
14679        final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14680            && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
14681
14682        mAdjSeq++;
14683
14684        boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
14685        final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14686            && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
14687        if (nowHidden != wasHidden) {
14688            // Changed to/from hidden state, so apps after it in the LRU
14689            // list may also be changed.
14690            updateOomAdjLocked();
14691        }
14692        return success;
14693    }
14694
14695    final void updateOomAdjLocked() {
14696        final ActivityRecord TOP_ACT = resumedAppLocked();
14697        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14698
14699        if (false) {
14700            RuntimeException e = new RuntimeException();
14701            e.fillInStackTrace();
14702            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
14703        }
14704
14705        mAdjSeq++;
14706        mNewNumServiceProcs = 0;
14707
14708        // Let's determine how many processes we have running vs.
14709        // how many slots we have for background processes; we may want
14710        // to put multiple processes in a slot of there are enough of
14711        // them.
14712        int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
14713        int factor = (mLruProcesses.size()-4)/numSlots;
14714        if (factor < 1) factor = 1;
14715        int step = 0;
14716        int numHidden = 0;
14717        int numTrimming = 0;
14718
14719        // First update the OOM adjustment for each of the
14720        // application processes based on their current state.
14721        int i = mLruProcesses.size();
14722        int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
14723        while (i > 0) {
14724            i--;
14725            ProcessRecord app = mLruProcesses.get(i);
14726            //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
14727            updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
14728            if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
14729                && app.curAdj == curHiddenAdj) {
14730                step++;
14731                if (step >= factor) {
14732                    step = 0;
14733                    curHiddenAdj++;
14734                }
14735            }
14736            if (!app.killedBackground) {
14737                if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
14738                    numHidden++;
14739                    if (numHidden > mProcessLimit) {
14740                        Slog.i(TAG, "No longer want " + app.processName
14741                                + " (pid " + app.pid + "): hidden #" + numHidden);
14742                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14743                                app.processName, app.setAdj, "too many background");
14744                        app.killedBackground = true;
14745                        Process.killProcessQuiet(app.pid);
14746                    }
14747                }
14748                if (!app.killedBackground && app.isolated && app.services.size() <= 0) {
14749                    // If this is an isolated process, and there are no
14750                    // services running in it, then the process is no longer
14751                    // needed.  We agressively kill these because we can by
14752                    // definition not re-use the same process again, and it is
14753                    // good to avoid having whatever code was running in them
14754                    // left sitting around after no longer needed.
14755                    Slog.i(TAG, "Isolated process " + app.processName
14756                            + " (pid " + app.pid + ") no longer needed");
14757                    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14758                            app.processName, app.setAdj, "isolated not needed");
14759                    app.killedBackground = true;
14760                    Process.killProcessQuiet(app.pid);
14761                }
14762                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
14763                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
14764                        && !app.killedBackground) {
14765                    numTrimming++;
14766                }
14767            }
14768        }
14769
14770        mNumServiceProcs = mNewNumServiceProcs;
14771
14772        // Now determine the memory trimming level of background processes.
14773        // Unfortunately we need to start at the back of the list to do this
14774        // properly.  We only do this if the number of background apps we
14775        // are managing to keep around is less than half the maximum we desire;
14776        // if we are keeping a good number around, we'll let them use whatever
14777        // memory they want.
14778        if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
14779            final int N = mLruProcesses.size();
14780            factor = numTrimming/3;
14781            int minFactor = 2;
14782            if (mHomeProcess != null) minFactor++;
14783            if (mPreviousProcess != null) minFactor++;
14784            if (factor < minFactor) factor = minFactor;
14785            step = 0;
14786            int fgTrimLevel;
14787            if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/5)) {
14788                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
14789            } else if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/3)) {
14790                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
14791            } else {
14792                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
14793            }
14794            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
14795            for (i=0; i<N; i++) {
14796                ProcessRecord app = mLruProcesses.get(i);
14797                if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
14798                        && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
14799                        && !app.killedBackground) {
14800                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
14801                        try {
14802                            app.thread.scheduleTrimMemory(curLevel);
14803                        } catch (RemoteException e) {
14804                        }
14805                        if (false) {
14806                            // For now we won't do this; our memory trimming seems
14807                            // to be good enough at this point that destroying
14808                            // activities causes more harm than good.
14809                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
14810                                    && app != mHomeProcess && app != mPreviousProcess) {
14811                                // Need to do this on its own message because the stack may not
14812                                // be in a consistent state at this point.
14813                                // For these apps we will also finish their activities
14814                                // to help them free memory.
14815                                mMainStack.scheduleDestroyActivities(app, false, "trim");
14816                            }
14817                        }
14818                    }
14819                    app.trimMemoryLevel = curLevel;
14820                    step++;
14821                    if (step >= factor) {
14822                        step = 0;
14823                        switch (curLevel) {
14824                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
14825                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
14826                                break;
14827                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
14828                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
14829                                break;
14830                        }
14831                    }
14832                } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14833                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
14834                            && app.thread != null) {
14835                        try {
14836                            app.thread.scheduleTrimMemory(
14837                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
14838                        } catch (RemoteException e) {
14839                        }
14840                    }
14841                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
14842                } else {
14843                    if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
14844                            && app.pendingUiClean) {
14845                        // If this application is now in the background and it
14846                        // had done UI, then give it the special trim level to
14847                        // have it free UI resources.
14848                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14849                        if (app.trimMemoryLevel < level && app.thread != null) {
14850                            try {
14851                                app.thread.scheduleTrimMemory(level);
14852                            } catch (RemoteException e) {
14853                            }
14854                        }
14855                        app.pendingUiClean = false;
14856                    }
14857                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
14858                        try {
14859                            app.thread.scheduleTrimMemory(fgTrimLevel);
14860                        } catch (RemoteException e) {
14861                        }
14862                    }
14863                    app.trimMemoryLevel = fgTrimLevel;
14864                }
14865            }
14866        } else {
14867            final int N = mLruProcesses.size();
14868            for (i=0; i<N; i++) {
14869                ProcessRecord app = mLruProcesses.get(i);
14870                if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
14871                        && app.pendingUiClean) {
14872                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14873                            && app.thread != null) {
14874                        try {
14875                            app.thread.scheduleTrimMemory(
14876                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14877                        } catch (RemoteException e) {
14878                        }
14879                    }
14880                    app.pendingUiClean = false;
14881                }
14882                app.trimMemoryLevel = 0;
14883            }
14884        }
14885
14886        if (mAlwaysFinishActivities) {
14887            // Need to do this on its own message because the stack may not
14888            // be in a consistent state at this point.
14889            mMainStack.scheduleDestroyActivities(null, false, "always-finish");
14890        }
14891    }
14892
14893    final void trimApplications() {
14894        synchronized (this) {
14895            int i;
14896
14897            // First remove any unused application processes whose package
14898            // has been removed.
14899            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
14900                final ProcessRecord app = mRemovedProcesses.get(i);
14901                if (app.activities.size() == 0
14902                        && app.curReceiver == null && app.services.size() == 0) {
14903                    Slog.i(
14904                        TAG, "Exiting empty application process "
14905                        + app.processName + " ("
14906                        + (app.thread != null ? app.thread.asBinder() : null)
14907                        + ")\n");
14908                    if (app.pid > 0 && app.pid != MY_PID) {
14909                        EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14910                                app.processName, app.setAdj, "empty");
14911                        Process.killProcessQuiet(app.pid);
14912                    } else {
14913                        try {
14914                            app.thread.scheduleExit();
14915                        } catch (Exception e) {
14916                            // Ignore exceptions.
14917                        }
14918                    }
14919                    cleanUpApplicationRecordLocked(app, false, true, -1);
14920                    mRemovedProcesses.remove(i);
14921
14922                    if (app.persistent) {
14923                        if (app.persistent) {
14924                            addAppLocked(app.info, false);
14925                        }
14926                    }
14927                }
14928            }
14929
14930            // Now update the oom adj for all processes.
14931            updateOomAdjLocked();
14932        }
14933    }
14934
14935    /** This method sends the specified signal to each of the persistent apps */
14936    public void signalPersistentProcesses(int sig) throws RemoteException {
14937        if (sig != Process.SIGNAL_USR1) {
14938            throw new SecurityException("Only SIGNAL_USR1 is allowed");
14939        }
14940
14941        synchronized (this) {
14942            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
14943                    != PackageManager.PERMISSION_GRANTED) {
14944                throw new SecurityException("Requires permission "
14945                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
14946            }
14947
14948            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14949                ProcessRecord r = mLruProcesses.get(i);
14950                if (r.thread != null && r.persistent) {
14951                    Process.sendSignal(r.pid, sig);
14952                }
14953            }
14954        }
14955    }
14956
14957    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
14958        if (proc == null || proc == mProfileProc) {
14959            proc = mProfileProc;
14960            path = mProfileFile;
14961            profileType = mProfileType;
14962            clearProfilerLocked();
14963        }
14964        if (proc == null) {
14965            return;
14966        }
14967        try {
14968            proc.thread.profilerControl(false, path, null, profileType);
14969        } catch (RemoteException e) {
14970            throw new IllegalStateException("Process disappeared");
14971        }
14972    }
14973
14974    private void clearProfilerLocked() {
14975        if (mProfileFd != null) {
14976            try {
14977                mProfileFd.close();
14978            } catch (IOException e) {
14979            }
14980        }
14981        mProfileApp = null;
14982        mProfileProc = null;
14983        mProfileFile = null;
14984        mProfileType = 0;
14985        mAutoStopProfiler = false;
14986    }
14987
14988    public boolean profileControl(String process, boolean start,
14989            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
14990
14991        try {
14992            synchronized (this) {
14993                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14994                // its own permission.
14995                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14996                        != PackageManager.PERMISSION_GRANTED) {
14997                    throw new SecurityException("Requires permission "
14998                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14999                }
15000
15001                if (start && fd == null) {
15002                    throw new IllegalArgumentException("null fd");
15003                }
15004
15005                ProcessRecord proc = null;
15006                if (process != null) {
15007                    try {
15008                        int pid = Integer.parseInt(process);
15009                        synchronized (mPidsSelfLocked) {
15010                            proc = mPidsSelfLocked.get(pid);
15011                        }
15012                    } catch (NumberFormatException e) {
15013                    }
15014
15015                    if (proc == null) {
15016                        HashMap<String, SparseArray<ProcessRecord>> all
15017                                = mProcessNames.getMap();
15018                        SparseArray<ProcessRecord> procs = all.get(process);
15019                        if (procs != null && procs.size() > 0) {
15020                            proc = procs.valueAt(0);
15021                        }
15022                    }
15023                }
15024
15025                if (start && (proc == null || proc.thread == null)) {
15026                    throw new IllegalArgumentException("Unknown process: " + process);
15027                }
15028
15029                if (start) {
15030                    stopProfilerLocked(null, null, 0);
15031                    setProfileApp(proc.info, proc.processName, path, fd, false);
15032                    mProfileProc = proc;
15033                    mProfileType = profileType;
15034                    try {
15035                        fd = fd.dup();
15036                    } catch (IOException e) {
15037                        fd = null;
15038                    }
15039                    proc.thread.profilerControl(start, path, fd, profileType);
15040                    fd = null;
15041                    mProfileFd = null;
15042                } else {
15043                    stopProfilerLocked(proc, path, profileType);
15044                    if (fd != null) {
15045                        try {
15046                            fd.close();
15047                        } catch (IOException e) {
15048                        }
15049                    }
15050                }
15051
15052                return true;
15053            }
15054        } catch (RemoteException e) {
15055            throw new IllegalStateException("Process disappeared");
15056        } finally {
15057            if (fd != null) {
15058                try {
15059                    fd.close();
15060                } catch (IOException e) {
15061                }
15062            }
15063        }
15064    }
15065
15066    public boolean dumpHeap(String process, boolean managed,
15067            String path, ParcelFileDescriptor fd) throws RemoteException {
15068
15069        try {
15070            synchronized (this) {
15071                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15072                // its own permission (same as profileControl).
15073                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15074                        != PackageManager.PERMISSION_GRANTED) {
15075                    throw new SecurityException("Requires permission "
15076                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15077                }
15078
15079                if (fd == null) {
15080                    throw new IllegalArgumentException("null fd");
15081                }
15082
15083                ProcessRecord proc = null;
15084                try {
15085                    int pid = Integer.parseInt(process);
15086                    synchronized (mPidsSelfLocked) {
15087                        proc = mPidsSelfLocked.get(pid);
15088                    }
15089                } catch (NumberFormatException e) {
15090                }
15091
15092                if (proc == null) {
15093                    HashMap<String, SparseArray<ProcessRecord>> all
15094                            = mProcessNames.getMap();
15095                    SparseArray<ProcessRecord> procs = all.get(process);
15096                    if (procs != null && procs.size() > 0) {
15097                        proc = procs.valueAt(0);
15098                    }
15099                }
15100
15101                if (proc == null || proc.thread == null) {
15102                    throw new IllegalArgumentException("Unknown process: " + process);
15103                }
15104
15105                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
15106                if (!isDebuggable) {
15107                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
15108                        throw new SecurityException("Process not debuggable: " + proc);
15109                    }
15110                }
15111
15112                proc.thread.dumpHeap(managed, path, fd);
15113                fd = null;
15114                return true;
15115            }
15116        } catch (RemoteException e) {
15117            throw new IllegalStateException("Process disappeared");
15118        } finally {
15119            if (fd != null) {
15120                try {
15121                    fd.close();
15122                } catch (IOException e) {
15123                }
15124            }
15125        }
15126    }
15127
15128    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
15129    public void monitor() {
15130        synchronized (this) { }
15131    }
15132
15133    void onCoreSettingsChange(Bundle settings) {
15134        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15135            ProcessRecord processRecord = mLruProcesses.get(i);
15136            try {
15137                if (processRecord.thread != null) {
15138                    processRecord.thread.setCoreSettings(settings);
15139                }
15140            } catch (RemoteException re) {
15141                /* ignore */
15142            }
15143        }
15144    }
15145
15146    // Multi-user methods
15147
15148    private int mCurrentUserId;
15149    private SparseIntArray mLoggedInUsers = new SparseIntArray(5);
15150
15151    public boolean switchUser(int userId) {
15152        final int callingUid = Binder.getCallingUid();
15153        if (callingUid != 0 && callingUid != Process.myUid()) {
15154            Slog.e(TAG, "Trying to switch user from unauthorized app");
15155            return false;
15156        }
15157        if (mCurrentUserId == userId)
15158            return true;
15159
15160        synchronized (this) {
15161            // Check if user is already logged in, otherwise check if user exists first before
15162            // adding to the list of logged in users.
15163            if (mLoggedInUsers.indexOfKey(userId) < 0) {
15164                if (!userExists(userId)) {
15165                    return false;
15166                }
15167                mLoggedInUsers.append(userId, userId);
15168            }
15169
15170            mCurrentUserId = userId;
15171            boolean haveActivities = mMainStack.switchUser(userId);
15172            if (!haveActivities) {
15173                startHomeActivityLocked(userId);
15174            }
15175
15176        }
15177
15178        // Inform of user switch
15179        Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
15180        addedIntent.putExtra(Intent.EXTRA_USERID, userId);
15181        mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS);
15182
15183        return true;
15184    }
15185
15186    @Override
15187    public UserInfo getCurrentUser() throws RemoteException {
15188        final int callingUid = Binder.getCallingUid();
15189        if (callingUid != 0 && callingUid != Process.myUid()) {
15190            Slog.e(TAG, "Trying to get user from unauthorized app");
15191            return null;
15192        }
15193        return AppGlobals.getPackageManager().getUser(mCurrentUserId);
15194    }
15195
15196    private void onUserRemoved(Intent intent) {
15197        int extraUserId = intent.getIntExtra(Intent.EXTRA_USERID, -1);
15198        if (extraUserId < 1) return;
15199
15200        // Kill all the processes for the user
15201        ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>();
15202        synchronized (this) {
15203            HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap();
15204            for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) {
15205                SparseArray<ProcessRecord> uids = uidMap.getValue();
15206                for (int i = 0; i < uids.size(); i++) {
15207                    if (UserId.getUserId(uids.keyAt(i)) == extraUserId) {
15208                        pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i)));
15209                    }
15210                }
15211            }
15212
15213            for (Pair<String,Integer> pkgAndUid : pkgAndUids) {
15214                forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second,
15215                        false, false, true, true, extraUserId);
15216            }
15217        }
15218    }
15219
15220    private boolean userExists(int userId) {
15221        try {
15222            UserInfo user = AppGlobals.getPackageManager().getUser(userId);
15223            return user != null;
15224        } catch (RemoteException re) {
15225            // Won't happen, in same process
15226        }
15227
15228        return false;
15229    }
15230
15231    private void checkValidCaller(int uid, int userId) {
15232        if (UserId.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
15233
15234        throw new SecurityException("Caller uid=" + uid
15235                + " is not privileged to communicate with user=" + userId);
15236    }
15237
15238    private int applyUserId(int uid, int userId) {
15239        return UserId.getUid(userId, uid);
15240    }
15241
15242    private ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
15243        if (info == null) return null;
15244        ApplicationInfo newInfo = new ApplicationInfo(info);
15245        newInfo.uid = applyUserId(info.uid, userId);
15246        newInfo.dataDir = USER_DATA_DIR + userId + "/"
15247                + info.packageName;
15248        return newInfo;
15249    }
15250
15251    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
15252        if (aInfo == null
15253                || (userId < 1 && aInfo.applicationInfo.uid < UserId.PER_USER_RANGE)) {
15254            return aInfo;
15255        }
15256
15257        ActivityInfo info = new ActivityInfo(aInfo);
15258        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
15259        return info;
15260    }
15261
15262    static class ServiceMap {
15263
15264        private final SparseArray<HashMap<ComponentName, ServiceRecord>> mServicesByNamePerUser
15265                = new SparseArray<HashMap<ComponentName, ServiceRecord>>();
15266        private final SparseArray<HashMap<Intent.FilterComparison, ServiceRecord>>
15267                mServicesByIntentPerUser = new SparseArray<
15268                    HashMap<Intent.FilterComparison, ServiceRecord>>();
15269
15270        ServiceRecord getServiceByName(ComponentName name, int callingUser) {
15271            // TODO: Deal with global services
15272            if (DEBUG_MU)
15273                Slog.v(TAG_MU, "getServiceByName(" + name + "), callingUser = " + callingUser);
15274            return getServices(callingUser).get(name);
15275        }
15276
15277        ServiceRecord getServiceByName(ComponentName name) {
15278            return getServiceByName(name, -1);
15279        }
15280
15281        ServiceRecord getServiceByIntent(Intent.FilterComparison filter, int callingUser) {
15282            // TODO: Deal with global services
15283            if (DEBUG_MU)
15284                Slog.v(TAG_MU, "getServiceByIntent(" + filter + "), callingUser = " + callingUser);
15285            return getServicesByIntent(callingUser).get(filter);
15286        }
15287
15288        ServiceRecord getServiceByIntent(Intent.FilterComparison filter) {
15289            return getServiceByIntent(filter, -1);
15290        }
15291
15292        void putServiceByName(ComponentName name, int callingUser, ServiceRecord value) {
15293            // TODO: Deal with global services
15294            getServices(callingUser).put(name, value);
15295        }
15296
15297        void putServiceByIntent(Intent.FilterComparison filter, int callingUser,
15298                ServiceRecord value) {
15299            // TODO: Deal with global services
15300            getServicesByIntent(callingUser).put(filter, value);
15301        }
15302
15303        void removeServiceByName(ComponentName name, int callingUser) {
15304            // TODO: Deal with global services
15305            ServiceRecord removed = getServices(callingUser).remove(name);
15306            if (DEBUG_MU)
15307                Slog.v(TAG, "removeServiceByName user=" + callingUser + " name=" + name
15308                        + " removed=" + removed);
15309        }
15310
15311        void removeServiceByIntent(Intent.FilterComparison filter, int callingUser) {
15312            // TODO: Deal with global services
15313            ServiceRecord removed = getServicesByIntent(callingUser).remove(filter);
15314            if (DEBUG_MU)
15315                Slog.v(TAG_MU, "removeServiceByIntent user=" + callingUser + " intent=" + filter
15316                        + " removed=" + removed);
15317        }
15318
15319        Collection<ServiceRecord> getAllServices(int callingUser) {
15320            // TODO: Deal with global services
15321            return getServices(callingUser).values();
15322        }
15323
15324        private HashMap<ComponentName, ServiceRecord> getServices(int callingUser) {
15325            HashMap map = mServicesByNamePerUser.get(callingUser);
15326            if (map == null) {
15327                map = new HashMap<ComponentName, ServiceRecord>();
15328                mServicesByNamePerUser.put(callingUser, map);
15329            }
15330            return map;
15331        }
15332
15333        private HashMap<Intent.FilterComparison, ServiceRecord> getServicesByIntent(
15334                int callingUser) {
15335            HashMap map = mServicesByIntentPerUser.get(callingUser);
15336            if (map == null) {
15337                map = new HashMap<Intent.FilterComparison, ServiceRecord>();
15338                mServicesByIntentPerUser.put(callingUser, map);
15339            }
15340            return map;
15341        }
15342    }
15343}
15344