• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.server.am;
18 
19 import com.android.internal.os.BatteryStatsImpl;
20 import com.android.server.AttributeCache;
21 import com.android.server.IntentResolver;
22 import com.android.server.ProcessMap;
23 import com.android.server.ProcessStats;
24 import com.android.server.SystemServer;
25 import com.android.server.Watchdog;
26 import com.android.server.WindowManagerService;
27 
28 import android.app.Activity;
29 import android.app.ActivityManager;
30 import android.app.ActivityManagerNative;
31 import android.app.ActivityThread;
32 import android.app.AlertDialog;
33 import android.app.ApplicationErrorReport;
34 import android.app.Dialog;
35 import android.app.IActivityController;
36 import android.app.IActivityWatcher;
37 import android.app.IApplicationThread;
38 import android.app.IInstrumentationWatcher;
39 import android.app.IServiceConnection;
40 import android.app.IThumbnailReceiver;
41 import android.app.Instrumentation;
42 import android.app.Notification;
43 import android.app.PendingIntent;
44 import android.app.ResultInfo;
45 import android.app.Service;
46 import android.backup.IBackupManager;
47 import android.content.ActivityNotFoundException;
48 import android.content.ComponentName;
49 import android.content.ContentResolver;
50 import android.content.Context;
51 import android.content.Intent;
52 import android.content.IntentFilter;
53 import android.content.IIntentReceiver;
54 import android.content.IIntentSender;
55 import android.content.IntentSender;
56 import android.content.pm.ActivityInfo;
57 import android.content.pm.ApplicationInfo;
58 import android.content.pm.ConfigurationInfo;
59 import android.content.pm.IPackageDataObserver;
60 import android.content.pm.IPackageManager;
61 import android.content.pm.InstrumentationInfo;
62 import android.content.pm.PackageManager;
63 import android.content.pm.PathPermission;
64 import android.content.pm.ProviderInfo;
65 import android.content.pm.ResolveInfo;
66 import android.content.pm.ServiceInfo;
67 import android.content.res.Configuration;
68 import android.graphics.Bitmap;
69 import android.net.Uri;
70 import android.os.Binder;
71 import android.os.Bundle;
72 import android.os.Debug;
73 import android.os.Environment;
74 import android.os.FileUtils;
75 import android.os.Handler;
76 import android.os.IBinder;
77 import android.os.IPermissionController;
78 import android.os.Looper;
79 import android.os.Message;
80 import android.os.Parcel;
81 import android.os.ParcelFileDescriptor;
82 import android.os.PowerManager;
83 import android.os.Process;
84 import android.os.RemoteCallbackList;
85 import android.os.RemoteException;
86 import android.os.ServiceManager;
87 import android.os.SystemClock;
88 import android.os.SystemProperties;
89 import android.provider.Checkin;
90 import android.provider.Settings;
91 import android.server.data.CrashData;
92 import android.server.data.StackTraceElementData;
93 import android.server.data.ThrowableData;
94 import android.text.TextUtils;
95 import android.util.Config;
96 import android.util.EventLog;
97 import android.util.Log;
98 import android.util.PrintWriterPrinter;
99 import android.util.SparseArray;
100 import android.view.Gravity;
101 import android.view.LayoutInflater;
102 import android.view.View;
103 import android.view.WindowManager;
104 import android.view.WindowManagerPolicy;
105 
106 import dalvik.system.Zygote;
107 
108 import java.io.ByteArrayInputStream;
109 import java.io.DataInputStream;
110 import java.io.File;
111 import java.io.FileDescriptor;
112 import java.io.FileInputStream;
113 import java.io.FileNotFoundException;
114 import java.io.IOException;
115 import java.io.PrintWriter;
116 import java.lang.IllegalStateException;
117 import java.lang.ref.WeakReference;
118 import java.util.ArrayList;
119 import java.util.HashMap;
120 import java.util.HashSet;
121 import java.util.Iterator;
122 import java.util.List;
123 import java.util.Locale;
124 import java.util.Map;
125 
126 public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor {
127     static final String TAG = "ActivityManager";
128     static final boolean DEBUG = false;
129     static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
130     static final boolean DEBUG_SWITCH = localLOGV || false;
131     static final boolean DEBUG_TASKS = localLOGV || false;
132     static final boolean DEBUG_PAUSE = localLOGV || false;
133     static final boolean DEBUG_OOM_ADJ = localLOGV || false;
134     static final boolean DEBUG_TRANSITION = localLOGV || false;
135     static final boolean DEBUG_BROADCAST = localLOGV || false;
136     static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
137     static final boolean DEBUG_SERVICE = localLOGV || false;
138     static final boolean DEBUG_VISBILITY = localLOGV || false;
139     static final boolean DEBUG_PROCESSES = localLOGV || false;
140     static final boolean DEBUG_PROVIDER = localLOGV || false;
141     static final boolean DEBUG_USER_LEAVING = localLOGV || false;
142     static final boolean DEBUG_RESULTS = localLOGV || false;
143     static final boolean DEBUG_BACKUP = localLOGV || false;
144     static final boolean DEBUG_CONFIGURATION = localLOGV || false;
145     static final boolean VALIDATE_TOKENS = false;
146     static final boolean SHOW_ACTIVITY_START_TIME = true;
147 
148     // Control over CPU and battery monitoring.
149     static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
150     static final boolean MONITOR_CPU_USAGE = true;
151     static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
152     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
153     static final boolean MONITOR_THREAD_CPU_USAGE = false;
154 
155     // Event log tags
156     static final int LOG_CONFIGURATION_CHANGED = 2719;
157     static final int LOG_CPU = 2721;
158     static final int LOG_AM_FINISH_ACTIVITY = 30001;
159     static final int LOG_TASK_TO_FRONT = 30002;
160     static final int LOG_AM_NEW_INTENT = 30003;
161     static final int LOG_AM_CREATE_TASK = 30004;
162     static final int LOG_AM_CREATE_ACTIVITY = 30005;
163     static final int LOG_AM_RESTART_ACTIVITY = 30006;
164     static final int LOG_AM_RESUME_ACTIVITY = 30007;
165     static final int LOG_ANR = 30008;
166     static final int LOG_ACTIVITY_LAUNCH_TIME = 30009;
167     static final int LOG_AM_PROCESS_BOUND = 30010;
168     static final int LOG_AM_PROCESS_DIED = 30011;
169     static final int LOG_AM_FAILED_TO_PAUSE_ACTIVITY = 30012;
170     static final int LOG_AM_PAUSE_ACTIVITY = 30013;
171     static final int LOG_AM_PROCESS_START = 30014;
172     static final int LOG_AM_PROCESS_BAD = 30015;
173     static final int LOG_AM_PROCESS_GOOD = 30016;
174     static final int LOG_AM_LOW_MEMORY = 30017;
175     static final int LOG_AM_DESTROY_ACTIVITY = 30018;
176     static final int LOG_AM_RELAUNCH_RESUME_ACTIVITY = 30019;
177     static final int LOG_AM_RELAUNCH_ACTIVITY = 30020;
178     static final int LOG_AM_KILL_FOR_MEMORY = 30023;
179     static final int LOG_AM_BROADCAST_DISCARD_FILTER = 30024;
180     static final int LOG_AM_BROADCAST_DISCARD_APP = 30025;
181     static final int LOG_AM_CREATE_SERVICE = 30030;
182     static final int LOG_AM_DESTROY_SERVICE = 30031;
183     static final int LOG_AM_PROCESS_CRASHED_TOO_MUCH = 30032;
184     static final int LOG_AM_DROP_PROCESS = 30033;
185     static final int LOG_AM_SERVICE_CRASHED_TOO_MUCH = 30034;
186     static final int LOG_AM_SCHEDULE_SERVICE_RESTART = 30035;
187     static final int LOG_AM_PROVIDER_LOST_PROCESS = 30036;
188     static final int LOG_AM_PROCESS_START_TIMEOUT = 30037;
189 
190     static final int LOG_BOOT_PROGRESS_AMS_READY = 3040;
191     static final int LOG_BOOT_PROGRESS_ENABLE_SCREEN = 3050;
192 
193     // The flags that are set for all calls we make to the package manager.
194     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
195 
196     private static final String SYSTEM_SECURE = "ro.secure";
197 
198     // This is the maximum number of application processes we would like
199     // to have running.  Due to the asynchronous nature of things, we can
200     // temporarily go beyond this limit.
201     static final int MAX_PROCESSES = 2;
202 
203     // Set to false to leave processes running indefinitely, relying on
204     // the kernel killing them as resources are required.
205     static final boolean ENFORCE_PROCESS_LIMIT = false;
206 
207     // This is the maximum number of activities that we would like to have
208     // running at a given time.
209     static final int MAX_ACTIVITIES = 20;
210 
211     // Maximum number of recent tasks that we can remember.
212     static final int MAX_RECENT_TASKS = 20;
213 
214     // Amount of time after a call to stopAppSwitches() during which we will
215     // prevent further untrusted switches from happening.
216     static final long APP_SWITCH_DELAY_TIME = 5*1000;
217 
218     // How long until we reset a task when the user returns to it.  Currently
219     // 30 minutes.
220     static final long ACTIVITY_INACTIVE_RESET_TIME = 1000*60*30;
221 
222     // Set to true to disable the icon that is shown while a new activity
223     // is being started.
224     static final boolean SHOW_APP_STARTING_ICON = true;
225 
226     // How long we wait until giving up on the last activity to pause.  This
227     // is short because it directly impacts the responsiveness of starting the
228     // next activity.
229     static final int PAUSE_TIMEOUT = 500;
230 
231     /**
232      * How long we can hold the launch wake lock before giving up.
233      */
234     static final int LAUNCH_TIMEOUT = 10*1000;
235 
236     // How long we wait for a launched process to attach to the activity manager
237     // before we decide it's never going to come up for real.
238     static final int PROC_START_TIMEOUT = 10*1000;
239 
240     // How long we wait until giving up on the last activity telling us it
241     // is idle.
242     static final int IDLE_TIMEOUT = 10*1000;
243 
244     // How long to wait after going idle before forcing apps to GC.
245     static final int GC_TIMEOUT = 5*1000;
246 
247     // The minimum amount of time between successive GC requests for a process.
248     static final int GC_MIN_INTERVAL = 60*1000;
249 
250     // How long we wait until giving up on an activity telling us it has
251     // finished destroying itself.
252     static final int DESTROY_TIMEOUT = 10*1000;
253 
254     // How long we allow a receiver to run before giving up on it.
255     static final int BROADCAST_TIMEOUT = 10*1000;
256 
257     // How long we wait for a service to finish executing.
258     static final int SERVICE_TIMEOUT = 20*1000;
259 
260     // How long a service needs to be running until restarting its process
261     // is no longer considered to be a relaunch of the service.
262     static final int SERVICE_RESTART_DURATION = 5*1000;
263 
264     // How long a service needs to be running until it will start back at
265     // SERVICE_RESTART_DURATION after being killed.
266     static final int SERVICE_RESET_RUN_DURATION = 60*1000;
267 
268     // Multiplying factor to increase restart duration time by, for each time
269     // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
270     static final int SERVICE_RESTART_DURATION_FACTOR = 4;
271 
272     // The minimum amount of time between restarting services that we allow.
273     // That is, when multiple services are restarting, we won't allow each
274     // to restart less than this amount of time from the last one.
275     static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
276 
277     // Maximum amount of time for there to be no activity on a service before
278     // we consider it non-essential and allow its process to go on the
279     // LRU background list.
280     static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
281 
282     // How long we wait until we timeout on key dispatching.
283     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
284 
285     // The minimum time we allow between crashes, for us to consider this
286     // application to be bad and stop and its services and reject broadcasts.
287     static final int MIN_CRASH_INTERVAL = 60*1000;
288 
289     // How long we wait until we timeout on key dispatching during instrumentation.
290     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
291 
292     // OOM adjustments for processes in various states:
293 
294     // This is a process without anything currently running in it.  Definitely
295     // the first to go! Value set in system/rootdir/init.rc on startup.
296     // This value is initalized in the constructor, careful when refering to
297     // this static variable externally.
298     static int EMPTY_APP_ADJ;
299 
300     // This is a process with a content provider that does not have any clients
301     // attached to it.  If it did have any clients, its adjustment would be the
302     // one for the highest-priority of those processes.
303     static int CONTENT_PROVIDER_ADJ;
304 
305     // This is a process only hosting activities that are not visible,
306     // so it can be killed without any disruption. Value set in
307     // system/rootdir/init.rc on startup.
308     final int HIDDEN_APP_MAX_ADJ;
309     static int HIDDEN_APP_MIN_ADJ;
310 
311     // This is a process holding the home application -- we want to try
312     // avoiding killing it, even if it would normally be in the background,
313     // because the user interacts with it so much.
314     final int HOME_APP_ADJ;
315 
316     // This is a process currently hosting a backup operation.  Killing it
317     // is not entirely fatal but is generally a bad idea.
318     final int BACKUP_APP_ADJ;
319 
320     // This is a process holding a secondary server -- killing it will not
321     // have much of an impact as far as the user is concerned. Value set in
322     // system/rootdir/init.rc on startup.
323     final int SECONDARY_SERVER_ADJ;
324 
325     // This is a process only hosting activities that are visible to the
326     // user, so we'd prefer they don't disappear. Value set in
327     // system/rootdir/init.rc on startup.
328     final int VISIBLE_APP_ADJ;
329 
330     // This is the process running the current foreground app.  We'd really
331     // rather not kill it! Value set in system/rootdir/init.rc on startup.
332     final int FOREGROUND_APP_ADJ;
333 
334     // This is a process running a core server, such as telephony.  Definitely
335     // don't want to kill it, but doing so is not completely fatal.
336     static final int CORE_SERVER_ADJ = -12;
337 
338     // The system process runs at the default adjustment.
339     static final int SYSTEM_ADJ = -16;
340 
341     // Memory pages are 4K.
342     static final int PAGE_SIZE = 4*1024;
343 
344     // System property defining error report receiver for system apps
345     static final String SYSTEM_APPS_ERROR_RECEIVER_PROPERTY = "ro.error.receiver.system.apps";
346 
347     // System property defining default error report receiver
348     static final String DEFAULT_ERROR_RECEIVER_PROPERTY = "ro.error.receiver.default";
349 
350     // Corresponding memory levels for above adjustments.
351     final int EMPTY_APP_MEM;
352     final int HIDDEN_APP_MEM;
353     final int HOME_APP_MEM;
354     final int BACKUP_APP_MEM;
355     final int SECONDARY_SERVER_MEM;
356     final int VISIBLE_APP_MEM;
357     final int FOREGROUND_APP_MEM;
358 
359     final int MY_PID;
360 
361     static final String[] EMPTY_STRING_ARRAY = new String[0];
362 
363     enum ActivityState {
364         INITIALIZING,
365         RESUMED,
366         PAUSING,
367         PAUSED,
368         STOPPING,
369         STOPPED,
370         FINISHING,
371         DESTROYING,
372         DESTROYED
373     }
374 
375     /**
376      * The back history of all previous (and possibly still
377      * running) activities.  It contains HistoryRecord objects.
378      */
379     final ArrayList mHistory = new ArrayList();
380 
381     /**
382      * Description of a request to start a new activity, which has been held
383      * due to app switches being disabled.
384      */
385     class PendingActivityLaunch {
386         HistoryRecord r;
387         HistoryRecord sourceRecord;
388         Uri[] grantedUriPermissions;
389         int grantedMode;
390         boolean onlyIfNeeded;
391     }
392 
393     final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
394             = new ArrayList<PendingActivityLaunch>();
395 
396     /**
397      * List of all active broadcasts that are to be executed immediately
398      * (without waiting for another broadcast to finish).  Currently this only
399      * contains broadcasts to registered receivers, to avoid spinning up
400      * a bunch of processes to execute IntentReceiver components.
401      */
402     final ArrayList<BroadcastRecord> mParallelBroadcasts
403             = new ArrayList<BroadcastRecord>();
404 
405     /**
406      * List of all active broadcasts that are to be executed one at a time.
407      * The object at the top of the list is the currently activity broadcasts;
408      * those after it are waiting for the top to finish..
409      */
410     final ArrayList<BroadcastRecord> mOrderedBroadcasts
411             = new ArrayList<BroadcastRecord>();
412 
413     /**
414      * Historical data of past broadcasts, for debugging.
415      */
416     static final int MAX_BROADCAST_HISTORY = 100;
417     final BroadcastRecord[] mBroadcastHistory
418             = new BroadcastRecord[MAX_BROADCAST_HISTORY];
419 
420     /**
421      * Set when we current have a BROADCAST_INTENT_MSG in flight.
422      */
423     boolean mBroadcastsScheduled = false;
424 
425     /**
426      * Set to indicate whether to issue an onUserLeaving callback when a
427      * newly launched activity is being brought in front of us.
428      */
429     boolean mUserLeaving = false;
430 
431     /**
432      * When we are in the process of pausing an activity, before starting the
433      * next one, this variable holds the activity that is currently being paused.
434      */
435     HistoryRecord mPausingActivity = null;
436 
437     /**
438      * Current activity that is resumed, or null if there is none.
439      */
440     HistoryRecord mResumedActivity = null;
441 
442     /**
443      * Activity we have told the window manager to have key focus.
444      */
445     HistoryRecord mFocusedActivity = null;
446 
447     /**
448      * This is the last activity that we put into the paused state.  This is
449      * used to determine if we need to do an activity transition while sleeping,
450      * when we normally hold the top activity paused.
451      */
452     HistoryRecord mLastPausedActivity = null;
453 
454     /**
455      * List of activities that are waiting for a new activity
456      * to become visible before completing whatever operation they are
457      * supposed to do.
458      */
459     final ArrayList mWaitingVisibleActivities = new ArrayList();
460 
461     /**
462      * List of activities that are ready to be stopped, but waiting
463      * for the next activity to settle down before doing so.  It contains
464      * HistoryRecord objects.
465      */
466     final ArrayList<HistoryRecord> mStoppingActivities
467             = new ArrayList<HistoryRecord>();
468 
469     /**
470      * Animations that for the current transition have requested not to
471      * be considered for the transition animation.
472      */
473     final ArrayList<HistoryRecord> mNoAnimActivities
474             = new ArrayList<HistoryRecord>();
475 
476     /**
477      * List of intents that were used to start the most recent tasks.
478      */
479     final ArrayList<TaskRecord> mRecentTasks
480             = new ArrayList<TaskRecord>();
481 
482     /**
483      * List of activities that are ready to be finished, but waiting
484      * for the previous activity to settle down before doing so.  It contains
485      * HistoryRecord objects.
486      */
487     final ArrayList mFinishingActivities = new ArrayList();
488 
489     /**
490      * All of the applications we currently have running organized by name.
491      * The keys are strings of the application package name (as
492      * returned by the package manager), and the keys are ApplicationRecord
493      * objects.
494      */
495     final ProcessMap<ProcessRecord> mProcessNames
496             = new ProcessMap<ProcessRecord>();
497 
498     /**
499      * The last time that various processes have crashed.
500      */
501     final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
502 
503     /**
504      * Set of applications that we consider to be bad, and will reject
505      * incoming broadcasts from (which the user has no control over).
506      * Processes are added to this set when they have crashed twice within
507      * a minimum amount of time; they are removed from it when they are
508      * later restarted (hopefully due to some user action).  The value is the
509      * time it was added to the list.
510      */
511     final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
512 
513     /**
514      * All of the processes we currently have running organized by pid.
515      * The keys are the pid running the application.
516      *
517      * <p>NOTE: This object is protected by its own lock, NOT the global
518      * activity manager lock!
519      */
520     final SparseArray<ProcessRecord> mPidsSelfLocked
521             = new SparseArray<ProcessRecord>();
522 
523     /**
524      * All of the processes that have been forced to be foreground.  The key
525      * is the pid of the caller who requested it (we hold a death
526      * link on it).
527      */
528     abstract class ForegroundToken implements IBinder.DeathRecipient {
529         int pid;
530         IBinder token;
531     }
532     final SparseArray<ForegroundToken> mForegroundProcesses
533             = new SparseArray<ForegroundToken>();
534 
535     /**
536      * List of records for processes that someone had tried to start before the
537      * system was ready.  We don't start them at that point, but ensure they
538      * are started by the time booting is complete.
539      */
540     final ArrayList<ProcessRecord> mProcessesOnHold
541             = new ArrayList<ProcessRecord>();
542 
543     /**
544      * List of records for processes that we have started and are waiting
545      * for them to call back.  This is really only needed when running in
546      * single processes mode, in which case we do not have a unique pid for
547      * each process.
548      */
549     final ArrayList<ProcessRecord> mStartingProcesses
550             = new ArrayList<ProcessRecord>();
551 
552     /**
553      * List of persistent applications that are in the process
554      * of being started.
555      */
556     final ArrayList<ProcessRecord> mPersistentStartingProcesses
557             = new ArrayList<ProcessRecord>();
558 
559     /**
560      * Processes that are being forcibly torn down.
561      */
562     final ArrayList<ProcessRecord> mRemovedProcesses
563             = new ArrayList<ProcessRecord>();
564 
565     /**
566      * List of running applications, sorted by recent usage.
567      * The first entry in the list is the least recently used.
568      * It contains ApplicationRecord objects.  This list does NOT include
569      * any persistent application records (since we never want to exit them).
570      */
571     final ArrayList<ProcessRecord> mLRUProcesses
572             = new ArrayList<ProcessRecord>();
573 
574     /**
575      * List of processes that should gc as soon as things are idle.
576      */
577     final ArrayList<ProcessRecord> mProcessesToGc
578             = new ArrayList<ProcessRecord>();
579 
580     /**
581      * This is the process holding what we currently consider to be
582      * the "home" activity.
583      */
584     private ProcessRecord mHomeProcess;
585 
586     /**
587      * List of running activities, sorted by recent usage.
588      * The first entry in the list is the least recently used.
589      * It contains HistoryRecord objects.
590      */
591     private final ArrayList mLRUActivities = new ArrayList();
592 
593     /**
594      * Set of PendingResultRecord objects that are currently active.
595      */
596     final HashSet mPendingResultRecords = new HashSet();
597 
598     /**
599      * Set of IntentSenderRecord objects that are currently active.
600      */
601     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
602             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
603 
604     /**
605      * Intent broadcast that we have tried to start, but are
606      * waiting for its application's process to be created.  We only
607      * need one (instead of a list) because we always process broadcasts
608      * one at a time, so no others can be started while waiting for this
609      * one.
610      */
611     BroadcastRecord mPendingBroadcast = null;
612 
613     /**
614      * Keeps track of all IIntentReceivers that have been registered for
615      * broadcasts.  Hash keys are the receiver IBinder, hash value is
616      * a ReceiverList.
617      */
618     final HashMap mRegisteredReceivers = new HashMap();
619 
620     /**
621      * Resolver for broadcast intents to registered receivers.
622      * Holds BroadcastFilter (subclass of IntentFilter).
623      */
624     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
625             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
626         @Override
627         protected boolean allowFilterResult(
628                 BroadcastFilter filter, List<BroadcastFilter> dest) {
629             IBinder target = filter.receiverList.receiver.asBinder();
630             for (int i=dest.size()-1; i>=0; i--) {
631                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
632                     return false;
633                 }
634             }
635             return true;
636         }
637     };
638 
639     /**
640      * State of all active sticky broadcasts.  Keys are the action of the
641      * sticky Intent, values are an ArrayList of all broadcasted intents with
642      * that action (which should usually be one).
643      */
644     final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
645             new HashMap<String, ArrayList<Intent>>();
646 
647     /**
648      * All currently running services.
649      */
650     final HashMap<ComponentName, ServiceRecord> mServices =
651         new HashMap<ComponentName, ServiceRecord>();
652 
653     /**
654      * All currently running services indexed by the Intent used to start them.
655      */
656     final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
657         new HashMap<Intent.FilterComparison, ServiceRecord>();
658 
659     /**
660      * All currently bound service connections.  Keys are the IBinder of
661      * the client's IServiceConnection.
662      */
663     final HashMap<IBinder, ConnectionRecord> mServiceConnections
664             = new HashMap<IBinder, ConnectionRecord>();
665 
666     /**
667      * List of services that we have been asked to start,
668      * but haven't yet been able to.  It is used to hold start requests
669      * while waiting for their corresponding application thread to get
670      * going.
671      */
672     final ArrayList<ServiceRecord> mPendingServices
673             = new ArrayList<ServiceRecord>();
674 
675     /**
676      * List of services that are scheduled to restart following a crash.
677      */
678     final ArrayList<ServiceRecord> mRestartingServices
679             = new ArrayList<ServiceRecord>();
680 
681     /**
682      * List of services that are in the process of being stopped.
683      */
684     final ArrayList<ServiceRecord> mStoppingServices
685             = new ArrayList<ServiceRecord>();
686 
687     /**
688      * Backup/restore process management
689      */
690     String mBackupAppName = null;
691     BackupRecord mBackupTarget = null;
692 
693     /**
694      * List of PendingThumbnailsRecord objects of clients who are still
695      * waiting to receive all of the thumbnails for a task.
696      */
697     final ArrayList mPendingThumbnails = new ArrayList();
698 
699     /**
700      * List of HistoryRecord objects that have been finished and must
701      * still report back to a pending thumbnail receiver.
702      */
703     final ArrayList mCancelledThumbnails = new ArrayList();
704 
705     /**
706      * All of the currently running global content providers.  Keys are a
707      * string containing the provider name and values are a
708      * ContentProviderRecord object containing the data about it.  Note
709      * that a single provider may be published under multiple names, so
710      * there may be multiple entries here for a single one in mProvidersByClass.
711      */
712     final HashMap mProvidersByName = new HashMap();
713 
714     /**
715      * All of the currently running global content providers.  Keys are a
716      * string containing the provider's implementation class and values are a
717      * ContentProviderRecord object containing the data about it.
718      */
719     final HashMap mProvidersByClass = new HashMap();
720 
721     /**
722      * List of content providers who have clients waiting for them.  The
723      * application is currently being launched and the provider will be
724      * removed from this list once it is published.
725      */
726     final ArrayList mLaunchingProviders = new ArrayList();
727 
728     /**
729      * Global set of specific Uri permissions that have been granted.
730      */
731     final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
732             = new SparseArray<HashMap<Uri, UriPermission>>();
733 
734     /**
735      * Thread-local storage used to carry caller permissions over through
736      * indirect content-provider access.
737      * @see #ActivityManagerService.openContentUri()
738      */
739     private class Identity {
740         public int pid;
741         public int uid;
742 
Identity(int _pid, int _uid)743         Identity(int _pid, int _uid) {
744             pid = _pid;
745             uid = _uid;
746         }
747     }
748     private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
749 
750     /**
751      * All information we have collected about the runtime performance of
752      * any user id that can impact battery performance.
753      */
754     final BatteryStatsService mBatteryStatsService;
755 
756     /**
757      * information about component usage
758      */
759     final UsageStatsService mUsageStatsService;
760 
761     /**
762      * Current configuration information.  HistoryRecord objects are given
763      * a reference to this object to indicate which configuration they are
764      * currently running in, so this object must be kept immutable.
765      */
766     Configuration mConfiguration = new Configuration();
767 
768     /**
769      * Hardware-reported OpenGLES version.
770      */
771     final int GL_ES_VERSION;
772 
773     /**
774      * List of initialization arguments to pass to all processes when binding applications to them.
775      * For example, references to the commonly used services.
776      */
777     HashMap<String, IBinder> mAppBindArgs;
778 
779     /**
780      * Temporary to avoid allocations.  Protected by main lock.
781      */
782     final StringBuilder mStringBuilder = new StringBuilder(256);
783 
784     /**
785      * Used to control how we initialize the service.
786      */
787     boolean mStartRunning = false;
788     ComponentName mTopComponent;
789     String mTopAction;
790     String mTopData;
791     boolean mSystemReady = false;
792     boolean mBooting = false;
793     boolean mWaitingUpdate = false;
794     boolean mDidUpdate = false;
795 
796     Context mContext;
797 
798     int mFactoryTest;
799 
800     boolean mCheckedForSetup;
801 
802     /**
803      * The time at which we will allow normal application switches again,
804      * after a call to {@link #stopAppSwitches()}.
805      */
806     long mAppSwitchesAllowedTime;
807 
808     /**
809      * This is set to true after the first switch after mAppSwitchesAllowedTime
810      * is set; any switches after that will clear the time.
811      */
812     boolean mDidAppSwitch;
813 
814     /**
815      * Set while we are wanting to sleep, to prevent any
816      * activities from being started/resumed.
817      */
818     boolean mSleeping = false;
819 
820     /**
821      * Set if we are shutting down the system, similar to sleeping.
822      */
823     boolean mShuttingDown = false;
824 
825     /**
826      * Set when the system is going to sleep, until we have
827      * successfully paused the current activity and released our wake lock.
828      * At that point the system is allowed to actually sleep.
829      */
830     PowerManager.WakeLock mGoingToSleep;
831 
832     /**
833      * We don't want to allow the device to go to sleep while in the process
834      * of launching an activity.  This is primarily to allow alarm intent
835      * receivers to launch an activity and get that to run before the device
836      * goes back to sleep.
837      */
838     PowerManager.WakeLock mLaunchingActivity;
839 
840     /**
841      * Task identifier that activities are currently being started
842      * in.  Incremented each time a new task is created.
843      * todo: Replace this with a TokenSpace class that generates non-repeating
844      * integers that won't wrap.
845      */
846     int mCurTask = 1;
847 
848     /**
849      * Current sequence id for oom_adj computation traversal.
850      */
851     int mAdjSeq = 0;
852 
853     /**
854      * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar
855      * is set, indicating the user wants processes started in such a way
856      * that they can use ANDROID_PROCESS_WRAPPER and know what will be
857      * running in each process (thus no pre-initialized process, etc).
858      */
859     boolean mSimpleProcessManagement = false;
860 
861     /**
862      * System monitoring: number of processes that died since the last
863      * N procs were started.
864      */
865     int[] mProcDeaths = new int[20];
866 
867     /**
868      * This is set if we had to do a delayed dexopt of an app before launching
869      * it, to increasing the ANR timeouts in that case.
870      */
871     boolean mDidDexOpt;
872 
873     String mDebugApp = null;
874     boolean mWaitForDebugger = false;
875     boolean mDebugTransient = false;
876     String mOrigDebugApp = null;
877     boolean mOrigWaitForDebugger = false;
878     boolean mAlwaysFinishActivities = false;
879     IActivityController mController = null;
880 
881     final RemoteCallbackList<IActivityWatcher> mWatchers
882             = new RemoteCallbackList<IActivityWatcher>();
883 
884     /**
885      * Callback of last caller to {@link #requestPss}.
886      */
887     Runnable mRequestPssCallback;
888 
889     /**
890      * Remaining processes for which we are waiting results from the last
891      * call to {@link #requestPss}.
892      */
893     final ArrayList<ProcessRecord> mRequestPssList
894             = new ArrayList<ProcessRecord>();
895 
896     /**
897      * Runtime statistics collection thread.  This object's lock is used to
898      * protect all related state.
899      */
900     final Thread mProcessStatsThread;
901 
902     /**
903      * Used to collect process stats when showing not responding dialog.
904      * Protected by mProcessStatsThread.
905      */
906     final ProcessStats mProcessStats = new ProcessStats(
907             MONITOR_THREAD_CPU_USAGE);
908     long mLastCpuTime = 0;
909     long mLastWriteTime = 0;
910 
911     long mInitialStartTime = 0;
912 
913     /**
914      * Set to true after the system has finished booting.
915      */
916     boolean mBooted = false;
917 
918     int mProcessLimit = 0;
919 
920     WindowManagerService mWindowManager;
921 
922     static ActivityManagerService mSelf;
923     static ActivityThread mSystemThread;
924 
925     private final class AppDeathRecipient implements IBinder.DeathRecipient {
926         final ProcessRecord mApp;
927         final int mPid;
928         final IApplicationThread mAppThread;
929 
AppDeathRecipient(ProcessRecord app, int pid, IApplicationThread thread)930         AppDeathRecipient(ProcessRecord app, int pid,
931                 IApplicationThread thread) {
932             if (localLOGV) Log.v(
933                 TAG, "New death recipient " + this
934                 + " for thread " + thread.asBinder());
935             mApp = app;
936             mPid = pid;
937             mAppThread = thread;
938         }
939 
binderDied()940         public void binderDied() {
941             if (localLOGV) Log.v(
942                 TAG, "Death received in " + this
943                 + " for thread " + mAppThread.asBinder());
944             removeRequestedPss(mApp);
945             synchronized(ActivityManagerService.this) {
946                 appDiedLocked(mApp, mPid, mAppThread);
947             }
948         }
949     }
950 
951     static final int SHOW_ERROR_MSG = 1;
952     static final int SHOW_NOT_RESPONDING_MSG = 2;
953     static final int SHOW_FACTORY_ERROR_MSG = 3;
954     static final int UPDATE_CONFIGURATION_MSG = 4;
955     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
956     static final int WAIT_FOR_DEBUGGER_MSG = 6;
957     static final int BROADCAST_INTENT_MSG = 7;
958     static final int BROADCAST_TIMEOUT_MSG = 8;
959     static final int PAUSE_TIMEOUT_MSG = 9;
960     static final int IDLE_TIMEOUT_MSG = 10;
961     static final int IDLE_NOW_MSG = 11;
962     static final int SERVICE_TIMEOUT_MSG = 12;
963     static final int UPDATE_TIME_ZONE = 13;
964     static final int SHOW_UID_ERROR_MSG = 14;
965     static final int IM_FEELING_LUCKY_MSG = 15;
966     static final int LAUNCH_TIMEOUT_MSG = 16;
967     static final int DESTROY_TIMEOUT_MSG = 17;
968     static final int SERVICE_ERROR_MSG = 18;
969     static final int RESUME_TOP_ACTIVITY_MSG = 19;
970     static final int PROC_START_TIMEOUT_MSG = 20;
971     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
972     static final int KILL_APPLICATION_MSG = 22;
973 
974     AlertDialog mUidAlert;
975 
976     final Handler mHandler = new Handler() {
977         //public Handler() {
978         //    if (localLOGV) Log.v(TAG, "Handler started!");
979         //}
980 
981         public void handleMessage(Message msg) {
982             switch (msg.what) {
983             case SHOW_ERROR_MSG: {
984                 HashMap data = (HashMap) msg.obj;
985                 byte[] crashData = (byte[])data.get("crashData");
986                 if (crashData != null) {
987                     // This needs to be *un*synchronized to avoid deadlock.
988                     ContentResolver resolver = mContext.getContentResolver();
989                     Checkin.reportCrash(resolver, crashData);
990                 }
991                 synchronized (ActivityManagerService.this) {
992                     ProcessRecord proc = (ProcessRecord)data.get("app");
993                     if (proc != null && proc.crashDialog != null) {
994                         Log.e(TAG, "App already has crash dialog: " + proc);
995                         return;
996                     }
997                     AppErrorResult res = (AppErrorResult) data.get("result");
998                     if (!mSleeping && !mShuttingDown) {
999                         Dialog d = new AppErrorDialog(
1000                                 mContext, res, proc,
1001                                 (Integer)data.get("flags"),
1002                                 (String)data.get("shortMsg"),
1003                                 (String)data.get("longMsg"));
1004                         d.show();
1005                         proc.crashDialog = d;
1006                     } else {
1007                         // The device is asleep, so just pretend that the user
1008                         // saw a crash dialog and hit "force quit".
1009                         res.set(0);
1010                     }
1011                 }
1012 
1013                 ensureBootCompleted();
1014             } break;
1015             case SHOW_NOT_RESPONDING_MSG: {
1016                 synchronized (ActivityManagerService.this) {
1017                     HashMap data = (HashMap) msg.obj;
1018                     ProcessRecord proc = (ProcessRecord)data.get("app");
1019                     if (proc != null && proc.anrDialog != null) {
1020                         Log.e(TAG, "App already has anr dialog: " + proc);
1021                         return;
1022                     }
1023 
1024                     broadcastIntentLocked(null, null, new Intent("android.intent.action.ANR"),
1025                             null, null, 0, null, null, null,
1026                             false, false, MY_PID, Process.SYSTEM_UID);
1027 
1028                     Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1029                             mContext, proc, (HistoryRecord)data.get("activity"));
1030                     d.show();
1031                     proc.anrDialog = d;
1032                 }
1033 
1034                 ensureBootCompleted();
1035             } break;
1036             case SHOW_FACTORY_ERROR_MSG: {
1037                 Dialog d = new FactoryErrorDialog(
1038                     mContext, msg.getData().getCharSequence("msg"));
1039                 d.show();
1040                 ensureBootCompleted();
1041             } break;
1042             case UPDATE_CONFIGURATION_MSG: {
1043                 final ContentResolver resolver = mContext.getContentResolver();
1044                 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1045             } break;
1046             case GC_BACKGROUND_PROCESSES_MSG: {
1047                 synchronized (ActivityManagerService.this) {
1048                     performAppGcsIfAppropriateLocked();
1049                 }
1050             } break;
1051             case WAIT_FOR_DEBUGGER_MSG: {
1052                 synchronized (ActivityManagerService.this) {
1053                     ProcessRecord app = (ProcessRecord)msg.obj;
1054                     if (msg.arg1 != 0) {
1055                         if (!app.waitedForDebugger) {
1056                             Dialog d = new AppWaitingForDebuggerDialog(
1057                                     ActivityManagerService.this,
1058                                     mContext, app);
1059                             app.waitDialog = d;
1060                             app.waitedForDebugger = true;
1061                             d.show();
1062                         }
1063                     } else {
1064                         if (app.waitDialog != null) {
1065                             app.waitDialog.dismiss();
1066                             app.waitDialog = null;
1067                         }
1068                     }
1069                 }
1070             } break;
1071             case BROADCAST_INTENT_MSG: {
1072                 if (DEBUG_BROADCAST) Log.v(
1073                         TAG, "Received BROADCAST_INTENT_MSG");
1074                 processNextBroadcast(true);
1075             } break;
1076             case BROADCAST_TIMEOUT_MSG: {
1077                 if (mDidDexOpt) {
1078                     mDidDexOpt = false;
1079                     Message nmsg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
1080                     mHandler.sendMessageDelayed(nmsg, BROADCAST_TIMEOUT);
1081                     return;
1082                 }
1083                 broadcastTimeout();
1084             } break;
1085             case PAUSE_TIMEOUT_MSG: {
1086                 IBinder token = (IBinder)msg.obj;
1087                 // We don't at this point know if the activity is fullscreen,
1088                 // so we need to be conservative and assume it isn't.
1089                 Log.w(TAG, "Activity pause timeout for " + token);
1090                 activityPaused(token, null, true);
1091             } break;
1092             case IDLE_TIMEOUT_MSG: {
1093                 if (mDidDexOpt) {
1094                     mDidDexOpt = false;
1095                     Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
1096                     nmsg.obj = msg.obj;
1097                     mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
1098                     return;
1099                 }
1100                 // We don't at this point know if the activity is fullscreen,
1101                 // so we need to be conservative and assume it isn't.
1102                 IBinder token = (IBinder)msg.obj;
1103                 Log.w(TAG, "Activity idle timeout for " + token);
1104                 activityIdleInternal(token, true, null);
1105             } break;
1106             case DESTROY_TIMEOUT_MSG: {
1107                 IBinder token = (IBinder)msg.obj;
1108                 // We don't at this point know if the activity is fullscreen,
1109                 // so we need to be conservative and assume it isn't.
1110                 Log.w(TAG, "Activity destroy timeout for " + token);
1111                 activityDestroyed(token);
1112             } break;
1113             case IDLE_NOW_MSG: {
1114                 IBinder token = (IBinder)msg.obj;
1115                 activityIdle(token, null);
1116             } break;
1117             case SERVICE_TIMEOUT_MSG: {
1118                 if (mDidDexOpt) {
1119                     mDidDexOpt = false;
1120                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1121                     nmsg.obj = msg.obj;
1122                     mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1123                     return;
1124                 }
1125                 serviceTimeout((ProcessRecord)msg.obj);
1126             } break;
1127             case UPDATE_TIME_ZONE: {
1128                 synchronized (ActivityManagerService.this) {
1129                     for (int i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) {
1130                         ProcessRecord r = mLRUProcesses.get(i);
1131                         if (r.thread != null) {
1132                             try {
1133                                 r.thread.updateTimeZone();
1134                             } catch (RemoteException ex) {
1135                                 Log.w(TAG, "Failed to update time zone for: " + r.info.processName);
1136                             }
1137                         }
1138                     }
1139                 }
1140             } break;
1141             case SHOW_UID_ERROR_MSG: {
1142                 // XXX This is a temporary dialog, no need to localize.
1143                 AlertDialog d = new BaseErrorDialog(mContext);
1144                 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1145                 d.setCancelable(false);
1146                 d.setTitle("System UIDs Inconsistent");
1147                 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
1148                 d.setButton("I'm Feeling Lucky",
1149                         mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1150                 mUidAlert = d;
1151                 d.show();
1152             } break;
1153             case IM_FEELING_LUCKY_MSG: {
1154                 if (mUidAlert != null) {
1155                     mUidAlert.dismiss();
1156                     mUidAlert = null;
1157                 }
1158             } break;
1159             case LAUNCH_TIMEOUT_MSG: {
1160                 if (mDidDexOpt) {
1161                     mDidDexOpt = false;
1162                     Message nmsg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG);
1163                     mHandler.sendMessageDelayed(nmsg, LAUNCH_TIMEOUT);
1164                     return;
1165                 }
1166                 synchronized (ActivityManagerService.this) {
1167                     if (mLaunchingActivity.isHeld()) {
1168                         Log.w(TAG, "Launch timeout has expired, giving up wake lock!");
1169                         mLaunchingActivity.release();
1170                     }
1171                 }
1172             } break;
1173             case SERVICE_ERROR_MSG: {
1174                 ServiceRecord srv = (ServiceRecord)msg.obj;
1175                 // This needs to be *un*synchronized to avoid deadlock.
1176                 Checkin.logEvent(mContext.getContentResolver(),
1177                         Checkin.Events.Tag.SYSTEM_SERVICE_LOOPING,
1178                         srv.name.toShortString());
1179             } break;
1180             case RESUME_TOP_ACTIVITY_MSG: {
1181                 synchronized (ActivityManagerService.this) {
1182                     resumeTopActivityLocked(null);
1183                 }
1184             } break;
1185             case PROC_START_TIMEOUT_MSG: {
1186                 if (mDidDexOpt) {
1187                     mDidDexOpt = false;
1188                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1189                     nmsg.obj = msg.obj;
1190                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1191                     return;
1192                 }
1193                 ProcessRecord app = (ProcessRecord)msg.obj;
1194                 synchronized (ActivityManagerService.this) {
1195                     processStartTimedOutLocked(app);
1196                 }
1197             } break;
1198             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1199                 synchronized (ActivityManagerService.this) {
1200                     doPendingActivityLaunchesLocked(true);
1201                 }
1202             } break;
1203             case KILL_APPLICATION_MSG: {
1204                 synchronized (ActivityManagerService.this) {
1205                     int uid = msg.arg1;
1206                     boolean restart = (msg.arg2 == 1);
1207                     String pkg = (String) msg.obj;
1208                     uninstallPackageLocked(pkg, uid, restart);
1209                 }
1210             } break;
1211             }
1212         }
1213     };
1214 
setSystemProcess()1215     public static void setSystemProcess() {
1216         try {
1217             ActivityManagerService m = mSelf;
1218 
1219             ServiceManager.addService("activity", m);
1220             ServiceManager.addService("meminfo", new MemBinder(m));
1221             if (MONITOR_CPU_USAGE) {
1222                 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1223             }
1224             ServiceManager.addService("activity.broadcasts", new BroadcastsBinder(m));
1225             ServiceManager.addService("activity.services", new ServicesBinder(m));
1226             ServiceManager.addService("activity.senders", new SendersBinder(m));
1227             ServiceManager.addService("activity.providers", new ProvidersBinder(m));
1228             ServiceManager.addService("permission", new PermissionController(m));
1229 
1230             ApplicationInfo info =
1231                 mSelf.mContext.getPackageManager().getApplicationInfo(
1232                         "android", STOCK_PM_FLAGS);
1233             mSystemThread.installSystemApplicationInfo(info);
1234 
1235             synchronized (mSelf) {
1236                 ProcessRecord app = mSelf.newProcessRecordLocked(
1237                         mSystemThread.getApplicationThread(), info,
1238                         info.processName);
1239                 app.persistent = true;
1240                 app.pid = Process.myPid();
1241                 app.maxAdj = SYSTEM_ADJ;
1242                 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1243                 synchronized (mSelf.mPidsSelfLocked) {
1244                     mSelf.mPidsSelfLocked.put(app.pid, app);
1245                 }
1246                 mSelf.updateLRUListLocked(app, true);
1247             }
1248         } catch (PackageManager.NameNotFoundException e) {
1249             throw new RuntimeException(
1250                     "Unable to find android system package", e);
1251         }
1252     }
1253 
setWindowManager(WindowManagerService wm)1254     public void setWindowManager(WindowManagerService wm) {
1255         mWindowManager = wm;
1256     }
1257 
main(int factoryTest)1258     public static final Context main(int factoryTest) {
1259         AThread thr = new AThread();
1260         thr.start();
1261 
1262         synchronized (thr) {
1263             while (thr.mService == null) {
1264                 try {
1265                     thr.wait();
1266                 } catch (InterruptedException e) {
1267                 }
1268             }
1269         }
1270 
1271         ActivityManagerService m = thr.mService;
1272         mSelf = m;
1273         ActivityThread at = ActivityThread.systemMain();
1274         mSystemThread = at;
1275         Context context = at.getSystemContext();
1276         m.mContext = context;
1277         m.mFactoryTest = factoryTest;
1278         PowerManager pm =
1279             (PowerManager)context.getSystemService(Context.POWER_SERVICE);
1280         m.mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
1281         m.mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
1282         m.mLaunchingActivity.setReferenceCounted(false);
1283 
1284         m.mBatteryStatsService.publish(context);
1285         m.mUsageStatsService.publish(context);
1286 
1287         synchronized (thr) {
1288             thr.mReady = true;
1289             thr.notifyAll();
1290         }
1291 
1292         m.startRunning(null, null, null, null);
1293 
1294         return context;
1295     }
1296 
self()1297     public static ActivityManagerService self() {
1298         return mSelf;
1299     }
1300 
1301     static class AThread extends Thread {
1302         ActivityManagerService mService;
1303         boolean mReady = false;
1304 
AThread()1305         public AThread() {
1306             super("ActivityManager");
1307         }
1308 
run()1309         public void run() {
1310             Looper.prepare();
1311 
1312             android.os.Process.setThreadPriority(
1313                     android.os.Process.THREAD_PRIORITY_FOREGROUND);
1314 
1315             ActivityManagerService m = new ActivityManagerService();
1316 
1317             synchronized (this) {
1318                 mService = m;
1319                 notifyAll();
1320             }
1321 
1322             synchronized (this) {
1323                 while (!mReady) {
1324                     try {
1325                         wait();
1326                     } catch (InterruptedException e) {
1327                     }
1328                 }
1329             }
1330 
1331             Looper.loop();
1332         }
1333     }
1334 
1335     static class BroadcastsBinder extends Binder {
1336         ActivityManagerService mActivityManagerService;
BroadcastsBinder(ActivityManagerService activityManagerService)1337         BroadcastsBinder(ActivityManagerService activityManagerService) {
1338             mActivityManagerService = activityManagerService;
1339         }
1340 
1341         @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)1342         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1343             mActivityManagerService.dumpBroadcasts(pw);
1344         }
1345     }
1346 
1347     static class ServicesBinder extends Binder {
1348         ActivityManagerService mActivityManagerService;
ServicesBinder(ActivityManagerService activityManagerService)1349         ServicesBinder(ActivityManagerService activityManagerService) {
1350             mActivityManagerService = activityManagerService;
1351         }
1352 
1353         @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)1354         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1355             mActivityManagerService.dumpServices(pw);
1356         }
1357     }
1358 
1359     static class SendersBinder extends Binder {
1360         ActivityManagerService mActivityManagerService;
SendersBinder(ActivityManagerService activityManagerService)1361         SendersBinder(ActivityManagerService activityManagerService) {
1362             mActivityManagerService = activityManagerService;
1363         }
1364 
1365         @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)1366         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1367             mActivityManagerService.dumpSenders(pw);
1368         }
1369     }
1370 
1371     static class ProvidersBinder extends Binder {
1372         ActivityManagerService mActivityManagerService;
ProvidersBinder(ActivityManagerService activityManagerService)1373         ProvidersBinder(ActivityManagerService activityManagerService) {
1374             mActivityManagerService = activityManagerService;
1375         }
1376 
1377         @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)1378         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1379             mActivityManagerService.dumpProviders(pw);
1380         }
1381     }
1382 
1383     static class MemBinder extends Binder {
1384         ActivityManagerService mActivityManagerService;
MemBinder(ActivityManagerService activityManagerService)1385         MemBinder(ActivityManagerService activityManagerService) {
1386             mActivityManagerService = activityManagerService;
1387         }
1388 
1389         @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)1390         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1391             ActivityManagerService service = mActivityManagerService;
1392             ArrayList<ProcessRecord> procs;
1393             synchronized (mActivityManagerService) {
1394                 if (args != null && args.length > 0
1395                         && args[0].charAt(0) != '-') {
1396                     procs = new ArrayList<ProcessRecord>();
1397                     int pid = -1;
1398                     try {
1399                         pid = Integer.parseInt(args[0]);
1400                     } catch (NumberFormatException e) {
1401 
1402                     }
1403                     for (int i=0; i<service.mLRUProcesses.size(); i++) {
1404                         ProcessRecord proc = service.mLRUProcesses.get(i);
1405                         if (proc.pid == pid) {
1406                             procs.add(proc);
1407                         } else if (proc.processName.equals(args[0])) {
1408                             procs.add(proc);
1409                         }
1410                     }
1411                     if (procs.size() <= 0) {
1412                         pw.println("No process found for: " + args[0]);
1413                         return;
1414                     }
1415                 } else {
1416                     procs = service.mLRUProcesses;
1417                 }
1418             }
1419             dumpApplicationMemoryUsage(fd, pw, procs, "  ", args);
1420         }
1421     }
1422 
1423     static class CpuBinder extends Binder {
1424         ActivityManagerService mActivityManagerService;
CpuBinder(ActivityManagerService activityManagerService)1425         CpuBinder(ActivityManagerService activityManagerService) {
1426             mActivityManagerService = activityManagerService;
1427         }
1428 
1429         @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)1430         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1431             synchronized (mActivityManagerService.mProcessStatsThread) {
1432                 pw.print(mActivityManagerService.mProcessStats.printCurrentState());
1433             }
1434         }
1435     }
1436 
ActivityManagerService()1437     private ActivityManagerService() {
1438         String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT");
1439         if (v != null && Integer.getInteger(v) != 0) {
1440             mSimpleProcessManagement = true;
1441         }
1442         v = System.getenv("ANDROID_DEBUG_APP");
1443         if (v != null) {
1444             mSimpleProcessManagement = true;
1445         }
1446 
1447         Log.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1448 
1449         MY_PID = Process.myPid();
1450 
1451         File dataDir = Environment.getDataDirectory();
1452         File systemDir = new File(dataDir, "system");
1453         systemDir.mkdirs();
1454         mBatteryStatsService = new BatteryStatsService(new File(
1455                 systemDir, "batterystats.bin").toString());
1456         mBatteryStatsService.getActiveStatistics().readLocked();
1457         mBatteryStatsService.getActiveStatistics().writeLocked();
1458 
1459         mUsageStatsService = new UsageStatsService( new File(
1460                 systemDir, "usagestats").toString());
1461 
1462         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1463             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1464 
1465         mConfiguration.makeDefault();
1466         mProcessStats.init();
1467 
1468         // Add ourself to the Watchdog monitors.
1469         Watchdog.getInstance().addMonitor(this);
1470 
1471         // These values are set in system/rootdir/init.rc on startup.
1472         FOREGROUND_APP_ADJ =
1473             Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_ADJ"));
1474         VISIBLE_APP_ADJ =
1475             Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_ADJ"));
1476         SECONDARY_SERVER_ADJ =
1477             Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_ADJ"));
1478         BACKUP_APP_ADJ =
1479             Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_ADJ"));
1480         HOME_APP_ADJ =
1481             Integer.valueOf(SystemProperties.get("ro.HOME_APP_ADJ"));
1482         HIDDEN_APP_MIN_ADJ =
1483             Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MIN_ADJ"));
1484         CONTENT_PROVIDER_ADJ =
1485             Integer.valueOf(SystemProperties.get("ro.CONTENT_PROVIDER_ADJ"));
1486         HIDDEN_APP_MAX_ADJ = CONTENT_PROVIDER_ADJ-1;
1487         EMPTY_APP_ADJ =
1488             Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_ADJ"));
1489         FOREGROUND_APP_MEM =
1490             Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_MEM"))*PAGE_SIZE;
1491         VISIBLE_APP_MEM =
1492             Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_MEM"))*PAGE_SIZE;
1493         SECONDARY_SERVER_MEM =
1494             Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_MEM"))*PAGE_SIZE;
1495         BACKUP_APP_MEM =
1496             Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_MEM"))*PAGE_SIZE;
1497         HOME_APP_MEM =
1498             Integer.valueOf(SystemProperties.get("ro.HOME_APP_MEM"))*PAGE_SIZE;
1499         HIDDEN_APP_MEM =
1500             Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MEM"))*PAGE_SIZE;
1501         EMPTY_APP_MEM =
1502             Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_MEM"))*PAGE_SIZE;
1503 
1504         mProcessStatsThread = new Thread("ProcessStats") {
1505             public void run() {
1506                 while (true) {
1507                     try {
1508                         try {
1509                             synchronized(this) {
1510                                 final long now = SystemClock.uptimeMillis();
1511                                 long nextCpuDelay = (mLastCpuTime+MONITOR_CPU_MAX_TIME)-now;
1512                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1513                                 //Log.i(TAG, "Cpu delay=" + nextCpuDelay
1514                                 //        + ", write delay=" + nextWriteDelay);
1515                                 if (nextWriteDelay < nextCpuDelay) {
1516                                     nextCpuDelay = nextWriteDelay;
1517                                 }
1518                                 if (nextCpuDelay > 0) {
1519                                     this.wait(nextCpuDelay);
1520                                 }
1521                             }
1522                         } catch (InterruptedException e) {
1523                         }
1524 
1525                         updateCpuStatsNow();
1526                     } catch (Exception e) {
1527                         Log.e(TAG, "Unexpected exception collecting process stats", e);
1528                     }
1529                 }
1530             }
1531         };
1532         mProcessStatsThread.start();
1533     }
1534 
1535     @Override
onTransact(int code, Parcel data, Parcel reply, int flags)1536     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1537             throws RemoteException {
1538         try {
1539             return super.onTransact(code, data, reply, flags);
1540         } catch (RuntimeException e) {
1541             // The activity manager only throws security exceptions, so let's
1542             // log all others.
1543             if (!(e instanceof SecurityException)) {
1544                 Log.e(TAG, "Activity Manager Crash", e);
1545             }
1546             throw e;
1547         }
1548     }
1549 
updateCpuStats()1550     void updateCpuStats() {
1551         synchronized (mProcessStatsThread) {
1552             final long now = SystemClock.uptimeMillis();
1553             if (mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) {
1554                 mProcessStatsThread.notify();
1555             }
1556         }
1557     }
1558 
updateCpuStatsNow()1559     void updateCpuStatsNow() {
1560         synchronized (mProcessStatsThread) {
1561             final long now = SystemClock.uptimeMillis();
1562             boolean haveNewCpuStats = false;
1563 
1564             if (MONITOR_CPU_USAGE &&
1565                     mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) {
1566                 mLastCpuTime = now;
1567                 haveNewCpuStats = true;
1568                 mProcessStats.update();
1569                 //Log.i(TAG, mProcessStats.printCurrentState());
1570                 //Log.i(TAG, "Total CPU usage: "
1571                 //        + mProcessStats.getTotalCpuPercent() + "%");
1572 
1573                 // Log the cpu usage if the property is set.
1574                 if ("true".equals(SystemProperties.get("events.cpu"))) {
1575                     int user = mProcessStats.getLastUserTime();
1576                     int system = mProcessStats.getLastSystemTime();
1577                     int iowait = mProcessStats.getLastIoWaitTime();
1578                     int irq = mProcessStats.getLastIrqTime();
1579                     int softIrq = mProcessStats.getLastSoftIrqTime();
1580                     int idle = mProcessStats.getLastIdleTime();
1581 
1582                     int total = user + system + iowait + irq + softIrq + idle;
1583                     if (total == 0) total = 1;
1584 
1585                     EventLog.writeEvent(LOG_CPU,
1586                             ((user+system+iowait+irq+softIrq) * 100) / total,
1587                             (user * 100) / total,
1588                             (system * 100) / total,
1589                             (iowait * 100) / total,
1590                             (irq * 100) / total,
1591                             (softIrq * 100) / total);
1592                 }
1593             }
1594 
1595             long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1596             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1597             synchronized(bstats) {
1598                 synchronized(mPidsSelfLocked) {
1599                     if (haveNewCpuStats) {
1600                         if (mBatteryStatsService.isOnBattery()) {
1601                             final int N = mProcessStats.countWorkingStats();
1602                             for (int i=0; i<N; i++) {
1603                                 ProcessStats.Stats st
1604                                         = mProcessStats.getWorkingStats(i);
1605                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1606                                 if (pr != null) {
1607                                     BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1608                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
1609                                     ps.addSpeedStepTimes(cpuSpeedTimes);
1610                                 } else {
1611                                     BatteryStatsImpl.Uid.Proc ps =
1612                                             bstats.getProcessStatsLocked(st.name, st.pid);
1613                                     if (ps != null) {
1614                                         ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
1615                                         ps.addSpeedStepTimes(cpuSpeedTimes);
1616                                     }
1617                                 }
1618                             }
1619                         }
1620                     }
1621                 }
1622 
1623                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1624                     mLastWriteTime = now;
1625                     mBatteryStatsService.getActiveStatistics().writeLocked();
1626                 }
1627             }
1628         }
1629     }
1630 
1631     /**
1632      * Initialize the application bind args. These are passed to each
1633      * process when the bindApplication() IPC is sent to the process. They're
1634      * lazily setup to make sure the services are running when they're asked for.
1635      */
getCommonServicesLocked()1636     private HashMap<String, IBinder> getCommonServicesLocked() {
1637         if (mAppBindArgs == null) {
1638             mAppBindArgs = new HashMap<String, IBinder>();
1639 
1640             // Setup the application init args
1641             mAppBindArgs.put("package", ServiceManager.getService("package"));
1642             mAppBindArgs.put("window", ServiceManager.getService("window"));
1643             mAppBindArgs.put(Context.ALARM_SERVICE,
1644                     ServiceManager.getService(Context.ALARM_SERVICE));
1645         }
1646         return mAppBindArgs;
1647     }
1648 
setFocusedActivityLocked(HistoryRecord r)1649     private final void setFocusedActivityLocked(HistoryRecord r) {
1650         if (mFocusedActivity != r) {
1651             mFocusedActivity = r;
1652             mWindowManager.setFocusedApp(r, true);
1653         }
1654     }
1655 
updateLRUListLocked(ProcessRecord app, boolean oomAdj)1656     private final void updateLRUListLocked(ProcessRecord app,
1657             boolean oomAdj) {
1658         // put it on the LRU to keep track of when it should be exited.
1659         int lrui = mLRUProcesses.indexOf(app);
1660         if (lrui >= 0) mLRUProcesses.remove(lrui);
1661         mLRUProcesses.add(app);
1662         //Log.i(TAG, "Putting proc to front: " + app.processName);
1663         if (oomAdj) {
1664             updateOomAdjLocked();
1665         }
1666     }
1667 
updateLRUListLocked(HistoryRecord r)1668     private final boolean updateLRUListLocked(HistoryRecord r) {
1669         final boolean hadit = mLRUActivities.remove(r);
1670         mLRUActivities.add(r);
1671         return hadit;
1672     }
1673 
topRunningActivityLocked(HistoryRecord notTop)1674     private final HistoryRecord topRunningActivityLocked(HistoryRecord notTop) {
1675         int i = mHistory.size()-1;
1676         while (i >= 0) {
1677             HistoryRecord r = (HistoryRecord)mHistory.get(i);
1678             if (!r.finishing && r != notTop) {
1679                 return r;
1680             }
1681             i--;
1682         }
1683         return null;
1684     }
1685 
topRunningNonDelayedActivityLocked(HistoryRecord notTop)1686     private final HistoryRecord topRunningNonDelayedActivityLocked(HistoryRecord notTop) {
1687         int i = mHistory.size()-1;
1688         while (i >= 0) {
1689             HistoryRecord r = (HistoryRecord)mHistory.get(i);
1690             if (!r.finishing && !r.delayedResume && r != notTop) {
1691                 return r;
1692             }
1693             i--;
1694         }
1695         return null;
1696     }
1697 
1698     /**
1699      * This is a simplified version of topRunningActivityLocked that provides a number of
1700      * optional skip-over modes.  It is intended for use with the ActivityController hook only.
1701      *
1702      * @param token If non-null, any history records matching this token will be skipped.
1703      * @param taskId If non-zero, we'll attempt to skip over records with the same task ID.
1704      *
1705      * @return Returns the HistoryRecord of the next activity on the stack.
1706      */
topRunningActivityLocked(IBinder token, int taskId)1707     private final HistoryRecord topRunningActivityLocked(IBinder token, int taskId) {
1708         int i = mHistory.size()-1;
1709         while (i >= 0) {
1710             HistoryRecord r = (HistoryRecord)mHistory.get(i);
1711             // Note: the taskId check depends on real taskId fields being non-zero
1712             if (!r.finishing && (token != r) && (taskId != r.task.taskId)) {
1713                 return r;
1714             }
1715             i--;
1716         }
1717         return null;
1718     }
1719 
getProcessRecordLocked( String processName, int uid)1720     private final ProcessRecord getProcessRecordLocked(
1721             String processName, int uid) {
1722         if (uid == Process.SYSTEM_UID) {
1723             // The system gets to run in any process.  If there are multiple
1724             // processes with the same uid, just pick the first (this
1725             // should never happen).
1726             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1727                     processName);
1728             return procs != null ? procs.valueAt(0) : null;
1729         }
1730         ProcessRecord proc = mProcessNames.get(processName, uid);
1731         return proc;
1732     }
1733 
ensurePackageDexOpt(String packageName)1734     private void ensurePackageDexOpt(String packageName) {
1735         IPackageManager pm = ActivityThread.getPackageManager();
1736         try {
1737             if (pm.performDexOpt(packageName)) {
1738                 mDidDexOpt = true;
1739             }
1740         } catch (RemoteException e) {
1741         }
1742     }
1743 
isNextTransitionForward()1744     private boolean isNextTransitionForward() {
1745         int transit = mWindowManager.getPendingAppTransition();
1746         return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1747                 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1748                 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1749     }
1750 
realStartActivityLocked(HistoryRecord r, ProcessRecord app, boolean andResume, boolean checkConfig)1751     private final boolean realStartActivityLocked(HistoryRecord r,
1752             ProcessRecord app, boolean andResume, boolean checkConfig)
1753             throws RemoteException {
1754 
1755         r.startFreezingScreenLocked(app, 0);
1756         mWindowManager.setAppVisibility(r, true);
1757 
1758         // Have the window manager re-evaluate the orientation of
1759         // the screen based on the new activity order.  Note that
1760         // as a result of this, it can call back into the activity
1761         // manager with a new orientation.  We don't care about that,
1762         // because the activity is not currently running so we are
1763         // just restarting it anyway.
1764         if (checkConfig) {
1765             Configuration config = mWindowManager.updateOrientationFromAppTokens(
1766                     mConfiguration,
1767                     r.mayFreezeScreenLocked(app) ? r : null);
1768             updateConfigurationLocked(config, r);
1769         }
1770 
1771         r.app = app;
1772 
1773         if (localLOGV) Log.v(TAG, "Launching: " + r);
1774 
1775         int idx = app.activities.indexOf(r);
1776         if (idx < 0) {
1777             app.activities.add(r);
1778         }
1779         updateLRUListLocked(app, true);
1780 
1781         try {
1782             if (app.thread == null) {
1783                 throw new RemoteException();
1784             }
1785             List<ResultInfo> results = null;
1786             List<Intent> newIntents = null;
1787             if (andResume) {
1788                 results = r.results;
1789                 newIntents = r.newIntents;
1790             }
1791             if (DEBUG_SWITCH) Log.v(TAG, "Launching: " + r
1792                     + " icicle=" + r.icicle
1793                     + " with results=" + results + " newIntents=" + newIntents
1794                     + " andResume=" + andResume);
1795             if (andResume) {
1796                 EventLog.writeEvent(LOG_AM_RESTART_ACTIVITY,
1797                         System.identityHashCode(r),
1798                         r.task.taskId, r.shortComponentName);
1799             }
1800             if (r.isHomeActivity) {
1801                 mHomeProcess = app;
1802             }
1803             ensurePackageDexOpt(r.intent.getComponent().getPackageName());
1804             app.thread.scheduleLaunchActivity(new Intent(r.intent), r,
1805                     System.identityHashCode(r),
1806                     r.info, r.icicle, results, newIntents, !andResume,
1807                     isNextTransitionForward());
1808         } catch (RemoteException e) {
1809             if (r.launchFailed) {
1810                 // This is the second time we failed -- finish activity
1811                 // and give up.
1812                 Log.e(TAG, "Second failure launching "
1813                       + r.intent.getComponent().flattenToShortString()
1814                       + ", giving up", e);
1815                 appDiedLocked(app, app.pid, app.thread);
1816                 requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null,
1817                         "2nd-crash");
1818                 return false;
1819             }
1820 
1821             // This is the first time we failed -- restart process and
1822             // retry.
1823             app.activities.remove(r);
1824             throw e;
1825         }
1826 
1827         r.launchFailed = false;
1828         if (updateLRUListLocked(r)) {
1829             Log.w(TAG, "Activity " + r
1830                   + " being launched, but already in LRU list");
1831         }
1832 
1833         if (andResume) {
1834             // As part of the process of launching, ActivityThread also performs
1835             // a resume.
1836             r.state = ActivityState.RESUMED;
1837             r.icicle = null;
1838             r.haveState = false;
1839             r.stopped = false;
1840             mResumedActivity = r;
1841             r.task.touchActiveTime();
1842             completeResumeLocked(r);
1843             pauseIfSleepingLocked();
1844         } else {
1845             // This activity is not starting in the resumed state... which
1846             // should look like we asked it to pause+stop (but remain visible),
1847             // and it has done so and reported back the current icicle and
1848             // other state.
1849             r.state = ActivityState.STOPPED;
1850             r.stopped = true;
1851         }
1852 
1853         // Launch the new version setup screen if needed.  We do this -after-
1854         // launching the initial activity (that is, home), so that it can have
1855         // a chance to initialize itself while in the background, making the
1856         // switch back to it faster and look better.
1857         startSetupActivityLocked();
1858 
1859         return true;
1860     }
1861 
startSpecificActivityLocked(HistoryRecord r, boolean andResume, boolean checkConfig)1862     private final void startSpecificActivityLocked(HistoryRecord r,
1863             boolean andResume, boolean checkConfig) {
1864         // Is this activity's application already running?
1865         ProcessRecord app = getProcessRecordLocked(r.processName,
1866                 r.info.applicationInfo.uid);
1867 
1868         if (r.startTime == 0) {
1869             r.startTime = SystemClock.uptimeMillis();
1870             if (mInitialStartTime == 0) {
1871                 mInitialStartTime = r.startTime;
1872             }
1873         } else if (mInitialStartTime == 0) {
1874             mInitialStartTime = SystemClock.uptimeMillis();
1875         }
1876 
1877         if (app != null && app.thread != null) {
1878             try {
1879                 realStartActivityLocked(r, app, andResume, checkConfig);
1880                 return;
1881             } catch (RemoteException e) {
1882                 Log.w(TAG, "Exception when starting activity "
1883                         + r.intent.getComponent().flattenToShortString(), e);
1884             }
1885 
1886             // If a dead object exception was thrown -- fall through to
1887             // restart the application.
1888         }
1889 
1890         startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
1891                 "activity", r.intent.getComponent(), false);
1892     }
1893 
startProcessLocked(String processName, ApplicationInfo info, boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, boolean allowWhileBooting)1894     private final ProcessRecord startProcessLocked(String processName,
1895             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1896             String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
1897         ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1898         // We don't have to do anything more if:
1899         // (1) There is an existing application record; and
1900         // (2) The caller doesn't think it is dead, OR there is no thread
1901         //     object attached to it so we know it couldn't have crashed; and
1902         // (3) There is a pid assigned to it, so it is either starting or
1903         //     already running.
1904         if (DEBUG_PROCESSES) Log.v(TAG, "startProcess: name=" + processName
1905                 + " app=" + app + " knownToBeDead=" + knownToBeDead
1906                 + " thread=" + (app != null ? app.thread : null)
1907                 + " pid=" + (app != null ? app.pid : -1));
1908         if (app != null &&
1909                 (!knownToBeDead || app.thread == null) && app.pid > 0) {
1910             return app;
1911         }
1912 
1913         String hostingNameStr = hostingName != null
1914                 ? hostingName.flattenToShortString() : null;
1915 
1916         if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1917             // If we are in the background, then check to see if this process
1918             // is bad.  If so, we will just silently fail.
1919             if (mBadProcesses.get(info.processName, info.uid) != null) {
1920                 return null;
1921             }
1922         } else {
1923             // When the user is explicitly starting a process, then clear its
1924             // crash count so that we won't make it bad until they see at
1925             // least one crash dialog again, and make the process good again
1926             // if it had been bad.
1927             mProcessCrashTimes.remove(info.processName, info.uid);
1928             if (mBadProcesses.get(info.processName, info.uid) != null) {
1929                 EventLog.writeEvent(LOG_AM_PROCESS_GOOD, info.uid,
1930                         info.processName);
1931                 mBadProcesses.remove(info.processName, info.uid);
1932                 if (app != null) {
1933                     app.bad = false;
1934                 }
1935             }
1936         }
1937 
1938         if (app == null) {
1939             app = newProcessRecordLocked(null, info, processName);
1940             mProcessNames.put(processName, info.uid, app);
1941         } else {
1942             // If this is a new package in the process, add the package to the list
1943             app.addPackage(info.packageName);
1944         }
1945 
1946         // If the system is not ready yet, then hold off on starting this
1947         // process until it is.
1948         if (!mSystemReady
1949                 && !isAllowedWhileBooting(info)
1950                 && !allowWhileBooting) {
1951             if (!mProcessesOnHold.contains(app)) {
1952                 mProcessesOnHold.add(app);
1953             }
1954             return app;
1955         }
1956 
1957         startProcessLocked(app, hostingType, hostingNameStr);
1958         return (app.pid != 0) ? app : null;
1959     }
1960 
isAllowedWhileBooting(ApplicationInfo ai)1961     boolean isAllowedWhileBooting(ApplicationInfo ai) {
1962         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1963     }
1964 
startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr)1965     private final void startProcessLocked(ProcessRecord app,
1966             String hostingType, String hostingNameStr) {
1967         if (app.pid > 0 && app.pid != MY_PID) {
1968             synchronized (mPidsSelfLocked) {
1969                 mPidsSelfLocked.remove(app.pid);
1970                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1971             }
1972             app.pid = 0;
1973         }
1974 
1975         mProcessesOnHold.remove(app);
1976 
1977         updateCpuStats();
1978 
1979         System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1980         mProcDeaths[0] = 0;
1981 
1982         try {
1983             int uid = app.info.uid;
1984             int[] gids = null;
1985             try {
1986                 gids = mContext.getPackageManager().getPackageGids(
1987                         app.info.packageName);
1988             } catch (PackageManager.NameNotFoundException e) {
1989                 Log.w(TAG, "Unable to retrieve gids", e);
1990             }
1991             if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1992                 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1993                         && mTopComponent != null
1994                         && app.processName.equals(mTopComponent.getPackageName())) {
1995                     uid = 0;
1996                 }
1997                 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1998                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1999                     uid = 0;
2000                 }
2001             }
2002             int debugFlags = 0;
2003             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2004                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2005             }
2006             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2007                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2008             }
2009             if ("1".equals(SystemProperties.get("debug.assert"))) {
2010                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2011             }
2012             int pid = Process.start("android.app.ActivityThread",
2013                     mSimpleProcessManagement ? app.processName : null, uid, uid,
2014                     gids, debugFlags, null);
2015             BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2016             synchronized (bs) {
2017                 if (bs.isOnBattery()) {
2018                     app.batteryStats.incStartsLocked();
2019                 }
2020             }
2021 
2022             EventLog.writeEvent(LOG_AM_PROCESS_START, pid, uid,
2023                     app.processName, hostingType,
2024                     hostingNameStr != null ? hostingNameStr : "");
2025 
2026             if (app.persistent) {
2027                 Watchdog.getInstance().processStarted(app, app.processName, pid);
2028             }
2029 
2030             StringBuilder buf = mStringBuilder;
2031             buf.setLength(0);
2032             buf.append("Start proc ");
2033             buf.append(app.processName);
2034             buf.append(" for ");
2035             buf.append(hostingType);
2036             if (hostingNameStr != null) {
2037                 buf.append(" ");
2038                 buf.append(hostingNameStr);
2039             }
2040             buf.append(": pid=");
2041             buf.append(pid);
2042             buf.append(" uid=");
2043             buf.append(uid);
2044             buf.append(" gids={");
2045             if (gids != null) {
2046                 for (int gi=0; gi<gids.length; gi++) {
2047                     if (gi != 0) buf.append(", ");
2048                     buf.append(gids[gi]);
2049 
2050                 }
2051             }
2052             buf.append("}");
2053             Log.i(TAG, buf.toString());
2054             if (pid == 0 || pid == MY_PID) {
2055                 // Processes are being emulated with threads.
2056                 app.pid = MY_PID;
2057                 app.removed = false;
2058                 mStartingProcesses.add(app);
2059             } else if (pid > 0) {
2060                 app.pid = pid;
2061                 app.removed = false;
2062                 synchronized (mPidsSelfLocked) {
2063                     this.mPidsSelfLocked.put(pid, app);
2064                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2065                     msg.obj = app;
2066                     mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
2067                 }
2068             } else {
2069                 app.pid = 0;
2070                 RuntimeException e = new RuntimeException(
2071                         "Failure starting process " + app.processName
2072                         + ": returned pid=" + pid);
2073                 Log.e(TAG, e.getMessage(), e);
2074             }
2075         } catch (RuntimeException e) {
2076             // XXX do better error recovery.
2077             app.pid = 0;
2078             Log.e(TAG, "Failure starting process " + app.processName, e);
2079         }
2080     }
2081 
startPausingLocked(boolean userLeaving, boolean uiSleeping)2082     private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) {
2083         if (mPausingActivity != null) {
2084             RuntimeException e = new RuntimeException();
2085             Log.e(TAG, "Trying to pause when pause is already pending for "
2086                   + mPausingActivity, e);
2087         }
2088         HistoryRecord prev = mResumedActivity;
2089         if (prev == null) {
2090             RuntimeException e = new RuntimeException();
2091             Log.e(TAG, "Trying to pause when nothing is resumed", e);
2092             resumeTopActivityLocked(null);
2093             return;
2094         }
2095         if (DEBUG_PAUSE) Log.v(TAG, "Start pausing: " + prev);
2096         mResumedActivity = null;
2097         mPausingActivity = prev;
2098         mLastPausedActivity = prev;
2099         prev.state = ActivityState.PAUSING;
2100         prev.task.touchActiveTime();
2101 
2102         updateCpuStats();
2103 
2104         if (prev.app != null && prev.app.thread != null) {
2105             if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending pause: " + prev);
2106             try {
2107                 EventLog.writeEvent(LOG_AM_PAUSE_ACTIVITY,
2108                         System.identityHashCode(prev),
2109                         prev.shortComponentName);
2110                 prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving,
2111                         prev.configChangeFlags);
2112                 updateUsageStats(prev, false);
2113             } catch (Exception e) {
2114                 // Ignore exception, if process died other code will cleanup.
2115                 Log.w(TAG, "Exception thrown during pause", e);
2116                 mPausingActivity = null;
2117                 mLastPausedActivity = null;
2118             }
2119         } else {
2120             mPausingActivity = null;
2121             mLastPausedActivity = null;
2122         }
2123 
2124         // If we are not going to sleep, we want to ensure the device is
2125         // awake until the next activity is started.
2126         if (!mSleeping && !mShuttingDown) {
2127             mLaunchingActivity.acquire();
2128             if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
2129                 // To be safe, don't allow the wake lock to be held for too long.
2130                 Message msg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG);
2131                 mHandler.sendMessageDelayed(msg, LAUNCH_TIMEOUT);
2132             }
2133         }
2134 
2135 
2136         if (mPausingActivity != null) {
2137             // Have the window manager pause its key dispatching until the new
2138             // activity has started.  If we're pausing the activity just because
2139             // the screen is being turned off and the UI is sleeping, don't interrupt
2140             // key dispatch; the same activity will pick it up again on wakeup.
2141             if (!uiSleeping) {
2142                 prev.pauseKeyDispatchingLocked();
2143             } else {
2144                 if (DEBUG_PAUSE) Log.v(TAG, "Key dispatch not paused for screen off");
2145             }
2146 
2147             // Schedule a pause timeout in case the app doesn't respond.
2148             // We don't give it much time because this directly impacts the
2149             // responsiveness seen by the user.
2150             Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
2151             msg.obj = prev;
2152             mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
2153             if (DEBUG_PAUSE) Log.v(TAG, "Waiting for pause to complete...");
2154         } else {
2155             // This activity failed to schedule the
2156             // pause, so just treat it as being paused now.
2157             if (DEBUG_PAUSE) Log.v(TAG, "Activity not running, resuming next.");
2158             resumeTopActivityLocked(null);
2159         }
2160     }
2161 
completePauseLocked()2162     private final void completePauseLocked() {
2163         HistoryRecord prev = mPausingActivity;
2164         if (DEBUG_PAUSE) Log.v(TAG, "Complete pause: " + prev);
2165 
2166         if (prev != null) {
2167             if (prev.finishing) {
2168                 if (DEBUG_PAUSE) Log.v(TAG, "Executing finish of activity: " + prev);
2169                 prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE);
2170             } else if (prev.app != null) {
2171                 if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending stop: " + prev);
2172                 if (prev.waitingVisible) {
2173                     prev.waitingVisible = false;
2174                     mWaitingVisibleActivities.remove(prev);
2175                     if (DEBUG_SWITCH || DEBUG_PAUSE) Log.v(
2176                             TAG, "Complete pause, no longer waiting: " + prev);
2177                 }
2178                 if (prev.configDestroy) {
2179                     // The previous is being paused because the configuration
2180                     // is changing, which means it is actually stopping...
2181                     // To juggle the fact that we are also starting a new
2182                     // instance right now, we need to first completely stop
2183                     // the current instance before starting the new one.
2184                     if (DEBUG_PAUSE) Log.v(TAG, "Destroying after pause: " + prev);
2185                     destroyActivityLocked(prev, true);
2186                 } else {
2187                     mStoppingActivities.add(prev);
2188                     if (mStoppingActivities.size() > 3) {
2189                         // If we already have a few activities waiting to stop,
2190                         // then give up on things going idle and start clearing
2191                         // them out.
2192                         if (DEBUG_PAUSE) Log.v(TAG, "To many pending stops, forcing idle");
2193                         Message msg = Message.obtain();
2194                         msg.what = ActivityManagerService.IDLE_NOW_MSG;
2195                         mHandler.sendMessage(msg);
2196                     }
2197                 }
2198             } else {
2199                 if (DEBUG_PAUSE) Log.v(TAG, "App died during pause, not stopping: " + prev);
2200                 prev = null;
2201             }
2202             mPausingActivity = null;
2203         }
2204 
2205         if (!mSleeping && !mShuttingDown) {
2206             resumeTopActivityLocked(prev);
2207         } else {
2208             if (mGoingToSleep.isHeld()) {
2209                 mGoingToSleep.release();
2210             }
2211             if (mShuttingDown) {
2212                 notifyAll();
2213             }
2214         }
2215 
2216         if (prev != null) {
2217             prev.resumeKeyDispatchingLocked();
2218         }
2219 
2220         if (prev.app != null && prev.cpuTimeAtResume > 0 && mBatteryStatsService.isOnBattery()) {
2221             long diff = 0;
2222             synchronized (mProcessStatsThread) {
2223                 diff = mProcessStats.getCpuTimeForPid(prev.app.pid) - prev.cpuTimeAtResume;
2224             }
2225             if (diff > 0) {
2226                 BatteryStatsImpl bsi = mBatteryStatsService.getActiveStatistics();
2227                 synchronized (bsi) {
2228                     BatteryStatsImpl.Uid.Proc ps =
2229                             bsi.getProcessStatsLocked(prev.info.applicationInfo.uid,
2230                             prev.info.packageName);
2231                     if (ps != null) {
2232                         ps.addForegroundTimeLocked(diff);
2233                     }
2234                 }
2235             }
2236         }
2237         prev.cpuTimeAtResume = 0; // reset it
2238     }
2239 
2240     /**
2241      * Once we know that we have asked an application to put an activity in
2242      * the resumed state (either by launching it or explicitly telling it),
2243      * this function updates the rest of our state to match that fact.
2244      */
completeResumeLocked(HistoryRecord next)2245     private final void completeResumeLocked(HistoryRecord next) {
2246         next.idle = false;
2247         next.results = null;
2248         next.newIntents = null;
2249 
2250         // schedule an idle timeout in case the app doesn't do it for us.
2251         Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2252         msg.obj = next;
2253         mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
2254 
2255         if (false) {
2256             // The activity was never told to pause, so just keep
2257             // things going as-is.  To maintain our own state,
2258             // we need to emulate it coming back and saying it is
2259             // idle.
2260             msg = mHandler.obtainMessage(IDLE_NOW_MSG);
2261             msg.obj = next;
2262             mHandler.sendMessage(msg);
2263         }
2264 
2265         reportResumedActivityLocked(next);
2266 
2267         next.thumbnail = null;
2268         setFocusedActivityLocked(next);
2269         next.resumeKeyDispatchingLocked();
2270         ensureActivitiesVisibleLocked(null, 0);
2271         mWindowManager.executeAppTransition();
2272         mNoAnimActivities.clear();
2273 
2274         // Mark the point when the activity is resuming
2275         // TODO: To be more accurate, the mark should be before the onCreate,
2276         //       not after the onResume. But for subsequent starts, onResume is fine.
2277         if (next.app != null) {
2278             synchronized (mProcessStatsThread) {
2279                 next.cpuTimeAtResume = mProcessStats.getCpuTimeForPid(next.app.pid);
2280             }
2281         } else {
2282             next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process
2283         }
2284     }
2285 
2286     /**
2287      * Make sure that all activities that need to be visible (that is, they
2288      * currently can be seen by the user) actually are.
2289      */
ensureActivitiesVisibleLocked(HistoryRecord top, HistoryRecord starting, String onlyThisProcess, int configChanges)2290     private final void ensureActivitiesVisibleLocked(HistoryRecord top,
2291             HistoryRecord starting, String onlyThisProcess, int configChanges) {
2292         if (DEBUG_VISBILITY) Log.v(
2293                 TAG, "ensureActivitiesVisible behind " + top
2294                 + " configChanges=0x" + Integer.toHexString(configChanges));
2295 
2296         // If the top activity is not fullscreen, then we need to
2297         // make sure any activities under it are now visible.
2298         final int count = mHistory.size();
2299         int i = count-1;
2300         while (mHistory.get(i) != top) {
2301             i--;
2302         }
2303         HistoryRecord r;
2304         boolean behindFullscreen = false;
2305         for (; i>=0; i--) {
2306             r = (HistoryRecord)mHistory.get(i);
2307             if (DEBUG_VISBILITY) Log.v(
2308                     TAG, "Make visible? " + r + " finishing=" + r.finishing
2309                     + " state=" + r.state);
2310             if (r.finishing) {
2311                 continue;
2312             }
2313 
2314             final boolean doThisProcess = onlyThisProcess == null
2315                     || onlyThisProcess.equals(r.processName);
2316 
2317             // First: if this is not the current activity being started, make
2318             // sure it matches the current configuration.
2319             if (r != starting && doThisProcess) {
2320                 ensureActivityConfigurationLocked(r, 0);
2321             }
2322 
2323             if (r.app == null || r.app.thread == null) {
2324                 if (onlyThisProcess == null
2325                         || onlyThisProcess.equals(r.processName)) {
2326                     // This activity needs to be visible, but isn't even
2327                     // running...  get it started, but don't resume it
2328                     // at this point.
2329                     if (DEBUG_VISBILITY) Log.v(
2330                             TAG, "Start and freeze screen for " + r);
2331                     if (r != starting) {
2332                         r.startFreezingScreenLocked(r.app, configChanges);
2333                     }
2334                     if (!r.visible) {
2335                         if (DEBUG_VISBILITY) Log.v(
2336                                 TAG, "Starting and making visible: " + r);
2337                         mWindowManager.setAppVisibility(r, true);
2338                     }
2339                     if (r != starting) {
2340                         startSpecificActivityLocked(r, false, false);
2341                     }
2342                 }
2343 
2344             } else if (r.visible) {
2345                 // If this activity is already visible, then there is nothing
2346                 // else to do here.
2347                 if (DEBUG_VISBILITY) Log.v(
2348                         TAG, "Skipping: already visible at " + r);
2349                 r.stopFreezingScreenLocked(false);
2350 
2351             } else if (onlyThisProcess == null) {
2352                 // This activity is not currently visible, but is running.
2353                 // Tell it to become visible.
2354                 r.visible = true;
2355                 if (r.state != ActivityState.RESUMED && r != starting) {
2356                     // If this activity is paused, tell it
2357                     // to now show its window.
2358                     if (DEBUG_VISBILITY) Log.v(
2359                             TAG, "Making visible and scheduling visibility: " + r);
2360                     try {
2361                         mWindowManager.setAppVisibility(r, true);
2362                         r.app.thread.scheduleWindowVisibility(r, true);
2363                         r.stopFreezingScreenLocked(false);
2364                     } catch (Exception e) {
2365                         // Just skip on any failure; we'll make it
2366                         // visible when it next restarts.
2367                         Log.w(TAG, "Exception thrown making visibile: "
2368                                 + r.intent.getComponent(), e);
2369                     }
2370                 }
2371             }
2372 
2373             // Aggregate current change flags.
2374             configChanges |= r.configChangeFlags;
2375 
2376             if (r.fullscreen) {
2377                 // At this point, nothing else needs to be shown
2378                 if (DEBUG_VISBILITY) Log.v(
2379                         TAG, "Stopping: fullscreen at " + r);
2380                 behindFullscreen = true;
2381                 i--;
2382                 break;
2383             }
2384         }
2385 
2386         // Now for any activities that aren't visible to the user, make
2387         // sure they no longer are keeping the screen frozen.
2388         while (i >= 0) {
2389             r = (HistoryRecord)mHistory.get(i);
2390             if (DEBUG_VISBILITY) Log.v(
2391                     TAG, "Make invisible? " + r + " finishing=" + r.finishing
2392                     + " state=" + r.state
2393                     + " behindFullscreen=" + behindFullscreen);
2394             if (!r.finishing) {
2395                 if (behindFullscreen) {
2396                     if (r.visible) {
2397                         if (DEBUG_VISBILITY) Log.v(
2398                                 TAG, "Making invisible: " + r);
2399                         r.visible = false;
2400                         try {
2401                             mWindowManager.setAppVisibility(r, false);
2402                             if ((r.state == ActivityState.STOPPING
2403                                     || r.state == ActivityState.STOPPED)
2404                                     && r.app != null && r.app.thread != null) {
2405                                 if (DEBUG_VISBILITY) Log.v(
2406                                         TAG, "Scheduling invisibility: " + r);
2407                                 r.app.thread.scheduleWindowVisibility(r, false);
2408                             }
2409                         } catch (Exception e) {
2410                             // Just skip on any failure; we'll make it
2411                             // visible when it next restarts.
2412                             Log.w(TAG, "Exception thrown making hidden: "
2413                                     + r.intent.getComponent(), e);
2414                         }
2415                     } else {
2416                         if (DEBUG_VISBILITY) Log.v(
2417                                 TAG, "Already invisible: " + r);
2418                     }
2419                 } else if (r.fullscreen) {
2420                     if (DEBUG_VISBILITY) Log.v(
2421                             TAG, "Now behindFullscreen: " + r);
2422                     behindFullscreen = true;
2423                 }
2424             }
2425             i--;
2426         }
2427     }
2428 
2429     /**
2430      * Version of ensureActivitiesVisible that can easily be called anywhere.
2431      */
ensureActivitiesVisibleLocked(HistoryRecord starting, int configChanges)2432     private final void ensureActivitiesVisibleLocked(HistoryRecord starting,
2433             int configChanges) {
2434         HistoryRecord r = topRunningActivityLocked(null);
2435         if (r != null) {
2436             ensureActivitiesVisibleLocked(r, starting, null, configChanges);
2437         }
2438     }
2439 
updateUsageStats(HistoryRecord resumedComponent, boolean resumed)2440     private void updateUsageStats(HistoryRecord resumedComponent, boolean resumed) {
2441         if (resumed) {
2442             mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2443         } else {
2444             mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2445         }
2446     }
2447 
startHomeActivityLocked()2448     private boolean startHomeActivityLocked() {
2449         if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2450                 && mTopAction == null) {
2451             // We are running in factory test mode, but unable to find
2452             // the factory test app, so just sit around displaying the
2453             // error message and don't try to start anything.
2454             return false;
2455         }
2456         Intent intent = new Intent(
2457             mTopAction,
2458             mTopData != null ? Uri.parse(mTopData) : null);
2459         intent.setComponent(mTopComponent);
2460         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2461             intent.addCategory(Intent.CATEGORY_HOME);
2462         }
2463         ActivityInfo aInfo =
2464             intent.resolveActivityInfo(mContext.getPackageManager(),
2465                     STOCK_PM_FLAGS);
2466         if (aInfo != null) {
2467             intent.setComponent(new ComponentName(
2468                     aInfo.applicationInfo.packageName, aInfo.name));
2469             // Don't do this if the home app is currently being
2470             // instrumented.
2471             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2472                     aInfo.applicationInfo.uid);
2473             if (app == null || app.instrumentationClass == null) {
2474                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2475                 startActivityLocked(null, intent, null, null, 0, aInfo,
2476                         null, null, 0, 0, 0, false, false);
2477             }
2478         }
2479 
2480 
2481         return true;
2482     }
2483 
2484     /**
2485      * Starts the "new version setup screen" if appropriate.
2486      */
startSetupActivityLocked()2487     private void startSetupActivityLocked() {
2488         // Only do this once per boot.
2489         if (mCheckedForSetup) {
2490             return;
2491         }
2492 
2493         // We will show this screen if the current one is a different
2494         // version than the last one shown, and we are not running in
2495         // low-level factory test mode.
2496         final ContentResolver resolver = mContext.getContentResolver();
2497         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2498                 Settings.Secure.getInt(resolver,
2499                         Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2500             mCheckedForSetup = true;
2501 
2502             // See if we should be showing the platform update setup UI.
2503             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2504             List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2505                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2506 
2507             // We don't allow third party apps to replace this.
2508             ResolveInfo ri = null;
2509             for (int i=0; ris != null && i<ris.size(); i++) {
2510                 if ((ris.get(i).activityInfo.applicationInfo.flags
2511                         & ApplicationInfo.FLAG_SYSTEM) != 0) {
2512                     ri = ris.get(i);
2513                     break;
2514                 }
2515             }
2516 
2517             if (ri != null) {
2518                 String vers = ri.activityInfo.metaData != null
2519                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2520                         : null;
2521                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2522                     vers = ri.activityInfo.applicationInfo.metaData.getString(
2523                             Intent.METADATA_SETUP_VERSION);
2524                 }
2525                 String lastVers = Settings.Secure.getString(
2526                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
2527                 if (vers != null && !vers.equals(lastVers)) {
2528                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2529                     intent.setComponent(new ComponentName(
2530                             ri.activityInfo.packageName, ri.activityInfo.name));
2531                     startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
2532                             null, null, 0, 0, 0, false, false);
2533                 }
2534             }
2535         }
2536     }
2537 
reportResumedActivityLocked(HistoryRecord r)2538     private void reportResumedActivityLocked(HistoryRecord r) {
2539         //Log.i(TAG, "**** REPORT RESUME: " + r);
2540 
2541         final int identHash = System.identityHashCode(r);
2542         updateUsageStats(r, true);
2543 
2544         int i = mWatchers.beginBroadcast();
2545         while (i > 0) {
2546             i--;
2547             IActivityWatcher w = mWatchers.getBroadcastItem(i);
2548             if (w != null) {
2549                 try {
2550                     w.activityResuming(identHash);
2551                 } catch (RemoteException e) {
2552                 }
2553             }
2554         }
2555         mWatchers.finishBroadcast();
2556     }
2557 
2558     /**
2559      * Ensure that the top activity in the stack is resumed.
2560      *
2561      * @param prev The previously resumed activity, for when in the process
2562      * of pausing; can be null to call from elsewhere.
2563      *
2564      * @return Returns true if something is being resumed, or false if
2565      * nothing happened.
2566      */
resumeTopActivityLocked(HistoryRecord prev)2567     private final boolean resumeTopActivityLocked(HistoryRecord prev) {
2568         // Find the first activity that is not finishing.
2569         HistoryRecord next = topRunningActivityLocked(null);
2570 
2571         // Remember how we'll process this pause/resume situation, and ensure
2572         // that the state is reset however we wind up proceeding.
2573         final boolean userLeaving = mUserLeaving;
2574         mUserLeaving = false;
2575 
2576         if (next == null) {
2577             // There are no more activities!  Let's just start up the
2578             // Launcher...
2579             return startHomeActivityLocked();
2580         }
2581 
2582         next.delayedResume = false;
2583 
2584         // If the top activity is the resumed one, nothing to do.
2585         if (mResumedActivity == next && next.state == ActivityState.RESUMED) {
2586             // Make sure we have executed any pending transitions, since there
2587             // should be nothing left to do at this point.
2588             mWindowManager.executeAppTransition();
2589             mNoAnimActivities.clear();
2590             return false;
2591         }
2592 
2593         // If we are sleeping, and there is no resumed activity, and the top
2594         // activity is paused, well that is the state we want.
2595         if ((mSleeping || mShuttingDown)
2596                 && mLastPausedActivity == next && next.state == ActivityState.PAUSED) {
2597             // Make sure we have executed any pending transitions, since there
2598             // should be nothing left to do at this point.
2599             mWindowManager.executeAppTransition();
2600             mNoAnimActivities.clear();
2601             return false;
2602         }
2603 
2604         // The activity may be waiting for stop, but that is no longer
2605         // appropriate for it.
2606         mStoppingActivities.remove(next);
2607         mWaitingVisibleActivities.remove(next);
2608 
2609         if (DEBUG_SWITCH) Log.v(TAG, "Resuming " + next);
2610 
2611         // If we are currently pausing an activity, then don't do anything
2612         // until that is done.
2613         if (mPausingActivity != null) {
2614             if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: pausing=" + mPausingActivity);
2615             return false;
2616         }
2617 
2618         // We need to start pausing the current activity so the top one
2619         // can be resumed...
2620         if (mResumedActivity != null) {
2621             if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: need to start pausing");
2622             startPausingLocked(userLeaving, false);
2623             return true;
2624         }
2625 
2626         if (prev != null && prev != next) {
2627             if (!prev.waitingVisible && next != null && !next.nowVisible) {
2628                 prev.waitingVisible = true;
2629                 mWaitingVisibleActivities.add(prev);
2630                 if (DEBUG_SWITCH) Log.v(
2631                         TAG, "Resuming top, waiting visible to hide: " + prev);
2632             } else {
2633                 // The next activity is already visible, so hide the previous
2634                 // activity's windows right now so we can show the new one ASAP.
2635                 // We only do this if the previous is finishing, which should mean
2636                 // it is on top of the one being resumed so hiding it quickly
2637                 // is good.  Otherwise, we want to do the normal route of allowing
2638                 // the resumed activity to be shown so we can decide if the
2639                 // previous should actually be hidden depending on whether the
2640                 // new one is found to be full-screen or not.
2641                 if (prev.finishing) {
2642                     mWindowManager.setAppVisibility(prev, false);
2643                     if (DEBUG_SWITCH) Log.v(TAG, "Not waiting for visible to hide: "
2644                             + prev + ", waitingVisible="
2645                             + (prev != null ? prev.waitingVisible : null)
2646                             + ", nowVisible=" + next.nowVisible);
2647                 } else {
2648                     if (DEBUG_SWITCH) Log.v(TAG, "Previous already visible but still waiting to hide: "
2649                         + prev + ", waitingVisible="
2650                         + (prev != null ? prev.waitingVisible : null)
2651                         + ", nowVisible=" + next.nowVisible);
2652                 }
2653             }
2654         }
2655 
2656         // We are starting up the next activity, so tell the window manager
2657         // that the previous one will be hidden soon.  This way it can know
2658         // to ignore it when computing the desired screen orientation.
2659         if (prev != null) {
2660             if (prev.finishing) {
2661                 if (DEBUG_TRANSITION) Log.v(TAG,
2662                         "Prepare close transition: prev=" + prev);
2663                 if (mNoAnimActivities.contains(prev)) {
2664                     mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
2665                 } else {
2666                     mWindowManager.prepareAppTransition(prev.task == next.task
2667                             ? WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE
2668                             : WindowManagerPolicy.TRANSIT_TASK_CLOSE);
2669                 }
2670                 mWindowManager.setAppWillBeHidden(prev);
2671                 mWindowManager.setAppVisibility(prev, false);
2672             } else {
2673                 if (DEBUG_TRANSITION) Log.v(TAG,
2674                         "Prepare open transition: prev=" + prev);
2675                 if (mNoAnimActivities.contains(next)) {
2676                     mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
2677                 } else {
2678                     mWindowManager.prepareAppTransition(prev.task == next.task
2679                             ? WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
2680                             : WindowManagerPolicy.TRANSIT_TASK_OPEN);
2681                 }
2682             }
2683             if (false) {
2684                 mWindowManager.setAppWillBeHidden(prev);
2685                 mWindowManager.setAppVisibility(prev, false);
2686             }
2687         } else if (mHistory.size() > 1) {
2688             if (DEBUG_TRANSITION) Log.v(TAG,
2689                     "Prepare open transition: no previous");
2690             if (mNoAnimActivities.contains(next)) {
2691                 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
2692             } else {
2693                 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
2694             }
2695         }
2696 
2697         if (next.app != null && next.app.thread != null) {
2698             if (DEBUG_SWITCH) Log.v(TAG, "Resume running: " + next);
2699 
2700             // This activity is now becoming visible.
2701             mWindowManager.setAppVisibility(next, true);
2702 
2703             HistoryRecord lastResumedActivity = mResumedActivity;
2704             ActivityState lastState = next.state;
2705 
2706             updateCpuStats();
2707 
2708             next.state = ActivityState.RESUMED;
2709             mResumedActivity = next;
2710             next.task.touchActiveTime();
2711             updateLRUListLocked(next.app, true);
2712             updateLRUListLocked(next);
2713 
2714             // Have the window manager re-evaluate the orientation of
2715             // the screen based on the new activity order.
2716             boolean updated;
2717             synchronized (this) {
2718                 Configuration config = mWindowManager.updateOrientationFromAppTokens(
2719                         mConfiguration,
2720                         next.mayFreezeScreenLocked(next.app) ? next : null);
2721                 if (config != null) {
2722                     /*
2723                      * Explicitly restore the locale to the one from the
2724                      * old configuration, since the one that comes back from
2725                      * the window manager has the default (boot) locale.
2726                      *
2727                      * It looks like previously the locale picker only worked
2728                      * by coincidence: usually it would do its setting of
2729                      * the locale after the activity transition, so it didn't
2730                      * matter that this lost it.  With the synchronized
2731                      * block now keeping them from happening at the same time,
2732                      * this one always would happen second and undo what the
2733                      * locale picker had just done.
2734                      */
2735                     config.locale = mConfiguration.locale;
2736                     next.frozenBeforeDestroy = true;
2737                 }
2738                 updated = updateConfigurationLocked(config, next);
2739             }
2740             if (!updated) {
2741                 // The configuration update wasn't able to keep the existing
2742                 // instance of the activity, and instead started a new one.
2743                 // We should be all done, but let's just make sure our activity
2744                 // is still at the top and schedule another run if something
2745                 // weird happened.
2746                 HistoryRecord nextNext = topRunningActivityLocked(null);
2747                 if (DEBUG_SWITCH) Log.i(TAG,
2748                         "Activity config changed during resume: " + next
2749                         + ", new next: " + nextNext);
2750                 if (nextNext != next) {
2751                     // Do over!
2752                     mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2753                 }
2754                 setFocusedActivityLocked(next);
2755                 ensureActivitiesVisibleLocked(null, 0);
2756                 mWindowManager.executeAppTransition();
2757                 mNoAnimActivities.clear();
2758                 return true;
2759             }
2760 
2761             try {
2762                 // Deliver all pending results.
2763                 ArrayList a = next.results;
2764                 if (a != null) {
2765                     final int N = a.size();
2766                     if (!next.finishing && N > 0) {
2767                         if (DEBUG_RESULTS) Log.v(
2768                                 TAG, "Delivering results to " + next
2769                                 + ": " + a);
2770                         next.app.thread.scheduleSendResult(next, a);
2771                     }
2772                 }
2773 
2774                 if (next.newIntents != null) {
2775                     next.app.thread.scheduleNewIntent(next.newIntents, next);
2776                 }
2777 
2778                 EventLog.writeEvent(LOG_AM_RESUME_ACTIVITY,
2779                         System.identityHashCode(next),
2780                         next.task.taskId, next.shortComponentName);
2781 
2782                 next.app.thread.scheduleResumeActivity(next,
2783                         isNextTransitionForward());
2784 
2785                 pauseIfSleepingLocked();
2786 
2787             } catch (Exception e) {
2788                 // Whoops, need to restart this activity!
2789                 next.state = lastState;
2790                 mResumedActivity = lastResumedActivity;
2791                 if (Config.LOGD) Log.d(TAG,
2792                         "Restarting because process died: " + next);
2793                 if (!next.hasBeenLaunched) {
2794                     next.hasBeenLaunched = true;
2795                 } else {
2796                     if (SHOW_APP_STARTING_ICON) {
2797                         mWindowManager.setAppStartingWindow(
2798                                 next, next.packageName, next.theme,
2799                                 next.nonLocalizedLabel,
2800                                 next.labelRes, next.icon, null, true);
2801                     }
2802                 }
2803                 startSpecificActivityLocked(next, true, false);
2804                 return true;
2805             }
2806 
2807             // From this point on, if something goes wrong there is no way
2808             // to recover the activity.
2809             try {
2810                 next.visible = true;
2811                 completeResumeLocked(next);
2812             } catch (Exception e) {
2813                 // If any exception gets thrown, toss away this
2814                 // activity and try the next one.
2815                 Log.w(TAG, "Exception thrown during resume of " + next, e);
2816                 requestFinishActivityLocked(next, Activity.RESULT_CANCELED, null,
2817                         "resume-exception");
2818                 return true;
2819             }
2820 
2821             // Didn't need to use the icicle, and it is now out of date.
2822             next.icicle = null;
2823             next.haveState = false;
2824             next.stopped = false;
2825 
2826         } else {
2827             // Whoops, need to restart this activity!
2828             if (!next.hasBeenLaunched) {
2829                 next.hasBeenLaunched = true;
2830             } else {
2831                 if (SHOW_APP_STARTING_ICON) {
2832                     mWindowManager.setAppStartingWindow(
2833                             next, next.packageName, next.theme,
2834                             next.nonLocalizedLabel,
2835                             next.labelRes, next.icon, null, true);
2836                 }
2837                 if (DEBUG_SWITCH) Log.v(TAG, "Restarting: " + next);
2838             }
2839             startSpecificActivityLocked(next, true, true);
2840         }
2841 
2842         return true;
2843     }
2844 
startActivityLocked(HistoryRecord r, boolean newTask, boolean doResume)2845     private final void startActivityLocked(HistoryRecord r, boolean newTask,
2846             boolean doResume) {
2847         final int NH = mHistory.size();
2848 
2849         int addPos = -1;
2850 
2851         if (!newTask) {
2852             // If starting in an existing task, find where that is...
2853             HistoryRecord next = null;
2854             boolean startIt = true;
2855             for (int i = NH-1; i >= 0; i--) {
2856                 HistoryRecord p = (HistoryRecord)mHistory.get(i);
2857                 if (p.finishing) {
2858                     continue;
2859                 }
2860                 if (p.task == r.task) {
2861                     // Here it is!  Now, if this is not yet visible to the
2862                     // user, then just add it without starting; it will
2863                     // get started when the user navigates back to it.
2864                     addPos = i+1;
2865                     if (!startIt) {
2866                         mHistory.add(addPos, r);
2867                         r.inHistory = true;
2868                         r.task.numActivities++;
2869                         mWindowManager.addAppToken(addPos, r, r.task.taskId,
2870                                 r.info.screenOrientation, r.fullscreen);
2871                         if (VALIDATE_TOKENS) {
2872                             mWindowManager.validateAppTokens(mHistory);
2873                         }
2874                         return;
2875                     }
2876                     break;
2877                 }
2878                 if (p.fullscreen) {
2879                     startIt = false;
2880                 }
2881                 next = p;
2882             }
2883         }
2884 
2885         // Place a new activity at top of stack, so it is next to interact
2886         // with the user.
2887         if (addPos < 0) {
2888             addPos = mHistory.size();
2889         }
2890 
2891         // If we are not placing the new activity frontmost, we do not want
2892         // to deliver the onUserLeaving callback to the actual frontmost
2893         // activity
2894         if (addPos < NH) {
2895             mUserLeaving = false;
2896             if (DEBUG_USER_LEAVING) Log.v(TAG, "startActivity() behind front, mUserLeaving=false");
2897         }
2898 
2899         // Slot the activity into the history stack and proceed
2900         mHistory.add(addPos, r);
2901         r.inHistory = true;
2902         r.frontOfTask = newTask;
2903         r.task.numActivities++;
2904         if (NH > 0) {
2905             // We want to show the starting preview window if we are
2906             // switching to a new task, or the next activity's process is
2907             // not currently running.
2908             boolean showStartingIcon = newTask;
2909             ProcessRecord proc = r.app;
2910             if (proc == null) {
2911                 proc = mProcessNames.get(r.processName, r.info.applicationInfo.uid);
2912             }
2913             if (proc == null || proc.thread == null) {
2914                 showStartingIcon = true;
2915             }
2916             if (DEBUG_TRANSITION) Log.v(TAG,
2917                     "Prepare open transition: starting " + r);
2918             if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
2919                 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
2920                 mNoAnimActivities.add(r);
2921             } else if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
2922                 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_OPEN);
2923                 mNoAnimActivities.remove(r);
2924             } else {
2925                 mWindowManager.prepareAppTransition(newTask
2926                         ? WindowManagerPolicy.TRANSIT_TASK_OPEN
2927                         : WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
2928                 mNoAnimActivities.remove(r);
2929             }
2930             mWindowManager.addAppToken(
2931                     addPos, r, r.task.taskId, r.info.screenOrientation, r.fullscreen);
2932             boolean doShow = true;
2933             if (newTask) {
2934                 // Even though this activity is starting fresh, we still need
2935                 // to reset it to make sure we apply affinities to move any
2936                 // existing activities from other tasks in to it.
2937                 // If the caller has requested that the target task be
2938                 // reset, then do so.
2939                 if ((r.intent.getFlags()
2940                         &Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
2941                     resetTaskIfNeededLocked(r, r);
2942                     doShow = topRunningNonDelayedActivityLocked(null) == r;
2943                 }
2944             }
2945             if (SHOW_APP_STARTING_ICON && doShow) {
2946                 // Figure out if we are transitioning from another activity that is
2947                 // "has the same starting icon" as the next one.  This allows the
2948                 // window manager to keep the previous window it had previously
2949                 // created, if it still had one.
2950                 HistoryRecord prev = mResumedActivity;
2951                 if (prev != null) {
2952                     // We don't want to reuse the previous starting preview if:
2953                     // (1) The current activity is in a different task.
2954                     if (prev.task != r.task) prev = null;
2955                     // (2) The current activity is already displayed.
2956                     else if (prev.nowVisible) prev = null;
2957                 }
2958                 mWindowManager.setAppStartingWindow(
2959                         r, r.packageName, r.theme, r.nonLocalizedLabel,
2960                         r.labelRes, r.icon, prev, showStartingIcon);
2961             }
2962         } else {
2963             // If this is the first activity, don't do any fancy animations,
2964             // because there is nothing for it to animate on top of.
2965             mWindowManager.addAppToken(addPos, r, r.task.taskId,
2966                     r.info.screenOrientation, r.fullscreen);
2967         }
2968         if (VALIDATE_TOKENS) {
2969             mWindowManager.validateAppTokens(mHistory);
2970         }
2971 
2972         if (doResume) {
2973             resumeTopActivityLocked(null);
2974         }
2975     }
2976 
2977     /**
2978      * Perform clear operation as requested by
2979      * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
2980      * stack to the given task, then look for
2981      * an instance of that activity in the stack and, if found, finish all
2982      * activities on top of it and return the instance.
2983      *
2984      * @param newR Description of the new activity being started.
2985      * @return Returns the old activity that should be continue to be used,
2986      * or null if none was found.
2987      */
performClearTaskLocked(int taskId, HistoryRecord newR, int launchFlags, boolean doClear)2988     private final HistoryRecord performClearTaskLocked(int taskId,
2989             HistoryRecord newR, int launchFlags, boolean doClear) {
2990         int i = mHistory.size();
2991 
2992         // First find the requested task.
2993         while (i > 0) {
2994             i--;
2995             HistoryRecord r = (HistoryRecord)mHistory.get(i);
2996             if (r.task.taskId == taskId) {
2997                 i++;
2998                 break;
2999             }
3000         }
3001 
3002         // Now clear it.
3003         while (i > 0) {
3004             i--;
3005             HistoryRecord r = (HistoryRecord)mHistory.get(i);
3006             if (r.finishing) {
3007                 continue;
3008             }
3009             if (r.task.taskId != taskId) {
3010                 return null;
3011             }
3012             if (r.realActivity.equals(newR.realActivity)) {
3013                 // Here it is!  Now finish everything in front...
3014                 HistoryRecord ret = r;
3015                 if (doClear) {
3016                     while (i < (mHistory.size()-1)) {
3017                         i++;
3018                         r = (HistoryRecord)mHistory.get(i);
3019                         if (r.finishing) {
3020                             continue;
3021                         }
3022                         if (finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3023                                 null, "clear")) {
3024                             i--;
3025                         }
3026                     }
3027                 }
3028 
3029                 // Finally, if this is a normal launch mode (that is, not
3030                 // expecting onNewIntent()), then we will finish the current
3031                 // instance of the activity so a new fresh one can be started.
3032                 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
3033                         && (launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) {
3034                     if (!ret.finishing) {
3035                         int index = indexOfTokenLocked(ret);
3036                         if (index >= 0) {
3037                             finishActivityLocked(ret, 0, Activity.RESULT_CANCELED,
3038                                     null, "clear");
3039                         }
3040                         return null;
3041                     }
3042                 }
3043 
3044                 return ret;
3045             }
3046         }
3047 
3048         return null;
3049     }
3050 
3051     /**
3052      * Find the activity in the history stack within the given task.  Returns
3053      * the index within the history at which it's found, or < 0 if not found.
3054      */
findActivityInHistoryLocked(HistoryRecord r, int task)3055     private final int findActivityInHistoryLocked(HistoryRecord r, int task) {
3056         int i = mHistory.size();
3057         while (i > 0) {
3058             i--;
3059             HistoryRecord candidate = (HistoryRecord)mHistory.get(i);
3060             if (candidate.task.taskId != task) {
3061                 break;
3062             }
3063             if (candidate.realActivity.equals(r.realActivity)) {
3064                 return i;
3065             }
3066         }
3067 
3068         return -1;
3069     }
3070 
3071     /**
3072      * Reorder the history stack so that the activity at the given index is
3073      * brought to the front.
3074      */
moveActivityToFrontLocked(int where)3075     private final HistoryRecord moveActivityToFrontLocked(int where) {
3076         HistoryRecord newTop = (HistoryRecord)mHistory.remove(where);
3077         int top = mHistory.size();
3078         HistoryRecord oldTop = (HistoryRecord)mHistory.get(top-1);
3079         mHistory.add(top, newTop);
3080         oldTop.frontOfTask = false;
3081         newTop.frontOfTask = true;
3082         return newTop;
3083     }
3084 
3085     /**
3086      * Deliver a new Intent to an existing activity, so that its onNewIntent()
3087      * method will be called at the proper time.
3088      */
deliverNewIntentLocked(HistoryRecord r, Intent intent)3089     private final void deliverNewIntentLocked(HistoryRecord r, Intent intent) {
3090         boolean sent = false;
3091         if (r.state == ActivityState.RESUMED
3092                 && r.app != null && r.app.thread != null) {
3093             try {
3094                 ArrayList<Intent> ar = new ArrayList<Intent>();
3095                 ar.add(new Intent(intent));
3096                 r.app.thread.scheduleNewIntent(ar, r);
3097                 sent = true;
3098             } catch (Exception e) {
3099                 Log.w(TAG, "Exception thrown sending new intent to " + r, e);
3100             }
3101         }
3102         if (!sent) {
3103             r.addNewIntentLocked(new Intent(intent));
3104         }
3105     }
3106 
logStartActivity(int tag, HistoryRecord r, TaskRecord task)3107     private final void logStartActivity(int tag, HistoryRecord r,
3108             TaskRecord task) {
3109         EventLog.writeEvent(tag,
3110                 System.identityHashCode(r), task.taskId,
3111                 r.shortComponentName, r.intent.getAction(),
3112                 r.intent.getType(), r.intent.getDataString(),
3113                 r.intent.getFlags());
3114     }
3115 
startActivityLocked(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, ActivityInfo aInfo, IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, boolean onlyIfNeeded, boolean componentSpecified)3116     private final int startActivityLocked(IApplicationThread caller,
3117             Intent intent, String resolvedType,
3118             Uri[] grantedUriPermissions,
3119             int grantedMode, ActivityInfo aInfo, IBinder resultTo,
3120             String resultWho, int requestCode,
3121             int callingPid, int callingUid, boolean onlyIfNeeded,
3122             boolean componentSpecified) {
3123         Log.i(TAG, "Starting activity: " + intent);
3124 
3125         HistoryRecord sourceRecord = null;
3126         HistoryRecord resultRecord = null;
3127         if (resultTo != null) {
3128             int index = indexOfTokenLocked(resultTo);
3129             if (DEBUG_RESULTS) Log.v(
3130                 TAG, "Sending result to " + resultTo + " (index " + index + ")");
3131             if (index >= 0) {
3132                 sourceRecord = (HistoryRecord)mHistory.get(index);
3133                 if (requestCode >= 0 && !sourceRecord.finishing) {
3134                     resultRecord = sourceRecord;
3135                 }
3136             }
3137         }
3138 
3139         int launchFlags = intent.getFlags();
3140 
3141         if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
3142                 && sourceRecord != null) {
3143             // Transfer the result target from the source activity to the new
3144             // one being started, including any failures.
3145             if (requestCode >= 0) {
3146                 return START_FORWARD_AND_REQUEST_CONFLICT;
3147             }
3148             resultRecord = sourceRecord.resultTo;
3149             resultWho = sourceRecord.resultWho;
3150             requestCode = sourceRecord.requestCode;
3151             sourceRecord.resultTo = null;
3152             if (resultRecord != null) {
3153                 resultRecord.removeResultsLocked(
3154                     sourceRecord, resultWho, requestCode);
3155             }
3156         }
3157 
3158         int err = START_SUCCESS;
3159 
3160         if (intent.getComponent() == null) {
3161             // We couldn't find a class that can handle the given Intent.
3162             // That's the end of that!
3163             err = START_INTENT_NOT_RESOLVED;
3164         }
3165 
3166         if (err == START_SUCCESS && aInfo == null) {
3167             // We couldn't find the specific class specified in the Intent.
3168             // Also the end of the line.
3169             err = START_CLASS_NOT_FOUND;
3170         }
3171 
3172         ProcessRecord callerApp = null;
3173         if (err == START_SUCCESS && caller != null) {
3174             callerApp = getRecordForAppLocked(caller);
3175             if (callerApp != null) {
3176                 callingPid = callerApp.pid;
3177                 callingUid = callerApp.info.uid;
3178             } else {
3179                 Log.w(TAG, "Unable to find app for caller " + caller
3180                       + " (pid=" + callingPid + ") when starting: "
3181                       + intent.toString());
3182                 err = START_PERMISSION_DENIED;
3183             }
3184         }
3185 
3186         if (err != START_SUCCESS) {
3187             if (resultRecord != null) {
3188                 sendActivityResultLocked(-1,
3189                     resultRecord, resultWho, requestCode,
3190                     Activity.RESULT_CANCELED, null);
3191             }
3192             return err;
3193         }
3194 
3195         final int perm = checkComponentPermission(aInfo.permission, callingPid,
3196                 callingUid, aInfo.exported ? -1 : aInfo.applicationInfo.uid);
3197         if (perm != PackageManager.PERMISSION_GRANTED) {
3198             if (resultRecord != null) {
3199                 sendActivityResultLocked(-1,
3200                     resultRecord, resultWho, requestCode,
3201                     Activity.RESULT_CANCELED, null);
3202             }
3203             String msg = "Permission Denial: starting " + intent.toString()
3204                     + " from " + callerApp + " (pid=" + callingPid
3205                     + ", uid=" + callingUid + ")"
3206                     + " requires " + aInfo.permission;
3207             Log.w(TAG, msg);
3208             throw new SecurityException(msg);
3209         }
3210 
3211         if (mController != null) {
3212             boolean abort = false;
3213             try {
3214                 // The Intent we give to the watcher has the extra data
3215                 // stripped off, since it can contain private information.
3216                 Intent watchIntent = intent.cloneFilter();
3217                 abort = !mController.activityStarting(watchIntent,
3218                         aInfo.applicationInfo.packageName);
3219             } catch (RemoteException e) {
3220                 mController = null;
3221             }
3222 
3223             if (abort) {
3224                 if (resultRecord != null) {
3225                     sendActivityResultLocked(-1,
3226                         resultRecord, resultWho, requestCode,
3227                         Activity.RESULT_CANCELED, null);
3228                 }
3229                 // We pretend to the caller that it was really started, but
3230                 // they will just get a cancel result.
3231                 return START_SUCCESS;
3232             }
3233         }
3234 
3235         HistoryRecord r = new HistoryRecord(this, callerApp, callingUid,
3236                 intent, resolvedType, aInfo, mConfiguration,
3237                 resultRecord, resultWho, requestCode, componentSpecified);
3238 
3239         if (mResumedActivity == null
3240                 || mResumedActivity.info.applicationInfo.uid != callingUid) {
3241             if (!checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
3242                 PendingActivityLaunch pal = new PendingActivityLaunch();
3243                 pal.r = r;
3244                 pal.sourceRecord = sourceRecord;
3245                 pal.grantedUriPermissions = grantedUriPermissions;
3246                 pal.grantedMode = grantedMode;
3247                 pal.onlyIfNeeded = onlyIfNeeded;
3248                 mPendingActivityLaunches.add(pal);
3249                 return START_SWITCHES_CANCELED;
3250             }
3251         }
3252 
3253         if (mDidAppSwitch) {
3254             // This is the second allowed switch since we stopped switches,
3255             // so now just generally allow switches.  Use case: user presses
3256             // home (switches disabled, switch to home, mDidAppSwitch now true);
3257             // user taps a home icon (coming from home so allowed, we hit here
3258             // and now allow anyone to switch again).
3259             mAppSwitchesAllowedTime = 0;
3260         } else {
3261             mDidAppSwitch = true;
3262         }
3263 
3264         doPendingActivityLaunchesLocked(false);
3265 
3266         return startActivityUncheckedLocked(r, sourceRecord,
3267                 grantedUriPermissions, grantedMode, onlyIfNeeded, true);
3268     }
3269 
doPendingActivityLaunchesLocked(boolean doResume)3270     private final void doPendingActivityLaunchesLocked(boolean doResume) {
3271         final int N = mPendingActivityLaunches.size();
3272         if (N <= 0) {
3273             return;
3274         }
3275         for (int i=0; i<N; i++) {
3276             PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3277             startActivityUncheckedLocked(pal.r, pal.sourceRecord,
3278                     pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
3279                     doResume && i == (N-1));
3280         }
3281         mPendingActivityLaunches.clear();
3282     }
3283 
startActivityUncheckedLocked(HistoryRecord r, HistoryRecord sourceRecord, Uri[] grantedUriPermissions, int grantedMode, boolean onlyIfNeeded, boolean doResume)3284     private final int startActivityUncheckedLocked(HistoryRecord r,
3285             HistoryRecord sourceRecord, Uri[] grantedUriPermissions,
3286             int grantedMode, boolean onlyIfNeeded, boolean doResume) {
3287         final Intent intent = r.intent;
3288         final int callingUid = r.launchedFromUid;
3289 
3290         int launchFlags = intent.getFlags();
3291 
3292         // We'll invoke onUserLeaving before onPause only if the launching
3293         // activity did not explicitly state that this is an automated launch.
3294         mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
3295         if (DEBUG_USER_LEAVING) Log.v(TAG,
3296                 "startActivity() => mUserLeaving=" + mUserLeaving);
3297 
3298         // If the caller has asked not to resume at this point, we make note
3299         // of this in the record so that we can skip it when trying to find
3300         // the top running activity.
3301         if (!doResume) {
3302             r.delayedResume = true;
3303         }
3304 
3305         HistoryRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
3306                 != 0 ? r : null;
3307 
3308         // If the onlyIfNeeded flag is set, then we can do this if the activity
3309         // being launched is the same as the one making the call...  or, as
3310         // a special case, if we do not know the caller then we count the
3311         // current top activity as the caller.
3312         if (onlyIfNeeded) {
3313             HistoryRecord checkedCaller = sourceRecord;
3314             if (checkedCaller == null) {
3315                 checkedCaller = topRunningNonDelayedActivityLocked(notTop);
3316             }
3317             if (!checkedCaller.realActivity.equals(r.realActivity)) {
3318                 // Caller is not the same as launcher, so always needed.
3319                 onlyIfNeeded = false;
3320             }
3321         }
3322 
3323         if (grantedUriPermissions != null && callingUid > 0) {
3324             for (int i=0; i<grantedUriPermissions.length; i++) {
3325                 grantUriPermissionLocked(callingUid, r.packageName,
3326                         grantedUriPermissions[i], grantedMode, r);
3327             }
3328         }
3329 
3330         grantUriPermissionFromIntentLocked(callingUid, r.packageName,
3331                 intent, r);
3332 
3333         if (sourceRecord == null) {
3334             // This activity is not being started from another...  in this
3335             // case we -always- start a new task.
3336             if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
3337                 Log.w(TAG, "startActivity called from non-Activity context; forcing Intent.FLAG_ACTIVITY_NEW_TASK for: "
3338                       + intent);
3339                 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
3340             }
3341         } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
3342             // The original activity who is starting us is running as a single
3343             // instance...  this new activity it is starting must go on its
3344             // own task.
3345             launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
3346         } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
3347                 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
3348             // The activity being started is a single instance...  it always
3349             // gets launched into its own task.
3350             launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
3351         }
3352 
3353         if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
3354             // For whatever reason this activity is being launched into a new
3355             // task...  yet the caller has requested a result back.  Well, that
3356             // is pretty messed up, so instead immediately send back a cancel
3357             // and let the new task continue launched as normal without a
3358             // dependency on its originator.
3359             Log.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
3360             sendActivityResultLocked(-1,
3361                     r.resultTo, r.resultWho, r.requestCode,
3362                 Activity.RESULT_CANCELED, null);
3363             r.resultTo = null;
3364         }
3365 
3366         boolean addingToTask = false;
3367         if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
3368                 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
3369                 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
3370                 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
3371             // If bring to front is requested, and no result is requested, and
3372             // we can find a task that was started with this same
3373             // component, then instead of launching bring that one to the front.
3374             if (r.resultTo == null) {
3375                 // See if there is a task to bring to the front.  If this is
3376                 // a SINGLE_INSTANCE activity, there can be one and only one
3377                 // instance of it in the history, and it is always in its own
3378                 // unique task, so we do a special search.
3379                 HistoryRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
3380                         ? findTaskLocked(intent, r.info)
3381                         : findActivityLocked(intent, r.info);
3382                 if (taskTop != null) {
3383                     if (taskTop.task.intent == null) {
3384                         // This task was started because of movement of
3385                         // the activity based on affinity...  now that we
3386                         // are actually launching it, we can assign the
3387                         // base intent.
3388                         taskTop.task.setIntent(intent, r.info);
3389                     }
3390                     // If the target task is not in the front, then we need
3391                     // to bring it to the front...  except...  well, with
3392                     // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
3393                     // to have the same behavior as if a new instance was
3394                     // being started, which means not bringing it to the front
3395                     // if the caller is not itself in the front.
3396                     HistoryRecord curTop = topRunningNonDelayedActivityLocked(notTop);
3397                     if (curTop.task != taskTop.task) {
3398                         r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
3399                         boolean callerAtFront = sourceRecord == null
3400                                 || curTop.task == sourceRecord.task;
3401                         if (callerAtFront) {
3402                             // We really do want to push this one into the
3403                             // user's face, right now.
3404                             moveTaskToFrontLocked(taskTop.task, r);
3405                         }
3406                     }
3407                     // If the caller has requested that the target task be
3408                     // reset, then do so.
3409                     if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
3410                         taskTop = resetTaskIfNeededLocked(taskTop, r);
3411                     }
3412                     if (onlyIfNeeded) {
3413                         // We don't need to start a new activity, and
3414                         // the client said not to do anything if that
3415                         // is the case, so this is it!  And for paranoia, make
3416                         // sure we have correctly resumed the top activity.
3417                         if (doResume) {
3418                             resumeTopActivityLocked(null);
3419                         }
3420                         return START_RETURN_INTENT_TO_CALLER;
3421                     }
3422                     if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
3423                             || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
3424                             || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
3425                         // In this situation we want to remove all activities
3426                         // from the task up to the one being started.  In most
3427                         // cases this means we are resetting the task to its
3428                         // initial state.
3429                         HistoryRecord top = performClearTaskLocked(
3430                                 taskTop.task.taskId, r, launchFlags, true);
3431                         if (top != null) {
3432                             if (top.frontOfTask) {
3433                                 // Activity aliases may mean we use different
3434                                 // intents for the top activity, so make sure
3435                                 // the task now has the identity of the new
3436                                 // intent.
3437                                 top.task.setIntent(r.intent, r.info);
3438                             }
3439                             logStartActivity(LOG_AM_NEW_INTENT, r, top.task);
3440                             deliverNewIntentLocked(top, r.intent);
3441                         } else {
3442                             // A special case: we need to
3443                             // start the activity because it is not currently
3444                             // running, and the caller has asked to clear the
3445                             // current task to have this activity at the top.
3446                             addingToTask = true;
3447                             // Now pretend like this activity is being started
3448                             // by the top of its task, so it is put in the
3449                             // right place.
3450                             sourceRecord = taskTop;
3451                         }
3452                     } else if (r.realActivity.equals(taskTop.task.realActivity)) {
3453                         // In this case the top activity on the task is the
3454                         // same as the one being launched, so we take that
3455                         // as a request to bring the task to the foreground.
3456                         // If the top activity in the task is the root
3457                         // activity, deliver this new intent to it if it
3458                         // desires.
3459                         if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
3460                                 && taskTop.realActivity.equals(r.realActivity)) {
3461                             logStartActivity(LOG_AM_NEW_INTENT, r, taskTop.task);
3462                             if (taskTop.frontOfTask) {
3463                                 taskTop.task.setIntent(r.intent, r.info);
3464                             }
3465                             deliverNewIntentLocked(taskTop, r.intent);
3466                         } else if (!r.intent.filterEquals(taskTop.task.intent)) {
3467                             // In this case we are launching the root activity
3468                             // of the task, but with a different intent.  We
3469                             // should start a new instance on top.
3470                             addingToTask = true;
3471                             sourceRecord = taskTop;
3472                         }
3473                     } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
3474                         // In this case an activity is being launched in to an
3475                         // existing task, without resetting that task.  This
3476                         // is typically the situation of launching an activity
3477                         // from a notification or shortcut.  We want to place
3478                         // the new activity on top of the current task.
3479                         addingToTask = true;
3480                         sourceRecord = taskTop;
3481                     } else if (!taskTop.task.rootWasReset) {
3482                         // In this case we are launching in to an existing task
3483                         // that has not yet been started from its front door.
3484                         // The current task has been brought to the front.
3485                         // Ideally, we'd probably like to place this new task
3486                         // at the bottom of its stack, but that's a little hard
3487                         // to do with the current organization of the code so
3488                         // for now we'll just drop it.
3489                         taskTop.task.setIntent(r.intent, r.info);
3490                     }
3491                     if (!addingToTask) {
3492                         // We didn't do anything...  but it was needed (a.k.a., client
3493                         // don't use that intent!)  And for paranoia, make
3494                         // sure we have correctly resumed the top activity.
3495                         if (doResume) {
3496                             resumeTopActivityLocked(null);
3497                         }
3498                         return START_TASK_TO_FRONT;
3499                     }
3500                 }
3501             }
3502         }
3503 
3504         //String uri = r.intent.toURI();
3505         //Intent intent2 = new Intent(uri);
3506         //Log.i(TAG, "Given intent: " + r.intent);
3507         //Log.i(TAG, "URI is: " + uri);
3508         //Log.i(TAG, "To intent: " + intent2);
3509 
3510         if (r.packageName != null) {
3511             // If the activity being launched is the same as the one currently
3512             // at the top, then we need to check if it should only be launched
3513             // once.
3514             HistoryRecord top = topRunningNonDelayedActivityLocked(notTop);
3515             if (top != null && r.resultTo == null) {
3516                 if (top.realActivity.equals(r.realActivity)) {
3517                     if (top.app != null && top.app.thread != null) {
3518                         if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
3519                             || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
3520                             || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
3521                             logStartActivity(LOG_AM_NEW_INTENT, top, top.task);
3522                             // For paranoia, make sure we have correctly
3523                             // resumed the top activity.
3524                             if (doResume) {
3525                                 resumeTopActivityLocked(null);
3526                             }
3527                             if (onlyIfNeeded) {
3528                                 // We don't need to start a new activity, and
3529                                 // the client said not to do anything if that
3530                                 // is the case, so this is it!
3531                                 return START_RETURN_INTENT_TO_CALLER;
3532                             }
3533                             deliverNewIntentLocked(top, r.intent);
3534                             return START_DELIVERED_TO_TOP;
3535                         }
3536                     }
3537                 }
3538             }
3539 
3540         } else {
3541             if (r.resultTo != null) {
3542                 sendActivityResultLocked(-1,
3543                         r.resultTo, r.resultWho, r.requestCode,
3544                     Activity.RESULT_CANCELED, null);
3545             }
3546             return START_CLASS_NOT_FOUND;
3547         }
3548 
3549         boolean newTask = false;
3550 
3551         // Should this be considered a new task?
3552         if (r.resultTo == null && !addingToTask
3553                 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
3554             // todo: should do better management of integers.
3555             mCurTask++;
3556             if (mCurTask <= 0) {
3557                 mCurTask = 1;
3558             }
3559             r.task = new TaskRecord(mCurTask, r.info, intent,
3560                     (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
3561             if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r
3562                     + " in new task " + r.task);
3563             newTask = true;
3564             addRecentTask(r.task);
3565 
3566         } else if (sourceRecord != null) {
3567             if (!addingToTask &&
3568                     (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
3569                 // In this case, we are adding the activity to an existing
3570                 // task, but the caller has asked to clear that task if the
3571                 // activity is already running.
3572                 HistoryRecord top = performClearTaskLocked(
3573                         sourceRecord.task.taskId, r, launchFlags, true);
3574                 if (top != null) {
3575                     logStartActivity(LOG_AM_NEW_INTENT, r, top.task);
3576                     deliverNewIntentLocked(top, r.intent);
3577                     // For paranoia, make sure we have correctly
3578                     // resumed the top activity.
3579                     if (doResume) {
3580                         resumeTopActivityLocked(null);
3581                     }
3582                     return START_DELIVERED_TO_TOP;
3583                 }
3584             } else if (!addingToTask &&
3585                     (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
3586                 // In this case, we are launching an activity in our own task
3587                 // that may already be running somewhere in the history, and
3588                 // we want to shuffle it to the front of the stack if so.
3589                 int where = findActivityInHistoryLocked(r, sourceRecord.task.taskId);
3590                 if (where >= 0) {
3591                     HistoryRecord top = moveActivityToFrontLocked(where);
3592                     logStartActivity(LOG_AM_NEW_INTENT, r, top.task);
3593                     deliverNewIntentLocked(top, r.intent);
3594                     if (doResume) {
3595                         resumeTopActivityLocked(null);
3596                     }
3597                     return START_DELIVERED_TO_TOP;
3598                 }
3599             }
3600             // An existing activity is starting this new activity, so we want
3601             // to keep the new one in the same task as the one that is starting
3602             // it.
3603             r.task = sourceRecord.task;
3604             if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r
3605                     + " in existing task " + r.task);
3606 
3607         } else {
3608             // This not being started from an existing activity, and not part
3609             // of a new task...  just put it in the top task, though these days
3610             // this case should never happen.
3611             final int N = mHistory.size();
3612             HistoryRecord prev =
3613                 N > 0 ? (HistoryRecord)mHistory.get(N-1) : null;
3614             r.task = prev != null
3615                 ? prev.task
3616                 : new TaskRecord(mCurTask, r.info, intent,
3617                         (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
3618             if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r
3619                     + " in new guessed " + r.task);
3620         }
3621         if (newTask) {
3622             EventLog.writeEvent(LOG_AM_CREATE_TASK, r.task.taskId);
3623         }
3624         logStartActivity(LOG_AM_CREATE_ACTIVITY, r, r.task);
3625         startActivityLocked(r, newTask, doResume);
3626         return START_SUCCESS;
3627     }
3628 
startActivity(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug)3629     public final int startActivity(IApplicationThread caller,
3630             Intent intent, String resolvedType, Uri[] grantedUriPermissions,
3631             int grantedMode, IBinder resultTo,
3632             String resultWho, int requestCode, boolean onlyIfNeeded,
3633             boolean debug) {
3634         // Refuse possible leaked file descriptors
3635         if (intent != null && intent.hasFileDescriptors()) {
3636             throw new IllegalArgumentException("File descriptors passed in Intent");
3637         }
3638 
3639         final boolean componentSpecified = intent.getComponent() != null;
3640 
3641         // Don't modify the client's object!
3642         intent = new Intent(intent);
3643 
3644         // Collect information about the target of the Intent.
3645         ActivityInfo aInfo;
3646         try {
3647             ResolveInfo rInfo =
3648                 ActivityThread.getPackageManager().resolveIntent(
3649                         intent, resolvedType,
3650                         PackageManager.MATCH_DEFAULT_ONLY
3651                         | STOCK_PM_FLAGS);
3652             aInfo = rInfo != null ? rInfo.activityInfo : null;
3653         } catch (RemoteException e) {
3654             aInfo = null;
3655         }
3656 
3657         if (aInfo != null) {
3658             // Store the found target back into the intent, because now that
3659             // we have it we never want to do this again.  For example, if the
3660             // user navigates back to this point in the history, we should
3661             // always restart the exact same activity.
3662             intent.setComponent(new ComponentName(
3663                     aInfo.applicationInfo.packageName, aInfo.name));
3664 
3665             // Don't debug things in the system process
3666             if (debug) {
3667                 if (!aInfo.processName.equals("system")) {
3668                     setDebugApp(aInfo.processName, true, false);
3669                 }
3670             }
3671         }
3672 
3673         synchronized(this) {
3674             final long origId = Binder.clearCallingIdentity();
3675             int res = startActivityLocked(caller, intent, resolvedType,
3676                     grantedUriPermissions, grantedMode, aInfo,
3677                     resultTo, resultWho, requestCode, -1, -1,
3678                     onlyIfNeeded, componentSpecified);
3679             Binder.restoreCallingIdentity(origId);
3680             return res;
3681         }
3682     }
3683 
startActivityIntentSender(IApplicationThread caller, IntentSender intent, Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flagsMask, int flagsValues)3684     public int startActivityIntentSender(IApplicationThread caller,
3685             IntentSender intent, Intent fillInIntent, String resolvedType,
3686             IBinder resultTo, String resultWho, int requestCode,
3687             int flagsMask, int flagsValues) {
3688         // Refuse possible leaked file descriptors
3689         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3690             throw new IllegalArgumentException("File descriptors passed in Intent");
3691         }
3692 
3693         IIntentSender sender = intent.getTarget();
3694         if (!(sender instanceof PendingIntentRecord)) {
3695             throw new IllegalArgumentException("Bad PendingIntent object");
3696         }
3697 
3698         PendingIntentRecord pir = (PendingIntentRecord)sender;
3699 
3700         synchronized (this) {
3701             // If this is coming from the currently resumed activity, it is
3702             // effectively saying that app switches are allowed at this point.
3703             if (mResumedActivity != null
3704                     && mResumedActivity.info.applicationInfo.uid ==
3705                             Binder.getCallingUid()) {
3706                 mAppSwitchesAllowedTime = 0;
3707             }
3708         }
3709 
3710         return pir.sendInner(0, fillInIntent, resolvedType,
3711                 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
3712     }
3713 
startNextMatchingActivity(IBinder callingActivity, Intent intent)3714     public boolean startNextMatchingActivity(IBinder callingActivity,
3715             Intent intent) {
3716         // Refuse possible leaked file descriptors
3717         if (intent != null && intent.hasFileDescriptors() == true) {
3718             throw new IllegalArgumentException("File descriptors passed in Intent");
3719         }
3720 
3721         synchronized (this) {
3722             int index = indexOfTokenLocked(callingActivity);
3723             if (index < 0) {
3724                 return false;
3725             }
3726             HistoryRecord r = (HistoryRecord)mHistory.get(index);
3727             if (r.app == null || r.app.thread == null) {
3728                 // The caller is not running...  d'oh!
3729                 return false;
3730             }
3731             intent = new Intent(intent);
3732             // The caller is not allowed to change the data.
3733             intent.setDataAndType(r.intent.getData(), r.intent.getType());
3734             // And we are resetting to find the next component...
3735             intent.setComponent(null);
3736 
3737             ActivityInfo aInfo = null;
3738             try {
3739                 List<ResolveInfo> resolves =
3740                     ActivityThread.getPackageManager().queryIntentActivities(
3741                             intent, r.resolvedType,
3742                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
3743 
3744                 // Look for the original activity in the list...
3745                 final int N = resolves != null ? resolves.size() : 0;
3746                 for (int i=0; i<N; i++) {
3747                     ResolveInfo rInfo = resolves.get(i);
3748                     if (rInfo.activityInfo.packageName.equals(r.packageName)
3749                             && rInfo.activityInfo.name.equals(r.info.name)) {
3750                         // We found the current one...  the next matching is
3751                         // after it.
3752                         i++;
3753                         if (i<N) {
3754                             aInfo = resolves.get(i).activityInfo;
3755                         }
3756                         break;
3757                     }
3758                 }
3759             } catch (RemoteException e) {
3760             }
3761 
3762             if (aInfo == null) {
3763                 // Nobody who is next!
3764                 return false;
3765             }
3766 
3767             intent.setComponent(new ComponentName(
3768                     aInfo.applicationInfo.packageName, aInfo.name));
3769             intent.setFlags(intent.getFlags()&~(
3770                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3771                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
3772                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3773                     Intent.FLAG_ACTIVITY_NEW_TASK));
3774 
3775             // Okay now we need to start the new activity, replacing the
3776             // currently running activity.  This is a little tricky because
3777             // we want to start the new one as if the current one is finished,
3778             // but not finish the current one first so that there is no flicker.
3779             // And thus...
3780             final boolean wasFinishing = r.finishing;
3781             r.finishing = true;
3782 
3783             // Propagate reply information over to the new activity.
3784             final HistoryRecord resultTo = r.resultTo;
3785             final String resultWho = r.resultWho;
3786             final int requestCode = r.requestCode;
3787             r.resultTo = null;
3788             if (resultTo != null) {
3789                 resultTo.removeResultsLocked(r, resultWho, requestCode);
3790             }
3791 
3792             final long origId = Binder.clearCallingIdentity();
3793             // XXX we are not dealing with propagating grantedUriPermissions...
3794             // those are not yet exposed to user code, so there is no need.
3795             int res = startActivityLocked(r.app.thread, intent,
3796                     r.resolvedType, null, 0, aInfo, resultTo, resultWho,
3797                     requestCode, -1, r.launchedFromUid, false, false);
3798             Binder.restoreCallingIdentity(origId);
3799 
3800             r.finishing = wasFinishing;
3801             if (res != START_SUCCESS) {
3802                 return false;
3803             }
3804             return true;
3805         }
3806     }
3807 
startActivityInPackage(int uid, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded)3808     public final int startActivityInPackage(int uid,
3809             Intent intent, String resolvedType, IBinder resultTo,
3810             String resultWho, int requestCode, boolean onlyIfNeeded) {
3811 
3812         // This is so super not safe, that only the system (or okay root)
3813         // can do it.
3814         final int callingUid = Binder.getCallingUid();
3815         if (callingUid != 0 && callingUid != Process.myUid()) {
3816             throw new SecurityException(
3817                     "startActivityInPackage only available to the system");
3818         }
3819 
3820         final boolean componentSpecified = intent.getComponent() != null;
3821 
3822         // Don't modify the client's object!
3823         intent = new Intent(intent);
3824 
3825         // Collect information about the target of the Intent.
3826         ActivityInfo aInfo;
3827         try {
3828             ResolveInfo rInfo =
3829                 ActivityThread.getPackageManager().resolveIntent(
3830                         intent, resolvedType,
3831                         PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
3832             aInfo = rInfo != null ? rInfo.activityInfo : null;
3833         } catch (RemoteException e) {
3834             aInfo = null;
3835         }
3836 
3837         if (aInfo != null) {
3838             // Store the found target back into the intent, because now that
3839             // we have it we never want to do this again.  For example, if the
3840             // user navigates back to this point in the history, we should
3841             // always restart the exact same activity.
3842             intent.setComponent(new ComponentName(
3843                     aInfo.applicationInfo.packageName, aInfo.name));
3844         }
3845 
3846         synchronized(this) {
3847             return startActivityLocked(null, intent, resolvedType,
3848                     null, 0, aInfo, resultTo, resultWho, requestCode, -1, uid,
3849                     onlyIfNeeded, componentSpecified);
3850         }
3851     }
3852 
addRecentTask(TaskRecord task)3853     private final void addRecentTask(TaskRecord task) {
3854         // Remove any existing entries that are the same kind of task.
3855         int N = mRecentTasks.size();
3856         for (int i=0; i<N; i++) {
3857             TaskRecord tr = mRecentTasks.get(i);
3858             if ((task.affinity != null && task.affinity.equals(tr.affinity))
3859                     || (task.intent != null && task.intent.filterEquals(tr.intent))) {
3860                 mRecentTasks.remove(i);
3861                 i--;
3862                 N--;
3863                 if (task.intent == null) {
3864                     // If the new recent task we are adding is not fully
3865                     // specified, then replace it with the existing recent task.
3866                     task = tr;
3867                 }
3868             }
3869         }
3870         if (N >= MAX_RECENT_TASKS) {
3871             mRecentTasks.remove(N-1);
3872         }
3873         mRecentTasks.add(0, task);
3874     }
3875 
setRequestedOrientation(IBinder token, int requestedOrientation)3876     public void setRequestedOrientation(IBinder token,
3877             int requestedOrientation) {
3878         synchronized (this) {
3879             int index = indexOfTokenLocked(token);
3880             if (index < 0) {
3881                 return;
3882             }
3883             HistoryRecord r = (HistoryRecord)mHistory.get(index);
3884             final long origId = Binder.clearCallingIdentity();
3885             mWindowManager.setAppOrientation(r, requestedOrientation);
3886             Configuration config = mWindowManager.updateOrientationFromAppTokens(
3887                     mConfiguration,
3888                     r.mayFreezeScreenLocked(r.app) ? r : null);
3889             if (config != null) {
3890                 r.frozenBeforeDestroy = true;
3891                 if (!updateConfigurationLocked(config, r)) {
3892                     resumeTopActivityLocked(null);
3893                 }
3894             }
3895             Binder.restoreCallingIdentity(origId);
3896         }
3897     }
3898 
getRequestedOrientation(IBinder token)3899     public int getRequestedOrientation(IBinder token) {
3900         synchronized (this) {
3901             int index = indexOfTokenLocked(token);
3902             if (index < 0) {
3903                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3904             }
3905             HistoryRecord r = (HistoryRecord)mHistory.get(index);
3906             return mWindowManager.getAppOrientation(r);
3907         }
3908     }
3909 
stopActivityLocked(HistoryRecord r)3910     private final void stopActivityLocked(HistoryRecord r) {
3911         if (DEBUG_SWITCH) Log.d(TAG, "Stopping: " + r);
3912         if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
3913                 || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
3914             if (!r.finishing) {
3915                 requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null,
3916                         "no-history");
3917             }
3918         } else if (r.app != null && r.app.thread != null) {
3919             if (mFocusedActivity == r) {
3920                 setFocusedActivityLocked(topRunningActivityLocked(null));
3921             }
3922             r.resumeKeyDispatchingLocked();
3923             try {
3924                 r.stopped = false;
3925                 r.state = ActivityState.STOPPING;
3926                 if (DEBUG_VISBILITY) Log.v(
3927                         TAG, "Stopping visible=" + r.visible + " for " + r);
3928                 if (!r.visible) {
3929                     mWindowManager.setAppVisibility(r, false);
3930                 }
3931                 r.app.thread.scheduleStopActivity(r, r.visible, r.configChangeFlags);
3932             } catch (Exception e) {
3933                 // Maybe just ignore exceptions here...  if the process
3934                 // has crashed, our death notification will clean things
3935                 // up.
3936                 Log.w(TAG, "Exception thrown during pause", e);
3937                 // Just in case, assume it to be stopped.
3938                 r.stopped = true;
3939                 r.state = ActivityState.STOPPED;
3940                 if (r.configDestroy) {
3941                     destroyActivityLocked(r, true);
3942                 }
3943             }
3944         }
3945     }
3946 
3947     /**
3948      * @return Returns true if the activity is being finished, false if for
3949      * some reason it is being left as-is.
3950      */
requestFinishActivityLocked(IBinder token, int resultCode, Intent resultData, String reason)3951     private final boolean requestFinishActivityLocked(IBinder token, int resultCode,
3952             Intent resultData, String reason) {
3953         if (DEBUG_RESULTS) Log.v(
3954             TAG, "Finishing activity: token=" + token
3955             + ", result=" + resultCode + ", data=" + resultData);
3956 
3957         int index = indexOfTokenLocked(token);
3958         if (index < 0) {
3959             return false;
3960         }
3961         HistoryRecord r = (HistoryRecord)mHistory.get(index);
3962 
3963         // Is this the last activity left?
3964         boolean lastActivity = true;
3965         for (int i=mHistory.size()-1; i>=0; i--) {
3966             HistoryRecord p = (HistoryRecord)mHistory.get(i);
3967             if (!p.finishing && p != r) {
3968                 lastActivity = false;
3969                 break;
3970             }
3971         }
3972 
3973         // If this is the last activity, but it is the home activity, then
3974         // just don't finish it.
3975         if (lastActivity) {
3976             if (r.intent.hasCategory(Intent.CATEGORY_HOME)) {
3977                 return false;
3978             }
3979         }
3980 
3981         finishActivityLocked(r, index, resultCode, resultData, reason);
3982         return true;
3983     }
3984 
3985     /**
3986      * @return Returns true if this activity has been removed from the history
3987      * list, or false if it is still in the list and will be removed later.
3988      */
finishActivityLocked(HistoryRecord r, int index, int resultCode, Intent resultData, String reason)3989     private final boolean finishActivityLocked(HistoryRecord r, int index,
3990             int resultCode, Intent resultData, String reason) {
3991         if (r.finishing) {
3992             Log.w(TAG, "Duplicate finish request for " + r);
3993             return false;
3994         }
3995 
3996         r.finishing = true;
3997         EventLog.writeEvent(LOG_AM_FINISH_ACTIVITY,
3998                 System.identityHashCode(r),
3999                 r.task.taskId, r.shortComponentName, reason);
4000         r.task.numActivities--;
4001         if (r.frontOfTask && index < (mHistory.size()-1)) {
4002             HistoryRecord next = (HistoryRecord)mHistory.get(index+1);
4003             if (next.task == r.task) {
4004                 next.frontOfTask = true;
4005             }
4006         }
4007 
4008         r.pauseKeyDispatchingLocked();
4009         if (mFocusedActivity == r) {
4010             setFocusedActivityLocked(topRunningActivityLocked(null));
4011         }
4012 
4013         // send the result
4014         HistoryRecord resultTo = r.resultTo;
4015         if (resultTo != null) {
4016             if (DEBUG_RESULTS) Log.v(TAG, "Adding result to " + resultTo
4017                     + " who=" + r.resultWho + " req=" + r.requestCode
4018                     + " res=" + resultCode + " data=" + resultData);
4019             if (r.info.applicationInfo.uid > 0) {
4020                 grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid,
4021                         r.packageName, resultData, r);
4022             }
4023             resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode,
4024                                      resultData);
4025             r.resultTo = null;
4026         }
4027         else if (DEBUG_RESULTS) Log.v(TAG, "No result destination from " + r);
4028 
4029         // Make sure this HistoryRecord is not holding on to other resources,
4030         // because clients have remote IPC references to this object so we
4031         // can't assume that will go away and want to avoid circular IPC refs.
4032         r.results = null;
4033         r.pendingResults = null;
4034         r.newIntents = null;
4035         r.icicle = null;
4036 
4037         if (mPendingThumbnails.size() > 0) {
4038             // There are clients waiting to receive thumbnails so, in case
4039             // this is an activity that someone is waiting for, add it
4040             // to the pending list so we can correctly update the clients.
4041             mCancelledThumbnails.add(r);
4042         }
4043 
4044         if (mResumedActivity == r) {
4045             boolean endTask = index <= 0
4046                     || ((HistoryRecord)mHistory.get(index-1)).task != r.task;
4047             if (DEBUG_TRANSITION) Log.v(TAG,
4048                     "Prepare close transition: finishing " + r);
4049             mWindowManager.prepareAppTransition(endTask
4050                     ? WindowManagerPolicy.TRANSIT_TASK_CLOSE
4051                     : WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE);
4052 
4053             // Tell window manager to prepare for this one to be removed.
4054             mWindowManager.setAppVisibility(r, false);
4055 
4056             if (mPausingActivity == null) {
4057                 if (DEBUG_PAUSE) Log.v(TAG, "Finish needs to pause: " + r);
4058                 if (DEBUG_USER_LEAVING) Log.v(TAG, "finish() => pause with userLeaving=false");
4059                 startPausingLocked(false, false);
4060             }
4061 
4062         } else if (r.state != ActivityState.PAUSING) {
4063             // If the activity is PAUSING, we will complete the finish once
4064             // it is done pausing; else we can just directly finish it here.
4065             if (DEBUG_PAUSE) Log.v(TAG, "Finish not pausing: " + r);
4066             return finishCurrentActivityLocked(r, index,
4067                     FINISH_AFTER_PAUSE) == null;
4068         } else {
4069             if (DEBUG_PAUSE) Log.v(TAG, "Finish waiting for pause of: " + r);
4070         }
4071 
4072         return false;
4073     }
4074 
4075     private static final int FINISH_IMMEDIATELY = 0;
4076     private static final int FINISH_AFTER_PAUSE = 1;
4077     private static final int FINISH_AFTER_VISIBLE = 2;
4078 
finishCurrentActivityLocked(HistoryRecord r, int mode)4079     private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r,
4080             int mode) {
4081         final int index = indexOfTokenLocked(r);
4082         if (index < 0) {
4083             return null;
4084         }
4085 
4086         return finishCurrentActivityLocked(r, index, mode);
4087     }
4088 
finishCurrentActivityLocked(HistoryRecord r, int index, int mode)4089     private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r,
4090             int index, int mode) {
4091         // First things first: if this activity is currently visible,
4092         // and the resumed activity is not yet visible, then hold off on
4093         // finishing until the resumed one becomes visible.
4094         if (mode == FINISH_AFTER_VISIBLE && r.nowVisible) {
4095             if (!mStoppingActivities.contains(r)) {
4096                 mStoppingActivities.add(r);
4097                 if (mStoppingActivities.size() > 3) {
4098                     // If we already have a few activities waiting to stop,
4099                     // then give up on things going idle and start clearing
4100                     // them out.
4101                     Message msg = Message.obtain();
4102                     msg.what = ActivityManagerService.IDLE_NOW_MSG;
4103                     mHandler.sendMessage(msg);
4104                 }
4105             }
4106             r.state = ActivityState.STOPPING;
4107             updateOomAdjLocked();
4108             return r;
4109         }
4110 
4111         // make sure the record is cleaned out of other places.
4112         mStoppingActivities.remove(r);
4113         mWaitingVisibleActivities.remove(r);
4114         if (mResumedActivity == r) {
4115             mResumedActivity = null;
4116         }
4117         final ActivityState prevState = r.state;
4118         r.state = ActivityState.FINISHING;
4119 
4120         if (mode == FINISH_IMMEDIATELY
4121                 || prevState == ActivityState.STOPPED
4122                 || prevState == ActivityState.INITIALIZING) {
4123             // If this activity is already stopped, we can just finish
4124             // it right now.
4125             return destroyActivityLocked(r, true) ? null : r;
4126         } else {
4127             // Need to go through the full pause cycle to get this
4128             // activity into the stopped state and then finish it.
4129             if (localLOGV) Log.v(TAG, "Enqueueing pending finish: " + r);
4130             mFinishingActivities.add(r);
4131             resumeTopActivityLocked(null);
4132         }
4133         return r;
4134     }
4135 
4136     /**
4137      * This is the internal entry point for handling Activity.finish().
4138      *
4139      * @param token The Binder token referencing the Activity we want to finish.
4140      * @param resultCode Result code, if any, from this Activity.
4141      * @param resultData Result data (Intent), if any, from this Activity.
4142      *
4143      * @result Returns true if the activity successfully finished, or false if it is still running.
4144      */
finishActivity(IBinder token, int resultCode, Intent resultData)4145     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
4146         // Refuse possible leaked file descriptors
4147         if (resultData != null && resultData.hasFileDescriptors() == true) {
4148             throw new IllegalArgumentException("File descriptors passed in Intent");
4149         }
4150 
4151         synchronized(this) {
4152             if (mController != null) {
4153                 // Find the first activity that is not finishing.
4154                 HistoryRecord next = topRunningActivityLocked(token, 0);
4155                 if (next != null) {
4156                     // ask watcher if this is allowed
4157                     boolean resumeOK = true;
4158                     try {
4159                         resumeOK = mController.activityResuming(next.packageName);
4160                     } catch (RemoteException e) {
4161                         mController = null;
4162                     }
4163 
4164                     if (!resumeOK) {
4165                         return false;
4166                     }
4167                 }
4168             }
4169             final long origId = Binder.clearCallingIdentity();
4170             boolean res = requestFinishActivityLocked(token, resultCode,
4171                     resultData, "app-request");
4172             Binder.restoreCallingIdentity(origId);
4173             return res;
4174         }
4175     }
4176 
sendActivityResultLocked(int callingUid, HistoryRecord r, String resultWho, int requestCode, int resultCode, Intent data)4177     void sendActivityResultLocked(int callingUid, HistoryRecord r,
4178             String resultWho, int requestCode, int resultCode, Intent data) {
4179 
4180         if (callingUid > 0) {
4181             grantUriPermissionFromIntentLocked(callingUid, r.packageName,
4182                     data, r);
4183         }
4184 
4185         if (DEBUG_RESULTS) Log.v(TAG, "Send activity result to " + r
4186                 + " : who=" + resultWho + " req=" + requestCode
4187                 + " res=" + resultCode + " data=" + data);
4188         if (mResumedActivity == r && r.app != null && r.app.thread != null) {
4189             try {
4190                 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
4191                 list.add(new ResultInfo(resultWho, requestCode,
4192                         resultCode, data));
4193                 r.app.thread.scheduleSendResult(r, list);
4194                 return;
4195             } catch (Exception e) {
4196                 Log.w(TAG, "Exception thrown sending result to " + r, e);
4197             }
4198         }
4199 
4200         r.addResultLocked(null, resultWho, requestCode, resultCode, data);
4201     }
4202 
finishSubActivity(IBinder token, String resultWho, int requestCode)4203     public final void finishSubActivity(IBinder token, String resultWho,
4204             int requestCode) {
4205         synchronized(this) {
4206             int index = indexOfTokenLocked(token);
4207             if (index < 0) {
4208                 return;
4209             }
4210             HistoryRecord self = (HistoryRecord)mHistory.get(index);
4211 
4212             final long origId = Binder.clearCallingIdentity();
4213 
4214             int i;
4215             for (i=mHistory.size()-1; i>=0; i--) {
4216                 HistoryRecord r = (HistoryRecord)mHistory.get(i);
4217                 if (r.resultTo == self && r.requestCode == requestCode) {
4218                     if ((r.resultWho == null && resultWho == null) ||
4219                         (r.resultWho != null && r.resultWho.equals(resultWho))) {
4220                         finishActivityLocked(r, i,
4221                                 Activity.RESULT_CANCELED, null, "request-sub");
4222                     }
4223                 }
4224             }
4225 
4226             Binder.restoreCallingIdentity(origId);
4227         }
4228     }
4229 
overridePendingTransition(IBinder token, String packageName, int enterAnim, int exitAnim)4230     public void overridePendingTransition(IBinder token, String packageName,
4231             int enterAnim, int exitAnim) {
4232         synchronized(this) {
4233             int index = indexOfTokenLocked(token);
4234             if (index < 0) {
4235                 return;
4236             }
4237             HistoryRecord self = (HistoryRecord)mHistory.get(index);
4238 
4239             final long origId = Binder.clearCallingIdentity();
4240 
4241             if (self.state == ActivityState.RESUMED
4242                     || self.state == ActivityState.PAUSING) {
4243                 mWindowManager.overridePendingAppTransition(packageName,
4244                         enterAnim, exitAnim);
4245             }
4246 
4247             Binder.restoreCallingIdentity(origId);
4248         }
4249     }
4250 
4251     /**
4252      * Perform clean-up of service connections in an activity record.
4253      */
cleanUpActivityServicesLocked(HistoryRecord r)4254     private final void cleanUpActivityServicesLocked(HistoryRecord r) {
4255         // Throw away any services that have been bound by this activity.
4256         if (r.connections != null) {
4257             Iterator<ConnectionRecord> it = r.connections.iterator();
4258             while (it.hasNext()) {
4259                 ConnectionRecord c = it.next();
4260                 removeConnectionLocked(c, null, r);
4261             }
4262             r.connections = null;
4263         }
4264     }
4265 
4266     /**
4267      * Perform the common clean-up of an activity record.  This is called both
4268      * as part of destroyActivityLocked() (when destroying the client-side
4269      * representation) and cleaning things up as a result of its hosting
4270      * processing going away, in which case there is no remaining client-side
4271      * state to destroy so only the cleanup here is needed.
4272      */
cleanUpActivityLocked(HistoryRecord r, boolean cleanServices)4273     private final void cleanUpActivityLocked(HistoryRecord r, boolean cleanServices) {
4274         if (mResumedActivity == r) {
4275             mResumedActivity = null;
4276         }
4277         if (mFocusedActivity == r) {
4278             mFocusedActivity = null;
4279         }
4280 
4281         r.configDestroy = false;
4282         r.frozenBeforeDestroy = false;
4283 
4284         // Make sure this record is no longer in the pending finishes list.
4285         // This could happen, for example, if we are trimming activities
4286         // down to the max limit while they are still waiting to finish.
4287         mFinishingActivities.remove(r);
4288         mWaitingVisibleActivities.remove(r);
4289 
4290         // Remove any pending results.
4291         if (r.finishing && r.pendingResults != null) {
4292             for (WeakReference<PendingIntentRecord> apr : r.pendingResults) {
4293                 PendingIntentRecord rec = apr.get();
4294                 if (rec != null) {
4295                     cancelIntentSenderLocked(rec, false);
4296                 }
4297             }
4298             r.pendingResults = null;
4299         }
4300 
4301         if (cleanServices) {
4302             cleanUpActivityServicesLocked(r);
4303         }
4304 
4305         if (mPendingThumbnails.size() > 0) {
4306             // There are clients waiting to receive thumbnails so, in case
4307             // this is an activity that someone is waiting for, add it
4308             // to the pending list so we can correctly update the clients.
4309             mCancelledThumbnails.add(r);
4310         }
4311 
4312         // Get rid of any pending idle timeouts.
4313         mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
4314         mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
4315     }
4316 
removeActivityFromHistoryLocked(HistoryRecord r)4317     private final void removeActivityFromHistoryLocked(HistoryRecord r) {
4318         if (r.state != ActivityState.DESTROYED) {
4319             mHistory.remove(r);
4320             r.inHistory = false;
4321             r.state = ActivityState.DESTROYED;
4322             mWindowManager.removeAppToken(r);
4323             if (VALIDATE_TOKENS) {
4324                 mWindowManager.validateAppTokens(mHistory);
4325             }
4326             cleanUpActivityServicesLocked(r);
4327             removeActivityUriPermissionsLocked(r);
4328         }
4329     }
4330 
4331     /**
4332      * Destroy the current CLIENT SIDE instance of an activity.  This may be
4333      * called both when actually finishing an activity, or when performing
4334      * a configuration switch where we destroy the current client-side object
4335      * but then create a new client-side object for this same HistoryRecord.
4336      */
destroyActivityLocked(HistoryRecord r, boolean removeFromApp)4337     private final boolean destroyActivityLocked(HistoryRecord r,
4338             boolean removeFromApp) {
4339         if (DEBUG_SWITCH) Log.v(
4340             TAG, "Removing activity: token=" + r
4341               + ", app=" + (r.app != null ? r.app.processName : "(null)"));
4342         EventLog.writeEvent(LOG_AM_DESTROY_ACTIVITY,
4343                 System.identityHashCode(r),
4344                 r.task.taskId, r.shortComponentName);
4345 
4346         boolean removedFromHistory = false;
4347 
4348         cleanUpActivityLocked(r, false);
4349 
4350         if (r.app != null) {
4351             if (removeFromApp) {
4352                 int idx = r.app.activities.indexOf(r);
4353                 if (idx >= 0) {
4354                     r.app.activities.remove(idx);
4355                 }
4356                 if (r.persistent) {
4357                     decPersistentCountLocked(r.app);
4358                 }
4359             }
4360 
4361             boolean skipDestroy = false;
4362 
4363             try {
4364                 if (DEBUG_SWITCH) Log.i(TAG, "Destroying: " + r);
4365                 r.app.thread.scheduleDestroyActivity(r, r.finishing,
4366                         r.configChangeFlags);
4367             } catch (Exception e) {
4368                 // We can just ignore exceptions here...  if the process
4369                 // has crashed, our death notification will clean things
4370                 // up.
4371                 //Log.w(TAG, "Exception thrown during finish", e);
4372                 if (r.finishing) {
4373                     removeActivityFromHistoryLocked(r);
4374                     removedFromHistory = true;
4375                     skipDestroy = true;
4376                 }
4377             }
4378 
4379             r.app = null;
4380             r.nowVisible = false;
4381 
4382             if (r.finishing && !skipDestroy) {
4383                 r.state = ActivityState.DESTROYING;
4384                 Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG);
4385                 msg.obj = r;
4386                 mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT);
4387             } else {
4388                 r.state = ActivityState.DESTROYED;
4389             }
4390         } else {
4391             // remove this record from the history.
4392             if (r.finishing) {
4393                 removeActivityFromHistoryLocked(r);
4394                 removedFromHistory = true;
4395             } else {
4396                 r.state = ActivityState.DESTROYED;
4397             }
4398         }
4399 
4400         r.configChangeFlags = 0;
4401 
4402         if (!mLRUActivities.remove(r)) {
4403             Log.w(TAG, "Activity " + r + " being finished, but not in LRU list");
4404         }
4405 
4406         return removedFromHistory;
4407     }
4408 
removeHistoryRecordsForAppLocked(ArrayList list, ProcessRecord app)4409     private static void removeHistoryRecordsForAppLocked(ArrayList list,
4410                                                          ProcessRecord app)
4411     {
4412         int i = list.size();
4413         if (localLOGV) Log.v(
4414             TAG, "Removing app " + app + " from list " + list
4415             + " with " + i + " entries");
4416         while (i > 0) {
4417             i--;
4418             HistoryRecord r = (HistoryRecord)list.get(i);
4419             if (localLOGV) Log.v(
4420                 TAG, "Record #" + i + " " + r + ": app=" + r.app);
4421             if (r.app == app) {
4422                 if (localLOGV) Log.v(TAG, "Removing this entry!");
4423                 list.remove(i);
4424             }
4425         }
4426     }
4427 
4428     /**
4429      * Main function for removing an existing process from the activity manager
4430      * as a result of that process going away.  Clears out all connections
4431      * to the process.
4432      */
handleAppDiedLocked(ProcessRecord app, boolean restarting)4433     private final void handleAppDiedLocked(ProcessRecord app,
4434             boolean restarting) {
4435         cleanUpApplicationRecordLocked(app, restarting, -1);
4436         if (!restarting) {
4437             mLRUProcesses.remove(app);
4438         }
4439 
4440         // Just in case...
4441         if (mPausingActivity != null && mPausingActivity.app == app) {
4442             if (DEBUG_PAUSE) Log.v(TAG, "App died while pausing: " + mPausingActivity);
4443             mPausingActivity = null;
4444         }
4445         if (mLastPausedActivity != null && mLastPausedActivity.app == app) {
4446             mLastPausedActivity = null;
4447         }
4448 
4449         // Remove this application's activities from active lists.
4450         removeHistoryRecordsForAppLocked(mLRUActivities, app);
4451         removeHistoryRecordsForAppLocked(mStoppingActivities, app);
4452         removeHistoryRecordsForAppLocked(mWaitingVisibleActivities, app);
4453         removeHistoryRecordsForAppLocked(mFinishingActivities, app);
4454 
4455         boolean atTop = true;
4456         boolean hasVisibleActivities = false;
4457 
4458         // Clean out the history list.
4459         int i = mHistory.size();
4460         if (localLOGV) Log.v(
4461             TAG, "Removing app " + app + " from history with " + i + " entries");
4462         while (i > 0) {
4463             i--;
4464             HistoryRecord r = (HistoryRecord)mHistory.get(i);
4465             if (localLOGV) Log.v(
4466                 TAG, "Record #" + i + " " + r + ": app=" + r.app);
4467             if (r.app == app) {
4468                 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
4469                     if (localLOGV) Log.v(
4470                         TAG, "Removing this entry!  frozen=" + r.haveState
4471                         + " finishing=" + r.finishing);
4472                     mHistory.remove(i);
4473 
4474                     r.inHistory = false;
4475                     mWindowManager.removeAppToken(r);
4476                     if (VALIDATE_TOKENS) {
4477                         mWindowManager.validateAppTokens(mHistory);
4478                     }
4479                     removeActivityUriPermissionsLocked(r);
4480 
4481                 } else {
4482                     // We have the current state for this activity, so
4483                     // it can be restarted later when needed.
4484                     if (localLOGV) Log.v(
4485                         TAG, "Keeping entry, setting app to null");
4486                     if (r.visible) {
4487                         hasVisibleActivities = true;
4488                     }
4489                     r.app = null;
4490                     r.nowVisible = false;
4491                     if (!r.haveState) {
4492                         r.icicle = null;
4493                     }
4494                 }
4495 
4496                 cleanUpActivityLocked(r, true);
4497                 r.state = ActivityState.STOPPED;
4498             }
4499             atTop = false;
4500         }
4501 
4502         app.activities.clear();
4503 
4504         if (app.instrumentationClass != null) {
4505             Log.w(TAG, "Crash of app " + app.processName
4506                   + " running instrumentation " + app.instrumentationClass);
4507             Bundle info = new Bundle();
4508             info.putString("shortMsg", "Process crashed.");
4509             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4510         }
4511 
4512         if (!restarting) {
4513             if (!resumeTopActivityLocked(null)) {
4514                 // If there was nothing to resume, and we are not already
4515                 // restarting this process, but there is a visible activity that
4516                 // is hosted by the process...  then make sure all visible
4517                 // activities are running, taking care of restarting this
4518                 // process.
4519                 if (hasVisibleActivities) {
4520                     ensureActivitiesVisibleLocked(null, 0);
4521                 }
4522             }
4523         }
4524     }
4525 
getLRURecordIndexForAppLocked(IApplicationThread thread)4526     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4527         IBinder threadBinder = thread.asBinder();
4528 
4529         // Find the application record.
4530         int count = mLRUProcesses.size();
4531         int i;
4532         for (i=0; i<count; i++) {
4533             ProcessRecord rec = mLRUProcesses.get(i);
4534             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4535                 return i;
4536             }
4537         }
4538         return -1;
4539     }
4540 
getRecordForAppLocked( IApplicationThread thread)4541     private final ProcessRecord getRecordForAppLocked(
4542             IApplicationThread thread) {
4543         if (thread == null) {
4544             return null;
4545         }
4546 
4547         int appIndex = getLRURecordIndexForAppLocked(thread);
4548         return appIndex >= 0 ? mLRUProcesses.get(appIndex) : null;
4549     }
4550 
appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread)4551     private final void appDiedLocked(ProcessRecord app, int pid,
4552             IApplicationThread thread) {
4553 
4554         mProcDeaths[0]++;
4555 
4556         if (app.thread != null && app.thread.asBinder() == thread.asBinder()) {
4557             Log.i(TAG, "Process " + app.processName + " (pid " + pid
4558                     + ") has died.");
4559             EventLog.writeEvent(LOG_AM_PROCESS_DIED, app.pid, app.processName);
4560             if (localLOGV) Log.v(
4561                 TAG, "Dying app: " + app + ", pid: " + pid
4562                 + ", thread: " + thread.asBinder());
4563             boolean doLowMem = app.instrumentationClass == null;
4564             handleAppDiedLocked(app, false);
4565 
4566             if (doLowMem) {
4567                 // If there are no longer any background processes running,
4568                 // and the app that died was not running instrumentation,
4569                 // then tell everyone we are now low on memory.
4570                 boolean haveBg = false;
4571                 int count = mLRUProcesses.size();
4572                 int i;
4573                 for (i=0; i<count; i++) {
4574                     ProcessRecord rec = mLRUProcesses.get(i);
4575                     if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
4576                         haveBg = true;
4577                         break;
4578                     }
4579                 }
4580 
4581                 if (!haveBg) {
4582                     Log.i(TAG, "Low Memory: No more background processes.");
4583                     EventLog.writeEvent(LOG_AM_LOW_MEMORY, mLRUProcesses.size());
4584                     long now = SystemClock.uptimeMillis();
4585                     for (i=0; i<count; i++) {
4586                         ProcessRecord rec = mLRUProcesses.get(i);
4587                         if (rec != app && rec.thread != null &&
4588                                 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4589                             // The low memory report is overriding any current
4590                             // state for a GC request.  Make sure to do
4591                             // visible/foreground processes first.
4592                             if (rec.setAdj <= VISIBLE_APP_ADJ) {
4593                                 rec.lastRequestedGc = 0;
4594                             } else {
4595                                 rec.lastRequestedGc = rec.lastLowMemory;
4596                             }
4597                             rec.reportLowMemory = true;
4598                             rec.lastLowMemory = now;
4599                             mProcessesToGc.remove(rec);
4600                             addProcessToGcListLocked(rec);
4601                         }
4602                     }
4603                     scheduleAppGcsLocked();
4604                 }
4605             }
4606         } else if (Config.LOGD) {
4607             Log.d(TAG, "Received spurious death notification for thread "
4608                     + thread.asBinder());
4609         }
4610     }
4611 
readFile(String filename)4612     final String readFile(String filename) {
4613         try {
4614             FileInputStream fs = new FileInputStream(filename);
4615             byte[] inp = new byte[8192];
4616             int size = fs.read(inp);
4617             fs.close();
4618             return new String(inp, 0, 0, size);
4619         } catch (java.io.IOException e) {
4620         }
4621         return "";
4622     }
4623 
appNotRespondingLocked(ProcessRecord app, HistoryRecord activity, HistoryRecord reportedActivity, final String annotation)4624     final void appNotRespondingLocked(ProcessRecord app, HistoryRecord activity,
4625             HistoryRecord reportedActivity, final String annotation) {
4626         if (app.notResponding || app.crashing) {
4627             return;
4628         }
4629 
4630         // Log the ANR to the event log.
4631         EventLog.writeEvent(LOG_ANR, app.pid, app.processName, annotation);
4632 
4633         // If we are on a secure build and the application is not interesting to the user (it is
4634         // not visible or in the background), just kill it instead of displaying a dialog.
4635         boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0"));
4636         if (isSecure && !app.isInterestingToUserLocked() && Process.myPid() != app.pid) {
4637             Process.killProcess(app.pid);
4638             return;
4639         }
4640 
4641         // DeviceMonitor.start();
4642 
4643         String processInfo = null;
4644         if (MONITOR_CPU_USAGE) {
4645             updateCpuStatsNow();
4646             synchronized (mProcessStatsThread) {
4647                 processInfo = mProcessStats.printCurrentState();
4648             }
4649         }
4650 
4651         StringBuilder info = mStringBuilder;
4652         info.setLength(0);
4653         info.append("ANR in process: ");
4654         info.append(app.processName);
4655         if (reportedActivity != null && reportedActivity.app != null) {
4656             info.append(" (last in ");
4657             info.append(reportedActivity.app.processName);
4658             info.append(")");
4659         }
4660         if (annotation != null) {
4661             info.append("\nAnnotation: ");
4662             info.append(annotation);
4663         }
4664         if (MONITOR_CPU_USAGE) {
4665             info.append("\nCPU usage:\n");
4666             info.append(processInfo);
4667         }
4668         Log.i(TAG, info.toString());
4669 
4670         // The application is not responding. Dump as many thread traces as we can.
4671         boolean fileDump = prepareTraceFile(true);
4672         if (!fileDump) {
4673             // Dumping traces to the log, just dump the process that isn't responding so
4674             // we don't overflow the log
4675             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4676         } else {
4677             // Dumping traces to a file so dump all active processes we know about
4678             synchronized (this) {
4679                 // First, these are the most important processes.
4680                 final int[] imppids = new int[3];
4681                 int i=0;
4682                 imppids[0] = app.pid;
4683                 i++;
4684                 if (reportedActivity != null && reportedActivity.app != null
4685                         && reportedActivity.app.thread != null
4686                         && reportedActivity.app.pid != app.pid) {
4687                     imppids[i] = reportedActivity.app.pid;
4688                     i++;
4689                 }
4690                 imppids[i] = Process.myPid();
4691                 for (i=0; i<imppids.length && imppids[i] != 0; i++) {
4692                     Process.sendSignal(imppids[i], Process.SIGNAL_QUIT);
4693                     synchronized (this) {
4694                         try {
4695                             wait(200);
4696                         } catch (InterruptedException e) {
4697                         }
4698                     }
4699                 }
4700                 for (i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) {
4701                     ProcessRecord r = mLRUProcesses.get(i);
4702                     boolean done = false;
4703                     for (int j=0; j<imppids.length && imppids[j] != 0; j++) {
4704                         if (imppids[j] == r.pid) {
4705                             done = true;
4706                             break;
4707                         }
4708                     }
4709                     if (!done && r.thread != null) {
4710                         Process.sendSignal(r.pid, Process.SIGNAL_QUIT);
4711                         synchronized (this) {
4712                             try {
4713                                 wait(200);
4714                             } catch (InterruptedException e) {
4715                             }
4716                         }
4717                     }
4718                 }
4719             }
4720         }
4721 
4722         if (mController != null) {
4723             try {
4724                 int res = mController.appNotResponding(app.processName,
4725                         app.pid, info.toString());
4726                 if (res != 0) {
4727                     if (res < 0) {
4728                         // wait until the SIGQUIT has had a chance to process before killing the
4729                         // process.
4730                         try {
4731                             wait(2000);
4732                         } catch (InterruptedException e) {
4733                         }
4734 
4735                         Process.killProcess(app.pid);
4736                         return;
4737                     }
4738                 }
4739             } catch (RemoteException e) {
4740                 mController = null;
4741             }
4742         }
4743 
4744         makeAppNotRespondingLocked(app,
4745                 activity != null ? activity.shortComponentName : null,
4746                 annotation != null ? "ANR " + annotation : "ANR",
4747                 info.toString(), null);
4748         Message msg = Message.obtain();
4749         HashMap map = new HashMap();
4750         msg.what = SHOW_NOT_RESPONDING_MSG;
4751         msg.obj = map;
4752         map.put("app", app);
4753         if (activity != null) {
4754             map.put("activity", activity);
4755         }
4756 
4757         mHandler.sendMessage(msg);
4758         return;
4759     }
4760 
4761     /**
4762      * If a stack trace file has been configured, prepare the filesystem
4763      * by creating the directory if it doesn't exist and optionally
4764      * removing the old trace file.
4765      *
4766      * @param removeExisting If set, the existing trace file will be removed.
4767      * @return Returns true if the trace file preparations succeeded
4768      */
prepareTraceFile(boolean removeExisting)4769     public static boolean prepareTraceFile(boolean removeExisting) {
4770         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4771         boolean fileReady = false;
4772         if (!TextUtils.isEmpty(tracesPath)) {
4773             File f = new File(tracesPath);
4774             if (!f.exists()) {
4775                 // Ensure the enclosing directory exists
4776                 File dir = f.getParentFile();
4777                 if (!dir.exists()) {
4778                     fileReady = dir.mkdirs();
4779                     FileUtils.setPermissions(dir.getAbsolutePath(),
4780                             FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IXOTH, -1, -1);
4781                 } else if (dir.isDirectory()) {
4782                     fileReady = true;
4783                 }
4784             } else if (removeExisting) {
4785                 // Remove the previous traces file, so we don't fill the disk.
4786                 // The VM will recreate it
4787                 Log.i(TAG, "Removing old ANR trace file from " + tracesPath);
4788                 fileReady = f.delete();
4789             }
4790 
4791             if (removeExisting) {
4792                 try {
4793                     f.createNewFile();
4794                     FileUtils.setPermissions(f.getAbsolutePath(),
4795                             FileUtils.S_IRWXU | FileUtils.S_IRWXG
4796                             | FileUtils.S_IWOTH | FileUtils.S_IROTH, -1, -1);
4797                     fileReady = true;
4798                 } catch (IOException e) {
4799                     Log.w(TAG, "Unable to make ANR traces file", e);
4800                 }
4801             }
4802         }
4803 
4804         return fileReady;
4805     }
4806 
4807 
decPersistentCountLocked(ProcessRecord app)4808     private final void decPersistentCountLocked(ProcessRecord app)
4809     {
4810         app.persistentActivities--;
4811         if (app.persistentActivities > 0) {
4812             // Still more of 'em...
4813             return;
4814         }
4815         if (app.persistent) {
4816             // Ah, but the application itself is persistent.  Whatever!
4817             return;
4818         }
4819 
4820         // App is no longer persistent...  make sure it and the ones
4821         // following it in the LRU list have the correc oom_adj.
4822         updateOomAdjLocked();
4823     }
4824 
setPersistent(IBinder token, boolean isPersistent)4825     public void setPersistent(IBinder token, boolean isPersistent) {
4826         if (checkCallingPermission(android.Manifest.permission.PERSISTENT_ACTIVITY)
4827                 != PackageManager.PERMISSION_GRANTED) {
4828             String msg = "Permission Denial: setPersistent() from pid="
4829                     + Binder.getCallingPid()
4830                     + ", uid=" + Binder.getCallingUid()
4831                     + " requires " + android.Manifest.permission.PERSISTENT_ACTIVITY;
4832             Log.w(TAG, msg);
4833             throw new SecurityException(msg);
4834         }
4835 
4836         synchronized(this) {
4837             int index = indexOfTokenLocked(token);
4838             if (index < 0) {
4839                 return;
4840             }
4841             HistoryRecord r = (HistoryRecord)mHistory.get(index);
4842             ProcessRecord app = r.app;
4843 
4844             if (localLOGV) Log.v(
4845                 TAG, "Setting persistence " + isPersistent + ": " + r);
4846 
4847             if (isPersistent) {
4848                 if (r.persistent) {
4849                     // Okay okay, I heard you already!
4850                     if (localLOGV) Log.v(TAG, "Already persistent!");
4851                     return;
4852                 }
4853                 r.persistent = true;
4854                 app.persistentActivities++;
4855                 if (localLOGV) Log.v(TAG, "Num persistent now: " + app.persistentActivities);
4856                 if (app.persistentActivities > 1) {
4857                     // We aren't the first...
4858                     if (localLOGV) Log.v(TAG, "Not the first!");
4859                     return;
4860                 }
4861                 if (app.persistent) {
4862                     // This would be redundant.
4863                     if (localLOGV) Log.v(TAG, "App is persistent!");
4864                     return;
4865                 }
4866 
4867                 // App is now persistent...  make sure it and the ones
4868                 // following it now have the correct oom_adj.
4869                 final long origId = Binder.clearCallingIdentity();
4870                 updateOomAdjLocked();
4871                 Binder.restoreCallingIdentity(origId);
4872 
4873             } else {
4874                 if (!r.persistent) {
4875                     // Okay okay, I heard you already!
4876                     return;
4877                 }
4878                 r.persistent = false;
4879                 final long origId = Binder.clearCallingIdentity();
4880                 decPersistentCountLocked(app);
4881                 Binder.restoreCallingIdentity(origId);
4882 
4883             }
4884         }
4885     }
4886 
clearApplicationUserData(final String packageName, final IPackageDataObserver observer)4887     public boolean clearApplicationUserData(final String packageName,
4888             final IPackageDataObserver observer) {
4889         int uid = Binder.getCallingUid();
4890         int pid = Binder.getCallingPid();
4891         long callingId = Binder.clearCallingIdentity();
4892         try {
4893             IPackageManager pm = ActivityThread.getPackageManager();
4894             int pkgUid = -1;
4895             synchronized(this) {
4896                 try {
4897                     pkgUid = pm.getPackageUid(packageName);
4898                 } catch (RemoteException e) {
4899                 }
4900                 if (pkgUid == -1) {
4901                     Log.w(TAG, "Invalid packageName:" + packageName);
4902                     return false;
4903                 }
4904                 if (uid == pkgUid || checkComponentPermission(
4905                         android.Manifest.permission.CLEAR_APP_USER_DATA,
4906                         pid, uid, -1)
4907                         == PackageManager.PERMISSION_GRANTED) {
4908                     restartPackageLocked(packageName, pkgUid);
4909                 } else {
4910                     throw new SecurityException(pid+" does not have permission:"+
4911                             android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
4912                                     "for process:"+packageName);
4913                 }
4914             }
4915 
4916             try {
4917                 //clear application user data
4918                 pm.clearApplicationUserData(packageName, observer);
4919                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4920                         Uri.fromParts("package", packageName, null));
4921                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
4922                 broadcastIntentLocked(null, null, intent,
4923                         null, null, 0, null, null, null,
4924                         false, false, MY_PID, Process.SYSTEM_UID);
4925             } catch (RemoteException e) {
4926             }
4927         } finally {
4928             Binder.restoreCallingIdentity(callingId);
4929         }
4930         return true;
4931     }
4932 
restartPackage(final String packageName)4933     public void restartPackage(final String packageName) {
4934         if (checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4935                 != PackageManager.PERMISSION_GRANTED) {
4936             String msg = "Permission Denial: restartPackage() from pid="
4937                     + Binder.getCallingPid()
4938                     + ", uid=" + Binder.getCallingUid()
4939                     + " requires " + android.Manifest.permission.RESTART_PACKAGES;
4940             Log.w(TAG, msg);
4941             throw new SecurityException(msg);
4942         }
4943 
4944         long callingId = Binder.clearCallingIdentity();
4945         try {
4946             IPackageManager pm = ActivityThread.getPackageManager();
4947             int pkgUid = -1;
4948             synchronized(this) {
4949                 try {
4950                     pkgUid = pm.getPackageUid(packageName);
4951                 } catch (RemoteException e) {
4952                 }
4953                 if (pkgUid == -1) {
4954                     Log.w(TAG, "Invalid packageName: " + packageName);
4955                     return;
4956                 }
4957                 restartPackageLocked(packageName, pkgUid);
4958             }
4959         } finally {
4960             Binder.restoreCallingIdentity(callingId);
4961         }
4962     }
4963 
4964     /*
4965      * The pkg name and uid have to be specified.
4966      * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
4967      */
killApplicationWithUid(String pkg, int uid)4968     public void killApplicationWithUid(String pkg, int uid) {
4969         if (pkg == null) {
4970             return;
4971         }
4972         // Make sure the uid is valid.
4973         if (uid < 0) {
4974             Log.w(TAG, "Invalid uid specified for pkg : " + pkg);
4975             return;
4976         }
4977         int callerUid = Binder.getCallingUid();
4978         // Only the system server can kill an application
4979         if (callerUid == Process.SYSTEM_UID) {
4980             // Post an aysnc message to kill the application
4981             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4982             msg.arg1 = uid;
4983             msg.arg2 = 0;
4984             msg.obj = pkg;
4985             mHandler.sendMessage(msg);
4986         } else {
4987             throw new SecurityException(callerUid + " cannot kill pkg: " +
4988                     pkg);
4989         }
4990     }
4991 
closeSystemDialogs(String reason)4992     public void closeSystemDialogs(String reason) {
4993         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4994         if (reason != null) {
4995             intent.putExtra("reason", reason);
4996         }
4997 
4998         final int uid = Binder.getCallingUid();
4999         final long origId = Binder.clearCallingIdentity();
5000         synchronized (this) {
5001             int i = mWatchers.beginBroadcast();
5002             while (i > 0) {
5003                 i--;
5004                 IActivityWatcher w = mWatchers.getBroadcastItem(i);
5005                 if (w != null) {
5006                     try {
5007                         w.closingSystemDialogs(reason);
5008                     } catch (RemoteException e) {
5009                     }
5010                 }
5011             }
5012             mWatchers.finishBroadcast();
5013 
5014             mWindowManager.closeSystemDialogs(reason);
5015 
5016             for (i=mHistory.size()-1; i>=0; i--) {
5017                 HistoryRecord r = (HistoryRecord)mHistory.get(i);
5018                 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
5019                     finishActivityLocked(r, i,
5020                             Activity.RESULT_CANCELED, null, "close-sys");
5021                 }
5022             }
5023 
5024             broadcastIntentLocked(null, null, intent, null,
5025                     null, 0, null, null, null, false, false, -1, uid);
5026         }
5027         Binder.restoreCallingIdentity(origId);
5028     }
5029 
getProcessMemoryInfo(int[] pids)5030     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
5031             throws RemoteException {
5032         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5033         for (int i=pids.length-1; i>=0; i--) {
5034             infos[i] = new Debug.MemoryInfo();
5035             Debug.getMemoryInfo(pids[i], infos[i]);
5036         }
5037         return infos;
5038     }
5039 
killApplicationProcess(String processName, int uid)5040     public void killApplicationProcess(String processName, int uid) {
5041         if (processName == null) {
5042             return;
5043         }
5044 
5045         int callerUid = Binder.getCallingUid();
5046         // Only the system server can kill an application
5047         if (callerUid == Process.SYSTEM_UID) {
5048             synchronized (this) {
5049                 ProcessRecord app = getProcessRecordLocked(processName, uid);
5050                 if (app != null) {
5051                     try {
5052                         app.thread.scheduleSuicide();
5053                     } catch (RemoteException e) {
5054                         // If the other end already died, then our work here is done.
5055                     }
5056                 } else {
5057                     Log.w(TAG, "Process/uid not found attempting kill of "
5058                             + processName + " / " + uid);
5059                 }
5060             }
5061         } else {
5062             throw new SecurityException(callerUid + " cannot kill app process: " +
5063                     processName);
5064         }
5065     }
5066 
restartPackageLocked(final String packageName, int uid)5067     private void restartPackageLocked(final String packageName, int uid) {
5068         uninstallPackageLocked(packageName, uid, false);
5069         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5070                 Uri.fromParts("package", packageName, null));
5071         intent.putExtra(Intent.EXTRA_UID, uid);
5072         broadcastIntentLocked(null, null, intent,
5073                 null, null, 0, null, null, null,
5074                 false, false, MY_PID, Process.SYSTEM_UID);
5075     }
5076 
uninstallPackageLocked(String name, int uid, boolean callerWillRestart)5077     private final void uninstallPackageLocked(String name, int uid,
5078             boolean callerWillRestart) {
5079         if (Config.LOGD) Log.d(TAG, "Uninstalling process " + name);
5080 
5081         int i, N;
5082 
5083         final String procNamePrefix = name + ":";
5084         if (uid < 0) {
5085             try {
5086                 uid = ActivityThread.getPackageManager().getPackageUid(name);
5087             } catch (RemoteException e) {
5088             }
5089         }
5090 
5091         Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
5092         while (badApps.hasNext()) {
5093             SparseArray<Long> ba = badApps.next();
5094             if (ba.get(uid) != null) {
5095                 badApps.remove();
5096             }
5097         }
5098 
5099         ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5100 
5101         // Remove all processes this package may have touched: all with the
5102         // same UID (except for the system or root user), and all whose name
5103         // matches the package name.
5104         for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
5105             final int NA = apps.size();
5106             for (int ia=0; ia<NA; ia++) {
5107                 ProcessRecord app = apps.valueAt(ia);
5108                 if (app.removed) {
5109                     procs.add(app);
5110                 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
5111                         || app.processName.equals(name)
5112                         || app.processName.startsWith(procNamePrefix)) {
5113                     app.removed = true;
5114                     procs.add(app);
5115                 }
5116             }
5117         }
5118 
5119         N = procs.size();
5120         for (i=0; i<N; i++) {
5121             removeProcessLocked(procs.get(i), callerWillRestart);
5122         }
5123 
5124         for (i=mHistory.size()-1; i>=0; i--) {
5125             HistoryRecord r = (HistoryRecord)mHistory.get(i);
5126             if (r.packageName.equals(name)) {
5127                 if (Config.LOGD) Log.d(
5128                     TAG, "  Force finishing activity "
5129                     + r.intent.getComponent().flattenToShortString());
5130                 if (r.app != null) {
5131                     r.app.removed = true;
5132                 }
5133                 r.app = null;
5134                 finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
5135             }
5136         }
5137 
5138         ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5139         for (ServiceRecord service : mServices.values()) {
5140             if (service.packageName.equals(name)) {
5141                 if (service.app != null) {
5142                     service.app.removed = true;
5143                 }
5144                 service.app = null;
5145                 services.add(service);
5146             }
5147         }
5148 
5149         N = services.size();
5150         for (i=0; i<N; i++) {
5151             bringDownServiceLocked(services.get(i), true);
5152         }
5153 
5154         resumeTopActivityLocked(null);
5155     }
5156 
removeProcessLocked(ProcessRecord app, boolean callerWillRestart)5157     private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) {
5158         final String name = app.processName;
5159         final int uid = app.info.uid;
5160         if (Config.LOGD) Log.d(
5161             TAG, "Force removing process " + app + " (" + name
5162             + "/" + uid + ")");
5163 
5164         mProcessNames.remove(name, uid);
5165         boolean needRestart = false;
5166         if (app.pid > 0 && app.pid != MY_PID) {
5167             int pid = app.pid;
5168             synchronized (mPidsSelfLocked) {
5169                 mPidsSelfLocked.remove(pid);
5170                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5171             }
5172             handleAppDiedLocked(app, true);
5173             mLRUProcesses.remove(app);
5174             Process.killProcess(pid);
5175 
5176             if (app.persistent) {
5177                 if (!callerWillRestart) {
5178                     addAppLocked(app.info);
5179                 } else {
5180                     needRestart = true;
5181                 }
5182             }
5183         } else {
5184             mRemovedProcesses.add(app);
5185         }
5186 
5187         return needRestart;
5188     }
5189 
processStartTimedOutLocked(ProcessRecord app)5190     private final void processStartTimedOutLocked(ProcessRecord app) {
5191         final int pid = app.pid;
5192         boolean gone = false;
5193         synchronized (mPidsSelfLocked) {
5194             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5195             if (knownApp != null && knownApp.thread == null) {
5196                 mPidsSelfLocked.remove(pid);
5197                 gone = true;
5198             }
5199         }
5200 
5201         if (gone) {
5202             Log.w(TAG, "Process " + app + " failed to attach");
5203             EventLog.writeEvent(LOG_AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
5204                     app.processName);
5205             mProcessNames.remove(app.processName, app.info.uid);
5206             // Take care of any launching providers waiting for this process.
5207             checkAppInLaunchingProvidersLocked(app, true);
5208             // Take care of any services that are waiting for the process.
5209             for (int i=0; i<mPendingServices.size(); i++) {
5210                 ServiceRecord sr = mPendingServices.get(i);
5211                 if (app.info.uid == sr.appInfo.uid
5212                         && app.processName.equals(sr.processName)) {
5213                     Log.w(TAG, "Forcing bringing down service: " + sr);
5214                     mPendingServices.remove(i);
5215                     i--;
5216                     bringDownServiceLocked(sr, true);
5217                 }
5218             }
5219             Process.killProcess(pid);
5220             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5221                 Log.w(TAG, "Unattached app died before backup, skipping");
5222                 try {
5223                     IBackupManager bm = IBackupManager.Stub.asInterface(
5224                             ServiceManager.getService(Context.BACKUP_SERVICE));
5225                     bm.agentDisconnected(app.info.packageName);
5226                 } catch (RemoteException e) {
5227                     // Can't happen; the backup manager is local
5228                 }
5229             }
5230             if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
5231                 Log.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5232                 mPendingBroadcast = null;
5233                 scheduleBroadcastsLocked();
5234             }
5235         } else {
5236             Log.w(TAG, "Spurious process start timeout - pid not known for " + app);
5237         }
5238     }
5239 
attachApplicationLocked(IApplicationThread thread, int pid)5240     private final boolean attachApplicationLocked(IApplicationThread thread,
5241             int pid) {
5242 
5243         // Find the application record that is being attached...  either via
5244         // the pid if we are running in multiple processes, or just pull the
5245         // next app record if we are emulating process with anonymous threads.
5246         ProcessRecord app;
5247         if (pid != MY_PID && pid >= 0) {
5248             synchronized (mPidsSelfLocked) {
5249                 app = mPidsSelfLocked.get(pid);
5250             }
5251         } else if (mStartingProcesses.size() > 0) {
5252             app = mStartingProcesses.remove(0);
5253             app.setPid(pid);
5254         } else {
5255             app = null;
5256         }
5257 
5258         if (app == null) {
5259             Log.w(TAG, "No pending application record for pid " + pid
5260                     + " (IApplicationThread " + thread + "); dropping process");
5261             EventLog.writeEvent(LOG_AM_DROP_PROCESS, pid);
5262             if (pid > 0 && pid != MY_PID) {
5263                 Process.killProcess(pid);
5264             } else {
5265                 try {
5266                     thread.scheduleExit();
5267                 } catch (Exception e) {
5268                     // Ignore exceptions.
5269                 }
5270             }
5271             return false;
5272         }
5273 
5274         // If this application record is still attached to a previous
5275         // process, clean it up now.
5276         if (app.thread != null) {
5277             handleAppDiedLocked(app, true);
5278         }
5279 
5280         // Tell the process all about itself.
5281 
5282         if (localLOGV) Log.v(
5283                 TAG, "Binding process pid " + pid + " to record " + app);
5284 
5285         String processName = app.processName;
5286         try {
5287             thread.asBinder().linkToDeath(new AppDeathRecipient(
5288                     app, pid, thread), 0);
5289         } catch (RemoteException e) {
5290             app.resetPackageList();
5291             startProcessLocked(app, "link fail", processName);
5292             return false;
5293         }
5294 
5295         EventLog.writeEvent(LOG_AM_PROCESS_BOUND, app.pid, app.processName);
5296 
5297         app.thread = thread;
5298         app.curAdj = app.setAdj = -100;
5299         app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5300         app.forcingToForeground = null;
5301         app.foregroundServices = false;
5302         app.debugging = false;
5303 
5304         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5305 
5306         boolean normalMode = mSystemReady || isAllowedWhileBooting(app.info);
5307         List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5308 
5309         if (!normalMode) {
5310             Log.i(TAG, "Launching preboot mode app: " + app);
5311         }
5312 
5313         if (localLOGV) Log.v(
5314             TAG, "New app record " + app
5315             + " thread=" + thread.asBinder() + " pid=" + pid);
5316         try {
5317             int testMode = IApplicationThread.DEBUG_OFF;
5318             if (mDebugApp != null && mDebugApp.equals(processName)) {
5319                 testMode = mWaitForDebugger
5320                     ? IApplicationThread.DEBUG_WAIT
5321                     : IApplicationThread.DEBUG_ON;
5322                 app.debugging = true;
5323                 if (mDebugTransient) {
5324                     mDebugApp = mOrigDebugApp;
5325                     mWaitForDebugger = mOrigWaitForDebugger;
5326                 }
5327             }
5328 
5329             // If the app is being launched for restore or full backup, set it up specially
5330             boolean isRestrictedBackupMode = false;
5331             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5332                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5333                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5334             }
5335 
5336             ensurePackageDexOpt(app.instrumentationInfo != null
5337                     ? app.instrumentationInfo.packageName
5338                     : app.info.packageName);
5339             if (app.instrumentationClass != null) {
5340                 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5341             }
5342             if (DEBUG_CONFIGURATION) Log.v(TAG, "Binding proc "
5343                     + processName + " with config " + mConfiguration);
5344             thread.bindApplication(processName, app.instrumentationInfo != null
5345                     ? app.instrumentationInfo : app.info, providers,
5346                     app.instrumentationClass, app.instrumentationProfileFile,
5347                     app.instrumentationArguments, app.instrumentationWatcher, testMode,
5348                     isRestrictedBackupMode || !normalMode,
5349                     mConfiguration, getCommonServicesLocked());
5350             updateLRUListLocked(app, false);
5351             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5352         } catch (Exception e) {
5353             // todo: Yikes!  What should we do?  For now we will try to
5354             // start another process, but that could easily get us in
5355             // an infinite loop of restarting processes...
5356             Log.w(TAG, "Exception thrown during bind!", e);
5357 
5358             app.resetPackageList();
5359             startProcessLocked(app, "bind fail", processName);
5360             return false;
5361         }
5362 
5363         // Remove this record from the list of starting applications.
5364         mPersistentStartingProcesses.remove(app);
5365         mProcessesOnHold.remove(app);
5366 
5367         boolean badApp = false;
5368         boolean didSomething = false;
5369 
5370         // See if the top visible activity is waiting to run in this process...
5371         HistoryRecord hr = topRunningActivityLocked(null);
5372         if (hr != null) {
5373             if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
5374                     && processName.equals(hr.processName)) {
5375                 try {
5376                     if (realStartActivityLocked(hr, app, true, true)) {
5377                         didSomething = true;
5378                     }
5379                 } catch (Exception e) {
5380                     Log.w(TAG, "Exception in new application when starting activity "
5381                           + hr.intent.getComponent().flattenToShortString(), e);
5382                     badApp = true;
5383                 }
5384             } else {
5385                 ensureActivitiesVisibleLocked(hr, null, processName, 0);
5386             }
5387         }
5388 
5389         // Find any services that should be running in this process...
5390         if (!badApp && mPendingServices.size() > 0) {
5391             ServiceRecord sr = null;
5392             try {
5393                 for (int i=0; i<mPendingServices.size(); i++) {
5394                     sr = mPendingServices.get(i);
5395                     if (app.info.uid != sr.appInfo.uid
5396                             || !processName.equals(sr.processName)) {
5397                         continue;
5398                     }
5399 
5400                     mPendingServices.remove(i);
5401                     i--;
5402                     realStartServiceLocked(sr, app);
5403                     didSomething = true;
5404                 }
5405             } catch (Exception e) {
5406                 Log.w(TAG, "Exception in new application when starting service "
5407                       + sr.shortName, e);
5408                 badApp = true;
5409             }
5410         }
5411 
5412         // Check if the next broadcast receiver is in this process...
5413         BroadcastRecord br = mPendingBroadcast;
5414         if (!badApp && br != null && br.curApp == app) {
5415             try {
5416                 mPendingBroadcast = null;
5417                 processCurBroadcastLocked(br, app);
5418                 didSomething = true;
5419             } catch (Exception e) {
5420                 Log.w(TAG, "Exception in new application when starting receiver "
5421                       + br.curComponent.flattenToShortString(), e);
5422                 badApp = true;
5423                 logBroadcastReceiverDiscard(br);
5424                 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
5425                         br.resultExtras, br.resultAbort, true);
5426                 scheduleBroadcastsLocked();
5427             }
5428         }
5429 
5430         // Check whether the next backup agent is in this process...
5431         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
5432             if (DEBUG_BACKUP) Log.v(TAG, "New app is backup target, launching agent for " + app);
5433             ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5434             try {
5435                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, mBackupTarget.backupMode);
5436             } catch (Exception e) {
5437                 Log.w(TAG, "Exception scheduling backup agent creation: ");
5438                 e.printStackTrace();
5439             }
5440         }
5441 
5442         if (badApp) {
5443             // todo: Also need to kill application to deal with all
5444             // kinds of exceptions.
5445             handleAppDiedLocked(app, false);
5446             return false;
5447         }
5448 
5449         if (!didSomething) {
5450             updateOomAdjLocked();
5451         }
5452 
5453         return true;
5454     }
5455 
attachApplication(IApplicationThread thread)5456     public final void attachApplication(IApplicationThread thread) {
5457         synchronized (this) {
5458             int callingPid = Binder.getCallingPid();
5459             final long origId = Binder.clearCallingIdentity();
5460             attachApplicationLocked(thread, callingPid);
5461             Binder.restoreCallingIdentity(origId);
5462         }
5463     }
5464 
activityIdle(IBinder token, Configuration config)5465     public final void activityIdle(IBinder token, Configuration config) {
5466         final long origId = Binder.clearCallingIdentity();
5467         activityIdleInternal(token, false, config);
5468         Binder.restoreCallingIdentity(origId);
5469     }
5470 
processStoppingActivitiesLocked( boolean remove)5471     final ArrayList<HistoryRecord> processStoppingActivitiesLocked(
5472             boolean remove) {
5473         int N = mStoppingActivities.size();
5474         if (N <= 0) return null;
5475 
5476         ArrayList<HistoryRecord> stops = null;
5477 
5478         final boolean nowVisible = mResumedActivity != null
5479                 && mResumedActivity.nowVisible
5480                 && !mResumedActivity.waitingVisible;
5481         for (int i=0; i<N; i++) {
5482             HistoryRecord s = mStoppingActivities.get(i);
5483             if (localLOGV) Log.v(TAG, "Stopping " + s + ": nowVisible="
5484                     + nowVisible + " waitingVisible=" + s.waitingVisible
5485                     + " finishing=" + s.finishing);
5486             if (s.waitingVisible && nowVisible) {
5487                 mWaitingVisibleActivities.remove(s);
5488                 s.waitingVisible = false;
5489                 if (s.finishing) {
5490                     // If this activity is finishing, it is sitting on top of
5491                     // everyone else but we now know it is no longer needed...
5492                     // so get rid of it.  Otherwise, we need to go through the
5493                     // normal flow and hide it once we determine that it is
5494                     // hidden by the activities in front of it.
5495                     if (localLOGV) Log.v(TAG, "Before stopping, can hide: " + s);
5496                     mWindowManager.setAppVisibility(s, false);
5497                 }
5498             }
5499             if (!s.waitingVisible && remove) {
5500                 if (localLOGV) Log.v(TAG, "Ready to stop: " + s);
5501                 if (stops == null) {
5502                     stops = new ArrayList<HistoryRecord>();
5503                 }
5504                 stops.add(s);
5505                 mStoppingActivities.remove(i);
5506                 N--;
5507                 i--;
5508             }
5509         }
5510 
5511         return stops;
5512     }
5513 
enableScreenAfterBoot()5514     void enableScreenAfterBoot() {
5515         EventLog.writeEvent(LOG_BOOT_PROGRESS_ENABLE_SCREEN,
5516                 SystemClock.uptimeMillis());
5517         mWindowManager.enableScreenAfterBoot();
5518     }
5519 
activityIdleInternal(IBinder token, boolean fromTimeout, Configuration config)5520     final void activityIdleInternal(IBinder token, boolean fromTimeout,
5521             Configuration config) {
5522         if (localLOGV) Log.v(TAG, "Activity idle: " + token);
5523 
5524         ArrayList<HistoryRecord> stops = null;
5525         ArrayList<HistoryRecord> finishes = null;
5526         ArrayList<HistoryRecord> thumbnails = null;
5527         int NS = 0;
5528         int NF = 0;
5529         int NT = 0;
5530         IApplicationThread sendThumbnail = null;
5531         boolean booting = false;
5532         boolean enableScreen = false;
5533 
5534         synchronized (this) {
5535             if (token != null) {
5536                 mHandler.removeMessages(IDLE_TIMEOUT_MSG, token);
5537             }
5538 
5539             // Get the activity record.
5540             int index = indexOfTokenLocked(token);
5541             if (index >= 0) {
5542                 HistoryRecord r = (HistoryRecord)mHistory.get(index);
5543 
5544                 // This is a hack to semi-deal with a race condition
5545                 // in the client where it can be constructed with a
5546                 // newer configuration from when we asked it to launch.
5547                 // We'll update with whatever configuration it now says
5548                 // it used to launch.
5549                 if (config != null) {
5550                     r.configuration = config;
5551                 }
5552 
5553                 // No longer need to keep the device awake.
5554                 if (mResumedActivity == r && mLaunchingActivity.isHeld()) {
5555                     mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
5556                     mLaunchingActivity.release();
5557                 }
5558 
5559                 // We are now idle.  If someone is waiting for a thumbnail from
5560                 // us, we can now deliver.
5561                 r.idle = true;
5562                 scheduleAppGcsLocked();
5563                 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
5564                     sendThumbnail = r.app.thread;
5565                     r.thumbnailNeeded = false;
5566                 }
5567 
5568                 // If this activity is fullscreen, set up to hide those under it.
5569 
5570                 if (DEBUG_VISBILITY) Log.v(TAG, "Idle activity for " + r);
5571                 ensureActivitiesVisibleLocked(null, 0);
5572 
5573                 //Log.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
5574                 if (!mBooted && !fromTimeout) {
5575                     mBooted = true;
5576                     enableScreen = true;
5577                 }
5578             }
5579 
5580             // Atomically retrieve all of the other things to do.
5581             stops = processStoppingActivitiesLocked(true);
5582             NS = stops != null ? stops.size() : 0;
5583             if ((NF=mFinishingActivities.size()) > 0) {
5584                 finishes = new ArrayList<HistoryRecord>(mFinishingActivities);
5585                 mFinishingActivities.clear();
5586             }
5587             if ((NT=mCancelledThumbnails.size()) > 0) {
5588                 thumbnails = new ArrayList<HistoryRecord>(mCancelledThumbnails);
5589                 mCancelledThumbnails.clear();
5590             }
5591 
5592             booting = mBooting;
5593             mBooting = false;
5594         }
5595 
5596         int i;
5597 
5598         // Send thumbnail if requested.
5599         if (sendThumbnail != null) {
5600             try {
5601                 sendThumbnail.requestThumbnail(token);
5602             } catch (Exception e) {
5603                 Log.w(TAG, "Exception thrown when requesting thumbnail", e);
5604                 sendPendingThumbnail(null, token, null, null, true);
5605             }
5606         }
5607 
5608         // Stop any activities that are scheduled to do so but have been
5609         // waiting for the next one to start.
5610         for (i=0; i<NS; i++) {
5611             HistoryRecord r = (HistoryRecord)stops.get(i);
5612             synchronized (this) {
5613                 if (r.finishing) {
5614                     finishCurrentActivityLocked(r, FINISH_IMMEDIATELY);
5615                 } else {
5616                     stopActivityLocked(r);
5617                 }
5618             }
5619         }
5620 
5621         // Finish any activities that are scheduled to do so but have been
5622         // waiting for the next one to start.
5623         for (i=0; i<NF; i++) {
5624             HistoryRecord r = (HistoryRecord)finishes.get(i);
5625             synchronized (this) {
5626                 destroyActivityLocked(r, true);
5627             }
5628         }
5629 
5630         // Report back to any thumbnail receivers.
5631         for (i=0; i<NT; i++) {
5632             HistoryRecord r = (HistoryRecord)thumbnails.get(i);
5633             sendPendingThumbnail(r, null, null, null, true);
5634         }
5635 
5636         if (booting) {
5637             finishBooting();
5638         }
5639 
5640         trimApplications();
5641         //dump();
5642         //mWindowManager.dump();
5643 
5644         if (enableScreen) {
5645             enableScreenAfterBoot();
5646         }
5647     }
5648 
finishBooting()5649     final void finishBooting() {
5650         // Ensure that any processes we had put on hold are now started
5651         // up.
5652         final int NP = mProcessesOnHold.size();
5653         if (NP > 0) {
5654             ArrayList<ProcessRecord> procs =
5655                 new ArrayList<ProcessRecord>(mProcessesOnHold);
5656             for (int ip=0; ip<NP; ip++) {
5657                 this.startProcessLocked(procs.get(ip), "on-hold", null);
5658             }
5659         }
5660         if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
5661             // Tell anyone interested that we are done booting!
5662             synchronized (this) {
5663                 broadcastIntentLocked(null, null,
5664                         new Intent(Intent.ACTION_BOOT_COMPLETED, null),
5665                         null, null, 0, null, null,
5666                         android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5667                         false, false, MY_PID, Process.SYSTEM_UID);
5668             }
5669         }
5670     }
5671 
ensureBootCompleted()5672     final void ensureBootCompleted() {
5673         boolean booting;
5674         boolean enableScreen;
5675         synchronized (this) {
5676             booting = mBooting;
5677             mBooting = false;
5678             enableScreen = !mBooted;
5679             mBooted = true;
5680         }
5681 
5682         if (booting) {
5683             finishBooting();
5684         }
5685 
5686         if (enableScreen) {
5687             enableScreenAfterBoot();
5688         }
5689     }
5690 
activityPaused(IBinder token, Bundle icicle)5691     public final void activityPaused(IBinder token, Bundle icicle) {
5692         // Refuse possible leaked file descriptors
5693         if (icicle != null && icicle.hasFileDescriptors()) {
5694             throw new IllegalArgumentException("File descriptors passed in Bundle");
5695         }
5696 
5697         final long origId = Binder.clearCallingIdentity();
5698         activityPaused(token, icicle, false);
5699         Binder.restoreCallingIdentity(origId);
5700     }
5701 
activityPaused(IBinder token, Bundle icicle, boolean timeout)5702     final void activityPaused(IBinder token, Bundle icicle, boolean timeout) {
5703         if (DEBUG_PAUSE) Log.v(
5704             TAG, "Activity paused: token=" + token + ", icicle=" + icicle
5705             + ", timeout=" + timeout);
5706 
5707         HistoryRecord r = null;
5708 
5709         synchronized (this) {
5710             int index = indexOfTokenLocked(token);
5711             if (index >= 0) {
5712                 r = (HistoryRecord)mHistory.get(index);
5713                 if (!timeout) {
5714                     r.icicle = icicle;
5715                     r.haveState = true;
5716                 }
5717                 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
5718                 if (mPausingActivity == r) {
5719                     r.state = ActivityState.PAUSED;
5720                     completePauseLocked();
5721                 } else {
5722                 	EventLog.writeEvent(LOG_AM_FAILED_TO_PAUSE_ACTIVITY,
5723                 	        System.identityHashCode(r), r.shortComponentName,
5724                 			mPausingActivity != null
5725                 			    ? mPausingActivity.shortComponentName : "(none)");
5726                 }
5727             }
5728         }
5729     }
5730 
activityStopped(IBinder token, Bitmap thumbnail, CharSequence description)5731     public final void activityStopped(IBinder token, Bitmap thumbnail,
5732             CharSequence description) {
5733         if (localLOGV) Log.v(
5734             TAG, "Activity stopped: token=" + token);
5735 
5736         HistoryRecord r = null;
5737 
5738         final long origId = Binder.clearCallingIdentity();
5739 
5740         synchronized (this) {
5741             int index = indexOfTokenLocked(token);
5742             if (index >= 0) {
5743                 r = (HistoryRecord)mHistory.get(index);
5744                 r.thumbnail = thumbnail;
5745                 r.description = description;
5746                 r.stopped = true;
5747                 r.state = ActivityState.STOPPED;
5748                 if (!r.finishing) {
5749                     if (r.configDestroy) {
5750                         destroyActivityLocked(r, true);
5751                         resumeTopActivityLocked(null);
5752                     }
5753                 }
5754             }
5755         }
5756 
5757         if (r != null) {
5758             sendPendingThumbnail(r, null, null, null, false);
5759         }
5760 
5761         trimApplications();
5762 
5763         Binder.restoreCallingIdentity(origId);
5764     }
5765 
activityDestroyed(IBinder token)5766     public final void activityDestroyed(IBinder token) {
5767         if (DEBUG_SWITCH) Log.v(TAG, "ACTIVITY DESTROYED: " + token);
5768         synchronized (this) {
5769             mHandler.removeMessages(DESTROY_TIMEOUT_MSG, token);
5770 
5771             int index = indexOfTokenLocked(token);
5772             if (index >= 0) {
5773                 HistoryRecord r = (HistoryRecord)mHistory.get(index);
5774                 if (r.state == ActivityState.DESTROYING) {
5775                     final long origId = Binder.clearCallingIdentity();
5776                     removeActivityFromHistoryLocked(r);
5777                     Binder.restoreCallingIdentity(origId);
5778                 }
5779             }
5780         }
5781     }
5782 
getCallingPackage(IBinder token)5783     public String getCallingPackage(IBinder token) {
5784         synchronized (this) {
5785             HistoryRecord r = getCallingRecordLocked(token);
5786             return r != null && r.app != null ? r.info.packageName : null;
5787         }
5788     }
5789 
getCallingActivity(IBinder token)5790     public ComponentName getCallingActivity(IBinder token) {
5791         synchronized (this) {
5792             HistoryRecord r = getCallingRecordLocked(token);
5793             return r != null ? r.intent.getComponent() : null;
5794         }
5795     }
5796 
getCallingRecordLocked(IBinder token)5797     private HistoryRecord getCallingRecordLocked(IBinder token) {
5798         int index = indexOfTokenLocked(token);
5799         if (index >= 0) {
5800             HistoryRecord r = (HistoryRecord)mHistory.get(index);
5801             if (r != null) {
5802                 return r.resultTo;
5803             }
5804         }
5805         return null;
5806     }
5807 
getActivityClassForToken(IBinder token)5808     public ComponentName getActivityClassForToken(IBinder token) {
5809         synchronized(this) {
5810             int index = indexOfTokenLocked(token);
5811             if (index >= 0) {
5812                 HistoryRecord r = (HistoryRecord)mHistory.get(index);
5813                 return r.intent.getComponent();
5814             }
5815             return null;
5816         }
5817     }
5818 
getPackageForToken(IBinder token)5819     public String getPackageForToken(IBinder token) {
5820         synchronized(this) {
5821             int index = indexOfTokenLocked(token);
5822             if (index >= 0) {
5823                 HistoryRecord r = (HistoryRecord)mHistory.get(index);
5824                 return r.packageName;
5825             }
5826             return null;
5827         }
5828     }
5829 
getIntentSender(int type, String packageName, IBinder token, String resultWho, int requestCode, Intent intent, String resolvedType, int flags)5830     public IIntentSender getIntentSender(int type,
5831             String packageName, IBinder token, String resultWho,
5832             int requestCode, Intent intent, String resolvedType, int flags) {
5833         // Refuse possible leaked file descriptors
5834         if (intent != null && intent.hasFileDescriptors() == true) {
5835             throw new IllegalArgumentException("File descriptors passed in Intent");
5836         }
5837 
5838         if (type == INTENT_SENDER_BROADCAST) {
5839             if ((intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5840                 throw new IllegalArgumentException(
5841                         "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5842             }
5843         }
5844 
5845         synchronized(this) {
5846             int callingUid = Binder.getCallingUid();
5847             try {
5848                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID &&
5849                         Process.supportsProcesses()) {
5850                     int uid = ActivityThread.getPackageManager()
5851                             .getPackageUid(packageName);
5852                     if (uid != Binder.getCallingUid()) {
5853                         String msg = "Permission Denial: getIntentSender() from pid="
5854                             + Binder.getCallingPid()
5855                             + ", uid=" + Binder.getCallingUid()
5856                             + ", (need uid=" + uid + ")"
5857                             + " is not allowed to send as package " + packageName;
5858                         Log.w(TAG, msg);
5859                         throw new SecurityException(msg);
5860                     }
5861                 }
5862             } catch (RemoteException e) {
5863                 throw new SecurityException(e);
5864             }
5865             HistoryRecord activity = null;
5866             if (type == INTENT_SENDER_ACTIVITY_RESULT) {
5867                 int index = indexOfTokenLocked(token);
5868                 if (index < 0) {
5869                     return null;
5870                 }
5871                 activity = (HistoryRecord)mHistory.get(index);
5872                 if (activity.finishing) {
5873                     return null;
5874                 }
5875             }
5876 
5877             final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5878             final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5879             final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5880             flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5881                     |PendingIntent.FLAG_UPDATE_CURRENT);
5882 
5883             PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5884                     type, packageName, activity, resultWho,
5885                     requestCode, intent, resolvedType, flags);
5886             WeakReference<PendingIntentRecord> ref;
5887             ref = mIntentSenderRecords.get(key);
5888             PendingIntentRecord rec = ref != null ? ref.get() : null;
5889             if (rec != null) {
5890                 if (!cancelCurrent) {
5891                     if (updateCurrent) {
5892                         rec.key.requestIntent.replaceExtras(intent);
5893                     }
5894                     return rec;
5895                 }
5896                 rec.canceled = true;
5897                 mIntentSenderRecords.remove(key);
5898             }
5899             if (noCreate) {
5900                 return rec;
5901             }
5902             rec = new PendingIntentRecord(this, key, callingUid);
5903             mIntentSenderRecords.put(key, rec.ref);
5904             if (type == INTENT_SENDER_ACTIVITY_RESULT) {
5905                 if (activity.pendingResults == null) {
5906                     activity.pendingResults
5907                             = new HashSet<WeakReference<PendingIntentRecord>>();
5908                 }
5909                 activity.pendingResults.add(rec.ref);
5910             }
5911             return rec;
5912         }
5913     }
5914 
cancelIntentSender(IIntentSender sender)5915     public void cancelIntentSender(IIntentSender sender) {
5916         if (!(sender instanceof PendingIntentRecord)) {
5917             return;
5918         }
5919         synchronized(this) {
5920             PendingIntentRecord rec = (PendingIntentRecord)sender;
5921             try {
5922                 int uid = ActivityThread.getPackageManager()
5923                         .getPackageUid(rec.key.packageName);
5924                 if (uid != Binder.getCallingUid()) {
5925                     String msg = "Permission Denial: cancelIntentSender() from pid="
5926                         + Binder.getCallingPid()
5927                         + ", uid=" + Binder.getCallingUid()
5928                         + " is not allowed to cancel packges "
5929                         + rec.key.packageName;
5930                     Log.w(TAG, msg);
5931                     throw new SecurityException(msg);
5932                 }
5933             } catch (RemoteException e) {
5934                 throw new SecurityException(e);
5935             }
5936             cancelIntentSenderLocked(rec, true);
5937         }
5938     }
5939 
cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity)5940     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5941         rec.canceled = true;
5942         mIntentSenderRecords.remove(rec.key);
5943         if (cleanActivity && rec.key.activity != null) {
5944             rec.key.activity.pendingResults.remove(rec.ref);
5945         }
5946     }
5947 
getPackageForIntentSender(IIntentSender pendingResult)5948     public String getPackageForIntentSender(IIntentSender pendingResult) {
5949         if (!(pendingResult instanceof PendingIntentRecord)) {
5950             return null;
5951         }
5952         synchronized(this) {
5953             try {
5954                 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5955                 return res.key.packageName;
5956             } catch (ClassCastException e) {
5957             }
5958         }
5959         return null;
5960     }
5961 
setProcessLimit(int max)5962     public void setProcessLimit(int max) {
5963         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5964                 "setProcessLimit()");
5965         mProcessLimit = max;
5966     }
5967 
getProcessLimit()5968     public int getProcessLimit() {
5969         return mProcessLimit;
5970     }
5971 
foregroundTokenDied(ForegroundToken token)5972     void foregroundTokenDied(ForegroundToken token) {
5973         synchronized (ActivityManagerService.this) {
5974             synchronized (mPidsSelfLocked) {
5975                 ForegroundToken cur
5976                     = mForegroundProcesses.get(token.pid);
5977                 if (cur != token) {
5978                     return;
5979                 }
5980                 mForegroundProcesses.remove(token.pid);
5981                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5982                 if (pr == null) {
5983                     return;
5984                 }
5985                 pr.forcingToForeground = null;
5986                 pr.foregroundServices = false;
5987             }
5988             updateOomAdjLocked();
5989         }
5990     }
5991 
setProcessForeground(IBinder token, int pid, boolean isForeground)5992     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5993         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5994                 "setProcessForeground()");
5995         synchronized(this) {
5996             boolean changed = false;
5997 
5998             synchronized (mPidsSelfLocked) {
5999                 ProcessRecord pr = mPidsSelfLocked.get(pid);
6000                 if (pr == null) {
6001                     Log.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6002                     return;
6003                 }
6004                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
6005                 if (oldToken != null) {
6006                     oldToken.token.unlinkToDeath(oldToken, 0);
6007                     mForegroundProcesses.remove(pid);
6008                     pr.forcingToForeground = null;
6009                     changed = true;
6010                 }
6011                 if (isForeground && token != null) {
6012                     ForegroundToken newToken = new ForegroundToken() {
6013                         public void binderDied() {
6014                             foregroundTokenDied(this);
6015                         }
6016                     };
6017                     newToken.pid = pid;
6018                     newToken.token = token;
6019                     try {
6020                         token.linkToDeath(newToken, 0);
6021                         mForegroundProcesses.put(pid, newToken);
6022                         pr.forcingToForeground = token;
6023                         changed = true;
6024                     } catch (RemoteException e) {
6025                         // If the process died while doing this, we will later
6026                         // do the cleanup with the process death link.
6027                     }
6028                 }
6029             }
6030 
6031             if (changed) {
6032                 updateOomAdjLocked();
6033             }
6034         }
6035     }
6036 
6037     // =========================================================
6038     // PERMISSIONS
6039     // =========================================================
6040 
6041     static class PermissionController extends IPermissionController.Stub {
6042         ActivityManagerService mActivityManagerService;
PermissionController(ActivityManagerService activityManagerService)6043         PermissionController(ActivityManagerService activityManagerService) {
6044             mActivityManagerService = activityManagerService;
6045         }
6046 
checkPermission(String permission, int pid, int uid)6047         public boolean checkPermission(String permission, int pid, int uid) {
6048             return mActivityManagerService.checkPermission(permission, pid,
6049                     uid) == PackageManager.PERMISSION_GRANTED;
6050         }
6051     }
6052 
6053     /**
6054      * This can be called with or without the global lock held.
6055      */
checkComponentPermission(String permission, int pid, int uid, int reqUid)6056     int checkComponentPermission(String permission, int pid, int uid,
6057             int reqUid) {
6058         // We might be performing an operation on behalf of an indirect binder
6059         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6060         // client identity accordingly before proceeding.
6061         Identity tlsIdentity = sCallerIdentity.get();
6062         if (tlsIdentity != null) {
6063             Log.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6064                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6065             uid = tlsIdentity.uid;
6066             pid = tlsIdentity.pid;
6067         }
6068 
6069         // Root, system server and our own process get to do everything.
6070         if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID ||
6071             !Process.supportsProcesses()) {
6072             return PackageManager.PERMISSION_GRANTED;
6073         }
6074         // If the target requires a specific UID, always fail for others.
6075         if (reqUid >= 0 && uid != reqUid) {
6076             return PackageManager.PERMISSION_DENIED;
6077         }
6078         if (permission == null) {
6079             return PackageManager.PERMISSION_GRANTED;
6080         }
6081         try {
6082             return ActivityThread.getPackageManager()
6083                     .checkUidPermission(permission, uid);
6084         } catch (RemoteException e) {
6085             // Should never happen, but if it does... deny!
6086             Log.e(TAG, "PackageManager is dead?!?", e);
6087         }
6088         return PackageManager.PERMISSION_DENIED;
6089     }
6090 
6091     /**
6092      * As the only public entry point for permissions checking, this method
6093      * can enforce the semantic that requesting a check on a null global
6094      * permission is automatically denied.  (Internally a null permission
6095      * string is used when calling {@link #checkComponentPermission} in cases
6096      * when only uid-based security is needed.)
6097      *
6098      * This can be called with or without the global lock held.
6099      */
checkPermission(String permission, int pid, int uid)6100     public int checkPermission(String permission, int pid, int uid) {
6101         if (permission == null) {
6102             return PackageManager.PERMISSION_DENIED;
6103         }
6104         return checkComponentPermission(permission, pid, uid, -1);
6105     }
6106 
6107     /**
6108      * Binder IPC calls go through the public entry point.
6109      * This can be called with or without the global lock held.
6110      */
checkCallingPermission(String permission)6111     int checkCallingPermission(String permission) {
6112         return checkPermission(permission,
6113                 Binder.getCallingPid(),
6114                 Binder.getCallingUid());
6115     }
6116 
6117     /**
6118      * This can be called with or without the global lock held.
6119      */
enforceCallingPermission(String permission, String func)6120     void enforceCallingPermission(String permission, String func) {
6121         if (checkCallingPermission(permission)
6122                 == PackageManager.PERMISSION_GRANTED) {
6123             return;
6124         }
6125 
6126         String msg = "Permission Denial: " + func + " from pid="
6127                 + Binder.getCallingPid()
6128                 + ", uid=" + Binder.getCallingUid()
6129                 + " requires " + permission;
6130         Log.w(TAG, msg);
6131         throw new SecurityException(msg);
6132     }
6133 
checkHoldingPermissionsLocked(IPackageManager pm, ProviderInfo pi, int uid, int modeFlags)6134     private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
6135             ProviderInfo pi, int uid, int modeFlags) {
6136         try {
6137             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6138                 if ((pi.readPermission != null) &&
6139                         (pm.checkUidPermission(pi.readPermission, uid)
6140                                 != PackageManager.PERMISSION_GRANTED)) {
6141                     return false;
6142                 }
6143             }
6144             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6145                 if ((pi.writePermission != null) &&
6146                         (pm.checkUidPermission(pi.writePermission, uid)
6147                                 != PackageManager.PERMISSION_GRANTED)) {
6148                     return false;
6149                 }
6150             }
6151             return true;
6152         } catch (RemoteException e) {
6153             return false;
6154         }
6155     }
6156 
checkUriPermissionLocked(Uri uri, int uid, int modeFlags)6157     private final boolean checkUriPermissionLocked(Uri uri, int uid,
6158             int modeFlags) {
6159         // Root gets to do everything.
6160         if (uid == 0 || !Process.supportsProcesses()) {
6161             return true;
6162         }
6163         HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6164         if (perms == null) return false;
6165         UriPermission perm = perms.get(uri);
6166         if (perm == null) return false;
6167         return (modeFlags&perm.modeFlags) == modeFlags;
6168     }
6169 
checkUriPermission(Uri uri, int pid, int uid, int modeFlags)6170     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
6171         // Another redirected-binder-call permissions check as in
6172         // {@link checkComponentPermission}.
6173         Identity tlsIdentity = sCallerIdentity.get();
6174         if (tlsIdentity != null) {
6175             uid = tlsIdentity.uid;
6176             pid = tlsIdentity.pid;
6177         }
6178 
6179         // Our own process gets to do everything.
6180         if (pid == MY_PID) {
6181             return PackageManager.PERMISSION_GRANTED;
6182         }
6183         synchronized(this) {
6184             return checkUriPermissionLocked(uri, uid, modeFlags)
6185                     ? PackageManager.PERMISSION_GRANTED
6186                     : PackageManager.PERMISSION_DENIED;
6187         }
6188     }
6189 
grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, int modeFlags, HistoryRecord activity)6190     private void grantUriPermissionLocked(int callingUid,
6191             String targetPkg, Uri uri, int modeFlags, HistoryRecord activity) {
6192         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6193                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6194         if (modeFlags == 0) {
6195             return;
6196         }
6197 
6198         final IPackageManager pm = ActivityThread.getPackageManager();
6199 
6200         // If this is not a content: uri, we can't do anything with it.
6201         if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
6202             return;
6203         }
6204 
6205         String name = uri.getAuthority();
6206         ProviderInfo pi = null;
6207         ContentProviderRecord cpr
6208                 = (ContentProviderRecord)mProvidersByName.get(name);
6209         if (cpr != null) {
6210             pi = cpr.info;
6211         } else {
6212             try {
6213                 pi = pm.resolveContentProvider(name,
6214                         PackageManager.GET_URI_PERMISSION_PATTERNS);
6215             } catch (RemoteException ex) {
6216             }
6217         }
6218         if (pi == null) {
6219             Log.w(TAG, "No content provider found for: " + name);
6220             return;
6221         }
6222 
6223         int targetUid;
6224         try {
6225             targetUid = pm.getPackageUid(targetPkg);
6226             if (targetUid < 0) {
6227                 return;
6228             }
6229         } catch (RemoteException ex) {
6230             return;
6231         }
6232 
6233         // First...  does the target actually need this permission?
6234         if (checkHoldingPermissionsLocked(pm, pi, targetUid, modeFlags)) {
6235             // No need to grant the target this permission.
6236             return;
6237         }
6238 
6239         // Second...  maybe someone else has already granted the
6240         // permission?
6241         if (checkUriPermissionLocked(uri, targetUid, modeFlags)) {
6242             // No need to grant the target this permission.
6243             return;
6244         }
6245 
6246         // Third...  is the provider allowing granting of URI permissions?
6247         if (!pi.grantUriPermissions) {
6248             throw new SecurityException("Provider " + pi.packageName
6249                     + "/" + pi.name
6250                     + " does not allow granting of Uri permissions (uri "
6251                     + uri + ")");
6252         }
6253         if (pi.uriPermissionPatterns != null) {
6254             final int N = pi.uriPermissionPatterns.length;
6255             boolean allowed = false;
6256             for (int i=0; i<N; i++) {
6257                 if (pi.uriPermissionPatterns[i] != null
6258                         && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6259                     allowed = true;
6260                     break;
6261                 }
6262             }
6263             if (!allowed) {
6264                 throw new SecurityException("Provider " + pi.packageName
6265                         + "/" + pi.name
6266                         + " does not allow granting of permission to path of Uri "
6267                         + uri);
6268             }
6269         }
6270 
6271         // Fourth...  does the caller itself have permission to access
6272         // this uri?
6273         if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) {
6274             if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6275                 throw new SecurityException("Uid " + callingUid
6276                         + " does not have permission to uri " + uri);
6277             }
6278         }
6279 
6280         // Okay!  So here we are: the caller has the assumed permission
6281         // to the uri, and the target doesn't.  Let's now give this to
6282         // the target.
6283 
6284         HashMap<Uri, UriPermission> targetUris
6285                 = mGrantedUriPermissions.get(targetUid);
6286         if (targetUris == null) {
6287             targetUris = new HashMap<Uri, UriPermission>();
6288             mGrantedUriPermissions.put(targetUid, targetUris);
6289         }
6290 
6291         UriPermission perm = targetUris.get(uri);
6292         if (perm == null) {
6293             perm = new UriPermission(targetUid, uri);
6294             targetUris.put(uri, perm);
6295 
6296         }
6297         perm.modeFlags |= modeFlags;
6298         if (activity == null) {
6299             perm.globalModeFlags |= modeFlags;
6300         } else if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6301             perm.readActivities.add(activity);
6302             if (activity.readUriPermissions == null) {
6303                 activity.readUriPermissions = new HashSet<UriPermission>();
6304             }
6305             activity.readUriPermissions.add(perm);
6306         } else if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6307             perm.writeActivities.add(activity);
6308             if (activity.writeUriPermissions == null) {
6309                 activity.writeUriPermissions = new HashSet<UriPermission>();
6310             }
6311             activity.writeUriPermissions.add(perm);
6312         }
6313     }
6314 
grantUriPermissionFromIntentLocked(int callingUid, String targetPkg, Intent intent, HistoryRecord activity)6315     private void grantUriPermissionFromIntentLocked(int callingUid,
6316             String targetPkg, Intent intent, HistoryRecord activity) {
6317         if (intent == null) {
6318             return;
6319         }
6320         Uri data = intent.getData();
6321         if (data == null) {
6322             return;
6323         }
6324         grantUriPermissionLocked(callingUid, targetPkg, data,
6325                 intent.getFlags(), activity);
6326     }
6327 
grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, int modeFlags)6328     public void grantUriPermission(IApplicationThread caller, String targetPkg,
6329             Uri uri, int modeFlags) {
6330         synchronized(this) {
6331             final ProcessRecord r = getRecordForAppLocked(caller);
6332             if (r == null) {
6333                 throw new SecurityException("Unable to find app for caller "
6334                         + caller
6335                         + " when granting permission to uri " + uri);
6336             }
6337             if (targetPkg == null) {
6338                 Log.w(TAG, "grantUriPermission: null target");
6339                 return;
6340             }
6341             if (uri == null) {
6342                 Log.w(TAG, "grantUriPermission: null uri");
6343                 return;
6344             }
6345 
6346             grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
6347                     null);
6348         }
6349     }
6350 
removeUriPermissionIfNeededLocked(UriPermission perm)6351     private void removeUriPermissionIfNeededLocked(UriPermission perm) {
6352         if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6353                 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6354             HashMap<Uri, UriPermission> perms
6355                     = mGrantedUriPermissions.get(perm.uid);
6356             if (perms != null) {
6357                 perms.remove(perm.uri);
6358                 if (perms.size() == 0) {
6359                     mGrantedUriPermissions.remove(perm.uid);
6360                 }
6361             }
6362         }
6363     }
6364 
removeActivityUriPermissionsLocked(HistoryRecord activity)6365     private void removeActivityUriPermissionsLocked(HistoryRecord activity) {
6366         if (activity.readUriPermissions != null) {
6367             for (UriPermission perm : activity.readUriPermissions) {
6368                 perm.readActivities.remove(activity);
6369                 if (perm.readActivities.size() == 0 && (perm.globalModeFlags
6370                         &Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0) {
6371                     perm.modeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
6372                     removeUriPermissionIfNeededLocked(perm);
6373                 }
6374             }
6375         }
6376         if (activity.writeUriPermissions != null) {
6377             for (UriPermission perm : activity.writeUriPermissions) {
6378                 perm.writeActivities.remove(activity);
6379                 if (perm.writeActivities.size() == 0 && (perm.globalModeFlags
6380                         &Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0) {
6381                     perm.modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
6382                     removeUriPermissionIfNeededLocked(perm);
6383                 }
6384             }
6385         }
6386     }
6387 
revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags)6388     private void revokeUriPermissionLocked(int callingUid, Uri uri,
6389             int modeFlags) {
6390         modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6391                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6392         if (modeFlags == 0) {
6393             return;
6394         }
6395 
6396         final IPackageManager pm = ActivityThread.getPackageManager();
6397 
6398         final String authority = uri.getAuthority();
6399         ProviderInfo pi = null;
6400         ContentProviderRecord cpr
6401                 = (ContentProviderRecord)mProvidersByName.get(authority);
6402         if (cpr != null) {
6403             pi = cpr.info;
6404         } else {
6405             try {
6406                 pi = pm.resolveContentProvider(authority,
6407                         PackageManager.GET_URI_PERMISSION_PATTERNS);
6408             } catch (RemoteException ex) {
6409             }
6410         }
6411         if (pi == null) {
6412             Log.w(TAG, "No content provider found for: " + authority);
6413             return;
6414         }
6415 
6416         // Does the caller have this permission on the URI?
6417         if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) {
6418             // Right now, if you are not the original owner of the permission,
6419             // you are not allowed to revoke it.
6420             //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6421                 throw new SecurityException("Uid " + callingUid
6422                         + " does not have permission to uri " + uri);
6423             //}
6424         }
6425 
6426         // Go through all of the permissions and remove any that match.
6427         final List<String> SEGMENTS = uri.getPathSegments();
6428         if (SEGMENTS != null) {
6429             final int NS = SEGMENTS.size();
6430             int N = mGrantedUriPermissions.size();
6431             for (int i=0; i<N; i++) {
6432                 HashMap<Uri, UriPermission> perms
6433                         = mGrantedUriPermissions.valueAt(i);
6434                 Iterator<UriPermission> it = perms.values().iterator();
6435             toploop:
6436                 while (it.hasNext()) {
6437                     UriPermission perm = it.next();
6438                     Uri targetUri = perm.uri;
6439                     if (!authority.equals(targetUri.getAuthority())) {
6440                         continue;
6441                     }
6442                     List<String> targetSegments = targetUri.getPathSegments();
6443                     if (targetSegments == null) {
6444                         continue;
6445                     }
6446                     if (targetSegments.size() < NS) {
6447                         continue;
6448                     }
6449                     for (int j=0; j<NS; j++) {
6450                         if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6451                             continue toploop;
6452                         }
6453                     }
6454                     perm.clearModes(modeFlags);
6455                     if (perm.modeFlags == 0) {
6456                         it.remove();
6457                     }
6458                 }
6459                 if (perms.size() == 0) {
6460                     mGrantedUriPermissions.remove(
6461                             mGrantedUriPermissions.keyAt(i));
6462                     N--;
6463                     i--;
6464                 }
6465             }
6466         }
6467     }
6468 
revokeUriPermission(IApplicationThread caller, Uri uri, int modeFlags)6469     public void revokeUriPermission(IApplicationThread caller, Uri uri,
6470             int modeFlags) {
6471         synchronized(this) {
6472             final ProcessRecord r = getRecordForAppLocked(caller);
6473             if (r == null) {
6474                 throw new SecurityException("Unable to find app for caller "
6475                         + caller
6476                         + " when revoking permission to uri " + uri);
6477             }
6478             if (uri == null) {
6479                 Log.w(TAG, "revokeUriPermission: null uri");
6480                 return;
6481             }
6482 
6483             modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6484                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6485             if (modeFlags == 0) {
6486                 return;
6487             }
6488 
6489             final IPackageManager pm = ActivityThread.getPackageManager();
6490 
6491             final String authority = uri.getAuthority();
6492             ProviderInfo pi = null;
6493             ContentProviderRecord cpr
6494                     = (ContentProviderRecord)mProvidersByName.get(authority);
6495             if (cpr != null) {
6496                 pi = cpr.info;
6497             } else {
6498                 try {
6499                     pi = pm.resolveContentProvider(authority,
6500                             PackageManager.GET_URI_PERMISSION_PATTERNS);
6501                 } catch (RemoteException ex) {
6502                 }
6503             }
6504             if (pi == null) {
6505                 Log.w(TAG, "No content provider found for: " + authority);
6506                 return;
6507             }
6508 
6509             revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
6510         }
6511     }
6512 
showWaitingForDebugger(IApplicationThread who, boolean waiting)6513     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6514         synchronized (this) {
6515             ProcessRecord app =
6516                 who != null ? getRecordForAppLocked(who) : null;
6517             if (app == null) return;
6518 
6519             Message msg = Message.obtain();
6520             msg.what = WAIT_FOR_DEBUGGER_MSG;
6521             msg.obj = app;
6522             msg.arg1 = waiting ? 1 : 0;
6523             mHandler.sendMessage(msg);
6524         }
6525     }
6526 
getMemoryInfo(ActivityManager.MemoryInfo outInfo)6527     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6528         outInfo.availMem = Process.getFreeMemory();
6529         outInfo.threshold = HOME_APP_MEM;
6530         outInfo.lowMemory = outInfo.availMem <
6531                 (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2));
6532     }
6533 
6534     // =========================================================
6535     // TASK MANAGEMENT
6536     // =========================================================
6537 
6538     public List getTasks(int maxNum, int flags,
6539                          IThumbnailReceiver receiver) {
6540         ArrayList list = new ArrayList();
6541 
6542         PendingThumbnailsRecord pending = null;
6543         IApplicationThread topThumbnail = null;
6544         HistoryRecord topRecord = null;
6545 
6546         synchronized(this) {
6547             if (localLOGV) Log.v(
6548                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6549                 + ", receiver=" + receiver);
6550 
6551             if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6552                     != PackageManager.PERMISSION_GRANTED) {
6553                 if (receiver != null) {
6554                     // If the caller wants to wait for pending thumbnails,
6555                     // it ain't gonna get them.
6556                     try {
6557                         receiver.finished();
6558                     } catch (RemoteException ex) {
6559                     }
6560                 }
6561                 String msg = "Permission Denial: getTasks() from pid="
6562                         + Binder.getCallingPid()
6563                         + ", uid=" + Binder.getCallingUid()
6564                         + " requires " + android.Manifest.permission.GET_TASKS;
6565                 Log.w(TAG, msg);
6566                 throw new SecurityException(msg);
6567             }
6568 
6569             int pos = mHistory.size()-1;
6570             HistoryRecord next =
6571                 pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null;
6572             HistoryRecord top = null;
6573             CharSequence topDescription = null;
6574             TaskRecord curTask = null;
6575             int numActivities = 0;
6576             int numRunning = 0;
6577             while (pos >= 0 && maxNum > 0) {
6578                 final HistoryRecord r = next;
6579                 pos--;
6580                 next = pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null;
6581 
6582                 // Initialize state for next task if needed.
6583                 if (top == null ||
6584                         (top.state == ActivityState.INITIALIZING
6585                             && top.task == r.task)) {
6586                     top = r;
6587                     topDescription = r.description;
6588                     curTask = r.task;
6589                     numActivities = numRunning = 0;
6590                 }
6591 
6592                 // Add 'r' into the current task.
6593                 numActivities++;
6594                 if (r.app != null && r.app.thread != null) {
6595                     numRunning++;
6596                 }
6597                 if (topDescription == null) {
6598                     topDescription = r.description;
6599                 }
6600 
6601                 if (localLOGV) Log.v(
6602                     TAG, r.intent.getComponent().flattenToShortString()
6603                     + ": task=" + r.task);
6604 
6605                 // If the next one is a different task, generate a new
6606                 // TaskInfo entry for what we have.
6607                 if (next == null || next.task != curTask) {
6608                     ActivityManager.RunningTaskInfo ci
6609                             = new ActivityManager.RunningTaskInfo();
6610                     ci.id = curTask.taskId;
6611                     ci.baseActivity = r.intent.getComponent();
6612                     ci.topActivity = top.intent.getComponent();
6613                     ci.thumbnail = top.thumbnail;
6614                     ci.description = topDescription;
6615                     ci.numActivities = numActivities;
6616                     ci.numRunning = numRunning;
6617                     //System.out.println(
6618                     //    "#" + maxNum + ": " + " descr=" + ci.description);
6619                     if (ci.thumbnail == null && receiver != null) {
6620                         if (localLOGV) Log.v(
6621                             TAG, "State=" + top.state + "Idle=" + top.idle
6622                             + " app=" + top.app
6623                             + " thr=" + (top.app != null ? top.app.thread : null));
6624                         if (top.state == ActivityState.RESUMED
6625                                 || top.state == ActivityState.PAUSING) {
6626                             if (top.idle && top.app != null
6627                                 && top.app.thread != null) {
6628                                 topRecord = top;
6629                                 topThumbnail = top.app.thread;
6630                             } else {
6631                                 top.thumbnailNeeded = true;
6632                             }
6633                         }
6634                         if (pending == null) {
6635                             pending = new PendingThumbnailsRecord(receiver);
6636                         }
6637                         pending.pendingRecords.add(top);
6638                     }
6639                     list.add(ci);
6640                     maxNum--;
6641                     top = null;
6642                 }
6643             }
6644 
6645             if (pending != null) {
6646                 mPendingThumbnails.add(pending);
6647             }
6648         }
6649 
Log.v(TAG, "We have pending thumbnails: " + pending)6650         if (localLOGV) Log.v(TAG, "We have pending thumbnails: " + pending);
6651 
6652         if (topThumbnail != null) {
Log.v(TAG, "Requesting top thumbnail")6653             if (localLOGV) Log.v(TAG, "Requesting top thumbnail");
6654             try {
6655                 topThumbnail.requestThumbnail(topRecord);
6656             } catch (Exception e) {
6657                 Log.w(TAG, "Exception thrown when requesting thumbnail", e);
6658                 sendPendingThumbnail(null, topRecord, null, null, true);
6659             }
6660         }
6661 
6662         if (pending == null && receiver != null) {
6663             // In this case all thumbnails were available and the client
6664             // is being asked to be told when the remaining ones come in...
6665             // which is unusually, since the top-most currently running
6666             // activity should never have a canned thumbnail!  Oh well.
6667             try {
receiver.finished()6668                 receiver.finished();
6669             } catch (RemoteException ex) {
6670             }
6671         }
6672 
6673         return list;
6674     }
6675 
getRecentTasks(int maxNum, int flags)6676     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6677             int flags) {
6678         synchronized (this) {
6679             enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6680                     "getRecentTasks()");
6681 
6682             final int N = mRecentTasks.size();
6683             ArrayList<ActivityManager.RecentTaskInfo> res
6684                     = new ArrayList<ActivityManager.RecentTaskInfo>(
6685                             maxNum < N ? maxNum : N);
6686             for (int i=0; i<N && maxNum > 0; i++) {
6687                 TaskRecord tr = mRecentTasks.get(i);
6688                 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6689                         || (tr.intent == null)
6690                         || ((tr.intent.getFlags()
6691                                 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6692                     ActivityManager.RecentTaskInfo rti
6693                             = new ActivityManager.RecentTaskInfo();
6694                     rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6695                     rti.baseIntent = new Intent(
6696                             tr.intent != null ? tr.intent : tr.affinityIntent);
6697                     rti.origActivity = tr.origActivity;
6698                     res.add(rti);
6699                     maxNum--;
6700                 }
6701             }
6702             return res;
6703         }
6704     }
6705 
findAffinityTaskTopLocked(int startIndex, String affinity)6706     private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
6707         int j;
6708         TaskRecord startTask = ((HistoryRecord)mHistory.get(startIndex)).task;
6709         TaskRecord jt = startTask;
6710 
6711         // First look backwards
6712         for (j=startIndex-1; j>=0; j--) {
6713             HistoryRecord r = (HistoryRecord)mHistory.get(j);
6714             if (r.task != jt) {
6715                 jt = r.task;
6716                 if (affinity.equals(jt.affinity)) {
6717                     return j;
6718                 }
6719             }
6720         }
6721 
6722         // Now look forwards
6723         final int N = mHistory.size();
6724         jt = startTask;
6725         for (j=startIndex+1; j<N; j++) {
6726             HistoryRecord r = (HistoryRecord)mHistory.get(j);
6727             if (r.task != jt) {
6728                 if (affinity.equals(jt.affinity)) {
6729                     return j;
6730                 }
6731                 jt = r.task;
6732             }
6733         }
6734 
6735         // Might it be at the top?
6736         if (affinity.equals(((HistoryRecord)mHistory.get(N-1)).task.affinity)) {
6737             return N-1;
6738         }
6739 
6740         return -1;
6741     }
6742 
6743     /**
6744      * Perform a reset of the given task, if needed as part of launching it.
6745      * Returns the new HistoryRecord at the top of the task.
6746      */
resetTaskIfNeededLocked(HistoryRecord taskTop, HistoryRecord newActivity)6747     private final HistoryRecord resetTaskIfNeededLocked(HistoryRecord taskTop,
6748             HistoryRecord newActivity) {
6749         boolean forceReset = (newActivity.info.flags
6750                 &ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0;
6751         if (taskTop.task.getInactiveDuration() > ACTIVITY_INACTIVE_RESET_TIME) {
6752             if ((newActivity.info.flags
6753                     &ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE) == 0) {
6754                 forceReset = true;
6755             }
6756         }
6757 
6758         final TaskRecord task = taskTop.task;
6759 
6760         // We are going to move through the history list so that we can look
6761         // at each activity 'target' with 'below' either the interesting
6762         // activity immediately below it in the stack or null.
6763         HistoryRecord target = null;
6764         int targetI = 0;
6765         int taskTopI = -1;
6766         int replyChainEnd = -1;
6767         int lastReparentPos = -1;
6768         for (int i=mHistory.size()-1; i>=-1; i--) {
6769             HistoryRecord below = i >= 0 ? (HistoryRecord)mHistory.get(i) : null;
6770 
6771             if (below != null && below.finishing) {
6772                 continue;
6773             }
6774             if (target == null) {
6775                 target = below;
6776                 targetI = i;
6777                 // If we were in the middle of a reply chain before this
6778                 // task, it doesn't appear like the root of the chain wants
6779                 // anything interesting, so drop it.
6780                 replyChainEnd = -1;
6781                 continue;
6782             }
6783 
6784             final int flags = target.info.flags;
6785 
6786             final boolean finishOnTaskLaunch =
6787                 (flags&ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0;
6788             final boolean allowTaskReparenting =
6789                 (flags&ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0;
6790 
6791             if (target.task == task) {
6792                 // We are inside of the task being reset...  we'll either
6793                 // finish this activity, push it out for another task,
6794                 // or leave it as-is.  We only do this
6795                 // for activities that are not the root of the task (since
6796                 // if we finish the root, we may no longer have the task!).
6797                 if (taskTopI < 0) {
6798                     taskTopI = targetI;
6799                 }
6800                 if (below != null && below.task == task) {
6801                     final boolean clearWhenTaskReset =
6802                             (target.intent.getFlags()
6803                                     &Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0;
6804                     if (!finishOnTaskLaunch && !clearWhenTaskReset && target.resultTo != null) {
6805                         // If this activity is sending a reply to a previous
6806                         // activity, we can't do anything with it now until
6807                         // we reach the start of the reply chain.
6808                         // XXX note that we are assuming the result is always
6809                         // to the previous activity, which is almost always
6810                         // the case but we really shouldn't count on.
6811                         if (replyChainEnd < 0) {
6812                             replyChainEnd = targetI;
6813                         }
6814                     } else if (!finishOnTaskLaunch && !clearWhenTaskReset && allowTaskReparenting
6815                             && target.taskAffinity != null
6816                             && !target.taskAffinity.equals(task.affinity)) {
6817                         // If this activity has an affinity for another
6818                         // task, then we need to move it out of here.  We will
6819                         // move it as far out of the way as possible, to the
6820                         // bottom of the activity stack.  This also keeps it
6821                         // correctly ordered with any activities we previously
6822                         // moved.
6823                         HistoryRecord p = (HistoryRecord)mHistory.get(0);
6824                         if (target.taskAffinity != null
6825                                 && target.taskAffinity.equals(p.task.affinity)) {
6826                             // If the activity currently at the bottom has the
6827                             // same task affinity as the one we are moving,
6828                             // then merge it into the same task.
6829                             target.task = p.task;
6830                             if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target
6831                                     + " out to bottom task " + p.task);
6832                         } else {
6833                             mCurTask++;
6834                             if (mCurTask <= 0) {
6835                                 mCurTask = 1;
6836                             }
6837                             target.task = new TaskRecord(mCurTask, target.info, null,
6838                                     (target.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
6839                             target.task.affinityIntent = target.intent;
6840                             if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target
6841                                     + " out to new task " + target.task);
6842                         }
6843                         mWindowManager.setAppGroupId(target, task.taskId);
6844                         if (replyChainEnd < 0) {
6845                             replyChainEnd = targetI;
6846                         }
6847                         int dstPos = 0;
6848                         for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
6849                             p = (HistoryRecord)mHistory.get(srcPos);
6850                             if (p.finishing) {
6851                                 continue;
6852                             }
6853                             if (DEBUG_TASKS) Log.v(TAG, "Pushing next activity " + p
6854                                     + " out to target's task " + target.task);
6855                             task.numActivities--;
6856                             p.task = target.task;
6857                             target.task.numActivities++;
6858                             mHistory.remove(srcPos);
6859                             mHistory.add(dstPos, p);
6860                             mWindowManager.moveAppToken(dstPos, p);
6861                             mWindowManager.setAppGroupId(p, p.task.taskId);
6862                             dstPos++;
6863                             if (VALIDATE_TOKENS) {
6864                                 mWindowManager.validateAppTokens(mHistory);
6865                             }
6866                             i++;
6867                         }
6868                         if (taskTop == p) {
6869                             taskTop = below;
6870                         }
6871                         if (taskTopI == replyChainEnd) {
6872                             taskTopI = -1;
6873                         }
6874                         replyChainEnd = -1;
6875                         addRecentTask(target.task);
6876                     } else if (forceReset || finishOnTaskLaunch
6877                             || clearWhenTaskReset) {
6878                         // If the activity should just be removed -- either
6879                         // because it asks for it, or the task should be
6880                         // cleared -- then finish it and anything that is
6881                         // part of its reply chain.
6882                         if (clearWhenTaskReset) {
6883                             // In this case, we want to finish this activity
6884                             // and everything above it, so be sneaky and pretend
6885                             // like these are all in the reply chain.
6886                             replyChainEnd = targetI+1;
6887                             while (replyChainEnd < mHistory.size() &&
6888                                     ((HistoryRecord)mHistory.get(
6889                                                 replyChainEnd)).task == task) {
6890                                 replyChainEnd++;
6891                             }
6892                             replyChainEnd--;
6893                         } else if (replyChainEnd < 0) {
6894                             replyChainEnd = targetI;
6895                         }
6896                         HistoryRecord p = null;
6897                         for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
6898                             p = (HistoryRecord)mHistory.get(srcPos);
6899                             if (p.finishing) {
6900                                 continue;
6901                             }
6902                             if (finishActivityLocked(p, srcPos,
6903                                     Activity.RESULT_CANCELED, null, "reset")) {
6904                                 replyChainEnd--;
6905                                 srcPos--;
6906                             }
6907                         }
6908                         if (taskTop == p) {
6909                             taskTop = below;
6910                         }
6911                         if (taskTopI == replyChainEnd) {
6912                             taskTopI = -1;
6913                         }
6914                         replyChainEnd = -1;
6915                     } else {
6916                         // If we were in the middle of a chain, well the
6917                         // activity that started it all doesn't want anything
6918                         // special, so leave it all as-is.
6919                         replyChainEnd = -1;
6920                     }
6921                 } else {
6922                     // Reached the bottom of the task -- any reply chain
6923                     // should be left as-is.
6924                     replyChainEnd = -1;
6925                 }
6926 
6927             } else if (target.resultTo != null) {
6928                 // If this activity is sending a reply to a previous
6929                 // activity, we can't do anything with it now until
6930                 // we reach the start of the reply chain.
6931                 // XXX note that we are assuming the result is always
6932                 // to the previous activity, which is almost always
6933                 // the case but we really shouldn't count on.
6934                 if (replyChainEnd < 0) {
6935                     replyChainEnd = targetI;
6936                 }
6937 
6938             } else if (taskTopI >= 0 && allowTaskReparenting
6939                     && task.affinity != null
6940                     && task.affinity.equals(target.taskAffinity)) {
6941                 // We are inside of another task...  if this activity has
6942                 // an affinity for our task, then either remove it if we are
6943                 // clearing or move it over to our task.  Note that
6944                 // we currently punt on the case where we are resetting a
6945                 // task that is not at the top but who has activities above
6946                 // with an affinity to it...  this is really not a normal
6947                 // case, and we will need to later pull that task to the front
6948                 // and usually at that point we will do the reset and pick
6949                 // up those remaining activities.  (This only happens if
6950                 // someone starts an activity in a new task from an activity
6951                 // in a task that is not currently on top.)
6952                 if (forceReset || finishOnTaskLaunch) {
6953                     if (replyChainEnd < 0) {
6954                         replyChainEnd = targetI;
6955                     }
6956                     HistoryRecord p = null;
6957                     for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
6958                         p = (HistoryRecord)mHistory.get(srcPos);
6959                         if (p.finishing) {
6960                             continue;
6961                         }
6962                         if (finishActivityLocked(p, srcPos,
6963                                 Activity.RESULT_CANCELED, null, "reset")) {
6964                             taskTopI--;
6965                             lastReparentPos--;
6966                             replyChainEnd--;
6967                             srcPos--;
6968                         }
6969                     }
6970                     replyChainEnd = -1;
6971                 } else {
6972                     if (replyChainEnd < 0) {
6973                         replyChainEnd = targetI;
6974                     }
6975                     for (int srcPos=replyChainEnd; srcPos>=targetI; srcPos--) {
6976                         HistoryRecord p = (HistoryRecord)mHistory.get(srcPos);
6977                         if (p.finishing) {
6978                             continue;
6979                         }
6980                         if (lastReparentPos < 0) {
6981                             lastReparentPos = taskTopI;
6982                             taskTop = p;
6983                         } else {
6984                             lastReparentPos--;
6985                         }
6986                         mHistory.remove(srcPos);
6987                         p.task.numActivities--;
6988                         p.task = task;
6989                         mHistory.add(lastReparentPos, p);
6990                         if (DEBUG_TASKS) Log.v(TAG, "Pulling activity " + p
6991                                 + " in to resetting task " + task);
6992                         task.numActivities++;
6993                         mWindowManager.moveAppToken(lastReparentPos, p);
6994                         mWindowManager.setAppGroupId(p, p.task.taskId);
6995                         if (VALIDATE_TOKENS) {
6996                             mWindowManager.validateAppTokens(mHistory);
6997                         }
6998                     }
6999                     replyChainEnd = -1;
7000 
7001                     // Now we've moved it in to place...  but what if this is
7002                     // a singleTop activity and we have put it on top of another
7003                     // instance of the same activity?  Then we drop the instance
7004                     // below so it remains singleTop.
7005                     if (target.info.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
7006                         for (int j=lastReparentPos-1; j>=0; j--) {
7007                             HistoryRecord p = (HistoryRecord)mHistory.get(j);
7008                             if (p.finishing) {
7009                                 continue;
7010                             }
7011                             if (p.intent.getComponent().equals(target.intent.getComponent())) {
7012                                 if (finishActivityLocked(p, j,
7013                                         Activity.RESULT_CANCELED, null, "replace")) {
7014                                     taskTopI--;
7015                                     lastReparentPos--;
7016                                 }
7017                             }
7018                         }
7019                     }
7020                 }
7021             }
7022 
7023             target = below;
7024             targetI = i;
7025         }
7026 
7027         return taskTop;
7028     }
7029 
7030     /**
7031      * TODO: Add mController hook
7032      */
moveTaskToFront(int task)7033     public void moveTaskToFront(int task) {
7034         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7035                 "moveTaskToFront()");
7036 
7037         synchronized(this) {
7038             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7039                     Binder.getCallingUid(), "Task to front")) {
7040                 return;
7041             }
7042             final long origId = Binder.clearCallingIdentity();
7043             try {
7044                 int N = mRecentTasks.size();
7045                 for (int i=0; i<N; i++) {
7046                     TaskRecord tr = mRecentTasks.get(i);
7047                     if (tr.taskId == task) {
7048                         moveTaskToFrontLocked(tr, null);
7049                         return;
7050                     }
7051                 }
7052                 for (int i=mHistory.size()-1; i>=0; i--) {
7053                     HistoryRecord hr = (HistoryRecord)mHistory.get(i);
7054                     if (hr.task.taskId == task) {
7055                         moveTaskToFrontLocked(hr.task, null);
7056                         return;
7057                     }
7058                 }
7059             } finally {
7060                 Binder.restoreCallingIdentity(origId);
7061             }
7062         }
7063     }
7064 
moveTaskToFrontLocked(TaskRecord tr, HistoryRecord reason)7065     private final void moveTaskToFrontLocked(TaskRecord tr, HistoryRecord reason) {
7066         if (DEBUG_SWITCH) Log.v(TAG, "moveTaskToFront: " + tr);
7067 
7068         final int task = tr.taskId;
7069         int top = mHistory.size()-1;
7070 
7071         if (top < 0 || ((HistoryRecord)mHistory.get(top)).task.taskId == task) {
7072             // nothing to do!
7073             return;
7074         }
7075 
7076         ArrayList moved = new ArrayList();
7077 
7078         // Applying the affinities may have removed entries from the history,
7079         // so get the size again.
7080         top = mHistory.size()-1;
7081         int pos = top;
7082 
7083         // Shift all activities with this task up to the top
7084         // of the stack, keeping them in the same internal order.
7085         while (pos >= 0) {
7086             HistoryRecord r = (HistoryRecord)mHistory.get(pos);
7087             if (localLOGV) Log.v(
7088                 TAG, "At " + pos + " ckp " + r.task + ": " + r);
7089             boolean first = true;
7090             if (r.task.taskId == task) {
7091                 if (localLOGV) Log.v(TAG, "Removing and adding at " + top);
7092                 mHistory.remove(pos);
7093                 mHistory.add(top, r);
7094                 moved.add(0, r);
7095                 top--;
7096                 if (first) {
7097                     addRecentTask(r.task);
7098                     first = false;
7099                 }
7100             }
7101             pos--;
7102         }
7103 
7104         if (DEBUG_TRANSITION) Log.v(TAG,
7105                 "Prepare to front transition: task=" + tr);
7106         if (reason != null &&
7107                 (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
7108             mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
7109             HistoryRecord r = topRunningActivityLocked(null);
7110             if (r != null) {
7111                 mNoAnimActivities.add(r);
7112             }
7113         } else {
7114             mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT);
7115         }
7116 
7117         mWindowManager.moveAppTokensToTop(moved);
7118         if (VALIDATE_TOKENS) {
7119             mWindowManager.validateAppTokens(mHistory);
7120         }
7121 
7122         finishTaskMove(task);
7123         EventLog.writeEvent(LOG_TASK_TO_FRONT, task);
7124     }
7125 
finishTaskMove(int task)7126     private final void finishTaskMove(int task) {
7127         resumeTopActivityLocked(null);
7128     }
7129 
moveTaskToBack(int task)7130     public void moveTaskToBack(int task) {
7131         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7132                 "moveTaskToBack()");
7133 
7134         synchronized(this) {
7135             if (mResumedActivity != null && mResumedActivity.task.taskId == task) {
7136                 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7137                         Binder.getCallingUid(), "Task to back")) {
7138                     return;
7139                 }
7140             }
7141             final long origId = Binder.clearCallingIdentity();
7142             moveTaskToBackLocked(task, null);
7143             Binder.restoreCallingIdentity(origId);
7144         }
7145     }
7146 
7147     /**
7148      * Moves an activity, and all of the other activities within the same task, to the bottom
7149      * of the history stack.  The activity's order within the task is unchanged.
7150      *
7151      * @param token A reference to the activity we wish to move
7152      * @param nonRoot If false then this only works if the activity is the root
7153      *                of a task; if true it will work for any activity in a task.
7154      * @return Returns true if the move completed, false if not.
7155      */
moveActivityTaskToBack(IBinder token, boolean nonRoot)7156     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7157         synchronized(this) {
7158             final long origId = Binder.clearCallingIdentity();
7159             int taskId = getTaskForActivityLocked(token, !nonRoot);
7160             if (taskId >= 0) {
7161                 return moveTaskToBackLocked(taskId, null);
7162             }
7163             Binder.restoreCallingIdentity(origId);
7164         }
7165         return false;
7166     }
7167 
7168     /**
7169      * Worker method for rearranging history stack.  Implements the function of moving all
7170      * activities for a specific task (gathering them if disjoint) into a single group at the
7171      * bottom of the stack.
7172      *
7173      * If a watcher is installed, the action is preflighted and the watcher has an opportunity
7174      * to premeptively cancel the move.
7175      *
7176      * @param task The taskId to collect and move to the bottom.
7177      * @return Returns true if the move completed, false if not.
7178      */
moveTaskToBackLocked(int task, HistoryRecord reason)7179     private final boolean moveTaskToBackLocked(int task, HistoryRecord reason) {
7180         Log.i(TAG, "moveTaskToBack: " + task);
7181 
7182         // If we have a watcher, preflight the move before committing to it.  First check
7183         // for *other* available tasks, but if none are available, then try again allowing the
7184         // current task to be selected.
7185         if (mController != null) {
7186             HistoryRecord next = topRunningActivityLocked(null, task);
7187             if (next == null) {
7188                 next = topRunningActivityLocked(null, 0);
7189             }
7190             if (next != null) {
7191                 // ask watcher if this is allowed
7192                 boolean moveOK = true;
7193                 try {
7194                     moveOK = mController.activityResuming(next.packageName);
7195                 } catch (RemoteException e) {
7196                     mController = null;
7197                 }
7198                 if (!moveOK) {
7199                     return false;
7200                 }
7201             }
7202         }
7203 
7204         ArrayList moved = new ArrayList();
7205 
7206         if (DEBUG_TRANSITION) Log.v(TAG,
7207                 "Prepare to back transition: task=" + task);
7208 
7209         final int N = mHistory.size();
7210         int bottom = 0;
7211         int pos = 0;
7212 
7213         // Shift all activities with this task down to the bottom
7214         // of the stack, keeping them in the same internal order.
7215         while (pos < N) {
7216             HistoryRecord r = (HistoryRecord)mHistory.get(pos);
7217             if (localLOGV) Log.v(
7218                 TAG, "At " + pos + " ckp " + r.task + ": " + r);
7219             if (r.task.taskId == task) {
7220                 if (localLOGV) Log.v(TAG, "Removing and adding at " + (N-1));
7221                 mHistory.remove(pos);
7222                 mHistory.add(bottom, r);
7223                 moved.add(r);
7224                 bottom++;
7225             }
7226             pos++;
7227         }
7228 
7229         if (reason != null &&
7230                 (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
7231             mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
7232             HistoryRecord r = topRunningActivityLocked(null);
7233             if (r != null) {
7234                 mNoAnimActivities.add(r);
7235             }
7236         } else {
7237             mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_BACK);
7238         }
7239         mWindowManager.moveAppTokensToBottom(moved);
7240         if (VALIDATE_TOKENS) {
7241             mWindowManager.validateAppTokens(mHistory);
7242         }
7243 
7244         finishTaskMove(task);
7245         return true;
7246     }
7247 
moveTaskBackwards(int task)7248     public void moveTaskBackwards(int task) {
7249         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7250                 "moveTaskBackwards()");
7251 
7252         synchronized(this) {
7253             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7254                     Binder.getCallingUid(), "Task backwards")) {
7255                 return;
7256             }
7257             final long origId = Binder.clearCallingIdentity();
7258             moveTaskBackwardsLocked(task);
7259             Binder.restoreCallingIdentity(origId);
7260         }
7261     }
7262 
moveTaskBackwardsLocked(int task)7263     private final void moveTaskBackwardsLocked(int task) {
7264         Log.e(TAG, "moveTaskBackwards not yet implemented!");
7265     }
7266 
getTaskForActivity(IBinder token, boolean onlyRoot)7267     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7268         synchronized(this) {
7269             return getTaskForActivityLocked(token, onlyRoot);
7270         }
7271     }
7272 
getTaskForActivityLocked(IBinder token, boolean onlyRoot)7273     int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
7274         final int N = mHistory.size();
7275         TaskRecord lastTask = null;
7276         for (int i=0; i<N; i++) {
7277             HistoryRecord r = (HistoryRecord)mHistory.get(i);
7278             if (r == token) {
7279                 if (!onlyRoot || lastTask != r.task) {
7280                     return r.task.taskId;
7281                 }
7282                 return -1;
7283             }
7284             lastTask = r.task;
7285         }
7286 
7287         return -1;
7288     }
7289 
7290     /**
7291      * Returns the top activity in any existing task matching the given
7292      * Intent.  Returns null if no such task is found.
7293      */
findTaskLocked(Intent intent, ActivityInfo info)7294     private HistoryRecord findTaskLocked(Intent intent, ActivityInfo info) {
7295         ComponentName cls = intent.getComponent();
7296         if (info.targetActivity != null) {
7297             cls = new ComponentName(info.packageName, info.targetActivity);
7298         }
7299 
7300         TaskRecord cp = null;
7301 
7302         final int N = mHistory.size();
7303         for (int i=(N-1); i>=0; i--) {
7304             HistoryRecord r = (HistoryRecord)mHistory.get(i);
7305             if (!r.finishing && r.task != cp
7306                     && r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
7307                 cp = r.task;
7308                 //Log.i(TAG, "Comparing existing cls=" + r.task.intent.getComponent().flattenToShortString()
7309                 //        + "/aff=" + r.task.affinity + " to new cls="
7310                 //        + intent.getComponent().flattenToShortString() + "/aff=" + taskAffinity);
7311                 if (r.task.affinity != null) {
7312                     if (r.task.affinity.equals(info.taskAffinity)) {
7313                         //Log.i(TAG, "Found matching affinity!");
7314                         return r;
7315                     }
7316                 } else if (r.task.intent != null
7317                         && r.task.intent.getComponent().equals(cls)) {
7318                     //Log.i(TAG, "Found matching class!");
7319                     //dump();
7320                     //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
7321                     return r;
7322                 } else if (r.task.affinityIntent != null
7323                         && r.task.affinityIntent.getComponent().equals(cls)) {
7324                     //Log.i(TAG, "Found matching class!");
7325                     //dump();
7326                     //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
7327                     return r;
7328                 }
7329             }
7330         }
7331 
7332         return null;
7333     }
7334 
7335     /**
7336      * Returns the first activity (starting from the top of the stack) that
7337      * is the same as the given activity.  Returns null if no such activity
7338      * is found.
7339      */
findActivityLocked(Intent intent, ActivityInfo info)7340     private HistoryRecord findActivityLocked(Intent intent, ActivityInfo info) {
7341         ComponentName cls = intent.getComponent();
7342         if (info.targetActivity != null) {
7343             cls = new ComponentName(info.packageName, info.targetActivity);
7344         }
7345 
7346         final int N = mHistory.size();
7347         for (int i=(N-1); i>=0; i--) {
7348             HistoryRecord r = (HistoryRecord)mHistory.get(i);
7349             if (!r.finishing) {
7350                 if (r.intent.getComponent().equals(cls)) {
7351                     //Log.i(TAG, "Found matching class!");
7352                     //dump();
7353                     //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
7354                     return r;
7355                 }
7356             }
7357         }
7358 
7359         return null;
7360     }
7361 
finishOtherInstances(IBinder token, ComponentName className)7362     public void finishOtherInstances(IBinder token, ComponentName className) {
7363         synchronized(this) {
7364             final long origId = Binder.clearCallingIdentity();
7365 
7366             int N = mHistory.size();
7367             TaskRecord lastTask = null;
7368             for (int i=0; i<N; i++) {
7369                 HistoryRecord r = (HistoryRecord)mHistory.get(i);
7370                 if (r.realActivity.equals(className)
7371                         && r != token && lastTask != r.task) {
7372                     if (finishActivityLocked(r, i, Activity.RESULT_CANCELED,
7373                             null, "others")) {
7374                         i--;
7375                         N--;
7376                     }
7377                 }
7378                 lastTask = r.task;
7379             }
7380 
7381             Binder.restoreCallingIdentity(origId);
7382         }
7383     }
7384 
7385     // =========================================================
7386     // THUMBNAILS
7387     // =========================================================
7388 
reportThumbnail(IBinder token, Bitmap thumbnail, CharSequence description)7389     public void reportThumbnail(IBinder token,
7390             Bitmap thumbnail, CharSequence description) {
7391         //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7392         final long origId = Binder.clearCallingIdentity();
7393         sendPendingThumbnail(null, token, thumbnail, description, true);
7394         Binder.restoreCallingIdentity(origId);
7395     }
7396 
sendPendingThumbnail(HistoryRecord r, IBinder token, Bitmap thumbnail, CharSequence description, boolean always)7397     final void sendPendingThumbnail(HistoryRecord r, IBinder token,
7398             Bitmap thumbnail, CharSequence description, boolean always) {
7399         TaskRecord task = null;
7400         ArrayList receivers = null;
7401 
7402         //System.out.println("Send pending thumbnail: " + r);
7403 
7404         synchronized(this) {
7405             if (r == null) {
7406                 int index = indexOfTokenLocked(token);
7407                 if (index < 0) {
7408                     return;
7409                 }
7410                 r = (HistoryRecord)mHistory.get(index);
7411             }
7412             if (thumbnail == null) {
7413                 thumbnail = r.thumbnail;
7414                 description = r.description;
7415             }
7416             if (thumbnail == null && !always) {
7417                 // If there is no thumbnail, and this entry is not actually
7418                 // going away, then abort for now and pick up the next
7419                 // thumbnail we get.
7420                 return;
7421             }
7422             task = r.task;
7423 
7424             int N = mPendingThumbnails.size();
7425             int i=0;
7426             while (i<N) {
7427                 PendingThumbnailsRecord pr =
7428                     (PendingThumbnailsRecord)mPendingThumbnails.get(i);
7429                 //System.out.println("Looking in " + pr.pendingRecords);
7430                 if (pr.pendingRecords.remove(r)) {
7431                     if (receivers == null) {
7432                         receivers = new ArrayList();
7433                     }
7434                     receivers.add(pr);
7435                     if (pr.pendingRecords.size() == 0) {
7436                         pr.finished = true;
7437                         mPendingThumbnails.remove(i);
7438                         N--;
7439                         continue;
7440                     }
7441                 }
7442                 i++;
7443             }
7444         }
7445 
7446         if (receivers != null) {
7447             final int N = receivers.size();
7448             for (int i=0; i<N; i++) {
7449                 try {
7450                     PendingThumbnailsRecord pr =
7451                         (PendingThumbnailsRecord)receivers.get(i);
7452                     pr.receiver.newThumbnail(
7453                         task != null ? task.taskId : -1, thumbnail, description);
7454                     if (pr.finished) {
7455                         pr.receiver.finished();
7456                     }
7457                 } catch (Exception e) {
7458                     Log.w(TAG, "Exception thrown when sending thumbnail", e);
7459                 }
7460             }
7461         }
7462     }
7463 
7464     // =========================================================
7465     // CONTENT PROVIDERS
7466     // =========================================================
7467 
generateApplicationProvidersLocked(ProcessRecord app)7468     private final List generateApplicationProvidersLocked(ProcessRecord app) {
7469         List providers = null;
7470         try {
7471             providers = ActivityThread.getPackageManager().
7472                 queryContentProviders(app.processName, app.info.uid,
7473                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7474         } catch (RemoteException ex) {
7475         }
7476         if (providers != null) {
7477             final int N = providers.size();
7478             for (int i=0; i<N; i++) {
7479                 ProviderInfo cpi =
7480                     (ProviderInfo)providers.get(i);
7481                 ContentProviderRecord cpr =
7482                     (ContentProviderRecord)mProvidersByClass.get(cpi.name);
7483                 if (cpr == null) {
7484                     cpr = new ContentProviderRecord(cpi, app.info);
7485                     mProvidersByClass.put(cpi.name, cpr);
7486                 }
7487                 app.pubProviders.put(cpi.name, cpr);
7488                 app.addPackage(cpi.applicationInfo.packageName);
7489                 ensurePackageDexOpt(cpi.applicationInfo.packageName);
7490             }
7491         }
7492         return providers;
7493     }
7494 
checkContentProviderPermissionLocked( ProviderInfo cpi, ProcessRecord r, int mode)7495     private final String checkContentProviderPermissionLocked(
7496             ProviderInfo cpi, ProcessRecord r, int mode) {
7497         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7498         final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
7499         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7500                 cpi.exported ? -1 : cpi.applicationInfo.uid)
7501                 == PackageManager.PERMISSION_GRANTED
7502                 && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) {
7503             return null;
7504         }
7505         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7506                 cpi.exported ? -1 : cpi.applicationInfo.uid)
7507                 == PackageManager.PERMISSION_GRANTED) {
7508             return null;
7509         }
7510 
7511         PathPermission[] pps = cpi.pathPermissions;
7512         if (pps != null) {
7513             int i = pps.length;
7514             while (i > 0) {
7515                 i--;
7516                 PathPermission pp = pps[i];
7517                 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7518                         cpi.exported ? -1 : cpi.applicationInfo.uid)
7519                         == PackageManager.PERMISSION_GRANTED
7520                         && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) {
7521                     return null;
7522                 }
7523                 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7524                         cpi.exported ? -1 : cpi.applicationInfo.uid)
7525                         == PackageManager.PERMISSION_GRANTED) {
7526                     return null;
7527                 }
7528             }
7529         }
7530 
7531         String msg = "Permission Denial: opening provider " + cpi.name
7532                 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7533                 + ", uid=" + callingUid + ") requires "
7534                 + cpi.readPermission + " or " + cpi.writePermission;
7535         Log.w(TAG, msg);
7536         return msg;
7537     }
7538 
getContentProviderImpl( IApplicationThread caller, String name)7539     private final ContentProviderHolder getContentProviderImpl(
7540         IApplicationThread caller, String name) {
7541         ContentProviderRecord cpr;
7542         ProviderInfo cpi = null;
7543 
7544         synchronized(this) {
7545             ProcessRecord r = null;
7546             if (caller != null) {
7547                 r = getRecordForAppLocked(caller);
7548                 if (r == null) {
7549                     throw new SecurityException(
7550                             "Unable to find app for caller " + caller
7551                           + " (pid=" + Binder.getCallingPid()
7552                           + ") when getting content provider " + name);
7553                 }
7554             }
7555 
7556             // First check if this content provider has been published...
7557             cpr = (ContentProviderRecord)mProvidersByName.get(name);
7558             if (cpr != null) {
7559                 cpi = cpr.info;
7560                 if (checkContentProviderPermissionLocked(cpi, r, -1) != null) {
7561                     return new ContentProviderHolder(cpi,
7562                             cpi.readPermission != null
7563                                     ? cpi.readPermission : cpi.writePermission);
7564                 }
7565 
7566                 if (r != null && cpr.canRunHere(r)) {
7567                     // This provider has been published or is in the process
7568                     // of being published...  but it is also allowed to run
7569                     // in the caller's process, so don't make a connection
7570                     // and just let the caller instantiate its own instance.
7571                     if (cpr.provider != null) {
7572                         // don't give caller the provider object, it needs
7573                         // to make its own.
7574                         cpr = new ContentProviderRecord(cpr);
7575                     }
7576                     return cpr;
7577                 }
7578 
7579                 final long origId = Binder.clearCallingIdentity();
7580 
7581                 // In this case the provider instance already exists, so we can
7582                 // return it right away.
7583                 if (r != null) {
7584                     if (DEBUG_PROVIDER) Log.v(TAG,
7585                             "Adding provider requested by "
7586                             + r.processName + " from process "
7587                             + cpr.info.processName);
7588                     Integer cnt = r.conProviders.get(cpr);
7589                     if (cnt == null) {
7590                         r.conProviders.put(cpr, new Integer(1));
7591                     } else {
7592                         r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
7593                     }
7594                     cpr.clients.add(r);
7595                 } else {
7596                     cpr.externals++;
7597                 }
7598 
7599                 if (cpr.app != null) {
7600                     updateOomAdjLocked(cpr.app);
7601                 }
7602 
7603                 Binder.restoreCallingIdentity(origId);
7604 
7605             } else {
7606                 try {
7607                     cpi = ActivityThread.getPackageManager().
7608                         resolveContentProvider(name,
7609                                 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7610                 } catch (RemoteException ex) {
7611                 }
7612                 if (cpi == null) {
7613                     return null;
7614                 }
7615 
7616                 if (checkContentProviderPermissionLocked(cpi, r, -1) != null) {
7617                     return new ContentProviderHolder(cpi,
7618                             cpi.readPermission != null
7619                                     ? cpi.readPermission : cpi.writePermission);
7620                 }
7621 
7622                 cpr = (ContentProviderRecord)mProvidersByClass.get(cpi.name);
7623                 final boolean firstClass = cpr == null;
7624                 if (firstClass) {
7625                     try {
7626                         ApplicationInfo ai =
7627                             ActivityThread.getPackageManager().
7628                                 getApplicationInfo(
7629                                         cpi.applicationInfo.packageName,
7630                                         STOCK_PM_FLAGS);
7631                         if (ai == null) {
7632                             Log.w(TAG, "No package info for content provider "
7633                                     + cpi.name);
7634                             return null;
7635                         }
7636                         cpr = new ContentProviderRecord(cpi, ai);
7637                     } catch (RemoteException ex) {
7638                         // pm is in same process, this will never happen.
7639                     }
7640                 }
7641 
7642                 if (r != null && cpr.canRunHere(r)) {
7643                     // If this is a multiprocess provider, then just return its
7644                     // info and allow the caller to instantiate it.  Only do
7645                     // this if the provider is the same user as the caller's
7646                     // process, or can run as root (so can be in any process).
7647                     return cpr;
7648                 }
7649 
7650                 if (DEBUG_PROVIDER) {
7651                     RuntimeException e = new RuntimeException("here");
7652                     Log.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
7653                           + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7654                 }
7655 
7656                 // This is single process, and our app is now connecting to it.
7657                 // See if we are already in the process of launching this
7658                 // provider.
7659                 final int N = mLaunchingProviders.size();
7660                 int i;
7661                 for (i=0; i<N; i++) {
7662                     if (mLaunchingProviders.get(i) == cpr) {
7663                         break;
7664                     }
7665                 }
7666 
7667                 // If the provider is not already being launched, then get it
7668                 // started.
7669                 if (i >= N) {
7670                     final long origId = Binder.clearCallingIdentity();
7671                     ProcessRecord proc = startProcessLocked(cpi.processName,
7672                             cpr.appInfo, false, 0, "content provider",
7673                             new ComponentName(cpi.applicationInfo.packageName,
7674                                     cpi.name), false);
7675                     if (proc == null) {
7676                         Log.w(TAG, "Unable to launch app "
7677                                 + cpi.applicationInfo.packageName + "/"
7678                                 + cpi.applicationInfo.uid + " for provider "
7679                                 + name + ": process is bad");
7680                         return null;
7681                     }
7682                     cpr.launchingApp = proc;
7683                     mLaunchingProviders.add(cpr);
7684                     Binder.restoreCallingIdentity(origId);
7685                 }
7686 
7687                 // Make sure the provider is published (the same provider class
7688                 // may be published under multiple names).
7689                 if (firstClass) {
7690                     mProvidersByClass.put(cpi.name, cpr);
7691                 }
7692                 mProvidersByName.put(name, cpr);
7693 
7694                 if (r != null) {
7695                     if (DEBUG_PROVIDER) Log.v(TAG,
7696                             "Adding provider requested by "
7697                             + r.processName + " from process "
7698                             + cpr.info.processName);
7699                     Integer cnt = r.conProviders.get(cpr);
7700                     if (cnt == null) {
7701                         r.conProviders.put(cpr, new Integer(1));
7702                     } else {
7703                         r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
7704                     }
7705                     cpr.clients.add(r);
7706                 } else {
7707                     cpr.externals++;
7708                 }
7709             }
7710         }
7711 
7712         // Wait for the provider to be published...
7713         synchronized (cpr) {
7714             while (cpr.provider == null) {
7715                 if (cpr.launchingApp == null) {
7716                     Log.w(TAG, "Unable to launch app "
7717                             + cpi.applicationInfo.packageName + "/"
7718                             + cpi.applicationInfo.uid + " for provider "
7719                             + name + ": launching app became null");
7720                     EventLog.writeEvent(LOG_AM_PROVIDER_LOST_PROCESS,
7721                             cpi.applicationInfo.packageName,
7722                             cpi.applicationInfo.uid, name);
7723                     return null;
7724                 }
7725                 try {
7726                     cpr.wait();
7727                 } catch (InterruptedException ex) {
7728                 }
7729             }
7730         }
7731         return cpr;
7732     }
7733 
getContentProvider( IApplicationThread caller, String name)7734     public final ContentProviderHolder getContentProvider(
7735             IApplicationThread caller, String name) {
7736         if (caller == null) {
7737             String msg = "null IApplicationThread when getting content provider "
7738                     + name;
7739             Log.w(TAG, msg);
7740             throw new SecurityException(msg);
7741         }
7742 
7743         return getContentProviderImpl(caller, name);
7744     }
7745 
getContentProviderExternal(String name)7746     private ContentProviderHolder getContentProviderExternal(String name) {
7747         return getContentProviderImpl(null, name);
7748     }
7749 
7750     /**
7751      * Drop a content provider from a ProcessRecord's bookkeeping
7752      * @param cpr
7753      */
removeContentProvider(IApplicationThread caller, String name)7754     public void removeContentProvider(IApplicationThread caller, String name) {
7755         synchronized (this) {
7756             ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name);
7757             if(cpr == null) {
7758                 // remove from mProvidersByClass
7759                 if (DEBUG_PROVIDER) Log.v(TAG, name +
7760                         " provider not found in providers list");
7761                 return;
7762             }
7763             final ProcessRecord r = getRecordForAppLocked(caller);
7764             if (r == null) {
7765                 throw new SecurityException(
7766                         "Unable to find app for caller " + caller +
7767                         " when removing content provider " + name);
7768             }
7769             //update content provider record entry info
7770             ContentProviderRecord localCpr = (ContentProviderRecord)
7771                     mProvidersByClass.get(cpr.info.name);
7772             if (DEBUG_PROVIDER) Log.v(TAG, "Removing provider requested by "
7773                     + r.info.processName + " from process "
7774                     + localCpr.appInfo.processName);
7775             if (localCpr.app == r) {
7776                 //should not happen. taken care of as a local provider
7777                 Log.w(TAG, "removeContentProvider called on local provider: "
7778                         + cpr.info.name + " in process " + r.processName);
7779                 return;
7780             } else {
7781                 Integer cnt = r.conProviders.get(localCpr);
7782                 if (cnt == null || cnt.intValue() <= 1) {
7783                     localCpr.clients.remove(r);
7784                     r.conProviders.remove(localCpr);
7785                 } else {
7786                     r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
7787                 }
7788             }
7789             updateOomAdjLocked();
7790         }
7791     }
7792 
removeContentProviderExternal(String name)7793     private void removeContentProviderExternal(String name) {
7794         synchronized (this) {
7795             ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name);
7796             if(cpr == null) {
7797                 //remove from mProvidersByClass
7798                 if(localLOGV) Log.v(TAG, name+" content provider not found in providers list");
7799                 return;
7800             }
7801 
7802             //update content provider record entry info
7803             ContentProviderRecord localCpr = (ContentProviderRecord) mProvidersByClass.get(cpr.info.name);
7804             localCpr.externals--;
7805             if (localCpr.externals < 0) {
7806                 Log.e(TAG, "Externals < 0 for content provider " + localCpr);
7807             }
7808             updateOomAdjLocked();
7809         }
7810     }
7811 
publishContentProviders(IApplicationThread caller, List<ContentProviderHolder> providers)7812     public final void publishContentProviders(IApplicationThread caller,
7813             List<ContentProviderHolder> providers) {
7814         if (providers == null) {
7815             return;
7816         }
7817 
7818         synchronized(this) {
7819             final ProcessRecord r = getRecordForAppLocked(caller);
7820             if (r == null) {
7821                 throw new SecurityException(
7822                         "Unable to find app for caller " + caller
7823                       + " (pid=" + Binder.getCallingPid()
7824                       + ") when publishing content providers");
7825             }
7826 
7827             final long origId = Binder.clearCallingIdentity();
7828 
7829             final int N = providers.size();
7830             for (int i=0; i<N; i++) {
7831                 ContentProviderHolder src = providers.get(i);
7832                 if (src == null || src.info == null || src.provider == null) {
7833                     continue;
7834                 }
7835                 ContentProviderRecord dst =
7836                     (ContentProviderRecord)r.pubProviders.get(src.info.name);
7837                 if (dst != null) {
7838                     mProvidersByClass.put(dst.info.name, dst);
7839                     String names[] = dst.info.authority.split(";");
7840                     for (int j = 0; j < names.length; j++) {
7841                         mProvidersByName.put(names[j], dst);
7842                     }
7843 
7844                     int NL = mLaunchingProviders.size();
7845                     int j;
7846                     for (j=0; j<NL; j++) {
7847                         if (mLaunchingProviders.get(j) == dst) {
7848                             mLaunchingProviders.remove(j);
7849                             j--;
7850                             NL--;
7851                         }
7852                     }
7853                     synchronized (dst) {
7854                         dst.provider = src.provider;
7855                         dst.app = r;
7856                         dst.notifyAll();
7857                     }
7858                     updateOomAdjLocked(r);
7859                 }
7860             }
7861 
7862             Binder.restoreCallingIdentity(origId);
7863         }
7864     }
7865 
installSystemProviders()7866     public static final void installSystemProviders() {
7867         ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
7868         List providers = mSelf.generateApplicationProvidersLocked(app);
7869         mSystemThread.installSystemProviders(providers);
7870     }
7871 
7872     // =========================================================
7873     // GLOBAL MANAGEMENT
7874     // =========================================================
7875 
newProcessRecordLocked(IApplicationThread thread, ApplicationInfo info, String customProcess)7876     final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
7877             ApplicationInfo info, String customProcess) {
7878         String proc = customProcess != null ? customProcess : info.processName;
7879         BatteryStatsImpl.Uid.Proc ps = null;
7880         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7881         synchronized (stats) {
7882             ps = stats.getProcessStatsLocked(info.uid, proc);
7883         }
7884         return new ProcessRecord(ps, thread, info, proc);
7885     }
7886 
addAppLocked(ApplicationInfo info)7887     final ProcessRecord addAppLocked(ApplicationInfo info) {
7888         ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
7889 
7890         if (app == null) {
7891             app = newProcessRecordLocked(null, info, null);
7892             mProcessNames.put(info.processName, info.uid, app);
7893             updateLRUListLocked(app, true);
7894         }
7895 
7896         if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
7897                 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7898             app.persistent = true;
7899             app.maxAdj = CORE_SERVER_ADJ;
7900         }
7901         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7902             mPersistentStartingProcesses.add(app);
7903             startProcessLocked(app, "added application", app.processName);
7904         }
7905 
7906         return app;
7907     }
7908 
unhandledBack()7909     public void unhandledBack() {
7910         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7911                 "unhandledBack()");
7912 
7913         synchronized(this) {
7914             int count = mHistory.size();
7915             if (Config.LOGD) Log.d(
7916                 TAG, "Performing unhandledBack(): stack size = " + count);
7917             if (count > 1) {
7918                 final long origId = Binder.clearCallingIdentity();
7919                 finishActivityLocked((HistoryRecord)mHistory.get(count-1),
7920                         count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
7921                 Binder.restoreCallingIdentity(origId);
7922             }
7923         }
7924     }
7925 
openContentUri(Uri uri)7926     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
7927         String name = uri.getAuthority();
7928         ContentProviderHolder cph = getContentProviderExternal(name);
7929         ParcelFileDescriptor pfd = null;
7930         if (cph != null) {
7931             // We record the binder invoker's uid in thread-local storage before
7932             // going to the content provider to open the file.  Later, in the code
7933             // that handles all permissions checks, we look for this uid and use
7934             // that rather than the Activity Manager's own uid.  The effect is that
7935             // we do the check against the caller's permissions even though it looks
7936             // to the content provider like the Activity Manager itself is making
7937             // the request.
7938             sCallerIdentity.set(new Identity(
7939                     Binder.getCallingPid(), Binder.getCallingUid()));
7940             try {
7941                 pfd = cph.provider.openFile(uri, "r");
7942             } catch (FileNotFoundException e) {
7943                 // do nothing; pfd will be returned null
7944             } finally {
7945                 // Ensure that whatever happens, we clean up the identity state
7946                 sCallerIdentity.remove();
7947             }
7948 
7949             // We've got the fd now, so we're done with the provider.
7950             removeContentProviderExternal(name);
7951         } else {
7952             Log.d(TAG, "Failed to get provider for authority '" + name + "'");
7953         }
7954         return pfd;
7955     }
7956 
goingToSleep()7957     public void goingToSleep() {
7958         synchronized(this) {
7959             mSleeping = true;
7960             mWindowManager.setEventDispatching(false);
7961 
7962             if (mResumedActivity != null) {
7963                 pauseIfSleepingLocked();
7964             } else {
7965                 Log.w(TAG, "goingToSleep with no resumed activity!");
7966             }
7967         }
7968     }
7969 
shutdown(int timeout)7970     public boolean shutdown(int timeout) {
7971         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7972                 != PackageManager.PERMISSION_GRANTED) {
7973             throw new SecurityException("Requires permission "
7974                     + android.Manifest.permission.SHUTDOWN);
7975         }
7976 
7977         boolean timedout = false;
7978 
7979         synchronized(this) {
7980             mShuttingDown = true;
7981             mWindowManager.setEventDispatching(false);
7982 
7983             if (mResumedActivity != null) {
7984                 pauseIfSleepingLocked();
7985                 final long endTime = System.currentTimeMillis() + timeout;
7986                 while (mResumedActivity != null || mPausingActivity != null) {
7987                     long delay = endTime - System.currentTimeMillis();
7988                     if (delay <= 0) {
7989                         Log.w(TAG, "Activity manager shutdown timed out");
7990                         timedout = true;
7991                         break;
7992                     }
7993                     try {
7994                         this.wait();
7995                     } catch (InterruptedException e) {
7996                     }
7997                 }
7998             }
7999         }
8000 
8001         mUsageStatsService.shutdown();
8002         mBatteryStatsService.shutdown();
8003 
8004         return timedout;
8005     }
8006 
pauseIfSleepingLocked()8007     void pauseIfSleepingLocked() {
8008         if (mSleeping || mShuttingDown) {
8009             if (!mGoingToSleep.isHeld()) {
8010                 mGoingToSleep.acquire();
8011                 if (mLaunchingActivity.isHeld()) {
8012                     mLaunchingActivity.release();
8013                     mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
8014                 }
8015             }
8016 
8017             // If we are not currently pausing an activity, get the current
8018             // one to pause.  If we are pausing one, we will just let that stuff
8019             // run and release the wake lock when all done.
8020             if (mPausingActivity == null) {
8021                 if (DEBUG_PAUSE) Log.v(TAG, "Sleep needs to pause...");
8022                 if (DEBUG_USER_LEAVING) Log.v(TAG, "Sleep => pause with userLeaving=false");
8023                 startPausingLocked(false, true);
8024             }
8025         }
8026     }
8027 
wakingUp()8028     public void wakingUp() {
8029         synchronized(this) {
8030             if (mGoingToSleep.isHeld()) {
8031                 mGoingToSleep.release();
8032             }
8033             mWindowManager.setEventDispatching(true);
8034             mSleeping = false;
8035             resumeTopActivityLocked(null);
8036         }
8037     }
8038 
stopAppSwitches()8039     public void stopAppSwitches() {
8040         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8041                 != PackageManager.PERMISSION_GRANTED) {
8042             throw new SecurityException("Requires permission "
8043                     + android.Manifest.permission.STOP_APP_SWITCHES);
8044         }
8045 
8046         synchronized(this) {
8047             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8048                     + APP_SWITCH_DELAY_TIME;
8049             mDidAppSwitch = false;
8050             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8051             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8052             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8053         }
8054     }
8055 
resumeAppSwitches()8056     public void resumeAppSwitches() {
8057         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8058                 != PackageManager.PERMISSION_GRANTED) {
8059             throw new SecurityException("Requires permission "
8060                     + android.Manifest.permission.STOP_APP_SWITCHES);
8061         }
8062 
8063         synchronized(this) {
8064             // Note that we don't execute any pending app switches... we will
8065             // let those wait until either the timeout, or the next start
8066             // activity request.
8067             mAppSwitchesAllowedTime = 0;
8068         }
8069     }
8070 
checkAppSwitchAllowedLocked(int callingPid, int callingUid, String name)8071     boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8072             String name) {
8073         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8074             return true;
8075         }
8076 
8077         final int perm = checkComponentPermission(
8078                 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8079                 callingUid, -1);
8080         if (perm == PackageManager.PERMISSION_GRANTED) {
8081             return true;
8082         }
8083 
8084         Log.w(TAG, name + " request from " + callingUid + " stopped");
8085         return false;
8086     }
8087 
setDebugApp(String packageName, boolean waitForDebugger, boolean persistent)8088     public void setDebugApp(String packageName, boolean waitForDebugger,
8089             boolean persistent) {
8090         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8091                 "setDebugApp()");
8092 
8093         // Note that this is not really thread safe if there are multiple
8094         // callers into it at the same time, but that's not a situation we
8095         // care about.
8096         if (persistent) {
8097             final ContentResolver resolver = mContext.getContentResolver();
8098             Settings.System.putString(
8099                 resolver, Settings.System.DEBUG_APP,
8100                 packageName);
8101             Settings.System.putInt(
8102                 resolver, Settings.System.WAIT_FOR_DEBUGGER,
8103                 waitForDebugger ? 1 : 0);
8104         }
8105 
8106         synchronized (this) {
8107             if (!persistent) {
8108                 mOrigDebugApp = mDebugApp;
8109                 mOrigWaitForDebugger = mWaitForDebugger;
8110             }
8111             mDebugApp = packageName;
8112             mWaitForDebugger = waitForDebugger;
8113             mDebugTransient = !persistent;
8114             if (packageName != null) {
8115                 final long origId = Binder.clearCallingIdentity();
8116                 uninstallPackageLocked(packageName, -1, false);
8117                 Binder.restoreCallingIdentity(origId);
8118             }
8119         }
8120     }
8121 
setAlwaysFinish(boolean enabled)8122     public void setAlwaysFinish(boolean enabled) {
8123         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8124                 "setAlwaysFinish()");
8125 
8126         Settings.System.putInt(
8127                 mContext.getContentResolver(),
8128                 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8129 
8130         synchronized (this) {
8131             mAlwaysFinishActivities = enabled;
8132         }
8133     }
8134 
setActivityController(IActivityController controller)8135     public void setActivityController(IActivityController controller) {
8136         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8137                 "setActivityController()");
8138         synchronized (this) {
8139             mController = controller;
8140         }
8141     }
8142 
registerActivityWatcher(IActivityWatcher watcher)8143     public void registerActivityWatcher(IActivityWatcher watcher) {
8144         mWatchers.register(watcher);
8145     }
8146 
unregisterActivityWatcher(IActivityWatcher watcher)8147     public void unregisterActivityWatcher(IActivityWatcher watcher) {
8148         mWatchers.unregister(watcher);
8149     }
8150 
enterSafeMode()8151     public final void enterSafeMode() {
8152         synchronized(this) {
8153             // It only makes sense to do this before the system is ready
8154             // and started launching other packages.
8155             if (!mSystemReady) {
8156                 try {
8157                     ActivityThread.getPackageManager().enterSafeMode();
8158                 } catch (RemoteException e) {
8159                 }
8160 
8161                 View v = LayoutInflater.from(mContext).inflate(
8162                         com.android.internal.R.layout.safe_mode, null);
8163                 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8164                 lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
8165                 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8166                 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8167                 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
8168                 lp.format = v.getBackground().getOpacity();
8169                 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8170                         | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8171                 ((WindowManager)mContext.getSystemService(
8172                         Context.WINDOW_SERVICE)).addView(v, lp);
8173             }
8174         }
8175     }
8176 
noteWakeupAlarm(IIntentSender sender)8177     public void noteWakeupAlarm(IIntentSender sender) {
8178         if (!(sender instanceof PendingIntentRecord)) {
8179             return;
8180         }
8181         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8182         synchronized (stats) {
8183             if (mBatteryStatsService.isOnBattery()) {
8184                 mBatteryStatsService.enforceCallingPermission();
8185                 PendingIntentRecord rec = (PendingIntentRecord)sender;
8186                 int MY_UID = Binder.getCallingUid();
8187                 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8188                 BatteryStatsImpl.Uid.Pkg pkg =
8189                     stats.getPackageStatsLocked(uid, rec.key.packageName);
8190                 pkg.incWakeupsLocked();
8191             }
8192         }
8193     }
8194 
killPidsForMemory(int[] pids)8195     public boolean killPidsForMemory(int[] pids) {
8196         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8197             throw new SecurityException("killPidsForMemory only available to the system");
8198         }
8199 
8200         // XXX Note: don't acquire main activity lock here, because the window
8201         // manager calls in with its locks held.
8202 
8203         boolean killed = false;
8204         synchronized (mPidsSelfLocked) {
8205             int[] types = new int[pids.length];
8206             int worstType = 0;
8207             for (int i=0; i<pids.length; i++) {
8208                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8209                 if (proc != null) {
8210                     int type = proc.setAdj;
8211                     types[i] = type;
8212                     if (type > worstType) {
8213                         worstType = type;
8214                     }
8215                 }
8216             }
8217 
8218             // If the worse oom_adj is somewhere in the hidden proc LRU range,
8219             // then constrain it so we will kill all hidden procs.
8220             if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
8221                 worstType = HIDDEN_APP_MIN_ADJ;
8222             }
8223             Log.w(TAG, "Killing processes for memory at adjustment " + worstType);
8224             for (int i=0; i<pids.length; i++) {
8225                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8226                 if (proc == null) {
8227                     continue;
8228                 }
8229                 int adj = proc.setAdj;
8230                 if (adj >= worstType) {
8231                     Log.w(TAG, "Killing for memory: " + proc + " (adj "
8232                             + adj + ")");
8233                     EventLog.writeEvent(LOG_AM_KILL_FOR_MEMORY, proc.pid,
8234                             proc.processName, adj);
8235                     killed = true;
8236                     Process.killProcess(pids[i]);
8237                 }
8238             }
8239         }
8240         return killed;
8241     }
8242 
reportPss(IApplicationThread caller, int pss)8243     public void reportPss(IApplicationThread caller, int pss) {
8244         Watchdog.PssRequestor req;
8245         String name;
8246         ProcessRecord callerApp;
8247         synchronized (this) {
8248             if (caller == null) {
8249                 return;
8250             }
8251             callerApp = getRecordForAppLocked(caller);
8252             if (callerApp == null) {
8253                 return;
8254             }
8255             callerApp.lastPss = pss;
8256             req = callerApp;
8257             name = callerApp.processName;
8258         }
8259         Watchdog.getInstance().reportPss(req, name, pss);
8260         if (!callerApp.persistent) {
8261             removeRequestedPss(callerApp);
8262         }
8263     }
8264 
requestPss(Runnable completeCallback)8265     public void requestPss(Runnable completeCallback) {
8266         ArrayList<ProcessRecord> procs;
8267         synchronized (this) {
8268             mRequestPssCallback = completeCallback;
8269             mRequestPssList.clear();
8270             for (int i=mLRUProcesses.size()-1; i>=0; i--) {
8271                 ProcessRecord proc = mLRUProcesses.get(i);
8272                 if (!proc.persistent) {
8273                     mRequestPssList.add(proc);
8274                 }
8275             }
8276             procs = new ArrayList<ProcessRecord>(mRequestPssList);
8277         }
8278 
8279         int oldPri = Process.getThreadPriority(Process.myTid());
8280         Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
8281         for (int i=procs.size()-1; i>=0; i--) {
8282             ProcessRecord proc = procs.get(i);
8283             proc.lastPss = 0;
8284             proc.requestPss();
8285         }
8286         Process.setThreadPriority(oldPri);
8287     }
8288 
removeRequestedPss(ProcessRecord proc)8289     void removeRequestedPss(ProcessRecord proc) {
8290         Runnable callback = null;
8291         synchronized (this) {
8292             if (mRequestPssList.remove(proc)) {
8293                 if (mRequestPssList.size() == 0) {
8294                     callback = mRequestPssCallback;
8295                     mRequestPssCallback = null;
8296                 }
8297             }
8298         }
8299 
8300         if (callback != null) {
8301             callback.run();
8302         }
8303     }
8304 
collectPss(Watchdog.PssStats stats)8305     public void collectPss(Watchdog.PssStats stats) {
8306         stats.mEmptyPss = 0;
8307         stats.mEmptyCount = 0;
8308         stats.mBackgroundPss = 0;
8309         stats.mBackgroundCount = 0;
8310         stats.mServicePss = 0;
8311         stats.mServiceCount = 0;
8312         stats.mVisiblePss = 0;
8313         stats.mVisibleCount = 0;
8314         stats.mForegroundPss = 0;
8315         stats.mForegroundCount = 0;
8316         stats.mNoPssCount = 0;
8317         synchronized (this) {
8318             int i;
8319             int NPD = mProcDeaths.length < stats.mProcDeaths.length
8320                     ? mProcDeaths.length : stats.mProcDeaths.length;
8321             int aggr = 0;
8322             for (i=0; i<NPD; i++) {
8323                 aggr += mProcDeaths[i];
8324                 stats.mProcDeaths[i] = aggr;
8325             }
8326             while (i<stats.mProcDeaths.length) {
8327                 stats.mProcDeaths[i] = 0;
8328                 i++;
8329             }
8330 
8331             for (i=mLRUProcesses.size()-1; i>=0; i--) {
8332                 ProcessRecord proc = mLRUProcesses.get(i);
8333                 if (proc.persistent) {
8334                     continue;
8335                 }
8336                 //Log.i(TAG, "Proc " + proc + ": pss=" + proc.lastPss);
8337                 if (proc.lastPss == 0) {
8338                     stats.mNoPssCount++;
8339                     continue;
8340                 }
8341                 if (proc.setAdj == EMPTY_APP_ADJ) {
8342                     stats.mEmptyPss += proc.lastPss;
8343                     stats.mEmptyCount++;
8344                 } else if (proc.setAdj == CONTENT_PROVIDER_ADJ) {
8345                     stats.mEmptyPss += proc.lastPss;
8346                     stats.mEmptyCount++;
8347                 } else if (proc.setAdj >= HIDDEN_APP_MIN_ADJ) {
8348                     stats.mBackgroundPss += proc.lastPss;
8349                     stats.mBackgroundCount++;
8350                 } else if (proc.setAdj >= VISIBLE_APP_ADJ) {
8351                     stats.mVisiblePss += proc.lastPss;
8352                     stats.mVisibleCount++;
8353                 } else {
8354                     stats.mForegroundPss += proc.lastPss;
8355                     stats.mForegroundCount++;
8356                 }
8357             }
8358         }
8359     }
8360 
8361     public final void startRunning(String pkg, String cls, String action,
8362             String data) {
8363         synchronized(this) {
8364             if (mStartRunning) {
8365                 return;
8366             }
8367             mStartRunning = true;
8368             mTopComponent = pkg != null && cls != null
8369                     ? new ComponentName(pkg, cls) : null;
8370             mTopAction = action != null ? action : Intent.ACTION_MAIN;
8371             mTopData = data;
8372             if (!mSystemReady) {
8373                 return;
8374             }
8375         }
8376 
8377         systemReady(null);
8378     }
8379 
8380     private void retrieveSettings() {
8381         final ContentResolver resolver = mContext.getContentResolver();
8382         String debugApp = Settings.System.getString(
8383             resolver, Settings.System.DEBUG_APP);
8384         boolean waitForDebugger = Settings.System.getInt(
8385             resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
8386         boolean alwaysFinishActivities = Settings.System.getInt(
8387             resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
8388 
8389         Configuration configuration = new Configuration();
8390         Settings.System.getConfiguration(resolver, configuration);
8391 
8392         synchronized (this) {
8393             mDebugApp = mOrigDebugApp = debugApp;
8394             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
8395             mAlwaysFinishActivities = alwaysFinishActivities;
8396             // This happens before any activities are started, so we can
8397             // change mConfiguration in-place.
8398             mConfiguration.updateFrom(configuration);
8399             if (DEBUG_CONFIGURATION) Log.v(TAG, "Initial config: " + mConfiguration);
8400         }
8401     }
8402 
8403     public boolean testIsSystemReady() {
8404         // no need to synchronize(this) just to read & return the value
8405         return mSystemReady;
8406     }
8407 
8408     public void systemReady(final Runnable goingCallback) {
8409         // In the simulator, startRunning will never have been called, which
8410         // normally sets a few crucial variables. Do it here instead.
8411         if (!Process.supportsProcesses()) {
8412             mStartRunning = true;
8413             mTopAction = Intent.ACTION_MAIN;
8414         }
8415 
8416         synchronized(this) {
8417             if (mSystemReady) {
8418                 if (goingCallback != null) goingCallback.run();
8419                 return;
8420             }
8421 
8422             // Check to see if there are any update receivers to run.
8423             if (!mDidUpdate) {
8424                 if (mWaitingUpdate) {
8425                     return;
8426                 }
8427                 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
8428                 List<ResolveInfo> ris = null;
8429                 try {
8430                     ris = ActivityThread.getPackageManager().queryIntentReceivers(
8431                                 intent, null, 0);
8432                 } catch (RemoteException e) {
8433                 }
8434                 if (ris != null) {
8435                     for (int i=ris.size()-1; i>=0; i--) {
8436                         if ((ris.get(i).activityInfo.applicationInfo.flags
8437                                 &ApplicationInfo.FLAG_SYSTEM) == 0) {
8438                             ris.remove(i);
8439                         }
8440                     }
8441                     intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
8442                     for (int i=0; i<ris.size(); i++) {
8443                         ActivityInfo ai = ris.get(i).activityInfo;
8444                         intent.setComponent(new ComponentName(ai.packageName, ai.name));
8445                         IIntentReceiver finisher = null;
8446                         if (i == 0) {
8447                             finisher = new IIntentReceiver.Stub() {
8448                                 public void performReceive(Intent intent, int resultCode,
8449                                         String data, Bundle extras, boolean ordered,
8450                                         boolean sticky)
8451                                         throws RemoteException {
8452                                     synchronized (ActivityManagerService.this) {
8453                                         mDidUpdate = true;
8454                                     }
8455                                     systemReady(goingCallback);
8456                                 }
8457                             };
8458                         }
8459                         Log.i(TAG, "Sending system update to: " + intent.getComponent());
8460                         broadcastIntentLocked(null, null, intent, null, finisher,
8461                                 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
8462                         if (i == 0) {
8463                             mWaitingUpdate = true;
8464                         }
8465                     }
8466                 }
8467                 if (mWaitingUpdate) {
8468                     return;
8469                 }
8470                 mDidUpdate = true;
8471             }
8472 
8473             mSystemReady = true;
8474             if (!mStartRunning) {
8475                 return;
8476             }
8477         }
8478 
8479         ArrayList<ProcessRecord> procsToKill = null;
8480         synchronized(mPidsSelfLocked) {
8481             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
8482                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8483                 if (!isAllowedWhileBooting(proc.info)){
8484                     if (procsToKill == null) {
8485                         procsToKill = new ArrayList<ProcessRecord>();
8486                     }
8487                     procsToKill.add(proc);
8488                 }
8489             }
8490         }
8491 
8492         if (procsToKill != null) {
8493             synchronized(this) {
8494                 for (int i=procsToKill.size()-1; i>=0; i--) {
8495                     ProcessRecord proc = procsToKill.get(i);
8496                     Log.i(TAG, "Removing system update proc: " + proc);
8497                     removeProcessLocked(proc, true);
8498                 }
8499             }
8500         }
8501 
8502         Log.i(TAG, "System now ready");
8503         EventLog.writeEvent(LOG_BOOT_PROGRESS_AMS_READY,
8504             SystemClock.uptimeMillis());
8505 
8506         synchronized(this) {
8507             // Make sure we have no pre-ready processes sitting around.
8508 
8509             if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
8510                 ResolveInfo ri = mContext.getPackageManager()
8511                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
8512                                 STOCK_PM_FLAGS);
8513                 CharSequence errorMsg = null;
8514                 if (ri != null) {
8515                     ActivityInfo ai = ri.activityInfo;
8516                     ApplicationInfo app = ai.applicationInfo;
8517                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
8518                         mTopAction = Intent.ACTION_FACTORY_TEST;
8519                         mTopData = null;
8520                         mTopComponent = new ComponentName(app.packageName,
8521                                 ai.name);
8522                     } else {
8523                         errorMsg = mContext.getResources().getText(
8524                                 com.android.internal.R.string.factorytest_not_system);
8525                     }
8526                 } else {
8527                     errorMsg = mContext.getResources().getText(
8528                             com.android.internal.R.string.factorytest_no_action);
8529                 }
8530                 if (errorMsg != null) {
8531                     mTopAction = null;
8532                     mTopData = null;
8533                     mTopComponent = null;
8534                     Message msg = Message.obtain();
8535                     msg.what = SHOW_FACTORY_ERROR_MSG;
8536                     msg.getData().putCharSequence("msg", errorMsg);
8537                     mHandler.sendMessage(msg);
8538                 }
8539             }
8540         }
8541 
8542         retrieveSettings();
8543 
8544         if (goingCallback != null) goingCallback.run();
8545 
8546         synchronized (this) {
8547             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
8548                 try {
8549                     List apps = ActivityThread.getPackageManager().
8550                         getPersistentApplications(STOCK_PM_FLAGS);
8551                     if (apps != null) {
8552                         int N = apps.size();
8553                         int i;
8554                         for (i=0; i<N; i++) {
8555                             ApplicationInfo info
8556                                 = (ApplicationInfo)apps.get(i);
8557                             if (info != null &&
8558                                     !info.packageName.equals("android")) {
8559                                 addAppLocked(info);
8560                             }
8561                         }
8562                     }
8563                 } catch (RemoteException ex) {
8564                     // pm is in same process, this will never happen.
8565                 }
8566             }
8567 
8568             // Start up initial activity.
8569             mBooting = true;
8570 
8571             try {
8572                 if (ActivityThread.getPackageManager().hasSystemUidErrors()) {
8573                     Message msg = Message.obtain();
8574                     msg.what = SHOW_UID_ERROR_MSG;
8575                     mHandler.sendMessage(msg);
8576                 }
8577             } catch (RemoteException e) {
8578             }
8579 
8580             resumeTopActivityLocked(null);
8581         }
8582     }
8583 
8584     boolean makeAppCrashingLocked(ProcessRecord app,
8585             String tag, String shortMsg, String longMsg, byte[] crashData) {
8586         app.crashing = true;
8587         app.crashingReport = generateProcessError(app,
8588                 ActivityManager.ProcessErrorStateInfo.CRASHED, tag, shortMsg, longMsg, crashData);
8589         startAppProblemLocked(app);
8590         app.stopFreezingAllLocked();
8591         return handleAppCrashLocked(app);
8592     }
8593 
8594     private ComponentName getErrorReportReceiver(ProcessRecord app) {
8595         // check if error reporting is enabled in Gservices
8596         int enabled = Settings.Gservices.getInt(mContext.getContentResolver(),
8597                 Settings.Gservices.SEND_ACTION_APP_ERROR, 0);
8598         if (enabled == 0) {
8599             return null;
8600         }
8601 
8602         IPackageManager pm = ActivityThread.getPackageManager();
8603 
8604         try {
8605             // look for receiver in the installer package
8606             String candidate = pm.getInstallerPackageName(app.info.packageName);
8607             ComponentName result = getErrorReportReceiver(pm, app.info.packageName, candidate);
8608             if (result != null) {
8609                 return result;
8610             }
8611 
8612             // if the error app is on the system image, look for system apps
8613             // error receiver
8614             if ((app.info.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
8615                 candidate = SystemProperties.get(SYSTEM_APPS_ERROR_RECEIVER_PROPERTY);
8616                 result = getErrorReportReceiver(pm, app.info.packageName, candidate);
8617                 if (result != null) {
8618                     return result;
8619                 }
8620             }
8621 
8622             // if there is a default receiver, try that
8623             candidate = SystemProperties.get(DEFAULT_ERROR_RECEIVER_PROPERTY);
8624             return getErrorReportReceiver(pm, app.info.packageName, candidate);
8625         } catch (RemoteException e) {
8626             // should not happen
8627             Log.e(TAG, "error talking to PackageManager", e);
8628             return null;
8629         }
8630     }
8631 
8632     /**
8633      * Return activity in receiverPackage that handles ACTION_APP_ERROR.
8634      *
8635      * @param pm PackageManager isntance
8636      * @param errorPackage package which caused the error
8637      * @param receiverPackage candidate package to receive the error
8638      * @return activity component within receiverPackage which handles
8639      * ACTION_APP_ERROR, or null if not found
8640      */
8641     private ComponentName getErrorReportReceiver(IPackageManager pm, String errorPackage,
8642             String receiverPackage) throws RemoteException {
8643         if (receiverPackage == null || receiverPackage.length() == 0) {
8644             return null;
8645         }
8646 
8647         // break the loop if it's the error report receiver package that crashed
8648         if (receiverPackage.equals(errorPackage)) {
8649             return null;
8650         }
8651 
8652         Intent intent = new Intent(Intent.ACTION_APP_ERROR);
8653         intent.setPackage(receiverPackage);
8654         ResolveInfo info = pm.resolveIntent(intent, null, 0);
8655         if (info == null || info.activityInfo == null) {
8656             return null;
8657         }
8658         return new ComponentName(receiverPackage, info.activityInfo.name);
8659     }
8660 
8661     void makeAppNotRespondingLocked(ProcessRecord app,
8662             String tag, String shortMsg, String longMsg, byte[] crashData) {
8663         app.notResponding = true;
8664         app.notRespondingReport = generateProcessError(app,
8665                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, tag, shortMsg, longMsg,
8666                 crashData);
8667         startAppProblemLocked(app);
8668         app.stopFreezingAllLocked();
8669     }
8670 
8671     /**
8672      * Generate a process error record, suitable for attachment to a ProcessRecord.
8673      *
8674      * @param app The ProcessRecord in which the error occurred.
8675      * @param condition Crashing, Application Not Responding, etc.  Values are defined in
8676      *                      ActivityManager.AppErrorStateInfo
8677      * @param tag The tag that was passed into handleApplicationError().  Typically the classname.
8678      * @param shortMsg Short message describing the crash.
8679      * @param longMsg Long message describing the crash.
8680      * @param crashData Raw data passed into handleApplicationError().  Typically a stack trace.
8681      *
8682      * @return Returns a fully-formed AppErrorStateInfo record.
8683      */
8684     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
8685             int condition, String tag, String shortMsg, String longMsg, byte[] crashData) {
8686         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
8687 
8688         report.condition = condition;
8689         report.processName = app.processName;
8690         report.pid = app.pid;
8691         report.uid = app.info.uid;
8692         report.tag = tag;
8693         report.shortMsg = shortMsg;
8694         report.longMsg = longMsg;
8695         report.crashData = crashData;
8696 
8697         return report;
8698     }
8699 
8700     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog,
8701             boolean crashed) {
8702         synchronized (this) {
8703             app.crashing = false;
8704             app.crashingReport = null;
8705             app.notResponding = false;
8706             app.notRespondingReport = null;
8707             if (app.anrDialog == fromDialog) {
8708                 app.anrDialog = null;
8709             }
8710             if (app.waitDialog == fromDialog) {
8711                 app.waitDialog = null;
8712             }
8713             if (app.pid > 0 && app.pid != MY_PID) {
8714                 if (crashed) {
8715                     handleAppCrashLocked(app);
8716                 }
8717                 Log.i(ActivityManagerService.TAG, "Killing process "
8718                         + app.processName
8719                         + " (pid=" + app.pid + ") at user's request");
8720                 Process.killProcess(app.pid);
8721             }
8722 
8723         }
8724     }
8725 
8726     boolean handleAppCrashLocked(ProcessRecord app) {
8727         long now = SystemClock.uptimeMillis();
8728 
8729         Long crashTime = mProcessCrashTimes.get(app.info.processName,
8730                 app.info.uid);
8731         if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
8732             // This process loses!
8733             Log.w(TAG, "Process " + app.info.processName
8734                     + " has crashed too many times: killing!");
8735             EventLog.writeEvent(LOG_AM_PROCESS_CRASHED_TOO_MUCH,
8736                     app.info.processName, app.info.uid);
8737             killServicesLocked(app, false);
8738             for (int i=mHistory.size()-1; i>=0; i--) {
8739                 HistoryRecord r = (HistoryRecord)mHistory.get(i);
8740                 if (r.app == app) {
8741                     if (Config.LOGD) Log.d(
8742                         TAG, "  Force finishing activity "
8743                         + r.intent.getComponent().flattenToShortString());
8744                     finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
8745                 }
8746             }
8747             if (!app.persistent) {
8748                 // We don't want to start this process again until the user
8749                 // explicitly does so...  but for persistent process, we really
8750                 // need to keep it running.  If a persistent process is actually
8751                 // repeatedly crashing, then badness for everyone.
8752                 EventLog.writeEvent(LOG_AM_PROCESS_BAD, app.info.uid,
8753                         app.info.processName);
8754                 mBadProcesses.put(app.info.processName, app.info.uid, now);
8755                 app.bad = true;
8756                 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
8757                 app.removed = true;
8758                 removeProcessLocked(app, false);
8759                 return false;
8760             }
8761         }
8762 
8763         // Bump up the crash count of any services currently running in the proc.
8764         if (app.services.size() != 0) {
8765             // Any services running in the application need to be placed
8766             // back in the pending list.
8767             Iterator it = app.services.iterator();
8768             while (it.hasNext()) {
8769                 ServiceRecord sr = (ServiceRecord)it.next();
8770                 sr.crashCount++;
8771             }
8772         }
8773 
8774         mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
8775         return true;
8776     }
8777 
8778     void startAppProblemLocked(ProcessRecord app) {
8779         app.errorReportReceiver = getErrorReportReceiver(app);
8780         skipCurrentReceiverLocked(app);
8781     }
8782 
8783     void skipCurrentReceiverLocked(ProcessRecord app) {
8784         boolean reschedule = false;
8785         BroadcastRecord r = app.curReceiver;
8786         if (r != null) {
8787             // The current broadcast is waiting for this app's receiver
8788             // to be finished.  Looks like that's not going to happen, so
8789             // let the broadcast continue.
8790             logBroadcastReceiverDiscard(r);
8791             finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
8792                     r.resultExtras, r.resultAbort, true);
8793             reschedule = true;
8794         }
8795         r = mPendingBroadcast;
8796         if (r != null && r.curApp == app) {
8797             if (DEBUG_BROADCAST) Log.v(TAG,
8798                     "skip & discard pending app " + r);
8799             logBroadcastReceiverDiscard(r);
8800             finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
8801                     r.resultExtras, r.resultAbort, true);
8802             reschedule = true;
8803         }
8804         if (reschedule) {
8805             scheduleBroadcastsLocked();
8806         }
8807     }
8808 
8809     public int handleApplicationError(IBinder app, int flags,
8810             String tag, String shortMsg, String longMsg, byte[] crashData) {
8811         AppErrorResult result = new AppErrorResult();
8812         ProcessRecord r = null;
8813         synchronized (this) {
8814             if (app != null) {
8815                 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8816                     final int NA = apps.size();
8817                     for (int ia=0; ia<NA; ia++) {
8818                         ProcessRecord p = apps.valueAt(ia);
8819                         if (p.thread != null && p.thread.asBinder() == app) {
8820                             r = p;
8821                             break;
8822                         }
8823                     }
8824                 }
8825             }
8826 
8827             if (r != null) {
8828                 // The application has crashed. Send the SIGQUIT to the process so
8829                 // that it can dump its state.
8830                 Process.sendSignal(r.pid, Process.SIGNAL_QUIT);
8831                 //Log.i(TAG, "Current system threads:");
8832                 //Process.sendSignal(MY_PID, Process.SIGNAL_QUIT);
8833             }
8834 
8835             if (mController != null) {
8836                 try {
8837                     String name = r != null ? r.processName : null;
8838                     int pid = r != null ? r.pid : Binder.getCallingPid();
8839                     if (!mController.appCrashed(name, pid,
8840                             shortMsg, longMsg, crashData)) {
8841                         Log.w(TAG, "Force-killing crashed app " + name
8842                                 + " at watcher's request");
8843                         Process.killProcess(pid);
8844                         return 0;
8845                     }
8846                 } catch (RemoteException e) {
8847                     mController = null;
8848                 }
8849             }
8850 
8851             final long origId = Binder.clearCallingIdentity();
8852 
8853             // If this process is running instrumentation, finish it.
8854             if (r != null && r.instrumentationClass != null) {
8855                 Log.w(TAG, "Error in app " + r.processName
8856                       + " running instrumentation " + r.instrumentationClass + ":");
8857                 if (shortMsg != null) Log.w(TAG, "  " + shortMsg);
8858                 if (longMsg != null) Log.w(TAG, "  " + longMsg);
8859                 Bundle info = new Bundle();
8860                 info.putString("shortMsg", shortMsg);
8861                 info.putString("longMsg", longMsg);
8862                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8863                 Binder.restoreCallingIdentity(origId);
8864                 return 0;
8865             }
8866 
8867             if (r != null) {
8868                 if (!makeAppCrashingLocked(r, tag, shortMsg, longMsg, crashData)) {
8869                     return 0;
8870                 }
8871             } else {
8872                 Log.w(TAG, "Some application object " + app + " tag " + tag
8873                         + " has crashed, but I don't know who it is.");
8874                 Log.w(TAG, "ShortMsg:" + shortMsg);
8875                 Log.w(TAG, "LongMsg:" + longMsg);
8876                 Binder.restoreCallingIdentity(origId);
8877                 return 0;
8878             }
8879 
8880             Message msg = Message.obtain();
8881             msg.what = SHOW_ERROR_MSG;
8882             HashMap data = new HashMap();
8883             data.put("result", result);
8884             data.put("app", r);
8885             data.put("flags", flags);
8886             data.put("shortMsg", shortMsg);
8887             data.put("longMsg", longMsg);
8888             if (r != null && (r.info.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
8889                 // For system processes, submit crash data to the server.
8890                 data.put("crashData", crashData);
8891             }
8892             msg.obj = data;
8893             mHandler.sendMessage(msg);
8894 
8895             Binder.restoreCallingIdentity(origId);
8896         }
8897 
8898         int res = result.get();
8899 
8900         Intent appErrorIntent = null;
8901         synchronized (this) {
8902             if (r != null) {
8903                 mProcessCrashTimes.put(r.info.processName, r.info.uid,
8904                         SystemClock.uptimeMillis());
8905             }
8906             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8907                 appErrorIntent = createAppErrorIntentLocked(r);
8908                 res = AppErrorDialog.FORCE_QUIT;
8909             }
8910         }
8911 
8912         if (appErrorIntent != null) {
8913             try {
8914                 mContext.startActivity(appErrorIntent);
8915             } catch (ActivityNotFoundException e) {
8916                 Log.w(TAG, "bug report receiver dissappeared", e);
8917             }
8918         }
8919 
8920         return res;
8921     }
8922 
8923     Intent createAppErrorIntentLocked(ProcessRecord r) {
8924         ApplicationErrorReport report = createAppErrorReportLocked(r);
8925         if (report == null) {
8926             return null;
8927         }
8928         Intent result = new Intent(Intent.ACTION_APP_ERROR);
8929         result.setComponent(r.errorReportReceiver);
8930         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8931         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8932         return result;
8933     }
8934 
8935     ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r) {
8936         if (r.errorReportReceiver == null) {
8937             return null;
8938         }
8939 
8940         if (!r.crashing && !r.notResponding) {
8941             return null;
8942         }
8943 
8944         try {
8945             ApplicationErrorReport report = new ApplicationErrorReport();
8946             report.packageName = r.info.packageName;
8947             report.installerPackageName = r.errorReportReceiver.getPackageName();
8948             report.processName = r.processName;
8949 
8950             if (r.crashing) {
8951                 report.type = ApplicationErrorReport.TYPE_CRASH;
8952                 report.crashInfo = new ApplicationErrorReport.CrashInfo();
8953 
8954                 ByteArrayInputStream byteStream = new ByteArrayInputStream(
8955                         r.crashingReport.crashData);
8956                 DataInputStream dataStream = new DataInputStream(byteStream);
8957                 CrashData crashData = new CrashData(dataStream);
8958                 ThrowableData throwData = crashData.getThrowableData();
8959 
8960                 report.time = crashData.getTime();
8961                 report.crashInfo.stackTrace = throwData.toString();
8962 
8963                 // Extract the source of the exception, useful for report
8964                 // clustering. Also extract the "deepest" non-null exception
8965                 // message.
8966                 String exceptionMessage = throwData.getMessage();
8967                 while (throwData.getCause() != null) {
8968                     throwData = throwData.getCause();
8969                     String msg = throwData.getMessage();
8970                     if (msg != null && msg.length() > 0) {
8971                        exceptionMessage = msg;
8972                     }
8973                 }
8974                 StackTraceElementData trace = throwData.getStackTrace()[0];
8975                 report.crashInfo.exceptionMessage = exceptionMessage;
8976                 report.crashInfo.exceptionClassName = throwData.getType();
8977                 report.crashInfo.throwFileName = trace.getFileName();
8978                 report.crashInfo.throwClassName = trace.getClassName();
8979                 report.crashInfo.throwMethodName = trace.getMethodName();
8980                 report.crashInfo.throwLineNumber = trace.getLineNumber();
8981             } else if (r.notResponding) {
8982                 report.type = ApplicationErrorReport.TYPE_ANR;
8983                 report.anrInfo = new ApplicationErrorReport.AnrInfo();
8984 
8985                 report.anrInfo.activity = r.notRespondingReport.tag;
8986                 report.anrInfo.cause = r.notRespondingReport.shortMsg;
8987                 report.anrInfo.info = r.notRespondingReport.longMsg;
8988             }
8989 
8990             return report;
8991         } catch (IOException e) {
8992             // we don't send it
8993         }
8994 
8995         return null;
8996     }
8997 
8998     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8999         // assume our apps are happy - lazy create the list
9000         List<ActivityManager.ProcessErrorStateInfo> errList = null;
9001 
9002         synchronized (this) {
9003 
9004             // iterate across all processes
9005             final int N = mLRUProcesses.size();
9006             for (int i = 0; i < N; i++) {
9007                 ProcessRecord app = mLRUProcesses.get(i);
9008                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
9009                     // This one's in trouble, so we'll generate a report for it
9010                     // crashes are higher priority (in case there's a crash *and* an anr)
9011                     ActivityManager.ProcessErrorStateInfo report = null;
9012                     if (app.crashing) {
9013                         report = app.crashingReport;
9014                     } else if (app.notResponding) {
9015                         report = app.notRespondingReport;
9016                     }
9017 
9018                     if (report != null) {
9019                         if (errList == null) {
9020                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
9021                         }
9022                         errList.add(report);
9023                     } else {
9024                         Log.w(TAG, "Missing app error report, app = " + app.processName +
9025                                 " crashing = " + app.crashing +
9026                                 " notResponding = " + app.notResponding);
9027                     }
9028                 }
9029             }
9030         }
9031 
9032         return errList;
9033     }
9034 
9035     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
9036         // Lazy instantiation of list
9037         List<ActivityManager.RunningAppProcessInfo> runList = null;
9038         synchronized (this) {
9039             // Iterate across all processes
9040             final int N = mLRUProcesses.size();
9041             for (int i = 0; i < N; i++) {
9042                 ProcessRecord app = mLRUProcesses.get(i);
9043                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
9044                     // Generate process state info for running application
9045                     ActivityManager.RunningAppProcessInfo currApp =
9046                         new ActivityManager.RunningAppProcessInfo(app.processName,
9047                                 app.pid, app.getPackageList());
9048                     currApp.uid = app.info.uid;
9049                     int adj = app.curAdj;
9050                     if (adj >= CONTENT_PROVIDER_ADJ) {
9051                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
9052                     } else if (adj >= HIDDEN_APP_MIN_ADJ) {
9053                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
9054                         currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
9055                     } else if (adj >= HOME_APP_ADJ) {
9056                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
9057                         currApp.lru = 0;
9058                     } else if (adj >= SECONDARY_SERVER_ADJ) {
9059                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
9060                     } else if (adj >= VISIBLE_APP_ADJ) {
9061                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
9062                     } else {
9063                         currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
9064                     }
9065                     currApp.importanceReasonCode = app.adjTypeCode;
9066                     if (app.adjSource instanceof ProcessRecord) {
9067                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
9068                     } else if (app.adjSource instanceof HistoryRecord) {
9069                         HistoryRecord r = (HistoryRecord)app.adjSource;
9070                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
9071                     }
9072                     if (app.adjTarget instanceof ComponentName) {
9073                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
9074                     }
9075                     //Log.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
9076                     //        + " lru=" + currApp.lru);
9077                     if (runList == null) {
9078                         runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
9079                     }
9080                     runList.add(currApp);
9081                 }
9082             }
9083         }
9084         return runList;
9085     }
9086 
9087     @Override
9088     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
9089         synchronized (this) {
9090             if (checkCallingPermission(android.Manifest.permission.DUMP)
9091                     != PackageManager.PERMISSION_GRANTED) {
9092                 pw.println("Permission Denial: can't dump ActivityManager from from pid="
9093                         + Binder.getCallingPid()
9094                         + ", uid=" + Binder.getCallingUid()
9095                         + " without permission "
9096                         + android.Manifest.permission.DUMP);
9097                 return;
9098             }
9099             if (args.length != 0 && "service".equals(args[0])) {
9100                 dumpService(fd, pw, args);
9101                 return;
9102             }
9103             pw.println("Activities in Current Activity Manager State:");
9104             dumpHistoryList(pw, mHistory, "  ", "Hist", true);
9105             pw.println(" ");
9106             pw.println("  Running activities (most recent first):");
9107             dumpHistoryList(pw, mLRUActivities, "  ", "Run", false);
9108             if (mWaitingVisibleActivities.size() > 0) {
9109                 pw.println(" ");
9110                 pw.println("  Activities waiting for another to become visible:");
9111                 dumpHistoryList(pw, mWaitingVisibleActivities, "  ", "Wait", false);
9112             }
9113             if (mStoppingActivities.size() > 0) {
9114                 pw.println(" ");
9115                 pw.println("  Activities waiting to stop:");
9116                 dumpHistoryList(pw, mStoppingActivities, "  ", "Stop", false);
9117             }
9118             if (mFinishingActivities.size() > 0) {
9119                 pw.println(" ");
9120                 pw.println("  Activities waiting to finish:");
9121                 dumpHistoryList(pw, mFinishingActivities, "  ", "Fin", false);
9122             }
9123 
9124             pw.println(" ");
9125             pw.println("  mPausingActivity: " + mPausingActivity);
9126             pw.println("  mResumedActivity: " + mResumedActivity);
9127             pw.println("  mFocusedActivity: " + mFocusedActivity);
9128             pw.println("  mLastPausedActivity: " + mLastPausedActivity);
9129 
9130             if (mRecentTasks.size() > 0) {
9131                 pw.println(" ");
9132                 pw.println("Recent tasks in Current Activity Manager State:");
9133 
9134                 final int N = mRecentTasks.size();
9135                 for (int i=0; i<N; i++) {
9136                     TaskRecord tr = mRecentTasks.get(i);
9137                     pw.print("  * Recent #"); pw.print(i); pw.print(": ");
9138                             pw.println(tr);
9139                     mRecentTasks.get(i).dump(pw, "    ");
9140                 }
9141             }
9142 
9143             pw.println(" ");
9144             pw.println("  mCurTask: " + mCurTask);
9145 
9146             pw.println(" ");
9147             pw.println("Processes in Current Activity Manager State:");
9148 
9149             boolean needSep = false;
9150             int numPers = 0;
9151 
9152             for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9153                 final int NA = procs.size();
9154                 for (int ia=0; ia<NA; ia++) {
9155                     if (!needSep) {
9156                         pw.println("  All known processes:");
9157                         needSep = true;
9158                     }
9159                     ProcessRecord r = procs.valueAt(ia);
9160                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
9161                         pw.print(" UID "); pw.print(procs.keyAt(ia));
9162                         pw.print(" "); pw.println(r);
9163                     r.dump(pw, "    ");
9164                     if (r.persistent) {
9165                         numPers++;
9166                     }
9167                 }
9168             }
9169 
9170             if (mLRUProcesses.size() > 0) {
9171                 if (needSep) pw.println(" ");
9172                 needSep = true;
9173                 pw.println("  Running processes (most recent first):");
9174                 dumpProcessList(pw, mLRUProcesses, "    ",
9175                         "App ", "PERS", true);
9176                 needSep = true;
9177             }
9178 
9179             synchronized (mPidsSelfLocked) {
9180                 if (mPidsSelfLocked.size() > 0) {
9181                     if (needSep) pw.println(" ");
9182                     needSep = true;
9183                     pw.println("  PID mappings:");
9184                     for (int i=0; i<mPidsSelfLocked.size(); i++) {
9185                         pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9186                             pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9187                     }
9188                 }
9189             }
9190 
9191             if (mForegroundProcesses.size() > 0) {
9192                 if (needSep) pw.println(" ");
9193                 needSep = true;
9194                 pw.println("  Foreground Processes:");
9195                 for (int i=0; i<mForegroundProcesses.size(); i++) {
9196                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9197                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9198                 }
9199             }
9200 
9201             if (mPersistentStartingProcesses.size() > 0) {
9202                 if (needSep) pw.println(" ");
9203                 needSep = true;
9204                 pw.println("  Persisent processes that are starting:");
9205                 dumpProcessList(pw, mPersistentStartingProcesses, "    ",
9206                         "Starting Norm", "Restarting PERS", false);
9207             }
9208 
9209             if (mStartingProcesses.size() > 0) {
9210                 if (needSep) pw.println(" ");
9211                 needSep = true;
9212                 pw.println("  Processes that are starting:");
9213                 dumpProcessList(pw, mStartingProcesses, "    ",
9214                         "Starting Norm", "Starting PERS", false);
9215             }
9216 
9217             if (mRemovedProcesses.size() > 0) {
9218                 if (needSep) pw.println(" ");
9219                 needSep = true;
9220                 pw.println("  Processes that are being removed:");
9221                 dumpProcessList(pw, mRemovedProcesses, "    ",
9222                         "Removed Norm", "Removed PERS", false);
9223             }
9224 
9225             if (mProcessesOnHold.size() > 0) {
9226                 if (needSep) pw.println(" ");
9227                 needSep = true;
9228                 pw.println("  Processes that are on old until the system is ready:");
9229                 dumpProcessList(pw, mProcessesOnHold, "    ",
9230                         "OnHold Norm", "OnHold PERS", false);
9231             }
9232 
9233             if (mProcessesToGc.size() > 0) {
9234                 if (needSep) pw.println(" ");
9235                 needSep = true;
9236                 pw.println("  Processes that are waiting to GC:");
9237                 long now = SystemClock.uptimeMillis();
9238                 for (int i=0; i<mProcessesToGc.size(); i++) {
9239                     ProcessRecord proc = mProcessesToGc.get(i);
9240                     pw.print("    Process "); pw.println(proc);
9241                     pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9242                             pw.print(", last gced=");
9243                             pw.print(now-proc.lastRequestedGc);
9244                             pw.print(" ms ago, last lowMem=");
9245                             pw.print(now-proc.lastLowMemory);
9246                             pw.println(" ms ago");
9247 
9248                 }
9249             }
9250 
9251             if (mProcessCrashTimes.getMap().size() > 0) {
9252                 if (needSep) pw.println(" ");
9253                 needSep = true;
9254                 pw.println("  Time since processes crashed:");
9255                 long now = SystemClock.uptimeMillis();
9256                 for (Map.Entry<String, SparseArray<Long>> procs
9257                         : mProcessCrashTimes.getMap().entrySet()) {
9258                     SparseArray<Long> uids = procs.getValue();
9259                     final int N = uids.size();
9260                     for (int i=0; i<N; i++) {
9261                         pw.print("    Process "); pw.print(procs.getKey());
9262                                 pw.print(" uid "); pw.print(uids.keyAt(i));
9263                                 pw.print(": last crashed ");
9264                                 pw.print((now-uids.valueAt(i)));
9265                                 pw.println(" ms ago");
9266                     }
9267                 }
9268             }
9269 
9270             if (mBadProcesses.getMap().size() > 0) {
9271                 if (needSep) pw.println(" ");
9272                 needSep = true;
9273                 pw.println("  Bad processes:");
9274                 for (Map.Entry<String, SparseArray<Long>> procs
9275                         : mBadProcesses.getMap().entrySet()) {
9276                     SparseArray<Long> uids = procs.getValue();
9277                     final int N = uids.size();
9278                     for (int i=0; i<N; i++) {
9279                         pw.print("    Bad process "); pw.print(procs.getKey());
9280                                 pw.print(" uid "); pw.print(uids.keyAt(i));
9281                                 pw.print(": crashed at time ");
9282                                 pw.println(uids.valueAt(i));
9283                     }
9284                 }
9285             }
9286 
9287             pw.println(" ");
9288             pw.println("  Total persistent processes: " + numPers);
9289             pw.println("  mHomeProcess: " + mHomeProcess);
9290             pw.println("  mConfiguration: " + mConfiguration);
9291             pw.println("  mStartRunning=" + mStartRunning
9292                     + " mSystemReady=" + mSystemReady
9293                     + " mBooting=" + mBooting
9294                     + " mBooted=" + mBooted
9295                     + " mFactoryTest=" + mFactoryTest);
9296             pw.println("  mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
9297             pw.println("  mGoingToSleep=" + mGoingToSleep);
9298             pw.println("  mLaunchingActivity=" + mLaunchingActivity);
9299             pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9300                     + " mDebugTransient=" + mDebugTransient
9301                     + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9302             pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9303                     + " mController=" + mController);
9304         }
9305     }
9306 
9307     /**
9308      * There are three ways to call this:
9309      *  - no service specified: dump all the services
9310      *  - a flattened component name that matched an existing service was specified as the
9311      *    first arg: dump that one service
9312      *  - the first arg isn't the flattened component name of an existing service:
9313      *    dump all services whose component contains the first arg as a substring
9314      */
9315     protected void dumpService(FileDescriptor fd, PrintWriter pw, String[] args) {
9316         String[] newArgs;
9317         String componentNameString;
9318         ServiceRecord r;
9319         if (args.length == 1) {
9320             componentNameString = null;
9321             newArgs = EMPTY_STRING_ARRAY;
9322             r = null;
9323         } else {
9324             componentNameString = args[1];
9325             ComponentName componentName = ComponentName.unflattenFromString(componentNameString);
9326             r = componentName != null ? mServices.get(componentName) : null;
9327             newArgs = new String[args.length - 2];
9328             if (args.length > 2) System.arraycopy(args, 2, newArgs, 0, args.length - 2);
9329         }
9330 
9331         if (r != null) {
9332             dumpService(fd, pw, r, newArgs);
9333         } else {
9334             for (ServiceRecord r1 : mServices.values()) {
9335                 if (componentNameString == null
9336                         || r1.name.flattenToString().contains(componentNameString)) {
9337                     dumpService(fd, pw, r1, newArgs);
9338                 }
9339             }
9340         }
9341     }
9342 
9343     /**
9344      * Invokes IApplicationThread.dumpService() on the thread of the specified service if
9345      * there is a thread associated with the service.
9346      */
9347     private void dumpService(FileDescriptor fd, PrintWriter pw, ServiceRecord r, String[] args) {
9348         pw.println("  Service " + r.name.flattenToString());
9349         if (r.app != null && r.app.thread != null) {
9350             try {
9351                 // flush anything that is already in the PrintWriter since the thread is going
9352                 // to write to the file descriptor directly
9353                 pw.flush();
9354                 r.app.thread.dumpService(fd, r, args);
9355                 pw.print("\n");
9356             } catch (RemoteException e) {
9357                 pw.println("got a RemoteException while dumping the service");
9358             }
9359         }
9360     }
9361 
9362     void dumpBroadcasts(PrintWriter pw) {
9363         synchronized (this) {
9364             if (checkCallingPermission(android.Manifest.permission.DUMP)
9365                     != PackageManager.PERMISSION_GRANTED) {
9366                 pw.println("Permission Denial: can't dump ActivityManager from from pid="
9367                         + Binder.getCallingPid()
9368                         + ", uid=" + Binder.getCallingUid()
9369                         + " without permission "
9370                         + android.Manifest.permission.DUMP);
9371                 return;
9372             }
9373             pw.println("Broadcasts in Current Activity Manager State:");
9374 
9375             if (mRegisteredReceivers.size() > 0) {
9376                 pw.println(" ");
9377                 pw.println("  Registered Receivers:");
9378                 Iterator it = mRegisteredReceivers.values().iterator();
9379                 while (it.hasNext()) {
9380                     ReceiverList r = (ReceiverList)it.next();
9381                     pw.print("  * "); pw.println(r);
9382                     r.dump(pw, "    ");
9383                 }
9384             }
9385 
9386             pw.println(" ");
9387             pw.println("Receiver Resolver Table:");
9388             mReceiverResolver.dump(pw, "  ");
9389 
9390             if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
9391                     || mPendingBroadcast != null) {
9392                 if (mParallelBroadcasts.size() > 0) {
9393                     pw.println(" ");
9394                     pw.println("  Active broadcasts:");
9395                 }
9396                 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
9397                     pw.println("  Broadcast #" + i + ":");
9398                     mParallelBroadcasts.get(i).dump(pw, "    ");
9399                 }
9400                 if (mOrderedBroadcasts.size() > 0) {
9401                     pw.println(" ");
9402                     pw.println("  Active serialized broadcasts:");
9403                 }
9404                 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
9405                     pw.println("  Serialized Broadcast #" + i + ":");
9406                     mOrderedBroadcasts.get(i).dump(pw, "    ");
9407                 }
9408                 pw.println(" ");
9409                 pw.println("  Pending broadcast:");
9410                 if (mPendingBroadcast != null) {
9411                     mPendingBroadcast.dump(pw, "    ");
9412                 } else {
9413                     pw.println("    (null)");
9414                 }
9415             }
9416 
9417             pw.println(" ");
9418             pw.println("  Historical broadcasts:");
9419             for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
9420                 BroadcastRecord r = mBroadcastHistory[i];
9421                 if (r == null) {
9422                     break;
9423                 }
9424                 pw.println("  Historical Broadcast #" + i + ":");
9425                 r.dump(pw, "    ");
9426             }
9427 
9428             pw.println(" ");
9429             pw.println("  mBroadcastsScheduled=" + mBroadcastsScheduled);
9430             if (mStickyBroadcasts != null) {
9431                 pw.println(" ");
9432                 pw.println("  Sticky broadcasts:");
9433                 StringBuilder sb = new StringBuilder(128);
9434                 for (Map.Entry<String, ArrayList<Intent>> ent
9435                         : mStickyBroadcasts.entrySet()) {
9436                     pw.print("  * Sticky action "); pw.print(ent.getKey());
9437                             pw.println(":");
9438                     ArrayList<Intent> intents = ent.getValue();
9439                     final int N = intents.size();
9440                     for (int i=0; i<N; i++) {
9441                         sb.setLength(0);
9442                         sb.append("    Intent: ");
9443                         intents.get(i).toShortString(sb, true, false);
9444                         pw.println(sb.toString());
9445                         Bundle bundle = intents.get(i).getExtras();
9446                         if (bundle != null) {
9447                             pw.print("      ");
9448                             pw.println(bundle.toString());
9449                         }
9450                     }
9451                 }
9452             }
9453 
9454             pw.println(" ");
9455             pw.println("  mHandler:");
9456             mHandler.dump(new PrintWriterPrinter(pw), "    ");
9457         }
9458     }
9459 
9460     void dumpServices(PrintWriter pw) {
9461         synchronized (this) {
9462             if (checkCallingPermission(android.Manifest.permission.DUMP)
9463                     != PackageManager.PERMISSION_GRANTED) {
9464                 pw.println("Permission Denial: can't dump ActivityManager from from pid="
9465                         + Binder.getCallingPid()
9466                         + ", uid=" + Binder.getCallingUid()
9467                         + " without permission "
9468                         + android.Manifest.permission.DUMP);
9469                 return;
9470             }
9471             pw.println("Services in Current Activity Manager State:");
9472 
9473             boolean needSep = false;
9474 
9475             if (mServices.size() > 0) {
9476                 pw.println("  Active services:");
9477                 Iterator<ServiceRecord> it = mServices.values().iterator();
9478                 while (it.hasNext()) {
9479                     ServiceRecord r = it.next();
9480                     pw.print("  * "); pw.println(r);
9481                     r.dump(pw, "    ");
9482                 }
9483                 needSep = true;
9484             }
9485 
9486             if (mPendingServices.size() > 0) {
9487                 if (needSep) pw.println(" ");
9488                 pw.println("  Pending services:");
9489                 for (int i=0; i<mPendingServices.size(); i++) {
9490                     ServiceRecord r = mPendingServices.get(i);
9491                     pw.print("  * Pending "); pw.println(r);
9492                     r.dump(pw, "    ");
9493                 }
9494                 needSep = true;
9495             }
9496 
9497             if (mRestartingServices.size() > 0) {
9498                 if (needSep) pw.println(" ");
9499                 pw.println("  Restarting services:");
9500                 for (int i=0; i<mRestartingServices.size(); i++) {
9501                     ServiceRecord r = mRestartingServices.get(i);
9502                     pw.print("  * Restarting "); pw.println(r);
9503                     r.dump(pw, "    ");
9504                 }
9505                 needSep = true;
9506             }
9507 
9508             if (mStoppingServices.size() > 0) {
9509                 if (needSep) pw.println(" ");
9510                 pw.println("  Stopping services:");
9511                 for (int i=0; i<mStoppingServices.size(); i++) {
9512                     ServiceRecord r = mStoppingServices.get(i);
9513                     pw.print("  * Stopping "); pw.println(r);
9514                     r.dump(pw, "    ");
9515                 }
9516                 needSep = true;
9517             }
9518 
9519             if (mServiceConnections.size() > 0) {
9520                 if (needSep) pw.println(" ");
9521                 pw.println("  Connection bindings to services:");
9522                 Iterator<ConnectionRecord> it
9523                         = mServiceConnections.values().iterator();
9524                 while (it.hasNext()) {
9525                     ConnectionRecord r = it.next();
9526                     pw.print("  * "); pw.println(r);
9527                     r.dump(pw, "    ");
9528                 }
9529             }
9530         }
9531     }
9532 
9533     void dumpProviders(PrintWriter pw) {
9534         synchronized (this) {
9535             if (checkCallingPermission(android.Manifest.permission.DUMP)
9536                     != PackageManager.PERMISSION_GRANTED) {
9537                 pw.println("Permission Denial: can't dump ActivityManager from from pid="
9538                         + Binder.getCallingPid()
9539                         + ", uid=" + Binder.getCallingUid()
9540                         + " without permission "
9541                         + android.Manifest.permission.DUMP);
9542                 return;
9543             }
9544 
9545             pw.println("Content Providers in Current Activity Manager State:");
9546 
9547             boolean needSep = false;
9548 
9549             if (mProvidersByClass.size() > 0) {
9550                 if (needSep) pw.println(" ");
9551                 pw.println("  Published content providers (by class):");
9552                 Iterator it = mProvidersByClass.entrySet().iterator();
9553                 while (it.hasNext()) {
9554                     Map.Entry e = (Map.Entry)it.next();
9555                     ContentProviderRecord r = (ContentProviderRecord)e.getValue();
9556                     pw.print("  * "); pw.println(r);
9557                     r.dump(pw, "    ");
9558                 }
9559                 needSep = true;
9560             }
9561 
9562             if (mProvidersByName.size() > 0) {
9563                 pw.println(" ");
9564                 pw.println("  Authority to provider mappings:");
9565                 Iterator it = mProvidersByName.entrySet().iterator();
9566                 while (it.hasNext()) {
9567                     Map.Entry e = (Map.Entry)it.next();
9568                     ContentProviderRecord r = (ContentProviderRecord)e.getValue();
9569                     pw.print("  "); pw.print(e.getKey()); pw.print(": ");
9570                             pw.println(r);
9571                 }
9572                 needSep = true;
9573             }
9574 
9575             if (mLaunchingProviders.size() > 0) {
9576                 if (needSep) pw.println(" ");
9577                 pw.println("  Launching content providers:");
9578                 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9579                     pw.print("  Launching #"); pw.print(i); pw.print(": ");
9580                             pw.println(mLaunchingProviders.get(i));
9581                 }
9582                 needSep = true;
9583             }
9584 
9585             if (mGrantedUriPermissions.size() > 0) {
9586                 pw.println();
9587                 pw.println("Granted Uri Permissions:");
9588                 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9589                     int uid = mGrantedUriPermissions.keyAt(i);
9590                     HashMap<Uri, UriPermission> perms
9591                             = mGrantedUriPermissions.valueAt(i);
9592                     pw.print("  * UID "); pw.print(uid);
9593                             pw.println(" holds:");
9594                     for (UriPermission perm : perms.values()) {
9595                         pw.print("    "); pw.println(perm);
9596                         perm.dump(pw, "      ");
9597                     }
9598                 }
9599             }
9600         }
9601     }
9602 
9603     void dumpSenders(PrintWriter pw) {
9604         synchronized (this) {
9605             if (checkCallingPermission(android.Manifest.permission.DUMP)
9606                     != PackageManager.PERMISSION_GRANTED) {
9607                 pw.println("Permission Denial: can't dump ActivityManager from from pid="
9608                         + Binder.getCallingPid()
9609                         + ", uid=" + Binder.getCallingUid()
9610                         + " without permission "
9611                         + android.Manifest.permission.DUMP);
9612                 return;
9613             }
9614 
9615             pw.println("Pending Intents in Current Activity Manager State:");
9616 
9617             if (this.mIntentSenderRecords.size() > 0) {
9618                 Iterator<WeakReference<PendingIntentRecord>> it
9619                         = mIntentSenderRecords.values().iterator();
9620                 while (it.hasNext()) {
9621                     WeakReference<PendingIntentRecord> ref = it.next();
9622                     PendingIntentRecord rec = ref != null ? ref.get(): null;
9623                     if (rec != null) {
9624                         pw.print("  * "); pw.println(rec);
9625                         rec.dump(pw, "    ");
9626                     } else {
9627                         pw.print("  * "); pw.print(ref);
9628                     }
9629                 }
9630             }
9631         }
9632     }
9633 
9634     private static final void dumpHistoryList(PrintWriter pw, List list,
9635             String prefix, String label, boolean complete) {
9636         TaskRecord lastTask = null;
9637         for (int i=list.size()-1; i>=0; i--) {
9638             HistoryRecord r = (HistoryRecord)list.get(i);
9639             final boolean full = complete || !r.inHistory;
9640             if (lastTask != r.task) {
9641                 lastTask = r.task;
9642                 pw.print(prefix);
9643                 pw.print(full ? "* " : "  ");
9644                 pw.println(lastTask);
9645                 if (full) {
9646                     lastTask.dump(pw, prefix + "  ");
9647                 }
9648             }
9649             pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9650             pw.print(" #"); pw.print(i); pw.print(": ");
9651             pw.println(r);
9652             if (full) {
9653                 r.dump(pw, prefix + "      ");
9654             }
9655         }
9656     }
9657 
9658     private static final int dumpProcessList(PrintWriter pw, List list,
9659             String prefix, String normalLabel, String persistentLabel,
9660             boolean inclOomAdj) {
9661         int numPers = 0;
9662         for (int i=list.size()-1; i>=0; i--) {
9663             ProcessRecord r = (ProcessRecord)list.get(i);
9664             if (false) {
9665                 pw.println(prefix + (r.persistent ? persistentLabel : normalLabel)
9666                       + " #" + i + ":");
9667                 r.dump(pw, prefix + "  ");
9668             } else if (inclOomAdj) {
9669                 pw.println(String.format("%s%s #%2d: adj=%4d/%d %s (%s)",
9670                         prefix, (r.persistent ? persistentLabel : normalLabel),
9671                         i, r.setAdj, r.setSchedGroup, r.toString(), r.adjType));
9672                 if (r.adjSource != null || r.adjTarget != null) {
9673                     pw.println(prefix + "          " + r.adjTarget
9674                             + " used by " + r.adjSource);
9675                 }
9676             } else {
9677                 pw.println(String.format("%s%s #%2d: %s",
9678                         prefix, (r.persistent ? persistentLabel : normalLabel),
9679                         i, r.toString()));
9680             }
9681             if (r.persistent) {
9682                 numPers++;
9683             }
9684         }
9685         return numPers;
9686     }
9687 
9688     private static final void dumpApplicationMemoryUsage(FileDescriptor fd,
9689             PrintWriter pw, List list, String prefix, String[] args) {
9690         final boolean isCheckinRequest = scanArgs(args, "--checkin");
9691         long uptime = SystemClock.uptimeMillis();
9692         long realtime = SystemClock.elapsedRealtime();
9693 
9694         if (isCheckinRequest) {
9695             // short checkin version
9696             pw.println(uptime + "," + realtime);
9697             pw.flush();
9698         } else {
9699             pw.println("Applications Memory Usage (kB):");
9700             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9701         }
9702         for (int i = list.size() - 1 ; i >= 0 ; i--) {
9703             ProcessRecord r = (ProcessRecord)list.get(i);
9704             if (r.thread != null) {
9705                 if (!isCheckinRequest) {
9706                     pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9707                     pw.flush();
9708                 }
9709                 try {
9710                     r.thread.asBinder().dump(fd, args);
9711                 } catch (RemoteException e) {
9712                     if (!isCheckinRequest) {
9713                         pw.println("Got RemoteException!");
9714                         pw.flush();
9715                     }
9716                 }
9717             }
9718         }
9719     }
9720 
9721     /**
9722      * Searches array of arguments for the specified string
9723      * @param args array of argument strings
9724      * @param value value to search for
9725      * @return true if the value is contained in the array
9726      */
9727     private static boolean scanArgs(String[] args, String value) {
9728         if (args != null) {
9729             for (String arg : args) {
9730                 if (value.equals(arg)) {
9731                     return true;
9732                 }
9733             }
9734         }
9735         return false;
9736     }
9737 
9738     private final int indexOfTokenLocked(IBinder token) {
9739         int count = mHistory.size();
9740 
9741         // convert the token to an entry in the history.
9742         HistoryRecord r = null;
9743         int index = -1;
9744         for (int i=count-1; i>=0; i--) {
9745             Object o = mHistory.get(i);
9746             if (o == token) {
9747                 r = (HistoryRecord)o;
9748                 index = i;
9749                 break;
9750             }
9751         }
9752 
9753         return index;
9754     }
9755 
9756     private final void killServicesLocked(ProcessRecord app,
9757             boolean allowRestart) {
9758         // Report disconnected services.
9759         if (false) {
9760             // XXX we are letting the client link to the service for
9761             // death notifications.
9762             if (app.services.size() > 0) {
9763                 Iterator it = app.services.iterator();
9764                 while (it.hasNext()) {
9765                     ServiceRecord r = (ServiceRecord)it.next();
9766                     if (r.connections.size() > 0) {
9767                         Iterator<ConnectionRecord> jt
9768                                 = r.connections.values().iterator();
9769                         while (jt.hasNext()) {
9770                             ConnectionRecord c = jt.next();
9771                             if (c.binding.client != app) {
9772                                 try {
9773                                     //c.conn.connected(r.className, null);
9774                                 } catch (Exception e) {
9775                                     // todo: this should be asynchronous!
9776                                     Log.w(TAG, "Exception thrown disconnected servce "
9777                                           + r.shortName
9778                                           + " from app " + app.processName, e);
9779                                 }
9780                             }
9781                         }
9782                     }
9783                 }
9784             }
9785         }
9786 
9787         // Clean up any connections this application has to other services.
9788         if (app.connections.size() > 0) {
9789             Iterator<ConnectionRecord> it = app.connections.iterator();
9790             while (it.hasNext()) {
9791                 ConnectionRecord r = it.next();
9792                 removeConnectionLocked(r, app, null);
9793             }
9794         }
9795         app.connections.clear();
9796 
9797         if (app.services.size() != 0) {
9798             // Any services running in the application need to be placed
9799             // back in the pending list.
9800             Iterator it = app.services.iterator();
9801             while (it.hasNext()) {
9802                 ServiceRecord sr = (ServiceRecord)it.next();
9803                 synchronized (sr.stats.getBatteryStats()) {
9804                     sr.stats.stopLaunchedLocked();
9805                 }
9806                 sr.app = null;
9807                 sr.executeNesting = 0;
9808                 mStoppingServices.remove(sr);
9809 
9810                 boolean hasClients = sr.bindings.size() > 0;
9811                 if (hasClients) {
9812                     Iterator<IntentBindRecord> bindings
9813                             = sr.bindings.values().iterator();
9814                     while (bindings.hasNext()) {
9815                         IntentBindRecord b = bindings.next();
9816                         if (DEBUG_SERVICE) Log.v(TAG, "Killing binding " + b
9817                                 + ": shouldUnbind=" + b.hasBound);
9818                         b.binder = null;
9819                         b.requested = b.received = b.hasBound = false;
9820                     }
9821                 }
9822 
9823                 if (sr.crashCount >= 2) {
9824                     Log.w(TAG, "Service crashed " + sr.crashCount
9825                             + " times, stopping: " + sr);
9826                     EventLog.writeEvent(LOG_AM_SERVICE_CRASHED_TOO_MUCH,
9827                             sr.crashCount, sr.shortName, app.pid);
9828                     bringDownServiceLocked(sr, true);
9829                 } else if (!allowRestart) {
9830                     bringDownServiceLocked(sr, true);
9831                 } else {
9832                     boolean canceled = scheduleServiceRestartLocked(sr, true);
9833 
9834                     // Should the service remain running?  Note that in the
9835                     // extreme case of so many attempts to deliver a command
9836                     // that it failed, that we also will stop it here.
9837                     if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9838                         if (sr.pendingStarts.size() == 0) {
9839                             sr.startRequested = false;
9840                             if (!hasClients) {
9841                                 // Whoops, no reason to restart!
9842                                 bringDownServiceLocked(sr, true);
9843                             }
9844                         }
9845                     }
9846                 }
9847             }
9848 
9849             if (!allowRestart) {
9850                 app.services.clear();
9851             }
9852         }
9853 
9854         // Make sure we have no more records on the stopping list.
9855         int i = mStoppingServices.size();
9856         while (i > 0) {
9857             i--;
9858             ServiceRecord sr = mStoppingServices.get(i);
9859             if (sr.app == app) {
9860                 mStoppingServices.remove(i);
9861             }
9862         }
9863 
9864         app.executingServices.clear();
9865     }
9866 
9867     private final void removeDyingProviderLocked(ProcessRecord proc,
9868             ContentProviderRecord cpr) {
9869         synchronized (cpr) {
9870             cpr.launchingApp = null;
9871             cpr.notifyAll();
9872         }
9873 
9874         mProvidersByClass.remove(cpr.info.name);
9875         String names[] = cpr.info.authority.split(";");
9876         for (int j = 0; j < names.length; j++) {
9877             mProvidersByName.remove(names[j]);
9878         }
9879 
9880         Iterator<ProcessRecord> cit = cpr.clients.iterator();
9881         while (cit.hasNext()) {
9882             ProcessRecord capp = cit.next();
9883             if (!capp.persistent && capp.thread != null
9884                     && capp.pid != 0
9885                     && capp.pid != MY_PID) {
9886                 Log.i(TAG, "Killing app " + capp.processName
9887                         + " (pid " + capp.pid
9888                         + ") because provider " + cpr.info.name
9889                         + " is in dying process " + proc.processName);
9890                 Process.killProcess(capp.pid);
9891             }
9892         }
9893 
9894         mLaunchingProviders.remove(cpr);
9895     }
9896 
9897     /**
9898      * Main code for cleaning up a process when it has gone away.  This is
9899      * called both as a result of the process dying, or directly when stopping
9900      * a process when running in single process mode.
9901      */
9902     private final void cleanUpApplicationRecordLocked(ProcessRecord app,
9903             boolean restarting, int index) {
9904         if (index >= 0) {
9905             mLRUProcesses.remove(index);
9906         }
9907 
9908         mProcessesToGc.remove(app);
9909 
9910         // Dismiss any open dialogs.
9911         if (app.crashDialog != null) {
9912             app.crashDialog.dismiss();
9913             app.crashDialog = null;
9914         }
9915         if (app.anrDialog != null) {
9916             app.anrDialog.dismiss();
9917             app.anrDialog = null;
9918         }
9919         if (app.waitDialog != null) {
9920             app.waitDialog.dismiss();
9921             app.waitDialog = null;
9922         }
9923 
9924         app.crashing = false;
9925         app.notResponding = false;
9926 
9927         app.resetPackageList();
9928         app.thread = null;
9929         app.forcingToForeground = null;
9930         app.foregroundServices = false;
9931 
9932         killServicesLocked(app, true);
9933 
9934         boolean restart = false;
9935 
9936         int NL = mLaunchingProviders.size();
9937 
9938         // Remove published content providers.
9939         if (!app.pubProviders.isEmpty()) {
9940             Iterator it = app.pubProviders.values().iterator();
9941             while (it.hasNext()) {
9942                 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9943                 cpr.provider = null;
9944                 cpr.app = null;
9945 
9946                 // See if someone is waiting for this provider...  in which
9947                 // case we don't remove it, but just let it restart.
9948                 int i = 0;
9949                 if (!app.bad) {
9950                     for (; i<NL; i++) {
9951                         if (mLaunchingProviders.get(i) == cpr) {
9952                             restart = true;
9953                             break;
9954                         }
9955                     }
9956                 } else {
9957                     i = NL;
9958                 }
9959 
9960                 if (i >= NL) {
9961                     removeDyingProviderLocked(app, cpr);
9962                     NL = mLaunchingProviders.size();
9963                 }
9964             }
9965             app.pubProviders.clear();
9966         }
9967 
9968         // Take care of any launching providers waiting for this process.
9969         if (checkAppInLaunchingProvidersLocked(app, false)) {
9970             restart = true;
9971         }
9972 
9973         // Unregister from connected content providers.
9974         if (!app.conProviders.isEmpty()) {
9975             Iterator it = app.conProviders.keySet().iterator();
9976             while (it.hasNext()) {
9977                 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9978                 cpr.clients.remove(app);
9979             }
9980             app.conProviders.clear();
9981         }
9982 
9983         // At this point there may be remaining entries in mLaunchingProviders
9984         // where we were the only one waiting, so they are no longer of use.
9985         // Look for these and clean up if found.
9986         // XXX Commented out for now.  Trying to figure out a way to reproduce
9987         // the actual situation to identify what is actually going on.
9988         if (false) {
9989             for (int i=0; i<NL; i++) {
9990                 ContentProviderRecord cpr = (ContentProviderRecord)
9991                         mLaunchingProviders.get(i);
9992                 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9993                     synchronized (cpr) {
9994                         cpr.launchingApp = null;
9995                         cpr.notifyAll();
9996                     }
9997                 }
9998             }
9999         }
10000 
10001         skipCurrentReceiverLocked(app);
10002 
10003         // Unregister any receivers.
10004         if (app.receivers.size() > 0) {
10005             Iterator<ReceiverList> it = app.receivers.iterator();
10006             while (it.hasNext()) {
10007                 removeReceiverLocked(it.next());
10008             }
10009             app.receivers.clear();
10010         }
10011 
10012         // If the app is undergoing backup, tell the backup manager about it
10013         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10014             if (DEBUG_BACKUP) Log.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10015             try {
10016                 IBackupManager bm = IBackupManager.Stub.asInterface(
10017                         ServiceManager.getService(Context.BACKUP_SERVICE));
10018                 bm.agentDisconnected(app.info.packageName);
10019             } catch (RemoteException e) {
10020                 // can't happen; backup manager is local
10021             }
10022         }
10023 
10024         // If the caller is restarting this app, then leave it in its
10025         // current lists and let the caller take care of it.
10026         if (restarting) {
10027             return;
10028         }
10029 
10030         if (!app.persistent) {
10031             if (DEBUG_PROCESSES) Log.v(TAG,
10032                     "Removing non-persistent process during cleanup: " + app);
10033             mProcessNames.remove(app.processName, app.info.uid);
10034         } else if (!app.removed) {
10035             // This app is persistent, so we need to keep its record around.
10036             // If it is not already on the pending app list, add it there
10037             // and start a new process for it.
10038             app.thread = null;
10039             app.forcingToForeground = null;
10040             app.foregroundServices = false;
10041             if (mPersistentStartingProcesses.indexOf(app) < 0) {
10042                 mPersistentStartingProcesses.add(app);
10043                 restart = true;
10044             }
10045         }
10046         mProcessesOnHold.remove(app);
10047 
10048         if (app == mHomeProcess) {
10049             mHomeProcess = null;
10050         }
10051 
10052         if (restart) {
10053             // We have components that still need to be running in the
10054             // process, so re-launch it.
10055             mProcessNames.put(app.processName, app.info.uid, app);
10056             startProcessLocked(app, "restart", app.processName);
10057         } else if (app.pid > 0 && app.pid != MY_PID) {
10058             // Goodbye!
10059             synchronized (mPidsSelfLocked) {
10060                 mPidsSelfLocked.remove(app.pid);
10061                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10062             }
10063             app.setPid(0);
10064         }
10065     }
10066 
10067     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10068         // Look through the content providers we are waiting to have launched,
10069         // and if any run in this process then either schedule a restart of
10070         // the process or kill the client waiting for it if this process has
10071         // gone bad.
10072         int NL = mLaunchingProviders.size();
10073         boolean restart = false;
10074         for (int i=0; i<NL; i++) {
10075             ContentProviderRecord cpr = (ContentProviderRecord)
10076                     mLaunchingProviders.get(i);
10077             if (cpr.launchingApp == app) {
10078                 if (!alwaysBad && !app.bad) {
10079                     restart = true;
10080                 } else {
10081                     removeDyingProviderLocked(app, cpr);
10082                     NL = mLaunchingProviders.size();
10083                 }
10084             }
10085         }
10086         return restart;
10087     }
10088 
10089     // =========================================================
10090     // SERVICES
10091     // =========================================================
10092 
10093     ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
10094         ActivityManager.RunningServiceInfo info =
10095             new ActivityManager.RunningServiceInfo();
10096         info.service = r.name;
10097         if (r.app != null) {
10098             info.pid = r.app.pid;
10099         }
10100         info.uid = r.appInfo.uid;
10101         info.process = r.processName;
10102         info.foreground = r.isForeground;
10103         info.activeSince = r.createTime;
10104         info.started = r.startRequested;
10105         info.clientCount = r.connections.size();
10106         info.crashCount = r.crashCount;
10107         info.lastActivityTime = r.lastActivity;
10108         if (r.isForeground) {
10109             info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
10110         }
10111         if (r.startRequested) {
10112             info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
10113         }
10114         if (r.app != null && r.app.pid == Process.myPid()) {
10115             info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
10116         }
10117         if (r.app != null && r.app.persistent) {
10118             info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
10119         }
10120         for (ConnectionRecord conn : r.connections.values()) {
10121             if (conn.clientLabel != 0) {
10122                 info.clientPackage = conn.binding.client.info.packageName;
10123                 info.clientLabel = conn.clientLabel;
10124                 break;
10125             }
10126         }
10127         return info;
10128     }
10129 
10130     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10131             int flags) {
10132         synchronized (this) {
10133             ArrayList<ActivityManager.RunningServiceInfo> res
10134                     = new ArrayList<ActivityManager.RunningServiceInfo>();
10135 
10136             if (mServices.size() > 0) {
10137                 Iterator<ServiceRecord> it = mServices.values().iterator();
10138                 while (it.hasNext() && res.size() < maxNum) {
10139                     res.add(makeRunningServiceInfoLocked(it.next()));
10140                 }
10141             }
10142 
10143             for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
10144                 ServiceRecord r = mRestartingServices.get(i);
10145                 ActivityManager.RunningServiceInfo info =
10146                         makeRunningServiceInfoLocked(r);
10147                 info.restarting = r.nextRestartTime;
10148                 res.add(info);
10149             }
10150 
10151             return res;
10152         }
10153     }
10154 
10155     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10156         synchronized (this) {
10157             ServiceRecord r = mServices.get(name);
10158             if (r != null) {
10159                 for (ConnectionRecord conn : r.connections.values()) {
10160                     if (conn.clientIntent != null) {
10161                         return conn.clientIntent;
10162                     }
10163                 }
10164             }
10165         }
10166         return null;
10167     }
10168 
10169     private final ServiceRecord findServiceLocked(ComponentName name,
10170             IBinder token) {
10171         ServiceRecord r = mServices.get(name);
10172         return r == token ? r : null;
10173     }
10174 
10175     private final class ServiceLookupResult {
10176         final ServiceRecord record;
10177         final String permission;
10178 
10179         ServiceLookupResult(ServiceRecord _record, String _permission) {
10180             record = _record;
10181             permission = _permission;
10182         }
10183     };
10184 
findServiceLocked(Intent service, String resolvedType)10185     private ServiceLookupResult findServiceLocked(Intent service,
10186             String resolvedType) {
10187         ServiceRecord r = null;
10188         if (service.getComponent() != null) {
10189             r = mServices.get(service.getComponent());
10190         }
10191         if (r == null) {
10192             Intent.FilterComparison filter = new Intent.FilterComparison(service);
10193             r = mServicesByIntent.get(filter);
10194         }
10195 
10196         if (r == null) {
10197             try {
10198                 ResolveInfo rInfo =
10199                     ActivityThread.getPackageManager().resolveService(
10200                             service, resolvedType, 0);
10201                 ServiceInfo sInfo =
10202                     rInfo != null ? rInfo.serviceInfo : null;
10203                 if (sInfo == null) {
10204                     return null;
10205                 }
10206 
10207                 ComponentName name = new ComponentName(
10208                         sInfo.applicationInfo.packageName, sInfo.name);
10209                 r = mServices.get(name);
10210             } catch (RemoteException ex) {
10211                 // pm is in same process, this will never happen.
10212             }
10213         }
10214         if (r != null) {
10215             int callingPid = Binder.getCallingPid();
10216             int callingUid = Binder.getCallingUid();
10217             if (checkComponentPermission(r.permission,
10218                     callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
10219                     != PackageManager.PERMISSION_GRANTED) {
10220                 Log.w(TAG, "Permission Denial: Accessing service " + r.name
10221                         + " from pid=" + callingPid
10222                         + ", uid=" + callingUid
10223                         + " requires " + r.permission);
10224                 return new ServiceLookupResult(null, r.permission);
10225             }
10226             return new ServiceLookupResult(r, null);
10227         }
10228         return null;
10229     }
10230 
10231     private class ServiceRestarter implements Runnable {
10232         private ServiceRecord mService;
10233 
setService(ServiceRecord service)10234         void setService(ServiceRecord service) {
10235             mService = service;
10236         }
10237 
run()10238         public void run() {
10239             synchronized(ActivityManagerService.this) {
10240                 performServiceRestartLocked(mService);
10241             }
10242         }
10243     }
10244 
retrieveServiceLocked(Intent service, String resolvedType, int callingPid, int callingUid)10245     private ServiceLookupResult retrieveServiceLocked(Intent service,
10246             String resolvedType, int callingPid, int callingUid) {
10247         ServiceRecord r = null;
10248         if (service.getComponent() != null) {
10249             r = mServices.get(service.getComponent());
10250         }
10251         Intent.FilterComparison filter = new Intent.FilterComparison(service);
10252         r = mServicesByIntent.get(filter);
10253         if (r == null) {
10254             try {
10255                 ResolveInfo rInfo =
10256                     ActivityThread.getPackageManager().resolveService(
10257                             service, resolvedType, STOCK_PM_FLAGS);
10258                 ServiceInfo sInfo =
10259                     rInfo != null ? rInfo.serviceInfo : null;
10260                 if (sInfo == null) {
10261                     Log.w(TAG, "Unable to start service " + service +
10262                           ": not found");
10263                     return null;
10264                 }
10265 
10266                 ComponentName name = new ComponentName(
10267                         sInfo.applicationInfo.packageName, sInfo.name);
10268                 r = mServices.get(name);
10269                 if (r == null) {
10270                     filter = new Intent.FilterComparison(service.cloneFilter());
10271                     ServiceRestarter res = new ServiceRestarter();
10272                     BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10273                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10274                     synchronized (stats) {
10275                         ss = stats.getServiceStatsLocked(
10276                                 sInfo.applicationInfo.uid, sInfo.packageName,
10277                                 sInfo.name);
10278                     }
10279                     r = new ServiceRecord(ss, name, filter, sInfo, res);
10280                     res.setService(r);
10281                     mServices.put(name, r);
10282                     mServicesByIntent.put(filter, r);
10283 
10284                     // Make sure this component isn't in the pending list.
10285                     int N = mPendingServices.size();
10286                     for (int i=0; i<N; i++) {
10287                         ServiceRecord pr = mPendingServices.get(i);
10288                         if (pr.name.equals(name)) {
10289                             mPendingServices.remove(i);
10290                             i--;
10291                             N--;
10292                         }
10293                     }
10294                 }
10295             } catch (RemoteException ex) {
10296                 // pm is in same process, this will never happen.
10297             }
10298         }
10299         if (r != null) {
10300             if (checkComponentPermission(r.permission,
10301                     callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
10302                     != PackageManager.PERMISSION_GRANTED) {
10303                 Log.w(TAG, "Permission Denial: Accessing service " + r.name
10304                         + " from pid=" + Binder.getCallingPid()
10305                         + ", uid=" + Binder.getCallingUid()
10306                         + " requires " + r.permission);
10307                 return new ServiceLookupResult(null, r.permission);
10308             }
10309             return new ServiceLookupResult(r, null);
10310         }
10311         return null;
10312     }
10313 
bumpServiceExecutingLocked(ServiceRecord r)10314     private final void bumpServiceExecutingLocked(ServiceRecord r) {
10315         long now = SystemClock.uptimeMillis();
10316         if (r.executeNesting == 0 && r.app != null) {
10317             if (r.app.executingServices.size() == 0) {
10318                 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10319                 msg.obj = r.app;
10320                 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
10321             }
10322             r.app.executingServices.add(r);
10323         }
10324         r.executeNesting++;
10325         r.executingStart = now;
10326     }
10327 
sendServiceArgsLocked(ServiceRecord r, boolean oomAdjusted)10328     private final void sendServiceArgsLocked(ServiceRecord r,
10329             boolean oomAdjusted) {
10330         final int N = r.pendingStarts.size();
10331         if (N == 0) {
10332             return;
10333         }
10334 
10335         int i = 0;
10336         while (i < N) {
10337             try {
10338                 ServiceRecord.StartItem si = r.pendingStarts.get(i);
10339                 if (DEBUG_SERVICE) Log.v(TAG, "Sending arguments to service: "
10340                         + r.name + " " + r.intent + " args=" + si.intent);
10341                 if (si.intent == null && N > 1) {
10342                     // If somehow we got a dummy start at the front, then
10343                     // just drop it here.
10344                     i++;
10345                     continue;
10346                 }
10347                 bumpServiceExecutingLocked(r);
10348                 if (!oomAdjusted) {
10349                     oomAdjusted = true;
10350                     updateOomAdjLocked(r.app);
10351                 }
10352                 int flags = 0;
10353                 if (si.deliveryCount > 0) {
10354                     flags |= Service.START_FLAG_RETRY;
10355                 }
10356                 if (si.doneExecutingCount > 0) {
10357                     flags |= Service.START_FLAG_REDELIVERY;
10358                 }
10359                 r.app.thread.scheduleServiceArgs(r, si.id, flags, si.intent);
10360                 si.deliveredTime = SystemClock.uptimeMillis();
10361                 r.deliveredStarts.add(si);
10362                 si.deliveryCount++;
10363                 i++;
10364             } catch (RemoteException e) {
10365                 // Remote process gone...  we'll let the normal cleanup take
10366                 // care of this.
10367                 break;
10368             } catch (Exception e) {
10369                 Log.w(TAG, "Unexpected exception", e);
10370                 break;
10371             }
10372         }
10373         if (i == N) {
10374             r.pendingStarts.clear();
10375         } else {
10376             while (i > 0) {
10377                 i--;
10378                 r.pendingStarts.remove(i);
10379             }
10380         }
10381     }
10382 
requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i, boolean rebind)10383     private final boolean requestServiceBindingLocked(ServiceRecord r,
10384             IntentBindRecord i, boolean rebind) {
10385         if (r.app == null || r.app.thread == null) {
10386             // If service is not currently running, can't yet bind.
10387             return false;
10388         }
10389         if ((!i.requested || rebind) && i.apps.size() > 0) {
10390             try {
10391                 bumpServiceExecutingLocked(r);
10392                 if (DEBUG_SERVICE) Log.v(TAG, "Connecting binding " + i
10393                         + ": shouldUnbind=" + i.hasBound);
10394                 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
10395                 if (!rebind) {
10396                     i.requested = true;
10397                 }
10398                 i.hasBound = true;
10399                 i.doRebind = false;
10400             } catch (RemoteException e) {
10401                 return false;
10402             }
10403         }
10404         return true;
10405     }
10406 
requestServiceBindingsLocked(ServiceRecord r)10407     private final void requestServiceBindingsLocked(ServiceRecord r) {
10408         Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
10409         while (bindings.hasNext()) {
10410             IntentBindRecord i = bindings.next();
10411             if (!requestServiceBindingLocked(r, i, false)) {
10412                 break;
10413             }
10414         }
10415     }
10416 
realStartServiceLocked(ServiceRecord r, ProcessRecord app)10417     private final void realStartServiceLocked(ServiceRecord r,
10418             ProcessRecord app) throws RemoteException {
10419         if (app.thread == null) {
10420             throw new RemoteException();
10421         }
10422 
10423         r.app = app;
10424         r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
10425 
10426         app.services.add(r);
10427         bumpServiceExecutingLocked(r);
10428         updateLRUListLocked(app, true);
10429 
10430         boolean created = false;
10431         try {
10432             if (DEBUG_SERVICE) Log.v(TAG, "Scheduling start service: "
10433                     + r.name + " " + r.intent);
10434             mStringBuilder.setLength(0);
10435             r.intent.getIntent().toShortString(mStringBuilder, false, true);
10436             EventLog.writeEvent(LOG_AM_CREATE_SERVICE,
10437                     System.identityHashCode(r), r.shortName,
10438                     mStringBuilder.toString(), r.app.pid);
10439             synchronized (r.stats.getBatteryStats()) {
10440                 r.stats.startLaunchedLocked();
10441             }
10442             ensurePackageDexOpt(r.serviceInfo.packageName);
10443             app.thread.scheduleCreateService(r, r.serviceInfo);
10444             r.postNotification();
10445             created = true;
10446         } finally {
10447             if (!created) {
10448                 app.services.remove(r);
10449                 scheduleServiceRestartLocked(r, false);
10450             }
10451         }
10452 
10453         requestServiceBindingsLocked(r);
10454 
10455         // If the service is in the started state, and there are no
10456         // pending arguments, then fake up one so its onStartCommand() will
10457         // be called.
10458         if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
10459             r.lastStartId++;
10460             if (r.lastStartId < 1) {
10461                 r.lastStartId = 1;
10462             }
10463             r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, null));
10464         }
10465 
10466         sendServiceArgsLocked(r, true);
10467     }
10468 
scheduleServiceRestartLocked(ServiceRecord r, boolean allowCancel)10469     private final boolean scheduleServiceRestartLocked(ServiceRecord r,
10470             boolean allowCancel) {
10471         boolean canceled = false;
10472 
10473         final long now = SystemClock.uptimeMillis();
10474         long minDuration = SERVICE_RESTART_DURATION;
10475         long resetTime = SERVICE_RESET_RUN_DURATION;
10476 
10477         // Any delivered but not yet finished starts should be put back
10478         // on the pending list.
10479         final int N = r.deliveredStarts.size();
10480         if (N > 0) {
10481             for (int i=N-1; i>=0; i--) {
10482                 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
10483                 if (si.intent == null) {
10484                     // We'll generate this again if needed.
10485                 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
10486                         && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
10487                     r.pendingStarts.add(0, si);
10488                     long dur = SystemClock.uptimeMillis() - si.deliveredTime;
10489                     dur *= 2;
10490                     if (minDuration < dur) minDuration = dur;
10491                     if (resetTime < dur) resetTime = dur;
10492                 } else {
10493                     Log.w(TAG, "Canceling start item " + si.intent + " in service "
10494                             + r.name);
10495                     canceled = true;
10496                 }
10497             }
10498             r.deliveredStarts.clear();
10499         }
10500 
10501         r.totalRestartCount++;
10502         if (r.restartDelay == 0) {
10503             r.restartCount++;
10504             r.restartDelay = minDuration;
10505         } else {
10506             // If it has been a "reasonably long time" since the service
10507             // was started, then reset our restart duration back to
10508             // the beginning, so we don't infinitely increase the duration
10509             // on a service that just occasionally gets killed (which is
10510             // a normal case, due to process being killed to reclaim memory).
10511             if (now > (r.restartTime+resetTime)) {
10512                 r.restartCount = 1;
10513                 r.restartDelay = minDuration;
10514             } else {
10515                 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
10516                 if (r.restartDelay < minDuration) {
10517                     r.restartDelay = minDuration;
10518                 }
10519             }
10520         }
10521 
10522         r.nextRestartTime = now + r.restartDelay;
10523 
10524         // Make sure that we don't end up restarting a bunch of services
10525         // all at the same time.
10526         boolean repeat;
10527         do {
10528             repeat = false;
10529             for (int i=mRestartingServices.size()-1; i>=0; i--) {
10530                 ServiceRecord r2 = mRestartingServices.get(i);
10531                 if (r2 != r && r.nextRestartTime
10532                         >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
10533                         && r.nextRestartTime
10534                         < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
10535                     r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
10536                     r.restartDelay = r.nextRestartTime - now;
10537                     repeat = true;
10538                     break;
10539                 }
10540             }
10541         } while (repeat);
10542 
10543         if (!mRestartingServices.contains(r)) {
10544             mRestartingServices.add(r);
10545         }
10546 
10547         r.cancelNotification();
10548 
10549         mHandler.removeCallbacks(r.restarter);
10550         mHandler.postAtTime(r.restarter, r.nextRestartTime);
10551         r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
10552         Log.w(TAG, "Scheduling restart of crashed service "
10553                 + r.shortName + " in " + r.restartDelay + "ms");
10554         EventLog.writeEvent(LOG_AM_SCHEDULE_SERVICE_RESTART,
10555                 r.shortName, r.restartDelay);
10556 
10557         Message msg = Message.obtain();
10558         msg.what = SERVICE_ERROR_MSG;
10559         msg.obj = r;
10560         mHandler.sendMessage(msg);
10561 
10562         return canceled;
10563     }
10564 
performServiceRestartLocked(ServiceRecord r)10565     final void performServiceRestartLocked(ServiceRecord r) {
10566         if (!mRestartingServices.contains(r)) {
10567             return;
10568         }
10569         bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
10570     }
10571 
unscheduleServiceRestartLocked(ServiceRecord r)10572     private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
10573         if (r.restartDelay == 0) {
10574             return false;
10575         }
10576         r.resetRestartCounter();
10577         mRestartingServices.remove(r);
10578         mHandler.removeCallbacks(r.restarter);
10579         return true;
10580     }
10581 
bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean whileRestarting)10582     private final boolean bringUpServiceLocked(ServiceRecord r,
10583             int intentFlags, boolean whileRestarting) {
10584         //Log.i(TAG, "Bring up service:");
10585         //r.dump("  ");
10586 
10587         if (r.app != null && r.app.thread != null) {
10588             sendServiceArgsLocked(r, false);
10589             return true;
10590         }
10591 
10592         if (!whileRestarting && r.restartDelay > 0) {
10593             // If waiting for a restart, then do nothing.
10594             return true;
10595         }
10596 
10597         if (DEBUG_SERVICE) Log.v(TAG, "Bringing up service " + r.name
10598                 + " " + r.intent);
10599 
10600         // We are now bringing the service up, so no longer in the
10601         // restarting state.
10602         mRestartingServices.remove(r);
10603 
10604         final String appName = r.processName;
10605         ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
10606         if (app != null && app.thread != null) {
10607             try {
10608                 realStartServiceLocked(r, app);
10609                 return true;
10610             } catch (RemoteException e) {
10611                 Log.w(TAG, "Exception when starting service " + r.shortName, e);
10612             }
10613 
10614             // If a dead object exception was thrown -- fall through to
10615             // restart the application.
10616         }
10617 
10618         // Not running -- get it started, and enqueue this service record
10619         // to be executed when the app comes up.
10620         if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10621                 "service", r.name, false) == null) {
10622             Log.w(TAG, "Unable to launch app "
10623                     + r.appInfo.packageName + "/"
10624                     + r.appInfo.uid + " for service "
10625                     + r.intent.getIntent() + ": process is bad");
10626             bringDownServiceLocked(r, true);
10627             return false;
10628         }
10629 
10630         if (!mPendingServices.contains(r)) {
10631             mPendingServices.add(r);
10632         }
10633 
10634         return true;
10635     }
10636 
bringDownServiceLocked(ServiceRecord r, boolean force)10637     private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
10638         //Log.i(TAG, "Bring down service:");
10639         //r.dump("  ");
10640 
10641         // Does it still need to run?
10642         if (!force && r.startRequested) {
10643             return;
10644         }
10645         if (r.connections.size() > 0) {
10646             if (!force) {
10647                 // XXX should probably keep a count of the number of auto-create
10648                 // connections directly in the service.
10649                 Iterator<ConnectionRecord> it = r.connections.values().iterator();
10650                 while (it.hasNext()) {
10651                     ConnectionRecord cr = it.next();
10652                     if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
10653                         return;
10654                     }
10655                 }
10656             }
10657 
10658             // Report to all of the connections that the service is no longer
10659             // available.
10660             Iterator<ConnectionRecord> it = r.connections.values().iterator();
10661             while (it.hasNext()) {
10662                 ConnectionRecord c = it.next();
10663                 try {
10664                     // todo: shouldn't be a synchronous call!
10665                     c.conn.connected(r.name, null);
10666                 } catch (Exception e) {
10667                     Log.w(TAG, "Failure disconnecting service " + r.name +
10668                           " to connection " + c.conn.asBinder() +
10669                           " (in " + c.binding.client.processName + ")", e);
10670                 }
10671             }
10672         }
10673 
10674         // Tell the service that it has been unbound.
10675         if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10676             Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10677             while (it.hasNext()) {
10678                 IntentBindRecord ibr = it.next();
10679                 if (DEBUG_SERVICE) Log.v(TAG, "Bringing down binding " + ibr
10680                         + ": hasBound=" + ibr.hasBound);
10681                 if (r.app != null && r.app.thread != null && ibr.hasBound) {
10682                     try {
10683                         bumpServiceExecutingLocked(r);
10684                         updateOomAdjLocked(r.app);
10685                         ibr.hasBound = false;
10686                         r.app.thread.scheduleUnbindService(r,
10687                                 ibr.intent.getIntent());
10688                     } catch (Exception e) {
10689                         Log.w(TAG, "Exception when unbinding service "
10690                                 + r.shortName, e);
10691                         serviceDoneExecutingLocked(r, true);
10692                     }
10693                 }
10694             }
10695         }
10696 
10697         if (DEBUG_SERVICE) Log.v(TAG, "Bringing down service " + r.name
10698                  + " " + r.intent);
10699         EventLog.writeEvent(LOG_AM_DESTROY_SERVICE,
10700                 System.identityHashCode(r), r.shortName,
10701                 (r.app != null) ? r.app.pid : -1);
10702 
10703         mServices.remove(r.name);
10704         mServicesByIntent.remove(r.intent);
10705         if (localLOGV) Log.v(TAG, "BRING DOWN SERVICE: " + r.shortName);
10706         r.totalRestartCount = 0;
10707         unscheduleServiceRestartLocked(r);
10708 
10709         // Also make sure it is not on the pending list.
10710         int N = mPendingServices.size();
10711         for (int i=0; i<N; i++) {
10712             if (mPendingServices.get(i) == r) {
10713                 mPendingServices.remove(i);
10714                 if (DEBUG_SERVICE) Log.v(
10715                     TAG, "Removed pending service: " + r.shortName);
10716                 i--;
10717                 N--;
10718             }
10719         }
10720 
10721         r.cancelNotification();
10722         r.isForeground = false;
10723         r.foregroundId = 0;
10724         r.foregroundNoti = null;
10725 
10726         // Clear start entries.
10727         r.deliveredStarts.clear();
10728         r.pendingStarts.clear();
10729 
10730         if (r.app != null) {
10731             synchronized (r.stats.getBatteryStats()) {
10732                 r.stats.stopLaunchedLocked();
10733             }
10734             r.app.services.remove(r);
10735             if (r.app.thread != null) {
10736                 try {
10737                     if (DEBUG_SERVICE) Log.v(TAG,
10738                             "Stopping service: " + r.shortName);
10739                     bumpServiceExecutingLocked(r);
10740                     mStoppingServices.add(r);
10741                     updateOomAdjLocked(r.app);
10742                     r.app.thread.scheduleStopService(r);
10743                 } catch (Exception e) {
10744                     Log.w(TAG, "Exception when stopping service "
10745                             + r.shortName, e);
10746                     serviceDoneExecutingLocked(r, true);
10747                 }
10748                 updateServiceForegroundLocked(r.app, false);
10749             } else {
10750                 if (DEBUG_SERVICE) Log.v(
10751                     TAG, "Removed service that has no process: " + r.shortName);
10752             }
10753         } else {
10754             if (DEBUG_SERVICE) Log.v(
10755                 TAG, "Removed service that is not running: " + r.shortName);
10756         }
10757     }
10758 
startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, int callingPid, int callingUid)10759     ComponentName startServiceLocked(IApplicationThread caller,
10760             Intent service, String resolvedType,
10761             int callingPid, int callingUid) {
10762         synchronized(this) {
10763             if (DEBUG_SERVICE) Log.v(TAG, "startService: " + service
10764                     + " type=" + resolvedType + " args=" + service.getExtras());
10765 
10766             if (caller != null) {
10767                 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10768                 if (callerApp == null) {
10769                     throw new SecurityException(
10770                             "Unable to find app for caller " + caller
10771                             + " (pid=" + Binder.getCallingPid()
10772                             + ") when starting service " + service);
10773                 }
10774             }
10775 
10776             ServiceLookupResult res =
10777                 retrieveServiceLocked(service, resolvedType,
10778                         callingPid, callingUid);
10779             if (res == null) {
10780                 return null;
10781             }
10782             if (res.record == null) {
10783                 return new ComponentName("!", res.permission != null
10784                         ? res.permission : "private to package");
10785             }
10786             ServiceRecord r = res.record;
10787             if (unscheduleServiceRestartLocked(r)) {
10788                 if (DEBUG_SERVICE) Log.v(TAG, "START SERVICE WHILE RESTART PENDING: "
10789                         + r.shortName);
10790             }
10791             r.startRequested = true;
10792             r.callStart = false;
10793             r.lastStartId++;
10794             if (r.lastStartId < 1) {
10795                 r.lastStartId = 1;
10796             }
10797             r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, service));
10798             r.lastActivity = SystemClock.uptimeMillis();
10799             synchronized (r.stats.getBatteryStats()) {
10800                 r.stats.startRunningLocked();
10801             }
10802             if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10803                 return new ComponentName("!", "Service process is bad");
10804             }
10805             return r.name;
10806         }
10807     }
10808 
startService(IApplicationThread caller, Intent service, String resolvedType)10809     public ComponentName startService(IApplicationThread caller, Intent service,
10810             String resolvedType) {
10811         // Refuse possible leaked file descriptors
10812         if (service != null && service.hasFileDescriptors() == true) {
10813             throw new IllegalArgumentException("File descriptors passed in Intent");
10814         }
10815 
10816         synchronized(this) {
10817             final int callingPid = Binder.getCallingPid();
10818             final int callingUid = Binder.getCallingUid();
10819             final long origId = Binder.clearCallingIdentity();
10820             ComponentName res = startServiceLocked(caller, service,
10821                     resolvedType, callingPid, callingUid);
10822             Binder.restoreCallingIdentity(origId);
10823             return res;
10824         }
10825     }
10826 
startServiceInPackage(int uid, Intent service, String resolvedType)10827     ComponentName startServiceInPackage(int uid,
10828             Intent service, String resolvedType) {
10829         synchronized(this) {
10830             final long origId = Binder.clearCallingIdentity();
10831             ComponentName res = startServiceLocked(null, service,
10832                     resolvedType, -1, uid);
10833             Binder.restoreCallingIdentity(origId);
10834             return res;
10835         }
10836     }
10837 
stopService(IApplicationThread caller, Intent service, String resolvedType)10838     public int stopService(IApplicationThread caller, Intent service,
10839             String resolvedType) {
10840         // Refuse possible leaked file descriptors
10841         if (service != null && service.hasFileDescriptors() == true) {
10842             throw new IllegalArgumentException("File descriptors passed in Intent");
10843         }
10844 
10845         synchronized(this) {
10846             if (DEBUG_SERVICE) Log.v(TAG, "stopService: " + service
10847                     + " type=" + resolvedType);
10848 
10849             final ProcessRecord callerApp = getRecordForAppLocked(caller);
10850             if (caller != null && callerApp == null) {
10851                 throw new SecurityException(
10852                         "Unable to find app for caller " + caller
10853                         + " (pid=" + Binder.getCallingPid()
10854                         + ") when stopping service " + service);
10855             }
10856 
10857             // If this service is active, make sure it is stopped.
10858             ServiceLookupResult r = findServiceLocked(service, resolvedType);
10859             if (r != null) {
10860                 if (r.record != null) {
10861                     synchronized (r.record.stats.getBatteryStats()) {
10862                         r.record.stats.stopRunningLocked();
10863                     }
10864                     r.record.startRequested = false;
10865                     r.record.callStart = false;
10866                     final long origId = Binder.clearCallingIdentity();
10867                     bringDownServiceLocked(r.record, false);
10868                     Binder.restoreCallingIdentity(origId);
10869                     return 1;
10870                 }
10871                 return -1;
10872             }
10873         }
10874 
10875         return 0;
10876     }
10877 
peekService(Intent service, String resolvedType)10878     public IBinder peekService(Intent service, String resolvedType) {
10879         // Refuse possible leaked file descriptors
10880         if (service != null && service.hasFileDescriptors() == true) {
10881             throw new IllegalArgumentException("File descriptors passed in Intent");
10882         }
10883 
10884         IBinder ret = null;
10885 
10886         synchronized(this) {
10887             ServiceLookupResult r = findServiceLocked(service, resolvedType);
10888 
10889             if (r != null) {
10890                 // r.record is null if findServiceLocked() failed the caller permission check
10891                 if (r.record == null) {
10892                     throw new SecurityException(
10893                             "Permission Denial: Accessing service " + r.record.name
10894                             + " from pid=" + Binder.getCallingPid()
10895                             + ", uid=" + Binder.getCallingUid()
10896                             + " requires " + r.permission);
10897                 }
10898                 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10899                 if (ib != null) {
10900                     ret = ib.binder;
10901                 }
10902             }
10903         }
10904 
10905         return ret;
10906     }
10907 
stopServiceToken(ComponentName className, IBinder token, int startId)10908     public boolean stopServiceToken(ComponentName className, IBinder token,
10909             int startId) {
10910         synchronized(this) {
10911             if (DEBUG_SERVICE) Log.v(TAG, "stopServiceToken: " + className
10912                     + " " + token + " startId=" + startId);
10913             ServiceRecord r = findServiceLocked(className, token);
10914             if (r != null) {
10915                 if (startId >= 0) {
10916                     // Asked to only stop if done with all work.  Note that
10917                     // to avoid leaks, we will take this as dropping all
10918                     // start items up to and including this one.
10919                     ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10920                     if (si != null) {
10921                         while (r.deliveredStarts.size() > 0) {
10922                             if (r.deliveredStarts.remove(0) == si) {
10923                                 break;
10924                             }
10925                         }
10926                     }
10927 
10928                     if (r.lastStartId != startId) {
10929                         return false;
10930                     }
10931 
10932                     if (r.deliveredStarts.size() > 0) {
10933                         Log.w(TAG, "stopServiceToken startId " + startId
10934                                 + " is last, but have " + r.deliveredStarts.size()
10935                                 + " remaining args");
10936                     }
10937                 }
10938 
10939                 synchronized (r.stats.getBatteryStats()) {
10940                     r.stats.stopRunningLocked();
10941                     r.startRequested = false;
10942                     r.callStart = false;
10943                 }
10944                 final long origId = Binder.clearCallingIdentity();
10945                 bringDownServiceLocked(r, false);
10946                 Binder.restoreCallingIdentity(origId);
10947                 return true;
10948             }
10949         }
10950         return false;
10951     }
10952 
setServiceForeground(ComponentName className, IBinder token, int id, Notification notification, boolean removeNotification)10953     public void setServiceForeground(ComponentName className, IBinder token,
10954             int id, Notification notification, boolean removeNotification) {
10955         final long origId = Binder.clearCallingIdentity();
10956         try {
10957         synchronized(this) {
10958             ServiceRecord r = findServiceLocked(className, token);
10959             if (r != null) {
10960                 if (id != 0) {
10961                     if (notification == null) {
10962                         throw new IllegalArgumentException("null notification");
10963                     }
10964                     if (r.foregroundId != id) {
10965                         r.cancelNotification();
10966                         r.foregroundId = id;
10967                     }
10968                     notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10969                     r.foregroundNoti = notification;
10970                     r.isForeground = true;
10971                     r.postNotification();
10972                     if (r.app != null) {
10973                         updateServiceForegroundLocked(r.app, true);
10974                     }
10975                 } else {
10976                     if (r.isForeground) {
10977                         r.isForeground = false;
10978                         if (r.app != null) {
10979                             updateServiceForegroundLocked(r.app, true);
10980                         }
10981                     }
10982                     if (removeNotification) {
10983                         r.cancelNotification();
10984                         r.foregroundId = 0;
10985                         r.foregroundNoti = null;
10986                     }
10987                 }
10988             }
10989         }
10990         } finally {
10991             Binder.restoreCallingIdentity(origId);
10992         }
10993     }
10994 
updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj)10995     public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10996         boolean anyForeground = false;
10997         for (ServiceRecord sr : (HashSet<ServiceRecord>)proc.services) {
10998             if (sr.isForeground) {
10999                 anyForeground = true;
11000                 break;
11001             }
11002         }
11003         if (anyForeground != proc.foregroundServices) {
11004             proc.foregroundServices = anyForeground;
11005             if (oomAdj) {
11006                 updateOomAdjLocked();
11007             }
11008         }
11009     }
11010 
bindService(IApplicationThread caller, IBinder token, Intent service, String resolvedType, IServiceConnection connection, int flags)11011     public int bindService(IApplicationThread caller, IBinder token,
11012             Intent service, String resolvedType,
11013             IServiceConnection connection, int flags) {
11014         // Refuse possible leaked file descriptors
11015         if (service != null && service.hasFileDescriptors() == true) {
11016             throw new IllegalArgumentException("File descriptors passed in Intent");
11017         }
11018 
11019         synchronized(this) {
11020             if (DEBUG_SERVICE) Log.v(TAG, "bindService: " + service
11021                     + " type=" + resolvedType + " conn=" + connection.asBinder()
11022                     + " flags=0x" + Integer.toHexString(flags));
11023             final ProcessRecord callerApp = getRecordForAppLocked(caller);
11024             if (callerApp == null) {
11025                 throw new SecurityException(
11026                         "Unable to find app for caller " + caller
11027                         + " (pid=" + Binder.getCallingPid()
11028                         + ") when binding service " + service);
11029             }
11030 
11031             HistoryRecord activity = null;
11032             if (token != null) {
11033                 int aindex = indexOfTokenLocked(token);
11034                 if (aindex < 0) {
11035                     Log.w(TAG, "Binding with unknown activity: " + token);
11036                     return 0;
11037                 }
11038                 activity = (HistoryRecord)mHistory.get(aindex);
11039             }
11040 
11041             int clientLabel = 0;
11042             PendingIntent clientIntent = null;
11043 
11044             if (callerApp.info.uid == Process.SYSTEM_UID) {
11045                 // Hacky kind of thing -- allow system stuff to tell us
11046                 // what they are, so we can report this elsewhere for
11047                 // others to know why certain services are running.
11048                 try {
11049                     clientIntent = (PendingIntent)service.getParcelableExtra(
11050                             Intent.EXTRA_CLIENT_INTENT);
11051                 } catch (RuntimeException e) {
11052                 }
11053                 if (clientIntent != null) {
11054                     clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
11055                     if (clientLabel != 0) {
11056                         // There are no useful extras in the intent, trash them.
11057                         // System code calling with this stuff just needs to know
11058                         // this will happen.
11059                         service = service.cloneFilter();
11060                     }
11061                 }
11062             }
11063 
11064             ServiceLookupResult res =
11065                 retrieveServiceLocked(service, resolvedType,
11066                         Binder.getCallingPid(), Binder.getCallingUid());
11067             if (res == null) {
11068                 return 0;
11069             }
11070             if (res.record == null) {
11071                 return -1;
11072             }
11073             ServiceRecord s = res.record;
11074 
11075             final long origId = Binder.clearCallingIdentity();
11076 
11077             if (unscheduleServiceRestartLocked(s)) {
11078                 if (DEBUG_SERVICE) Log.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
11079                         + s.shortName);
11080             }
11081 
11082             AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
11083             ConnectionRecord c = new ConnectionRecord(b, activity,
11084                     connection, flags, clientLabel, clientIntent);
11085 
11086             IBinder binder = connection.asBinder();
11087             s.connections.put(binder, c);
11088             b.connections.add(c);
11089             if (activity != null) {
11090                 if (activity.connections == null) {
11091                     activity.connections = new HashSet<ConnectionRecord>();
11092                 }
11093                 activity.connections.add(c);
11094             }
11095             b.client.connections.add(c);
11096             mServiceConnections.put(binder, c);
11097 
11098             if ((flags&Context.BIND_AUTO_CREATE) != 0) {
11099                 s.lastActivity = SystemClock.uptimeMillis();
11100                 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
11101                     return 0;
11102                 }
11103             }
11104 
11105             if (s.app != null) {
11106                 // This could have made the service more important.
11107                 updateOomAdjLocked(s.app);
11108             }
11109 
11110             if (DEBUG_SERVICE) Log.v(TAG, "Bind " + s + " with " + b
11111                     + ": received=" + b.intent.received
11112                     + " apps=" + b.intent.apps.size()
11113                     + " doRebind=" + b.intent.doRebind);
11114 
11115             if (s.app != null && b.intent.received) {
11116                 // Service is already running, so we can immediately
11117                 // publish the connection.
11118                 try {
11119                     c.conn.connected(s.name, b.intent.binder);
11120                 } catch (Exception e) {
11121                     Log.w(TAG, "Failure sending service " + s.shortName
11122                             + " to connection " + c.conn.asBinder()
11123                             + " (in " + c.binding.client.processName + ")", e);
11124                 }
11125 
11126                 // If this is the first app connected back to this binding,
11127                 // and the service had previously asked to be told when
11128                 // rebound, then do so.
11129                 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
11130                     requestServiceBindingLocked(s, b.intent, true);
11131                 }
11132             } else if (!b.intent.requested) {
11133                 requestServiceBindingLocked(s, b.intent, false);
11134             }
11135 
11136             Binder.restoreCallingIdentity(origId);
11137         }
11138 
11139         return 1;
11140     }
11141 
removeConnectionLocked( ConnectionRecord c, ProcessRecord skipApp, HistoryRecord skipAct)11142     private void removeConnectionLocked(
11143         ConnectionRecord c, ProcessRecord skipApp, HistoryRecord skipAct) {
11144         IBinder binder = c.conn.asBinder();
11145         AppBindRecord b = c.binding;
11146         ServiceRecord s = b.service;
11147         s.connections.remove(binder);
11148         b.connections.remove(c);
11149         if (c.activity != null && c.activity != skipAct) {
11150             if (c.activity.connections != null) {
11151                 c.activity.connections.remove(c);
11152             }
11153         }
11154         if (b.client != skipApp) {
11155             b.client.connections.remove(c);
11156         }
11157         mServiceConnections.remove(binder);
11158 
11159         if (b.connections.size() == 0) {
11160             b.intent.apps.remove(b.client);
11161         }
11162 
11163         if (DEBUG_SERVICE) Log.v(TAG, "Disconnecting binding " + b.intent
11164                 + ": shouldUnbind=" + b.intent.hasBound);
11165         if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
11166                 && b.intent.hasBound) {
11167             try {
11168                 bumpServiceExecutingLocked(s);
11169                 updateOomAdjLocked(s.app);
11170                 b.intent.hasBound = false;
11171                 // Assume the client doesn't want to know about a rebind;
11172                 // we will deal with that later if it asks for one.
11173                 b.intent.doRebind = false;
11174                 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
11175             } catch (Exception e) {
11176                 Log.w(TAG, "Exception when unbinding service " + s.shortName, e);
11177                 serviceDoneExecutingLocked(s, true);
11178             }
11179         }
11180 
11181         if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
11182             bringDownServiceLocked(s, false);
11183         }
11184     }
11185 
unbindService(IServiceConnection connection)11186     public boolean unbindService(IServiceConnection connection) {
11187         synchronized (this) {
11188             IBinder binder = connection.asBinder();
11189             if (DEBUG_SERVICE) Log.v(TAG, "unbindService: conn=" + binder);
11190             ConnectionRecord r = mServiceConnections.get(binder);
11191             if (r == null) {
11192                 Log.w(TAG, "Unbind failed: could not find connection for "
11193                       + connection.asBinder());
11194                 return false;
11195             }
11196 
11197             final long origId = Binder.clearCallingIdentity();
11198 
11199             removeConnectionLocked(r, null, null);
11200 
11201             if (r.binding.service.app != null) {
11202                 // This could have made the service less important.
11203                 updateOomAdjLocked(r.binding.service.app);
11204             }
11205 
11206             Binder.restoreCallingIdentity(origId);
11207         }
11208 
11209         return true;
11210     }
11211 
publishService(IBinder token, Intent intent, IBinder service)11212     public void publishService(IBinder token, Intent intent, IBinder service) {
11213         // Refuse possible leaked file descriptors
11214         if (intent != null && intent.hasFileDescriptors() == true) {
11215             throw new IllegalArgumentException("File descriptors passed in Intent");
11216         }
11217 
11218         synchronized(this) {
11219             if (!(token instanceof ServiceRecord)) {
11220                 throw new IllegalArgumentException("Invalid service token");
11221             }
11222             ServiceRecord r = (ServiceRecord)token;
11223 
11224             final long origId = Binder.clearCallingIdentity();
11225 
11226             if (DEBUG_SERVICE) Log.v(TAG, "PUBLISHING SERVICE " + r.name
11227                     + " " + intent + ": " + service);
11228             if (r != null) {
11229                 Intent.FilterComparison filter
11230                         = new Intent.FilterComparison(intent);
11231                 IntentBindRecord b = r.bindings.get(filter);
11232                 if (b != null && !b.received) {
11233                     b.binder = service;
11234                     b.requested = true;
11235                     b.received = true;
11236                     if (r.connections.size() > 0) {
11237                         Iterator<ConnectionRecord> it
11238                                 = r.connections.values().iterator();
11239                         while (it.hasNext()) {
11240                             ConnectionRecord c = it.next();
11241                             if (!filter.equals(c.binding.intent.intent)) {
11242                                 if (DEBUG_SERVICE) Log.v(
11243                                         TAG, "Not publishing to: " + c);
11244                                 if (DEBUG_SERVICE) Log.v(
11245                                         TAG, "Bound intent: " + c.binding.intent.intent);
11246                                 if (DEBUG_SERVICE) Log.v(
11247                                         TAG, "Published intent: " + intent);
11248                                 continue;
11249                             }
11250                             if (DEBUG_SERVICE) Log.v(TAG, "Publishing to: " + c);
11251                             try {
11252                                 c.conn.connected(r.name, service);
11253                             } catch (Exception e) {
11254                                 Log.w(TAG, "Failure sending service " + r.name +
11255                                       " to connection " + c.conn.asBinder() +
11256                                       " (in " + c.binding.client.processName + ")", e);
11257                             }
11258                         }
11259                     }
11260                 }
11261 
11262                 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
11263 
11264                 Binder.restoreCallingIdentity(origId);
11265             }
11266         }
11267     }
11268 
unbindFinished(IBinder token, Intent intent, boolean doRebind)11269     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11270         // Refuse possible leaked file descriptors
11271         if (intent != null && intent.hasFileDescriptors() == true) {
11272             throw new IllegalArgumentException("File descriptors passed in Intent");
11273         }
11274 
11275         synchronized(this) {
11276             if (!(token instanceof ServiceRecord)) {
11277                 throw new IllegalArgumentException("Invalid service token");
11278             }
11279             ServiceRecord r = (ServiceRecord)token;
11280 
11281             final long origId = Binder.clearCallingIdentity();
11282 
11283             if (r != null) {
11284                 Intent.FilterComparison filter
11285                         = new Intent.FilterComparison(intent);
11286                 IntentBindRecord b = r.bindings.get(filter);
11287                 if (DEBUG_SERVICE) Log.v(TAG, "unbindFinished in " + r
11288                         + " at " + b + ": apps="
11289                         + (b != null ? b.apps.size() : 0));
11290                 if (b != null) {
11291                     if (b.apps.size() > 0) {
11292                         // Applications have already bound since the last
11293                         // unbind, so just rebind right here.
11294                         requestServiceBindingLocked(r, b, true);
11295                     } else {
11296                         // Note to tell the service the next time there is
11297                         // a new client.
11298                         b.doRebind = true;
11299                     }
11300                 }
11301 
11302                 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
11303 
11304                 Binder.restoreCallingIdentity(origId);
11305             }
11306         }
11307     }
11308 
serviceDoneExecuting(IBinder token, int type, int startId, int res)11309     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
11310         synchronized(this) {
11311             if (!(token instanceof ServiceRecord)) {
11312                 throw new IllegalArgumentException("Invalid service token");
11313             }
11314             ServiceRecord r = (ServiceRecord)token;
11315             boolean inStopping = mStoppingServices.contains(token);
11316             if (r != null) {
11317                 if (DEBUG_SERVICE) Log.v(TAG, "DONE EXECUTING SERVICE " + r.name
11318                         + ": nesting=" + r.executeNesting
11319                         + ", inStopping=" + inStopping);
11320                 if (r != token) {
11321                     Log.w(TAG, "Done executing service " + r.name
11322                           + " with incorrect token: given " + token
11323                           + ", expected " + r);
11324                     return;
11325                 }
11326 
11327                 if (type == 1) {
11328                     // This is a call from a service start...  take care of
11329                     // book-keeping.
11330                     r.callStart = true;
11331                     switch (res) {
11332                         case Service.START_STICKY_COMPATIBILITY:
11333                         case Service.START_STICKY: {
11334                             // We are done with the associated start arguments.
11335                             r.findDeliveredStart(startId, true);
11336                             // Don't stop if killed.
11337                             r.stopIfKilled = false;
11338                             break;
11339                         }
11340                         case Service.START_NOT_STICKY: {
11341                             // We are done with the associated start arguments.
11342                             r.findDeliveredStart(startId, true);
11343                             if (r.lastStartId == startId) {
11344                                 // There is no more work, and this service
11345                                 // doesn't want to hang around if killed.
11346                                 r.stopIfKilled = true;
11347                             }
11348                             break;
11349                         }
11350                         case Service.START_REDELIVER_INTENT: {
11351                             // We'll keep this item until they explicitly
11352                             // call stop for it, but keep track of the fact
11353                             // that it was delivered.
11354                             ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11355                             if (si != null) {
11356                                 si.deliveryCount = 0;
11357                                 si.doneExecutingCount++;
11358                                 // Don't stop if killed.
11359                                 r.stopIfKilled = true;
11360                             }
11361                             break;
11362                         }
11363                         default:
11364                             throw new IllegalArgumentException(
11365                                     "Unknown service start result: " + res);
11366                     }
11367                     if (res == Service.START_STICKY_COMPATIBILITY) {
11368                         r.callStart = false;
11369                     }
11370                 }
11371 
11372                 final long origId = Binder.clearCallingIdentity();
11373                 serviceDoneExecutingLocked(r, inStopping);
11374                 Binder.restoreCallingIdentity(origId);
11375             } else {
11376                 Log.w(TAG, "Done executing unknown service " + r.name
11377                         + " with token " + token);
11378             }
11379         }
11380     }
11381 
serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping)11382     public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
11383         r.executeNesting--;
11384         if (r.executeNesting <= 0 && r.app != null) {
11385             r.app.executingServices.remove(r);
11386             if (r.app.executingServices.size() == 0) {
11387                 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
11388             }
11389             if (inStopping) {
11390                 mStoppingServices.remove(r);
11391             }
11392             updateOomAdjLocked(r.app);
11393         }
11394     }
11395 
serviceTimeout(ProcessRecord proc)11396     void serviceTimeout(ProcessRecord proc) {
11397         synchronized(this) {
11398             if (proc.executingServices.size() == 0 || proc.thread == null) {
11399                 return;
11400             }
11401             long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
11402             Iterator<ServiceRecord> it = proc.executingServices.iterator();
11403             ServiceRecord timeout = null;
11404             long nextTime = 0;
11405             while (it.hasNext()) {
11406                 ServiceRecord sr = it.next();
11407                 if (sr.executingStart < maxTime) {
11408                     timeout = sr;
11409                     break;
11410                 }
11411                 if (sr.executingStart > nextTime) {
11412                     nextTime = sr.executingStart;
11413                 }
11414             }
11415             if (timeout != null && mLRUProcesses.contains(proc)) {
11416                 Log.w(TAG, "Timeout executing service: " + timeout);
11417                 appNotRespondingLocked(proc, null, null, "Executing service "
11418                         + timeout.name);
11419             } else {
11420                 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11421                 msg.obj = proc;
11422                 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
11423             }
11424         }
11425     }
11426 
11427     // =========================================================
11428     // BACKUP AND RESTORE
11429     // =========================================================
11430 
11431     // Cause the target app to be launched if necessary and its backup agent
11432     // instantiated.  The backup agent will invoke backupAgentCreated() on the
11433     // activity manager to announce its creation.
bindBackupAgent(ApplicationInfo app, int backupMode)11434     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
11435         if (DEBUG_BACKUP) Log.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
11436         enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11437 
11438         synchronized(this) {
11439             // !!! TODO: currently no check here that we're already bound
11440             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11441             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11442             synchronized (stats) {
11443                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11444             }
11445 
11446             BackupRecord r = new BackupRecord(ss, app, backupMode);
11447             ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName);
11448             // startProcessLocked() returns existing proc's record if it's already running
11449             ProcessRecord proc = startProcessLocked(app.processName, app,
11450                     false, 0, "backup", hostingName, false);
11451             if (proc == null) {
11452                 Log.e(TAG, "Unable to start backup agent process " + r);
11453                 return false;
11454             }
11455 
11456             r.app = proc;
11457             mBackupTarget = r;
11458             mBackupAppName = app.packageName;
11459 
11460             // Try not to kill the process during backup
11461             updateOomAdjLocked(proc);
11462 
11463             // If the process is already attached, schedule the creation of the backup agent now.
11464             // If it is not yet live, this will be done when it attaches to the framework.
11465             if (proc.thread != null) {
11466                 if (DEBUG_BACKUP) Log.v(TAG, "Agent proc already running: " + proc);
11467                 try {
11468                     proc.thread.scheduleCreateBackupAgent(app, backupMode);
11469                 } catch (RemoteException e) {
11470                     // Will time out on the backup manager side
11471                 }
11472             } else {
11473                 if (DEBUG_BACKUP) Log.v(TAG, "Agent proc not running, waiting for attach");
11474             }
11475             // Invariants: at this point, the target app process exists and the application
11476             // is either already running or in the process of coming up.  mBackupTarget and
11477             // mBackupAppName describe the app, so that when it binds back to the AM we
11478             // know that it's scheduled for a backup-agent operation.
11479         }
11480 
11481         return true;
11482     }
11483 
11484     // A backup agent has just come up
backupAgentCreated(String agentPackageName, IBinder agent)11485     public void backupAgentCreated(String agentPackageName, IBinder agent) {
11486         if (DEBUG_BACKUP) Log.v(TAG, "backupAgentCreated: " + agentPackageName
11487                 + " = " + agent);
11488 
11489         synchronized(this) {
11490             if (!agentPackageName.equals(mBackupAppName)) {
11491                 Log.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
11492                 return;
11493             }
11494 
11495             long oldIdent = Binder.clearCallingIdentity();
11496             try {
11497                 IBackupManager bm = IBackupManager.Stub.asInterface(
11498                         ServiceManager.getService(Context.BACKUP_SERVICE));
11499                 bm.agentConnected(agentPackageName, agent);
11500             } catch (RemoteException e) {
11501                 // can't happen; the backup manager service is local
11502             } catch (Exception e) {
11503                 Log.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11504                 e.printStackTrace();
11505             } finally {
11506                 Binder.restoreCallingIdentity(oldIdent);
11507             }
11508         }
11509     }
11510 
11511     // done with this agent
unbindBackupAgent(ApplicationInfo appInfo)11512     public void unbindBackupAgent(ApplicationInfo appInfo) {
11513         if (DEBUG_BACKUP) Log.v(TAG, "unbindBackupAgent: " + appInfo);
11514         if (appInfo == null) {
11515             Log.w(TAG, "unbind backup agent for null app");
11516             return;
11517         }
11518 
11519         synchronized(this) {
11520             if (mBackupAppName == null) {
11521                 Log.w(TAG, "Unbinding backup agent with no active backup");
11522                 return;
11523             }
11524 
11525             if (!mBackupAppName.equals(appInfo.packageName)) {
11526                 Log.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11527                 return;
11528             }
11529 
11530             ProcessRecord proc = mBackupTarget.app;
11531             mBackupTarget = null;
11532             mBackupAppName = null;
11533 
11534             // Not backing this app up any more; reset its OOM adjustment
11535             updateOomAdjLocked(proc);
11536 
11537             // If the app crashed during backup, 'thread' will be null here
11538             if (proc.thread != null) {
11539                 try {
11540                     proc.thread.scheduleDestroyBackupAgent(appInfo);
11541                 } catch (Exception e) {
11542                     Log.e(TAG, "Exception when unbinding backup agent:");
11543                     e.printStackTrace();
11544                 }
11545             }
11546         }
11547     }
11548     // =========================================================
11549     // BROADCASTS
11550     // =========================================================
11551 
getStickies(String action, IntentFilter filter, List cur)11552     private final List getStickies(String action, IntentFilter filter,
11553             List cur) {
11554         final ContentResolver resolver = mContext.getContentResolver();
11555         final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11556         if (list == null) {
11557             return cur;
11558         }
11559         int N = list.size();
11560         for (int i=0; i<N; i++) {
11561             Intent intent = list.get(i);
11562             if (filter.match(resolver, intent, true, TAG) >= 0) {
11563                 if (cur == null) {
11564                     cur = new ArrayList<Intent>();
11565                 }
11566                 cur.add(intent);
11567             }
11568         }
11569         return cur;
11570     }
11571 
scheduleBroadcastsLocked()11572     private final void scheduleBroadcastsLocked() {
11573         if (DEBUG_BROADCAST) Log.v(TAG, "Schedule broadcasts: current="
11574                 + mBroadcastsScheduled);
11575 
11576         if (mBroadcastsScheduled) {
11577             return;
11578         }
11579         mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11580         mBroadcastsScheduled = true;
11581     }
11582 
registerReceiver(IApplicationThread caller, IIntentReceiver receiver, IntentFilter filter, String permission)11583     public Intent registerReceiver(IApplicationThread caller,
11584             IIntentReceiver receiver, IntentFilter filter, String permission) {
11585         synchronized(this) {
11586             ProcessRecord callerApp = null;
11587             if (caller != null) {
11588                 callerApp = getRecordForAppLocked(caller);
11589                 if (callerApp == null) {
11590                     throw new SecurityException(
11591                             "Unable to find app for caller " + caller
11592                             + " (pid=" + Binder.getCallingPid()
11593                             + ") when registering receiver " + receiver);
11594                 }
11595             }
11596 
11597             List allSticky = null;
11598 
11599             // Look for any matching sticky broadcasts...
11600             Iterator actions = filter.actionsIterator();
11601             if (actions != null) {
11602                 while (actions.hasNext()) {
11603                     String action = (String)actions.next();
11604                     allSticky = getStickies(action, filter, allSticky);
11605                 }
11606             } else {
11607                 allSticky = getStickies(null, filter, allSticky);
11608             }
11609 
11610             // The first sticky in the list is returned directly back to
11611             // the client.
11612             Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11613 
11614             if (DEBUG_BROADCAST) Log.v(TAG, "Register receiver " + filter
11615                     + ": " + sticky);
11616 
11617             if (receiver == null) {
11618                 return sticky;
11619             }
11620 
11621             ReceiverList rl
11622                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11623             if (rl == null) {
11624                 rl = new ReceiverList(this, callerApp,
11625                         Binder.getCallingPid(),
11626                         Binder.getCallingUid(), receiver);
11627                 if (rl.app != null) {
11628                     rl.app.receivers.add(rl);
11629                 } else {
11630                     try {
11631                         receiver.asBinder().linkToDeath(rl, 0);
11632                     } catch (RemoteException e) {
11633                         return sticky;
11634                     }
11635                     rl.linkedToDeath = true;
11636                 }
11637                 mRegisteredReceivers.put(receiver.asBinder(), rl);
11638             }
11639             BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
11640             rl.add(bf);
11641             if (!bf.debugCheck()) {
11642                 Log.w(TAG, "==> For Dynamic broadast");
11643             }
11644             mReceiverResolver.addFilter(bf);
11645 
11646             // Enqueue broadcasts for all existing stickies that match
11647             // this filter.
11648             if (allSticky != null) {
11649                 ArrayList receivers = new ArrayList();
11650                 receivers.add(bf);
11651 
11652                 int N = allSticky.size();
11653                 for (int i=0; i<N; i++) {
11654                     Intent intent = (Intent)allSticky.get(i);
11655                     BroadcastRecord r = new BroadcastRecord(intent, null,
11656                             null, -1, -1, null, receivers, null, 0, null, null,
11657                             false, true, true);
11658                     if (mParallelBroadcasts.size() == 0) {
11659                         scheduleBroadcastsLocked();
11660                     }
11661                     mParallelBroadcasts.add(r);
11662                 }
11663             }
11664 
11665             return sticky;
11666         }
11667     }
11668 
unregisterReceiver(IIntentReceiver receiver)11669     public void unregisterReceiver(IIntentReceiver receiver) {
11670         if (DEBUG_BROADCAST) Log.v(TAG, "Unregister receiver: " + receiver);
11671 
11672         boolean doNext = false;
11673 
11674         synchronized(this) {
11675             ReceiverList rl
11676                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11677             if (rl != null) {
11678                 if (rl.curBroadcast != null) {
11679                     BroadcastRecord r = rl.curBroadcast;
11680                     doNext = finishReceiverLocked(
11681                         receiver.asBinder(), r.resultCode, r.resultData,
11682                         r.resultExtras, r.resultAbort, true);
11683                 }
11684 
11685                 if (rl.app != null) {
11686                     rl.app.receivers.remove(rl);
11687                 }
11688                 removeReceiverLocked(rl);
11689                 if (rl.linkedToDeath) {
11690                     rl.linkedToDeath = false;
11691                     rl.receiver.asBinder().unlinkToDeath(rl, 0);
11692                 }
11693             }
11694         }
11695 
11696         if (!doNext) {
11697             return;
11698         }
11699 
11700         final long origId = Binder.clearCallingIdentity();
11701         processNextBroadcast(false);
11702         trimApplications();
11703         Binder.restoreCallingIdentity(origId);
11704     }
11705 
removeReceiverLocked(ReceiverList rl)11706     void removeReceiverLocked(ReceiverList rl) {
11707         mRegisteredReceivers.remove(rl.receiver.asBinder());
11708         int N = rl.size();
11709         for (int i=0; i<N; i++) {
11710             mReceiverResolver.removeFilter(rl.get(i));
11711         }
11712     }
11713 
broadcastIntentLocked(ProcessRecord callerApp, String callerPackage, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle map, String requiredPermission, boolean ordered, boolean sticky, int callingPid, int callingUid)11714     private final int broadcastIntentLocked(ProcessRecord callerApp,
11715             String callerPackage, Intent intent, String resolvedType,
11716             IIntentReceiver resultTo, int resultCode, String resultData,
11717             Bundle map, String requiredPermission,
11718             boolean ordered, boolean sticky, int callingPid, int callingUid) {
11719         intent = new Intent(intent);
11720 
11721         if (DEBUG_BROADCAST_LIGHT) Log.v(
11722             TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11723             + " ordered=" + ordered);
11724         if ((resultTo != null) && !ordered) {
11725             Log.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11726         }
11727 
11728         // Handle special intents: if this broadcast is from the package
11729         // manager about a package being removed, we need to remove all of
11730         // its activities from the history stack.
11731         final boolean uidRemoved = intent.ACTION_UID_REMOVED.equals(
11732                 intent.getAction());
11733         if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11734                 || intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11735                 || uidRemoved) {
11736             if (checkComponentPermission(
11737                     android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11738                     callingPid, callingUid, -1)
11739                     == PackageManager.PERMISSION_GRANTED) {
11740                 if (uidRemoved) {
11741                     final Bundle intentExtras = intent.getExtras();
11742                     final int uid = intentExtras != null
11743                             ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11744                     if (uid >= 0) {
11745                         BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11746                         synchronized (bs) {
11747                             bs.removeUidStatsLocked(uid);
11748                         }
11749                     }
11750                 } else {
11751                     Uri data = intent.getData();
11752                     String ssp;
11753                     if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11754                         if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11755                             uninstallPackageLocked(ssp,
11756                                     intent.getIntExtra(Intent.EXTRA_UID, -1), false);
11757                             AttributeCache ac = AttributeCache.instance();
11758                             if (ac != null) {
11759                                 ac.removePackage(ssp);
11760                             }
11761                         }
11762                     }
11763                 }
11764             } else {
11765                 String msg = "Permission Denial: " + intent.getAction()
11766                         + " broadcast from " + callerPackage + " (pid=" + callingPid
11767                         + ", uid=" + callingUid + ")"
11768                         + " requires "
11769                         + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11770                 Log.w(TAG, msg);
11771                 throw new SecurityException(msg);
11772             }
11773         }
11774 
11775         /*
11776          * If this is the time zone changed action, queue up a message that will reset the timezone
11777          * of all currently running processes. This message will get queued up before the broadcast
11778          * happens.
11779          */
11780         if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11781             mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11782         }
11783 
11784         /*
11785          * Prevent non-system code (defined here to be non-persistent
11786          * processes) from sending protected broadcasts.
11787          */
11788         if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11789                 || callingUid == Process.SHELL_UID || callingUid == 0) {
11790             // Always okay.
11791         } else if (callerApp == null || !callerApp.persistent) {
11792             try {
11793                 if (ActivityThread.getPackageManager().isProtectedBroadcast(
11794                         intent.getAction())) {
11795                     String msg = "Permission Denial: not allowed to send broadcast "
11796                             + intent.getAction() + " from pid="
11797                             + callingPid + ", uid=" + callingUid;
11798                     Log.w(TAG, msg);
11799                     throw new SecurityException(msg);
11800                 }
11801             } catch (RemoteException e) {
11802                 Log.w(TAG, "Remote exception", e);
11803                 return BROADCAST_SUCCESS;
11804             }
11805         }
11806 
11807         // Add to the sticky list if requested.
11808         if (sticky) {
11809             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11810                     callingPid, callingUid)
11811                     != PackageManager.PERMISSION_GRANTED) {
11812                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11813                         + callingPid + ", uid=" + callingUid
11814                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11815                 Log.w(TAG, msg);
11816                 throw new SecurityException(msg);
11817             }
11818             if (requiredPermission != null) {
11819                 Log.w(TAG, "Can't broadcast sticky intent " + intent
11820                         + " and enforce permission " + requiredPermission);
11821                 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11822             }
11823             if (intent.getComponent() != null) {
11824                 throw new SecurityException(
11825                         "Sticky broadcasts can't target a specific component");
11826             }
11827             ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11828             if (list == null) {
11829                 list = new ArrayList<Intent>();
11830                 mStickyBroadcasts.put(intent.getAction(), list);
11831             }
11832             int N = list.size();
11833             int i;
11834             for (i=0; i<N; i++) {
11835                 if (intent.filterEquals(list.get(i))) {
11836                     // This sticky already exists, replace it.
11837                     list.set(i, new Intent(intent));
11838                     break;
11839                 }
11840             }
11841             if (i >= N) {
11842                 list.add(new Intent(intent));
11843             }
11844         }
11845 
11846         // Figure out who all will receive this broadcast.
11847         List receivers = null;
11848         List<BroadcastFilter> registeredReceivers = null;
11849         try {
11850             if (intent.getComponent() != null) {
11851                 // Broadcast is going to one specific receiver class...
11852                 ActivityInfo ai = ActivityThread.getPackageManager().
11853                     getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
11854                 if (ai != null) {
11855                     receivers = new ArrayList();
11856                     ResolveInfo ri = new ResolveInfo();
11857                     ri.activityInfo = ai;
11858                     receivers.add(ri);
11859                 }
11860             } else {
11861                 // Need to resolve the intent to interested receivers...
11862                 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11863                          == 0) {
11864                     receivers =
11865                         ActivityThread.getPackageManager().queryIntentReceivers(
11866                                 intent, resolvedType, STOCK_PM_FLAGS);
11867                 }
11868                 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
11869             }
11870         } catch (RemoteException ex) {
11871             // pm is in same process, this will never happen.
11872         }
11873 
11874         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11875         if (!ordered && NR > 0) {
11876             // If we are not serializing this broadcast, then send the
11877             // registered receivers separately so they don't wait for the
11878             // components to be launched.
11879             BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11880                     callerPackage, callingPid, callingUid, requiredPermission,
11881                     registeredReceivers, resultTo, resultCode, resultData, map,
11882                     ordered, sticky, false);
11883             if (DEBUG_BROADCAST) Log.v(
11884                     TAG, "Enqueueing parallel broadcast " + r
11885                     + ": prev had " + mParallelBroadcasts.size());
11886             mParallelBroadcasts.add(r);
11887             scheduleBroadcastsLocked();
11888             registeredReceivers = null;
11889             NR = 0;
11890         }
11891 
11892         // Merge into one list.
11893         int ir = 0;
11894         if (receivers != null) {
11895             // A special case for PACKAGE_ADDED: do not allow the package
11896             // being added to see this broadcast.  This prevents them from
11897             // using this as a back door to get run as soon as they are
11898             // installed.  Maybe in the future we want to have a special install
11899             // broadcast or such for apps, but we'd like to deliberately make
11900             // this decision.
11901             boolean skip = false;
11902             if (intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11903                 skip = true;
11904             } else if (intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())) {
11905                 skip = true;
11906             } else if (intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11907                 skip = true;
11908             }
11909             String skipPackage = (skip && intent.getData() != null)
11910                     ? intent.getData().getSchemeSpecificPart()
11911                     : null;
11912             if (skipPackage != null && receivers != null) {
11913                 int NT = receivers.size();
11914                 for (int it=0; it<NT; it++) {
11915                     ResolveInfo curt = (ResolveInfo)receivers.get(it);
11916                     if (curt.activityInfo.packageName.equals(skipPackage)) {
11917                         receivers.remove(it);
11918                         it--;
11919                         NT--;
11920                     }
11921                 }
11922             }
11923 
11924             int NT = receivers != null ? receivers.size() : 0;
11925             int it = 0;
11926             ResolveInfo curt = null;
11927             BroadcastFilter curr = null;
11928             while (it < NT && ir < NR) {
11929                 if (curt == null) {
11930                     curt = (ResolveInfo)receivers.get(it);
11931                 }
11932                 if (curr == null) {
11933                     curr = registeredReceivers.get(ir);
11934                 }
11935                 if (curr.getPriority() >= curt.priority) {
11936                     // Insert this broadcast record into the final list.
11937                     receivers.add(it, curr);
11938                     ir++;
11939                     curr = null;
11940                     it++;
11941                     NT++;
11942                 } else {
11943                     // Skip to the next ResolveInfo in the final list.
11944                     it++;
11945                     curt = null;
11946                 }
11947             }
11948         }
11949         while (ir < NR) {
11950             if (receivers == null) {
11951                 receivers = new ArrayList();
11952             }
11953             receivers.add(registeredReceivers.get(ir));
11954             ir++;
11955         }
11956 
11957         if ((receivers != null && receivers.size() > 0)
11958                 || resultTo != null) {
11959             BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11960                     callerPackage, callingPid, callingUid, requiredPermission,
11961                     receivers, resultTo, resultCode, resultData, map, ordered,
11962                     sticky, false);
11963             if (DEBUG_BROADCAST) Log.v(
11964                     TAG, "Enqueueing ordered broadcast " + r
11965                     + ": prev had " + mOrderedBroadcasts.size());
11966             if (DEBUG_BROADCAST) {
11967                 int seq = r.intent.getIntExtra("seq", -1);
11968                 Log.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11969             }
11970             mOrderedBroadcasts.add(r);
11971             scheduleBroadcastsLocked();
11972         }
11973 
11974         return BROADCAST_SUCCESS;
11975     }
11976 
broadcastIntent(IApplicationThread caller, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle map, String requiredPermission, boolean serialized, boolean sticky)11977     public final int broadcastIntent(IApplicationThread caller,
11978             Intent intent, String resolvedType, IIntentReceiver resultTo,
11979             int resultCode, String resultData, Bundle map,
11980             String requiredPermission, boolean serialized, boolean sticky) {
11981         // Refuse possible leaked file descriptors
11982         if (intent != null && intent.hasFileDescriptors() == true) {
11983             throw new IllegalArgumentException("File descriptors passed in Intent");
11984         }
11985 
11986         synchronized(this) {
11987             int flags = intent.getFlags();
11988 
11989             if (!mSystemReady) {
11990                 // if the caller really truly claims to know what they're doing, go
11991                 // ahead and allow the broadcast without launching any receivers
11992                 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11993                     intent = new Intent(intent);
11994                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11995                 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0){
11996                     Log.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11997                             + " before boot completion");
11998                     throw new IllegalStateException("Cannot broadcast before boot completed");
11999                 }
12000             }
12001 
12002             if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
12003                 throw new IllegalArgumentException(
12004                         "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
12005             }
12006 
12007             final ProcessRecord callerApp = getRecordForAppLocked(caller);
12008             final int callingPid = Binder.getCallingPid();
12009             final int callingUid = Binder.getCallingUid();
12010             final long origId = Binder.clearCallingIdentity();
12011             int res = broadcastIntentLocked(callerApp,
12012                     callerApp != null ? callerApp.info.packageName : null,
12013                     intent, resolvedType, resultTo,
12014                     resultCode, resultData, map, requiredPermission, serialized,
12015                     sticky, callingPid, callingUid);
12016             Binder.restoreCallingIdentity(origId);
12017             return res;
12018         }
12019     }
12020 
broadcastIntentInPackage(String packageName, int uid, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle map, String requiredPermission, boolean serialized, boolean sticky)12021     int broadcastIntentInPackage(String packageName, int uid,
12022             Intent intent, String resolvedType, IIntentReceiver resultTo,
12023             int resultCode, String resultData, Bundle map,
12024             String requiredPermission, boolean serialized, boolean sticky) {
12025         synchronized(this) {
12026             final long origId = Binder.clearCallingIdentity();
12027             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
12028                     resultTo, resultCode, resultData, map, requiredPermission,
12029                     serialized, sticky, -1, uid);
12030             Binder.restoreCallingIdentity(origId);
12031             return res;
12032         }
12033     }
12034 
unbroadcastIntent(IApplicationThread caller, Intent intent)12035     public final void unbroadcastIntent(IApplicationThread caller,
12036             Intent intent) {
12037         // Refuse possible leaked file descriptors
12038         if (intent != null && intent.hasFileDescriptors() == true) {
12039             throw new IllegalArgumentException("File descriptors passed in Intent");
12040         }
12041 
12042         synchronized(this) {
12043             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
12044                     != PackageManager.PERMISSION_GRANTED) {
12045                 String msg = "Permission Denial: unbroadcastIntent() from pid="
12046                         + Binder.getCallingPid()
12047                         + ", uid=" + Binder.getCallingUid()
12048                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
12049                 Log.w(TAG, msg);
12050                 throw new SecurityException(msg);
12051             }
12052             ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12053             if (list != null) {
12054                 int N = list.size();
12055                 int i;
12056                 for (i=0; i<N; i++) {
12057                     if (intent.filterEquals(list.get(i))) {
12058                         list.remove(i);
12059                         break;
12060                     }
12061                 }
12062             }
12063         }
12064     }
12065 
finishReceiverLocked(IBinder receiver, int resultCode, String resultData, Bundle resultExtras, boolean resultAbort, boolean explicit)12066     private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
12067             String resultData, Bundle resultExtras, boolean resultAbort,
12068             boolean explicit) {
12069         if (mOrderedBroadcasts.size() == 0) {
12070             if (explicit) {
12071                 Log.w(TAG, "finishReceiver called but no pending broadcasts");
12072             }
12073             return false;
12074         }
12075         BroadcastRecord r = mOrderedBroadcasts.get(0);
12076         if (r.receiver == null) {
12077             if (explicit) {
12078                 Log.w(TAG, "finishReceiver called but none active");
12079             }
12080             return false;
12081         }
12082         if (r.receiver != receiver) {
12083             Log.w(TAG, "finishReceiver called but active receiver is different");
12084             return false;
12085         }
12086         int state = r.state;
12087         r.state = r.IDLE;
12088         if (state == r.IDLE) {
12089             if (explicit) {
12090                 Log.w(TAG, "finishReceiver called but state is IDLE");
12091             }
12092         }
12093         r.receiver = null;
12094         r.intent.setComponent(null);
12095         if (r.curApp != null) {
12096             r.curApp.curReceiver = null;
12097         }
12098         if (r.curFilter != null) {
12099             r.curFilter.receiverList.curBroadcast = null;
12100         }
12101         r.curFilter = null;
12102         r.curApp = null;
12103         r.curComponent = null;
12104         r.curReceiver = null;
12105         mPendingBroadcast = null;
12106 
12107         r.resultCode = resultCode;
12108         r.resultData = resultData;
12109         r.resultExtras = resultExtras;
12110         r.resultAbort = resultAbort;
12111 
12112         // We will process the next receiver right now if this is finishing
12113         // an app receiver (which is always asynchronous) or after we have
12114         // come back from calling a receiver.
12115         return state == BroadcastRecord.APP_RECEIVE
12116                 || state == BroadcastRecord.CALL_DONE_RECEIVE;
12117     }
12118 
finishReceiver(IBinder who, int resultCode, String resultData, Bundle resultExtras, boolean resultAbort)12119     public void finishReceiver(IBinder who, int resultCode, String resultData,
12120             Bundle resultExtras, boolean resultAbort) {
12121         if (DEBUG_BROADCAST) Log.v(TAG, "Finish receiver: " + who);
12122 
12123         // Refuse possible leaked file descriptors
12124         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12125             throw new IllegalArgumentException("File descriptors passed in Bundle");
12126         }
12127 
12128         boolean doNext;
12129 
12130         final long origId = Binder.clearCallingIdentity();
12131 
12132         synchronized(this) {
12133             doNext = finishReceiverLocked(
12134                 who, resultCode, resultData, resultExtras, resultAbort, true);
12135         }
12136 
12137         if (doNext) {
12138             processNextBroadcast(false);
12139         }
12140         trimApplications();
12141 
12142         Binder.restoreCallingIdentity(origId);
12143     }
12144 
logBroadcastReceiverDiscard(BroadcastRecord r)12145     private final void logBroadcastReceiverDiscard(BroadcastRecord r) {
12146         if (r.nextReceiver > 0) {
12147             Object curReceiver = r.receivers.get(r.nextReceiver-1);
12148             if (curReceiver instanceof BroadcastFilter) {
12149                 BroadcastFilter bf = (BroadcastFilter) curReceiver;
12150                 EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_FILTER,
12151                         System.identityHashCode(r),
12152                         r.intent.getAction(),
12153                         r.nextReceiver - 1,
12154                         System.identityHashCode(bf));
12155             } else {
12156                 EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_APP,
12157                         System.identityHashCode(r),
12158                         r.intent.getAction(),
12159                         r.nextReceiver - 1,
12160                         ((ResolveInfo)curReceiver).toString());
12161             }
12162         } else {
12163             Log.w(TAG, "Discarding broadcast before first receiver is invoked: "
12164                     + r);
12165             EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_APP,
12166                     System.identityHashCode(r),
12167                     r.intent.getAction(),
12168                     r.nextReceiver,
12169                     "NONE");
12170         }
12171     }
12172 
broadcastTimeout()12173     private final void broadcastTimeout() {
12174         synchronized (this) {
12175             if (mOrderedBroadcasts.size() == 0) {
12176                 return;
12177             }
12178             long now = SystemClock.uptimeMillis();
12179             BroadcastRecord r = mOrderedBroadcasts.get(0);
12180             if ((r.receiverTime+BROADCAST_TIMEOUT) > now) {
12181                 if (DEBUG_BROADCAST) Log.v(TAG,
12182                         "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
12183                         + (r.receiverTime + BROADCAST_TIMEOUT));
12184                 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
12185                 mHandler.sendMessageAtTime(msg, r.receiverTime+BROADCAST_TIMEOUT);
12186                 return;
12187             }
12188 
12189             Log.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver);
12190             r.receiverTime = now;
12191             r.anrCount++;
12192 
12193             // Current receiver has passed its expiration date.
12194             if (r.nextReceiver <= 0) {
12195                 Log.w(TAG, "Timeout on receiver with nextReceiver <= 0");
12196                 return;
12197             }
12198 
12199             ProcessRecord app = null;
12200 
12201             Object curReceiver = r.receivers.get(r.nextReceiver-1);
12202             Log.w(TAG, "Receiver during timeout: " + curReceiver);
12203             logBroadcastReceiverDiscard(r);
12204             if (curReceiver instanceof BroadcastFilter) {
12205                 BroadcastFilter bf = (BroadcastFilter)curReceiver;
12206                 if (bf.receiverList.pid != 0
12207                         && bf.receiverList.pid != MY_PID) {
12208                     synchronized (this.mPidsSelfLocked) {
12209                         app = this.mPidsSelfLocked.get(
12210                                 bf.receiverList.pid);
12211                     }
12212                 }
12213             } else {
12214                 app = r.curApp;
12215             }
12216 
12217             if (app != null) {
12218                 appNotRespondingLocked(app, null, null,
12219                         "Broadcast of " + r.intent.toString());
12220             }
12221 
12222             if (mPendingBroadcast == r) {
12223                 mPendingBroadcast = null;
12224             }
12225 
12226             // Move on to the next receiver.
12227             finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12228                     r.resultExtras, r.resultAbort, true);
12229             scheduleBroadcastsLocked();
12230         }
12231     }
12232 
processCurBroadcastLocked(BroadcastRecord r, ProcessRecord app)12233     private final void processCurBroadcastLocked(BroadcastRecord r,
12234             ProcessRecord app) throws RemoteException {
12235         if (app.thread == null) {
12236             throw new RemoteException();
12237         }
12238         r.receiver = app.thread.asBinder();
12239         r.curApp = app;
12240         app.curReceiver = r;
12241         updateLRUListLocked(app, true);
12242 
12243         // Tell the application to launch this receiver.
12244         r.intent.setComponent(r.curComponent);
12245 
12246         boolean started = false;
12247         try {
12248             if (DEBUG_BROADCAST_LIGHT) Log.v(TAG,
12249                     "Delivering to component " + r.curComponent
12250                     + ": " + r);
12251             ensurePackageDexOpt(r.intent.getComponent().getPackageName());
12252             app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
12253                     r.resultCode, r.resultData, r.resultExtras, r.ordered);
12254             started = true;
12255         } finally {
12256             if (!started) {
12257                 r.receiver = null;
12258                 r.curApp = null;
12259                 app.curReceiver = null;
12260             }
12261         }
12262 
12263     }
12264 
performReceive(ProcessRecord app, IIntentReceiver receiver, Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky)12265     static void performReceive(ProcessRecord app, IIntentReceiver receiver,
12266             Intent intent, int resultCode, String data, Bundle extras,
12267             boolean ordered, boolean sticky) throws RemoteException {
12268         if (app != null && app.thread != null) {
12269             // If we have an app thread, do the call through that so it is
12270             // correctly ordered with other one-way calls.
12271             app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
12272                     data, extras, ordered, sticky);
12273         } else {
12274             receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
12275         }
12276     }
12277 
deliverToRegisteredReceiver(BroadcastRecord r, BroadcastFilter filter, boolean ordered)12278     private final void deliverToRegisteredReceiver(BroadcastRecord r,
12279             BroadcastFilter filter, boolean ordered) {
12280         boolean skip = false;
12281         if (filter.requiredPermission != null) {
12282             int perm = checkComponentPermission(filter.requiredPermission,
12283                     r.callingPid, r.callingUid, -1);
12284             if (perm != PackageManager.PERMISSION_GRANTED) {
12285                 Log.w(TAG, "Permission Denial: broadcasting "
12286                         + r.intent.toString()
12287                         + " from " + r.callerPackage + " (pid="
12288                         + r.callingPid + ", uid=" + r.callingUid + ")"
12289                         + " requires " + filter.requiredPermission
12290                         + " due to registered receiver " + filter);
12291                 skip = true;
12292             }
12293         }
12294         if (r.requiredPermission != null) {
12295             int perm = checkComponentPermission(r.requiredPermission,
12296                     filter.receiverList.pid, filter.receiverList.uid, -1);
12297             if (perm != PackageManager.PERMISSION_GRANTED) {
12298                 Log.w(TAG, "Permission Denial: receiving "
12299                         + r.intent.toString()
12300                         + " to " + filter.receiverList.app
12301                         + " (pid=" + filter.receiverList.pid
12302                         + ", uid=" + filter.receiverList.uid + ")"
12303                         + " requires " + r.requiredPermission
12304                         + " due to sender " + r.callerPackage
12305                         + " (uid " + r.callingUid + ")");
12306                 skip = true;
12307             }
12308         }
12309 
12310         if (!skip) {
12311             // If this is not being sent as an ordered broadcast, then we
12312             // don't want to touch the fields that keep track of the current
12313             // state of ordered broadcasts.
12314             if (ordered) {
12315                 r.receiver = filter.receiverList.receiver.asBinder();
12316                 r.curFilter = filter;
12317                 filter.receiverList.curBroadcast = r;
12318                 r.state = BroadcastRecord.CALL_IN_RECEIVE;
12319                 if (filter.receiverList.app != null) {
12320                     // Bump hosting application to no longer be in background
12321                     // scheduling class.  Note that we can't do that if there
12322                     // isn't an app...  but we can only be in that case for
12323                     // things that directly call the IActivityManager API, which
12324                     // are already core system stuff so don't matter for this.
12325                     r.curApp = filter.receiverList.app;
12326                     filter.receiverList.app.curReceiver = r;
12327                     updateOomAdjLocked();
12328                 }
12329             }
12330             try {
12331                 if (DEBUG_BROADCAST_LIGHT) {
12332                     int seq = r.intent.getIntExtra("seq", -1);
12333                     Log.i(TAG, "Delivering to " + filter.receiverList.app
12334                             + " (seq=" + seq + "): " + r);
12335                 }
12336                 performReceive(filter.receiverList.app, filter.receiverList.receiver,
12337                     new Intent(r.intent), r.resultCode,
12338                     r.resultData, r.resultExtras, r.ordered, r.initialSticky);
12339                 if (ordered) {
12340                     r.state = BroadcastRecord.CALL_DONE_RECEIVE;
12341                 }
12342             } catch (RemoteException e) {
12343                 Log.w(TAG, "Failure sending broadcast " + r.intent, e);
12344                 if (ordered) {
12345                     r.receiver = null;
12346                     r.curFilter = null;
12347                     filter.receiverList.curBroadcast = null;
12348                     if (filter.receiverList.app != null) {
12349                         filter.receiverList.app.curReceiver = null;
12350                     }
12351                 }
12352             }
12353         }
12354     }
12355 
addBroadcastToHistoryLocked(BroadcastRecord r)12356     private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
12357         if (r.callingUid < 0) {
12358             // This was from a registerReceiver() call; ignore it.
12359             return;
12360         }
12361         System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
12362                 MAX_BROADCAST_HISTORY-1);
12363         r.finishTime = SystemClock.uptimeMillis();
12364         mBroadcastHistory[0] = r;
12365     }
12366 
processNextBroadcast(boolean fromMsg)12367     private final void processNextBroadcast(boolean fromMsg) {
12368         synchronized(this) {
12369             BroadcastRecord r;
12370 
12371             if (DEBUG_BROADCAST) Log.v(TAG, "processNextBroadcast: "
12372                     + mParallelBroadcasts.size() + " broadcasts, "
12373                     + mOrderedBroadcasts.size() + " serialized broadcasts");
12374 
12375             updateCpuStats();
12376 
12377             if (fromMsg) {
12378                 mBroadcastsScheduled = false;
12379             }
12380 
12381             // First, deliver any non-serialized broadcasts right away.
12382             while (mParallelBroadcasts.size() > 0) {
12383                 r = mParallelBroadcasts.remove(0);
12384                 r.dispatchTime = SystemClock.uptimeMillis();
12385                 final int N = r.receivers.size();
12386                 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Processing parallel broadcast "
12387                         + r);
12388                 for (int i=0; i<N; i++) {
12389                     Object target = r.receivers.get(i);
12390                     if (DEBUG_BROADCAST)  Log.v(TAG,
12391                             "Delivering non-serialized to registered "
12392                             + target + ": " + r);
12393                     deliverToRegisteredReceiver(r, (BroadcastFilter)target, false);
12394                 }
12395                 addBroadcastToHistoryLocked(r);
12396                 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Done with parallel broadcast "
12397                         + r);
12398             }
12399 
12400             // Now take care of the next serialized one...
12401 
12402             // If we are waiting for a process to come up to handle the next
12403             // broadcast, then do nothing at this point.  Just in case, we
12404             // check that the process we're waiting for still exists.
12405             if (mPendingBroadcast != null) {
12406                 if (DEBUG_BROADCAST_LIGHT) {
12407                     Log.v(TAG, "processNextBroadcast: waiting for "
12408                             + mPendingBroadcast.curApp);
12409                 }
12410 
12411                 boolean isDead;
12412                 synchronized (mPidsSelfLocked) {
12413                     isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12414                 }
12415                 if (!isDead) {
12416                     // It's still alive, so keep waiting
12417                     return;
12418                 } else {
12419                     Log.w(TAG, "pending app " + mPendingBroadcast.curApp
12420                             + " died before responding to broadcast");
12421                     mPendingBroadcast = null;
12422                 }
12423             }
12424 
12425             boolean looped = false;
12426 
12427             do {
12428                 if (mOrderedBroadcasts.size() == 0) {
12429                     // No more broadcasts pending, so all done!
12430                     scheduleAppGcsLocked();
12431                     if (looped) {
12432                         // If we had finished the last ordered broadcast, then
12433                         // make sure all processes have correct oom and sched
12434                         // adjustments.
12435                         updateOomAdjLocked();
12436                     }
12437                     return;
12438                 }
12439                 r = mOrderedBroadcasts.get(0);
12440                 boolean forceReceive = false;
12441 
12442                 // Ensure that even if something goes awry with the timeout
12443                 // detection, we catch "hung" broadcasts here, discard them,
12444                 // and continue to make progress.
12445                 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
12446                 long now = SystemClock.uptimeMillis();
12447                 if (r.dispatchTime > 0) {
12448                     if ((numReceivers > 0) &&
12449                             (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
12450                         Log.w(TAG, "Hung broadcast discarded after timeout failure:"
12451                                 + " now=" + now
12452                                 + " dispatchTime=" + r.dispatchTime
12453                                 + " startTime=" + r.receiverTime
12454                                 + " intent=" + r.intent
12455                                 + " numReceivers=" + numReceivers
12456                                 + " nextReceiver=" + r.nextReceiver
12457                                 + " state=" + r.state);
12458                         broadcastTimeout(); // forcibly finish this broadcast
12459                         forceReceive = true;
12460                         r.state = BroadcastRecord.IDLE;
12461                     }
12462                 }
12463 
12464                 if (r.state != BroadcastRecord.IDLE) {
12465                     if (DEBUG_BROADCAST) Log.d(TAG,
12466                             "processNextBroadcast() called when not idle (state="
12467                             + r.state + ")");
12468                     return;
12469                 }
12470 
12471                 if (r.receivers == null || r.nextReceiver >= numReceivers
12472                         || r.resultAbort || forceReceive) {
12473                     // No more receivers for this broadcast!  Send the final
12474                     // result if requested...
12475                     if (r.resultTo != null) {
12476                         try {
12477                             if (DEBUG_BROADCAST) {
12478                                 int seq = r.intent.getIntExtra("seq", -1);
12479                                 Log.i(TAG, "Finishing broadcast " + r.intent.getAction()
12480                                         + " seq=" + seq + " app=" + r.callerApp);
12481                             }
12482                             performReceive(r.callerApp, r.resultTo,
12483                                 new Intent(r.intent), r.resultCode,
12484                                 r.resultData, r.resultExtras, false, false);
12485                         } catch (RemoteException e) {
12486                             Log.w(TAG, "Failure sending broadcast result of " + r.intent, e);
12487                         }
12488                     }
12489 
12490                     if (DEBUG_BROADCAST) Log.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
12491                     mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
12492 
12493                     if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Finished with ordered broadcast "
12494                             + r);
12495 
12496                     // ... and on to the next...
12497                     addBroadcastToHistoryLocked(r);
12498                     mOrderedBroadcasts.remove(0);
12499                     r = null;
12500                     looped = true;
12501                     continue;
12502                 }
12503             } while (r == null);
12504 
12505             // Get the next receiver...
12506             int recIdx = r.nextReceiver++;
12507 
12508             // Keep track of when this receiver started, and make sure there
12509             // is a timeout message pending to kill it if need be.
12510             r.receiverTime = SystemClock.uptimeMillis();
12511             if (recIdx == 0) {
12512                 r.dispatchTime = r.receiverTime;
12513 
12514                 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Processing ordered broadcast "
12515                         + r);
12516                 if (DEBUG_BROADCAST) Log.v(TAG,
12517                         "Submitting BROADCAST_TIMEOUT_MSG for "
12518                         + (r.receiverTime + BROADCAST_TIMEOUT));
12519                 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
12520                 mHandler.sendMessageAtTime(msg, r.receiverTime+BROADCAST_TIMEOUT);
12521             }
12522 
12523             Object nextReceiver = r.receivers.get(recIdx);
12524             if (nextReceiver instanceof BroadcastFilter) {
12525                 // Simple case: this is a registered receiver who gets
12526                 // a direct call.
12527                 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
12528                 if (DEBUG_BROADCAST)  Log.v(TAG,
12529                         "Delivering serialized to registered "
12530                         + filter + ": " + r);
12531                 deliverToRegisteredReceiver(r, filter, r.ordered);
12532                 if (r.receiver == null || !r.ordered) {
12533                     // The receiver has already finished, so schedule to
12534                     // process the next one.
12535                     r.state = BroadcastRecord.IDLE;
12536                     scheduleBroadcastsLocked();
12537                 }
12538                 return;
12539             }
12540 
12541             // Hard case: need to instantiate the receiver, possibly
12542             // starting its application process to host it.
12543 
12544             ResolveInfo info =
12545                 (ResolveInfo)nextReceiver;
12546 
12547             boolean skip = false;
12548             int perm = checkComponentPermission(info.activityInfo.permission,
12549                     r.callingPid, r.callingUid,
12550                     info.activityInfo.exported
12551                             ? -1 : info.activityInfo.applicationInfo.uid);
12552             if (perm != PackageManager.PERMISSION_GRANTED) {
12553                 Log.w(TAG, "Permission Denial: broadcasting "
12554                         + r.intent.toString()
12555                         + " from " + r.callerPackage + " (pid=" + r.callingPid
12556                         + ", uid=" + r.callingUid + ")"
12557                         + " requires " + info.activityInfo.permission
12558                         + " due to receiver " + info.activityInfo.packageName
12559                         + "/" + info.activityInfo.name);
12560                 skip = true;
12561             }
12562             if (r.callingUid != Process.SYSTEM_UID &&
12563                 r.requiredPermission != null) {
12564                 try {
12565                     perm = ActivityThread.getPackageManager().
12566                             checkPermission(r.requiredPermission,
12567                                     info.activityInfo.applicationInfo.packageName);
12568                 } catch (RemoteException e) {
12569                     perm = PackageManager.PERMISSION_DENIED;
12570                 }
12571                 if (perm != PackageManager.PERMISSION_GRANTED) {
12572                     Log.w(TAG, "Permission Denial: receiving "
12573                             + r.intent + " to "
12574                             + info.activityInfo.applicationInfo.packageName
12575                             + " requires " + r.requiredPermission
12576                             + " due to sender " + r.callerPackage
12577                             + " (uid " + r.callingUid + ")");
12578                     skip = true;
12579                 }
12580             }
12581             if (r.curApp != null && r.curApp.crashing) {
12582                 // If the target process is crashing, just skip it.
12583                 skip = true;
12584             }
12585 
12586             if (skip) {
12587                 r.receiver = null;
12588                 r.curFilter = null;
12589                 r.state = BroadcastRecord.IDLE;
12590                 scheduleBroadcastsLocked();
12591                 return;
12592             }
12593 
12594             r.state = BroadcastRecord.APP_RECEIVE;
12595             String targetProcess = info.activityInfo.processName;
12596             r.curComponent = new ComponentName(
12597                     info.activityInfo.applicationInfo.packageName,
12598                     info.activityInfo.name);
12599             r.curReceiver = info.activityInfo;
12600 
12601             // Is this receiver's application already running?
12602             ProcessRecord app = getProcessRecordLocked(targetProcess,
12603                     info.activityInfo.applicationInfo.uid);
12604             if (app != null && app.thread != null) {
12605                 try {
12606                     processCurBroadcastLocked(r, app);
12607                     return;
12608                 } catch (RemoteException e) {
12609                     Log.w(TAG, "Exception when sending broadcast to "
12610                           + r.curComponent, e);
12611                 }
12612 
12613                 // If a dead object exception was thrown -- fall through to
12614                 // restart the application.
12615             }
12616 
12617             // Not running -- get it started, to be executed when the app comes up.
12618             if ((r.curApp=startProcessLocked(targetProcess,
12619                     info.activityInfo.applicationInfo, true,
12620                     r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
12621                     "broadcast", r.curComponent,
12622                     (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12623                             == null) {
12624                 // Ah, this recipient is unavailable.  Finish it if necessary,
12625                 // and mark the broadcast record as ready for the next.
12626                 Log.w(TAG, "Unable to launch app "
12627                         + info.activityInfo.applicationInfo.packageName + "/"
12628                         + info.activityInfo.applicationInfo.uid + " for broadcast "
12629                         + r.intent + ": process is bad");
12630                 logBroadcastReceiverDiscard(r);
12631                 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12632                         r.resultExtras, r.resultAbort, true);
12633                 scheduleBroadcastsLocked();
12634                 r.state = BroadcastRecord.IDLE;
12635                 return;
12636             }
12637 
12638             mPendingBroadcast = r;
12639         }
12640     }
12641 
12642     // =========================================================
12643     // INSTRUMENTATION
12644     // =========================================================
12645 
startInstrumentation(ComponentName className, String profileFile, int flags, Bundle arguments, IInstrumentationWatcher watcher)12646     public boolean startInstrumentation(ComponentName className,
12647             String profileFile, int flags, Bundle arguments,
12648             IInstrumentationWatcher watcher) {
12649         // Refuse possible leaked file descriptors
12650         if (arguments != null && arguments.hasFileDescriptors()) {
12651             throw new IllegalArgumentException("File descriptors passed in Bundle");
12652         }
12653 
12654         synchronized(this) {
12655             InstrumentationInfo ii = null;
12656             ApplicationInfo ai = null;
12657             try {
12658                 ii = mContext.getPackageManager().getInstrumentationInfo(
12659                     className, STOCK_PM_FLAGS);
12660                 ai = mContext.getPackageManager().getApplicationInfo(
12661                     ii.targetPackage, STOCK_PM_FLAGS);
12662             } catch (PackageManager.NameNotFoundException e) {
12663             }
12664             if (ii == null) {
12665                 reportStartInstrumentationFailure(watcher, className,
12666                         "Unable to find instrumentation info for: " + className);
12667                 return false;
12668             }
12669             if (ai == null) {
12670                 reportStartInstrumentationFailure(watcher, className,
12671                         "Unable to find instrumentation target package: " + ii.targetPackage);
12672                 return false;
12673             }
12674 
12675             int match = mContext.getPackageManager().checkSignatures(
12676                     ii.targetPackage, ii.packageName);
12677             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12678                 String msg = "Permission Denial: starting instrumentation "
12679                         + className + " from pid="
12680                         + Binder.getCallingPid()
12681                         + ", uid=" + Binder.getCallingPid()
12682                         + " not allowed because package " + ii.packageName
12683                         + " does not have a signature matching the target "
12684                         + ii.targetPackage;
12685                 reportStartInstrumentationFailure(watcher, className, msg);
12686                 throw new SecurityException(msg);
12687             }
12688 
12689             final long origId = Binder.clearCallingIdentity();
12690             uninstallPackageLocked(ii.targetPackage, -1, true);
12691             ProcessRecord app = addAppLocked(ai);
12692             app.instrumentationClass = className;
12693             app.instrumentationInfo = ai;
12694             app.instrumentationProfileFile = profileFile;
12695             app.instrumentationArguments = arguments;
12696             app.instrumentationWatcher = watcher;
12697             app.instrumentationResultClass = className;
12698             Binder.restoreCallingIdentity(origId);
12699         }
12700 
12701         return true;
12702     }
12703 
12704     /**
12705      * Report errors that occur while attempting to start Instrumentation.  Always writes the
12706      * error to the logs, but if somebody is watching, send the report there too.  This enables
12707      * the "am" command to report errors with more information.
12708      *
12709      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
12710      * @param cn The component name of the instrumentation.
12711      * @param report The error report.
12712      */
reportStartInstrumentationFailure(IInstrumentationWatcher watcher, ComponentName cn, String report)12713     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12714             ComponentName cn, String report) {
12715         Log.w(TAG, report);
12716         try {
12717             if (watcher != null) {
12718                 Bundle results = new Bundle();
12719                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12720                 results.putString("Error", report);
12721                 watcher.instrumentationStatus(cn, -1, results);
12722             }
12723         } catch (RemoteException e) {
12724             Log.w(TAG, e);
12725         }
12726     }
12727 
finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results)12728     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12729         if (app.instrumentationWatcher != null) {
12730             try {
12731                 // NOTE:  IInstrumentationWatcher *must* be oneway here
12732                 app.instrumentationWatcher.instrumentationFinished(
12733                     app.instrumentationClass,
12734                     resultCode,
12735                     results);
12736             } catch (RemoteException e) {
12737             }
12738         }
12739         app.instrumentationWatcher = null;
12740         app.instrumentationClass = null;
12741         app.instrumentationInfo = null;
12742         app.instrumentationProfileFile = null;
12743         app.instrumentationArguments = null;
12744 
12745         uninstallPackageLocked(app.processName, -1, false);
12746     }
12747 
finishInstrumentation(IApplicationThread target, int resultCode, Bundle results)12748     public void finishInstrumentation(IApplicationThread target,
12749             int resultCode, Bundle results) {
12750         // Refuse possible leaked file descriptors
12751         if (results != null && results.hasFileDescriptors()) {
12752             throw new IllegalArgumentException("File descriptors passed in Intent");
12753         }
12754 
12755         synchronized(this) {
12756             ProcessRecord app = getRecordForAppLocked(target);
12757             if (app == null) {
12758                 Log.w(TAG, "finishInstrumentation: no app for " + target);
12759                 return;
12760             }
12761             final long origId = Binder.clearCallingIdentity();
12762             finishInstrumentationLocked(app, resultCode, results);
12763             Binder.restoreCallingIdentity(origId);
12764         }
12765     }
12766 
12767     // =========================================================
12768     // CONFIGURATION
12769     // =========================================================
12770 
getDeviceConfigurationInfo()12771     public ConfigurationInfo getDeviceConfigurationInfo() {
12772         ConfigurationInfo config = new ConfigurationInfo();
12773         synchronized (this) {
12774             config.reqTouchScreen = mConfiguration.touchscreen;
12775             config.reqKeyboardType = mConfiguration.keyboard;
12776             config.reqNavigation = mConfiguration.navigation;
12777             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12778                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
12779                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12780             }
12781             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12782                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
12783                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12784             }
12785             config.reqGlEsVersion = GL_ES_VERSION;
12786         }
12787         return config;
12788     }
12789 
getConfiguration()12790     public Configuration getConfiguration() {
12791         Configuration ci;
12792         synchronized(this) {
12793             ci = new Configuration(mConfiguration);
12794         }
12795         return ci;
12796     }
12797 
updateConfiguration(Configuration values)12798     public void updateConfiguration(Configuration values) {
12799         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12800                 "updateConfiguration()");
12801 
12802         synchronized(this) {
12803             if (values == null && mWindowManager != null) {
12804                 // sentinel: fetch the current configuration from the window manager
12805                 values = mWindowManager.computeNewConfiguration();
12806             }
12807 
12808             final long origId = Binder.clearCallingIdentity();
12809             updateConfigurationLocked(values, null);
12810             Binder.restoreCallingIdentity(origId);
12811         }
12812     }
12813 
12814     /**
12815      * Do either or both things: (1) change the current configuration, and (2)
12816      * make sure the given activity is running with the (now) current
12817      * configuration.  Returns true if the activity has been left running, or
12818      * false if <var>starting</var> is being destroyed to match the new
12819      * configuration.
12820      */
updateConfigurationLocked(Configuration values, HistoryRecord starting)12821     public boolean updateConfigurationLocked(Configuration values,
12822             HistoryRecord starting) {
12823         int changes = 0;
12824 
12825         boolean kept = true;
12826 
12827         if (values != null) {
12828             Configuration newConfig = new Configuration(mConfiguration);
12829             changes = newConfig.updateFrom(values);
12830             if (changes != 0) {
12831                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12832                     Log.i(TAG, "Updating configuration to: " + values);
12833                 }
12834 
12835                 EventLog.writeEvent(LOG_CONFIGURATION_CHANGED, changes);
12836 
12837                 if (values.locale != null) {
12838                     saveLocaleLocked(values.locale,
12839                                      !values.locale.equals(mConfiguration.locale),
12840                                      values.userSetLocale);
12841                 }
12842 
12843                 mConfiguration = newConfig;
12844                 Log.i(TAG, "Config changed: " + newConfig);
12845 
12846                 AttributeCache ac = AttributeCache.instance();
12847                 if (ac != null) {
12848                     ac.updateConfiguration(mConfiguration);
12849                 }
12850 
12851                 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12852                 msg.obj = new Configuration(mConfiguration);
12853                 mHandler.sendMessage(msg);
12854 
12855                 final int N = mLRUProcesses.size();
12856                 for (int i=0; i<N; i++) {
12857                     ProcessRecord app = mLRUProcesses.get(i);
12858                     try {
12859                         if (app.thread != null) {
12860                             if (DEBUG_CONFIGURATION) Log.v(TAG, "Sending to proc "
12861                                     + app.processName + " new config " + mConfiguration);
12862                             app.thread.scheduleConfigurationChanged(mConfiguration);
12863                         }
12864                     } catch (Exception e) {
12865                     }
12866                 }
12867                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12868                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12869                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12870                         null, false, false, MY_PID, Process.SYSTEM_UID);
12871                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12872                     broadcastIntentLocked(null, null,
12873                             new Intent(Intent.ACTION_LOCALE_CHANGED),
12874                             null, null, 0, null, null,
12875                             null, false, false, MY_PID, Process.SYSTEM_UID);
12876                 }
12877             }
12878         }
12879 
12880         if (changes != 0 && starting == null) {
12881             // If the configuration changed, and the caller is not already
12882             // in the process of starting an activity, then find the top
12883             // activity to check if its configuration needs to change.
12884             starting = topRunningActivityLocked(null);
12885         }
12886 
12887         if (starting != null) {
12888             kept = ensureActivityConfigurationLocked(starting, changes);
12889             if (kept) {
12890                 // If this didn't result in the starting activity being
12891                 // destroyed, then we need to make sure at this point that all
12892                 // other activities are made visible.
12893                 if (DEBUG_SWITCH) Log.i(TAG, "Config didn't destroy " + starting
12894                         + ", ensuring others are correct.");
12895                 ensureActivitiesVisibleLocked(starting, changes);
12896             }
12897         }
12898 
12899         return kept;
12900     }
12901 
relaunchActivityLocked(HistoryRecord r, int changes, boolean andResume)12902     private final boolean relaunchActivityLocked(HistoryRecord r,
12903             int changes, boolean andResume) {
12904         List<ResultInfo> results = null;
12905         List<Intent> newIntents = null;
12906         if (andResume) {
12907             results = r.results;
12908             newIntents = r.newIntents;
12909         }
12910         if (DEBUG_SWITCH) Log.v(TAG, "Relaunching: " + r
12911                 + " with results=" + results + " newIntents=" + newIntents
12912                 + " andResume=" + andResume);
12913         EventLog.writeEvent(andResume ? LOG_AM_RELAUNCH_RESUME_ACTIVITY
12914                 : LOG_AM_RELAUNCH_ACTIVITY, System.identityHashCode(r),
12915                 r.task.taskId, r.shortComponentName);
12916 
12917         r.startFreezingScreenLocked(r.app, 0);
12918 
12919         try {
12920             if (DEBUG_SWITCH) Log.i(TAG, "Switch is restarting resumed " + r);
12921             r.app.thread.scheduleRelaunchActivity(r, results, newIntents,
12922                     changes, !andResume);
12923             // Note: don't need to call pauseIfSleepingLocked() here, because
12924             // the caller will only pass in 'andResume' if this activity is
12925             // currently resumed, which implies we aren't sleeping.
12926         } catch (RemoteException e) {
12927             return false;
12928         }
12929 
12930         if (andResume) {
12931             r.results = null;
12932             r.newIntents = null;
12933             reportResumedActivityLocked(r);
12934         }
12935 
12936         return true;
12937     }
12938 
12939     /**
12940      * Make sure the given activity matches the current configuration.  Returns
12941      * false if the activity had to be destroyed.  Returns true if the
12942      * configuration is the same, or the activity will remain running as-is
12943      * for whatever reason.  Ensures the HistoryRecord is updated with the
12944      * correct configuration and all other bookkeeping is handled.
12945      */
ensureActivityConfigurationLocked(HistoryRecord r, int globalChanges)12946     private final boolean ensureActivityConfigurationLocked(HistoryRecord r,
12947             int globalChanges) {
12948         if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
12949                 "Ensuring correct configuration: " + r);
12950 
12951         // Short circuit: if the two configurations are the exact same
12952         // object (the common case), then there is nothing to do.
12953         Configuration newConfig = mConfiguration;
12954         if (r.configuration == newConfig) {
12955             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
12956                     "Configuration unchanged in " + r);
12957             return true;
12958         }
12959 
12960         // We don't worry about activities that are finishing.
12961         if (r.finishing) {
12962             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
12963                     "Configuration doesn't matter in finishing " + r);
12964             r.stopFreezingScreenLocked(false);
12965             return true;
12966         }
12967 
12968         // Okay we now are going to make this activity have the new config.
12969         // But then we need to figure out how it needs to deal with that.
12970         Configuration oldConfig = r.configuration;
12971         r.configuration = newConfig;
12972 
12973         // If the activity isn't currently running, just leave the new
12974         // configuration and it will pick that up next time it starts.
12975         if (r.app == null || r.app.thread == null) {
12976             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
12977                     "Configuration doesn't matter not running " + r);
12978             r.stopFreezingScreenLocked(false);
12979             return true;
12980         }
12981 
12982         // If the activity isn't persistent, there is a chance we will
12983         // need to restart it.
12984         if (!r.persistent) {
12985 
12986             // Figure out what has changed between the two configurations.
12987             int changes = oldConfig.diff(newConfig);
12988             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12989                 Log.v(TAG, "Checking to restart " + r.info.name + ": changed=0x"
12990                         + Integer.toHexString(changes) + ", handles=0x"
12991                         + Integer.toHexString(r.info.configChanges)
12992                         + ", newConfig=" + newConfig);
12993             }
12994             if ((changes&(~r.info.configChanges)) != 0) {
12995                 // Aha, the activity isn't handling the change, so DIE DIE DIE.
12996                 r.configChangeFlags |= changes;
12997                 r.startFreezingScreenLocked(r.app, globalChanges);
12998                 if (r.app == null || r.app.thread == null) {
12999                     if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
13000                             "Switch is destroying non-running " + r);
13001                     destroyActivityLocked(r, true);
13002                 } else if (r.state == ActivityState.PAUSING) {
13003                     // A little annoying: we are waiting for this activity to
13004                     // finish pausing.  Let's not do anything now, but just
13005                     // flag that it needs to be restarted when done pausing.
13006                     if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
13007                             "Switch is skipping already pausing " + r);
13008                     r.configDestroy = true;
13009                     return true;
13010                 } else if (r.state == ActivityState.RESUMED) {
13011                     // Try to optimize this case: the configuration is changing
13012                     // and we need to restart the top, resumed activity.
13013                     // Instead of doing the normal handshaking, just say
13014                     // "restart!".
13015                     if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
13016                             "Switch is restarting resumed " + r);
13017                     relaunchActivityLocked(r, r.configChangeFlags, true);
13018                     r.configChangeFlags = 0;
13019                 } else {
13020                     if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
13021                             "Switch is restarting non-resumed " + r);
13022                     relaunchActivityLocked(r, r.configChangeFlags, false);
13023                     r.configChangeFlags = 0;
13024                 }
13025 
13026                 // All done...  tell the caller we weren't able to keep this
13027                 // activity around.
13028                 return false;
13029             }
13030         }
13031 
13032         // Default case: the activity can handle this new configuration, so
13033         // hand it over.  Note that we don't need to give it the new
13034         // configuration, since we always send configuration changes to all
13035         // process when they happen so it can just use whatever configuration
13036         // it last got.
13037         if (r.app != null && r.app.thread != null) {
13038             try {
13039                 if (DEBUG_CONFIGURATION) Log.v(TAG, "Sending new config to " + r);
13040                 r.app.thread.scheduleActivityConfigurationChanged(r);
13041             } catch (RemoteException e) {
13042                 // If process died, whatever.
13043             }
13044         }
13045         r.stopFreezingScreenLocked(false);
13046 
13047         return true;
13048     }
13049 
13050     /**
13051      * Save the locale.  You must be inside a synchronized (this) block.
13052      */
saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist)13053     private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
13054         if(isDiff) {
13055             SystemProperties.set("user.language", l.getLanguage());
13056             SystemProperties.set("user.region", l.getCountry());
13057         }
13058 
13059         if(isPersist) {
13060             SystemProperties.set("persist.sys.language", l.getLanguage());
13061             SystemProperties.set("persist.sys.country", l.getCountry());
13062             SystemProperties.set("persist.sys.localevar", l.getVariant());
13063         }
13064     }
13065 
13066     // =========================================================
13067     // LIFETIME MANAGEMENT
13068     // =========================================================
13069 
computeOomAdjLocked( ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP)13070     private final int computeOomAdjLocked(
13071         ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
13072         if (mAdjSeq == app.adjSeq) {
13073             // This adjustment has already been computed.
13074             return app.curAdj;
13075         }
13076 
13077         if (app.thread == null) {
13078             app.adjSeq = mAdjSeq;
13079             return (app.curAdj=EMPTY_APP_ADJ);
13080         }
13081 
13082         if (app.maxAdj <= FOREGROUND_APP_ADJ) {
13083             // The max adjustment doesn't allow this app to be anything
13084             // below foreground, so it is not worth doing work for it.
13085             app.adjType = "fixed";
13086             app.adjSeq = mAdjSeq;
13087             app.curRawAdj = app.maxAdj;
13088             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
13089             return (app.curAdj=app.maxAdj);
13090        }
13091 
13092         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
13093         app.adjSource = null;
13094         app.adjTarget = null;
13095 
13096         // Determine the importance of the process, starting with most
13097         // important to least, and assign an appropriate OOM adjustment.
13098         int adj;
13099         int N;
13100         if (app == TOP_APP) {
13101             // The last app on the list is the foreground app.
13102             adj = FOREGROUND_APP_ADJ;
13103             app.adjType = "top-activity";
13104         } else if (app.instrumentationClass != null) {
13105             // Don't want to kill running instrumentation.
13106             adj = FOREGROUND_APP_ADJ;
13107             app.adjType = "instrumentation";
13108         } else if (app.persistentActivities > 0) {
13109             // Special persistent activities...  shouldn't be used these days.
13110             adj = FOREGROUND_APP_ADJ;
13111             app.adjType = "persistent";
13112         } else if (app.curReceiver != null ||
13113                 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
13114             // An app that is currently receiving a broadcast also
13115             // counts as being in the foreground.
13116             adj = FOREGROUND_APP_ADJ;
13117             app.adjType = "broadcast";
13118         } else if (app.executingServices.size() > 0) {
13119             // An app that is currently executing a service callback also
13120             // counts as being in the foreground.
13121             adj = FOREGROUND_APP_ADJ;
13122             app.adjType = "exec-service";
13123         } else if (app.foregroundServices) {
13124             // The user is aware of this app, so make it visible.
13125             adj = VISIBLE_APP_ADJ;
13126             app.adjType = "foreground-service";
13127         } else if (app.forcingToForeground != null) {
13128             // The user is aware of this app, so make it visible.
13129             adj = VISIBLE_APP_ADJ;
13130             app.adjType = "force-foreground";
13131             app.adjSource = app.forcingToForeground;
13132         } else if (app == mHomeProcess) {
13133             // This process is hosting what we currently consider to be the
13134             // home app, so we don't want to let it go into the background.
13135             adj = HOME_APP_ADJ;
13136             app.adjType = "home";
13137         } else if ((N=app.activities.size()) != 0) {
13138             // This app is in the background with paused activities.
13139             adj = hiddenAdj;
13140             app.adjType = "bg-activities";
13141             for (int j=0; j<N; j++) {
13142                 if (((HistoryRecord)app.activities.get(j)).visible) {
13143                     // This app has a visible activity!
13144                     adj = VISIBLE_APP_ADJ;
13145                     app.adjType = "visible";
13146                     break;
13147                 }
13148             }
13149         } else {
13150             // A very not-needed process.
13151             adj = EMPTY_APP_ADJ;
13152             app.adjType = "empty";
13153         }
13154 
13155         // By default, we use the computed adjustment.  It may be changed if
13156         // there are applications dependent on our services or providers, but
13157         // this gives us a baseline and makes sure we don't get into an
13158         // infinite recursion.
13159         app.adjSeq = mAdjSeq;
13160         app.curRawAdj = adj;
13161         app.curAdj = adj <= app.maxAdj ? adj : app.maxAdj;
13162 
13163         if (mBackupTarget != null && app == mBackupTarget.app) {
13164             // If possible we want to avoid killing apps while they're being backed up
13165             if (adj > BACKUP_APP_ADJ) {
13166                 if (DEBUG_BACKUP) Log.v(TAG, "oom BACKUP_APP_ADJ for " + app);
13167                 adj = BACKUP_APP_ADJ;
13168                 app.adjType = "backup";
13169             }
13170         }
13171 
13172         if (app.services.size() != 0 && adj > FOREGROUND_APP_ADJ) {
13173             final long now = SystemClock.uptimeMillis();
13174             // This process is more important if the top activity is
13175             // bound to the service.
13176             Iterator jt = app.services.iterator();
13177             while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
13178                 ServiceRecord s = (ServiceRecord)jt.next();
13179                 if (s.startRequested) {
13180                     if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13181                         // This service has seen some activity within
13182                         // recent memory, so we will keep its process ahead
13183                         // of the background processes.
13184                         if (adj > SECONDARY_SERVER_ADJ) {
13185                             adj = SECONDARY_SERVER_ADJ;
13186                             app.adjType = "started-services";
13187                         }
13188                     }
13189                 }
13190                 if (s.connections.size() > 0 && adj > FOREGROUND_APP_ADJ) {
13191                     Iterator<ConnectionRecord> kt
13192                             = s.connections.values().iterator();
13193                     while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
13194                         // XXX should compute this based on the max of
13195                         // all connected clients.
13196                         ConnectionRecord cr = kt.next();
13197                         if (cr.binding.client == app) {
13198                             // Binding to ourself is not interesting.
13199                             continue;
13200                         }
13201                         if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
13202                             ProcessRecord client = cr.binding.client;
13203                             int myHiddenAdj = hiddenAdj;
13204                             if (myHiddenAdj > client.hiddenAdj) {
13205                                 if (client.hiddenAdj > VISIBLE_APP_ADJ) {
13206                                     myHiddenAdj = client.hiddenAdj;
13207                                 } else {
13208                                     myHiddenAdj = VISIBLE_APP_ADJ;
13209                                 }
13210                             }
13211                             int clientAdj = computeOomAdjLocked(
13212                                 client, myHiddenAdj, TOP_APP);
13213                             if (adj > clientAdj) {
13214                                 adj = clientAdj > VISIBLE_APP_ADJ
13215                                         ? clientAdj : VISIBLE_APP_ADJ;
13216                                 app.adjType = "service";
13217                                 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13218                                         .REASON_SERVICE_IN_USE;
13219                                 app.adjSource = cr.binding.client;
13220                                 app.adjTarget = s.serviceInfo.name;
13221                             }
13222                         }
13223                         HistoryRecord a = cr.activity;
13224                         //if (a != null) {
13225                         //    Log.i(TAG, "Connection to " + a ": state=" + a.state);
13226                         //}
13227                         if (a != null && adj > FOREGROUND_APP_ADJ &&
13228                                 (a.state == ActivityState.RESUMED
13229                                  || a.state == ActivityState.PAUSING)) {
13230                             adj = FOREGROUND_APP_ADJ;
13231                             app.adjType = "service";
13232                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13233                                     .REASON_SERVICE_IN_USE;
13234                             app.adjSource = a;
13235                             app.adjTarget = s.serviceInfo.name;
13236                         }
13237                     }
13238                 }
13239             }
13240 
13241             // Finally, f this process has active services running in it, we
13242             // would like to avoid killing it unless it would prevent the current
13243             // application from running.  By default we put the process in
13244             // with the rest of the background processes; as we scan through
13245             // its services we may bump it up from there.
13246             if (adj > hiddenAdj) {
13247                 adj = hiddenAdj;
13248                 app.adjType = "bg-services";
13249             }
13250         }
13251 
13252         if (app.pubProviders.size() != 0 && adj > FOREGROUND_APP_ADJ) {
13253             Iterator jt = app.pubProviders.values().iterator();
13254             while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
13255                 ContentProviderRecord cpr = (ContentProviderRecord)jt.next();
13256                 if (cpr.clients.size() != 0) {
13257                     Iterator<ProcessRecord> kt = cpr.clients.iterator();
13258                     while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
13259                         ProcessRecord client = kt.next();
13260                         if (client == app) {
13261                             // Being our own client is not interesting.
13262                             continue;
13263                         }
13264                         int myHiddenAdj = hiddenAdj;
13265                         if (myHiddenAdj > client.hiddenAdj) {
13266                             if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
13267                                 myHiddenAdj = client.hiddenAdj;
13268                             } else {
13269                                 myHiddenAdj = FOREGROUND_APP_ADJ;
13270                             }
13271                         }
13272                         int clientAdj = computeOomAdjLocked(
13273                             client, myHiddenAdj, TOP_APP);
13274                         if (adj > clientAdj) {
13275                             adj = clientAdj > FOREGROUND_APP_ADJ
13276                                     ? clientAdj : FOREGROUND_APP_ADJ;
13277                             app.adjType = "provider";
13278                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13279                                     .REASON_PROVIDER_IN_USE;
13280                             app.adjSource = client;
13281                             app.adjTarget = cpr.info.name;
13282                         }
13283                     }
13284                 }
13285                 // If the provider has external (non-framework) process
13286                 // dependencies, ensure that its adjustment is at least
13287                 // FOREGROUND_APP_ADJ.
13288                 if (cpr.externals != 0) {
13289                     if (adj > FOREGROUND_APP_ADJ) {
13290                         adj = FOREGROUND_APP_ADJ;
13291                         app.adjType = "provider";
13292                         app.adjTarget = cpr.info.name;
13293                     }
13294                 }
13295             }
13296 
13297             // Finally, if this process has published any content providers,
13298             // then its adjustment makes it at least as important as any of the
13299             // processes using those providers, and no less important than
13300             // CONTENT_PROVIDER_ADJ, which is just shy of EMPTY.
13301             if (adj > CONTENT_PROVIDER_ADJ) {
13302                 adj = CONTENT_PROVIDER_ADJ;
13303                 app.adjType = "pub-providers";
13304             }
13305         }
13306 
13307         app.curRawAdj = adj;
13308 
13309         //Log.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
13310         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13311         if (adj > app.maxAdj) {
13312             adj = app.maxAdj;
13313         }
13314 
13315         app.curAdj = adj;
13316         app.curSchedGroup = adj > VISIBLE_APP_ADJ
13317                 ? Process.THREAD_GROUP_BG_NONINTERACTIVE
13318                 : Process.THREAD_GROUP_DEFAULT;
13319 
13320         return adj;
13321     }
13322 
13323     /**
13324      * Ask a given process to GC right now.
13325      */
performAppGcLocked(ProcessRecord app)13326     final void performAppGcLocked(ProcessRecord app) {
13327         try {
13328             app.lastRequestedGc = SystemClock.uptimeMillis();
13329             if (app.thread != null) {
13330                 if (app.reportLowMemory) {
13331                     app.reportLowMemory = false;
13332                     app.thread.scheduleLowMemory();
13333                 } else {
13334                     app.thread.processInBackground();
13335                 }
13336             }
13337         } catch (Exception e) {
13338             // whatever.
13339         }
13340     }
13341 
13342     /**
13343      * Returns true if things are idle enough to perform GCs.
13344      */
canGcNow()13345     private final boolean canGcNow() {
13346         return mParallelBroadcasts.size() == 0
13347                 && mOrderedBroadcasts.size() == 0
13348                 && (mSleeping || (mResumedActivity != null &&
13349                         mResumedActivity.idle));
13350     }
13351 
13352     /**
13353      * Perform GCs on all processes that are waiting for it, but only
13354      * if things are idle.
13355      */
performAppGcsLocked()13356     final void performAppGcsLocked() {
13357         final int N = mProcessesToGc.size();
13358         if (N <= 0) {
13359             return;
13360         }
13361         if (canGcNow()) {
13362             while (mProcessesToGc.size() > 0) {
13363                 ProcessRecord proc = mProcessesToGc.remove(0);
13364                 if (proc.curRawAdj > VISIBLE_APP_ADJ || proc.reportLowMemory) {
13365                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13366                             <= SystemClock.uptimeMillis()) {
13367                         // To avoid spamming the system, we will GC processes one
13368                         // at a time, waiting a few seconds between each.
13369                         performAppGcLocked(proc);
13370                         scheduleAppGcsLocked();
13371                         return;
13372                     } else {
13373                         // It hasn't been long enough since we last GCed this
13374                         // process...  put it in the list to wait for its time.
13375                         addProcessToGcListLocked(proc);
13376                         break;
13377                     }
13378                 }
13379             }
13380 
13381             scheduleAppGcsLocked();
13382         }
13383     }
13384 
13385     /**
13386      * If all looks good, perform GCs on all processes waiting for them.
13387      */
performAppGcsIfAppropriateLocked()13388     final void performAppGcsIfAppropriateLocked() {
13389         if (canGcNow()) {
13390             performAppGcsLocked();
13391             return;
13392         }
13393         // Still not idle, wait some more.
13394         scheduleAppGcsLocked();
13395     }
13396 
13397     /**
13398      * Schedule the execution of all pending app GCs.
13399      */
scheduleAppGcsLocked()13400     final void scheduleAppGcsLocked() {
13401         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
13402 
13403         if (mProcessesToGc.size() > 0) {
13404             // Schedule a GC for the time to the next process.
13405             ProcessRecord proc = mProcessesToGc.get(0);
13406             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13407 
13408             long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL;
13409             long now = SystemClock.uptimeMillis();
13410             if (when < (now+GC_TIMEOUT)) {
13411                 when = now + GC_TIMEOUT;
13412             }
13413             mHandler.sendMessageAtTime(msg, when);
13414         }
13415     }
13416 
13417     /**
13418      * Add a process to the array of processes waiting to be GCed.  Keeps the
13419      * list in sorted order by the last GC time.  The process can't already be
13420      * on the list.
13421      */
addProcessToGcListLocked(ProcessRecord proc)13422     final void addProcessToGcListLocked(ProcessRecord proc) {
13423         boolean added = false;
13424         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13425             if (mProcessesToGc.get(i).lastRequestedGc <
13426                     proc.lastRequestedGc) {
13427                 added = true;
13428                 mProcessesToGc.add(i+1, proc);
13429                 break;
13430             }
13431         }
13432         if (!added) {
13433             mProcessesToGc.add(0, proc);
13434         }
13435     }
13436 
13437     /**
13438      * Set up to ask a process to GC itself.  This will either do it
13439      * immediately, or put it on the list of processes to gc the next
13440      * time things are idle.
13441      */
scheduleAppGcLocked(ProcessRecord app)13442     final void scheduleAppGcLocked(ProcessRecord app) {
13443         long now = SystemClock.uptimeMillis();
13444         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13445             return;
13446         }
13447         if (!mProcessesToGc.contains(app)) {
13448             addProcessToGcListLocked(app);
13449             scheduleAppGcsLocked();
13450         }
13451     }
13452 
updateOomAdjLocked( ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP)13453     private final boolean updateOomAdjLocked(
13454         ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
13455         app.hiddenAdj = hiddenAdj;
13456 
13457         if (app.thread == null) {
13458             return true;
13459         }
13460 
13461         int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP);
13462 
13463         if (app.pid != 0 && app.pid != MY_PID) {
13464             if (app.curRawAdj != app.setRawAdj) {
13465                 if (app.curRawAdj > FOREGROUND_APP_ADJ
13466                         && app.setRawAdj <= FOREGROUND_APP_ADJ) {
13467                     // If this app is transitioning from foreground to
13468                     // non-foreground, have it do a gc.
13469                     scheduleAppGcLocked(app);
13470                 } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
13471                         && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
13472                     // Likewise do a gc when an app is moving in to the
13473                     // background (such as a service stopping).
13474                     scheduleAppGcLocked(app);
13475                 }
13476                 app.setRawAdj = app.curRawAdj;
13477             }
13478             if (adj != app.setAdj) {
13479                 if (Process.setOomAdj(app.pid, adj)) {
13480                     if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v(
13481                         TAG, "Set app " + app.processName +
13482                         " oom adj to " + adj);
13483                     app.setAdj = adj;
13484                 } else {
13485                     return false;
13486                 }
13487             }
13488             if (app.setSchedGroup != app.curSchedGroup) {
13489                 app.setSchedGroup = app.curSchedGroup;
13490                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v(TAG,
13491                         "Setting process group of " + app.processName
13492                         + " to " + app.curSchedGroup);
13493                 if (true) {
13494                     long oldId = Binder.clearCallingIdentity();
13495                     try {
13496                         Process.setProcessGroup(app.pid, app.curSchedGroup);
13497                     } catch (Exception e) {
13498                         Log.w(TAG, "Failed setting process group of " + app.pid
13499                                 + " to " + app.curSchedGroup);
13500                         e.printStackTrace();
13501                     } finally {
13502                         Binder.restoreCallingIdentity(oldId);
13503                     }
13504                 }
13505                 if (false) {
13506                     if (app.thread != null) {
13507                         try {
13508                             app.thread.setSchedulingGroup(app.curSchedGroup);
13509                         } catch (RemoteException e) {
13510                         }
13511                     }
13512                 }
13513             }
13514         }
13515 
13516         return true;
13517     }
13518 
resumedAppLocked()13519     private final HistoryRecord resumedAppLocked() {
13520         HistoryRecord resumedActivity = mResumedActivity;
13521         if (resumedActivity == null || resumedActivity.app == null) {
13522             resumedActivity = mPausingActivity;
13523             if (resumedActivity == null || resumedActivity.app == null) {
13524                 resumedActivity = topRunningActivityLocked(null);
13525             }
13526         }
13527         return resumedActivity;
13528     }
13529 
updateOomAdjLocked(ProcessRecord app)13530     private final boolean updateOomAdjLocked(ProcessRecord app) {
13531         final HistoryRecord TOP_ACT = resumedAppLocked();
13532         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13533         int curAdj = app.curAdj;
13534         final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
13535             && app.curAdj <= HIDDEN_APP_MAX_ADJ;
13536 
13537         mAdjSeq++;
13538 
13539         final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
13540         if (res) {
13541             final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
13542                 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
13543             if (nowHidden != wasHidden) {
13544                 // Changed to/from hidden state, so apps after it in the LRU
13545                 // list may also be changed.
13546                 updateOomAdjLocked();
13547             }
13548         }
13549         return res;
13550     }
13551 
updateOomAdjLocked()13552     private final boolean updateOomAdjLocked() {
13553         boolean didOomAdj = true;
13554         final HistoryRecord TOP_ACT = resumedAppLocked();
13555         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13556 
13557         if (false) {
13558             RuntimeException e = new RuntimeException();
13559             e.fillInStackTrace();
13560             Log.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13561         }
13562 
13563         mAdjSeq++;
13564 
13565         // First try updating the OOM adjustment for each of the
13566         // application processes based on their current state.
13567         int i = mLRUProcesses.size();
13568         int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
13569         while (i > 0) {
13570             i--;
13571             ProcessRecord app = mLRUProcesses.get(i);
13572             if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
13573                 if (curHiddenAdj < HIDDEN_APP_MAX_ADJ
13574                     && app.curAdj == curHiddenAdj) {
13575                     curHiddenAdj++;
13576                 }
13577             } else {
13578                 didOomAdj = false;
13579             }
13580         }
13581 
13582         // todo: for now pretend like OOM ADJ didn't work, because things
13583         // aren't behaving as expected on Linux -- it's not killing processes.
13584         return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj;
13585     }
13586 
trimApplications()13587     private final void trimApplications() {
13588         synchronized (this) {
13589             int i;
13590 
13591             // First remove any unused application processes whose package
13592             // has been removed.
13593             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13594                 final ProcessRecord app = mRemovedProcesses.get(i);
13595                 if (app.activities.size() == 0
13596                         && app.curReceiver == null && app.services.size() == 0) {
13597                     Log.i(
13598                         TAG, "Exiting empty application process "
13599                         + app.processName + " ("
13600                         + (app.thread != null ? app.thread.asBinder() : null)
13601                         + ")\n");
13602                     if (app.pid > 0 && app.pid != MY_PID) {
13603                         Process.killProcess(app.pid);
13604                     } else {
13605                         try {
13606                             app.thread.scheduleExit();
13607                         } catch (Exception e) {
13608                             // Ignore exceptions.
13609                         }
13610                     }
13611                     cleanUpApplicationRecordLocked(app, false, -1);
13612                     mRemovedProcesses.remove(i);
13613 
13614                     if (app.persistent) {
13615                         if (app.persistent) {
13616                             addAppLocked(app.info);
13617                         }
13618                     }
13619                 }
13620             }
13621 
13622             // Now try updating the OOM adjustment for each of the
13623             // application processes based on their current state.
13624             // If the setOomAdj() API is not supported, then go with our
13625             // back-up plan...
13626             if (!updateOomAdjLocked()) {
13627 
13628                 // Count how many processes are running services.
13629                 int numServiceProcs = 0;
13630                 for (i=mLRUProcesses.size()-1; i>=0; i--) {
13631                     final ProcessRecord app = mLRUProcesses.get(i);
13632 
13633                     if (app.persistent || app.services.size() != 0
13634                             || app.curReceiver != null
13635                             || app.persistentActivities > 0) {
13636                         // Don't count processes holding services against our
13637                         // maximum process count.
13638                         if (localLOGV) Log.v(
13639                             TAG, "Not trimming app " + app + " with services: "
13640                             + app.services);
13641                         numServiceProcs++;
13642                     }
13643                 }
13644 
13645                 int curMaxProcs = mProcessLimit;
13646                 if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES;
13647                 if (mAlwaysFinishActivities) {
13648                     curMaxProcs = 1;
13649                 }
13650                 curMaxProcs += numServiceProcs;
13651 
13652                 // Quit as many processes as we can to get down to the desired
13653                 // process count.  First remove any processes that no longer
13654                 // have activites running in them.
13655                 for (   i=0;
13656                         i<mLRUProcesses.size()
13657                             && mLRUProcesses.size() > curMaxProcs;
13658                         i++) {
13659                     final ProcessRecord app = mLRUProcesses.get(i);
13660                     // Quit an application only if it is not currently
13661                     // running any activities.
13662                     if (!app.persistent && app.activities.size() == 0
13663                             && app.curReceiver == null && app.services.size() == 0) {
13664                         Log.i(
13665                             TAG, "Exiting empty application process "
13666                             + app.processName + " ("
13667                             + (app.thread != null ? app.thread.asBinder() : null)
13668                             + ")\n");
13669                         if (app.pid > 0 && app.pid != MY_PID) {
13670                             Process.killProcess(app.pid);
13671                         } else {
13672                             try {
13673                                 app.thread.scheduleExit();
13674                             } catch (Exception e) {
13675                                 // Ignore exceptions.
13676                             }
13677                         }
13678                         // todo: For now we assume the application is not buggy
13679                         // or evil, and will quit as a result of our request.
13680                         // Eventually we need to drive this off of the death
13681                         // notification, and kill the process if it takes too long.
13682                         cleanUpApplicationRecordLocked(app, false, i);
13683                         i--;
13684                     }
13685                 }
13686 
13687                 // If we still have too many processes, now from the least
13688                 // recently used process we start finishing activities.
13689                 if (Config.LOGV) Log.v(
13690                     TAG, "*** NOW HAVE " + mLRUProcesses.size() +
13691                     " of " + curMaxProcs + " processes");
13692                 for (   i=0;
13693                         i<mLRUProcesses.size()
13694                             && mLRUProcesses.size() > curMaxProcs;
13695                         i++) {
13696                     final ProcessRecord app = mLRUProcesses.get(i);
13697                     // Quit the application only if we have a state saved for
13698                     // all of its activities.
13699                     boolean canQuit = !app.persistent && app.curReceiver == null
13700                         && app.services.size() == 0
13701                         && app.persistentActivities == 0;
13702                     int NUMA = app.activities.size();
13703                     int j;
13704                     if (Config.LOGV) Log.v(
13705                         TAG, "Looking to quit " + app.processName);
13706                     for (j=0; j<NUMA && canQuit; j++) {
13707                         HistoryRecord r = (HistoryRecord)app.activities.get(j);
13708                         if (Config.LOGV) Log.v(
13709                             TAG, "  " + r.intent.getComponent().flattenToShortString()
13710                             + ": frozen=" + r.haveState + ", visible=" + r.visible);
13711                         canQuit = (r.haveState || !r.stateNotNeeded)
13712                                 && !r.visible && r.stopped;
13713                     }
13714                     if (canQuit) {
13715                         // Finish all of the activities, and then the app itself.
13716                         for (j=0; j<NUMA; j++) {
13717                             HistoryRecord r = (HistoryRecord)app.activities.get(j);
13718                             if (!r.finishing) {
13719                                 destroyActivityLocked(r, false);
13720                             }
13721                             r.resultTo = null;
13722                         }
13723                         Log.i(TAG, "Exiting application process "
13724                               + app.processName + " ("
13725                               + (app.thread != null ? app.thread.asBinder() : null)
13726                               + ")\n");
13727                         if (app.pid > 0 && app.pid != MY_PID) {
13728                             Process.killProcess(app.pid);
13729                         } else {
13730                             try {
13731                                 app.thread.scheduleExit();
13732                             } catch (Exception e) {
13733                                 // Ignore exceptions.
13734                             }
13735                         }
13736                         // todo: For now we assume the application is not buggy
13737                         // or evil, and will quit as a result of our request.
13738                         // Eventually we need to drive this off of the death
13739                         // notification, and kill the process if it takes too long.
13740                         cleanUpApplicationRecordLocked(app, false, i);
13741                         i--;
13742                         //dump();
13743                     }
13744                 }
13745 
13746             }
13747 
13748             int curMaxActivities = MAX_ACTIVITIES;
13749             if (mAlwaysFinishActivities) {
13750                 curMaxActivities = 1;
13751             }
13752 
13753             // Finally, if there are too many activities now running, try to
13754             // finish as many as we can to get back down to the limit.
13755             for (   i=0;
13756                     i<mLRUActivities.size()
13757                         && mLRUActivities.size() > curMaxActivities;
13758                     i++) {
13759                 final HistoryRecord r
13760                     = (HistoryRecord)mLRUActivities.get(i);
13761 
13762                 // We can finish this one if we have its icicle saved and
13763                 // it is not persistent.
13764                 if ((r.haveState || !r.stateNotNeeded) && !r.visible
13765                         && r.stopped && !r.persistent && !r.finishing) {
13766                     final int origSize = mLRUActivities.size();
13767                     destroyActivityLocked(r, true);
13768 
13769                     // This will remove it from the LRU list, so keep
13770                     // our index at the same value.  Note that this check to
13771                     // see if the size changes is just paranoia -- if
13772                     // something unexpected happens, we don't want to end up
13773                     // in an infinite loop.
13774                     if (origSize > mLRUActivities.size()) {
13775                         i--;
13776                     }
13777                 }
13778             }
13779         }
13780     }
13781 
13782     /** This method sends the specified signal to each of the persistent apps */
signalPersistentProcesses(int sig)13783     public void signalPersistentProcesses(int sig) throws RemoteException {
13784         if (sig != Process.SIGNAL_USR1) {
13785             throw new SecurityException("Only SIGNAL_USR1 is allowed");
13786         }
13787 
13788         synchronized (this) {
13789             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13790                     != PackageManager.PERMISSION_GRANTED) {
13791                 throw new SecurityException("Requires permission "
13792                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13793             }
13794 
13795             for (int i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) {
13796                 ProcessRecord r = mLRUProcesses.get(i);
13797                 if (r.thread != null && r.persistent) {
13798                     Process.sendSignal(r.pid, sig);
13799                 }
13800             }
13801         }
13802     }
13803 
profileControl(String process, boolean start, String path, ParcelFileDescriptor fd)13804     public boolean profileControl(String process, boolean start,
13805             String path, ParcelFileDescriptor fd) throws RemoteException {
13806 
13807         try {
13808             synchronized (this) {
13809                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13810                 // its own permission.
13811                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13812                         != PackageManager.PERMISSION_GRANTED) {
13813                     throw new SecurityException("Requires permission "
13814                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13815                 }
13816 
13817                 if (start && fd == null) {
13818                     throw new IllegalArgumentException("null fd");
13819                 }
13820 
13821                 ProcessRecord proc = null;
13822                 try {
13823                     int pid = Integer.parseInt(process);
13824                     synchronized (mPidsSelfLocked) {
13825                         proc = mPidsSelfLocked.get(pid);
13826                     }
13827                 } catch (NumberFormatException e) {
13828                 }
13829 
13830                 if (proc == null) {
13831                     HashMap<String, SparseArray<ProcessRecord>> all
13832                             = mProcessNames.getMap();
13833                     SparseArray<ProcessRecord> procs = all.get(process);
13834                     if (procs != null && procs.size() > 0) {
13835                         proc = procs.valueAt(0);
13836                     }
13837                 }
13838 
13839                 if (proc == null || proc.thread == null) {
13840                     throw new IllegalArgumentException("Unknown process: " + process);
13841                 }
13842 
13843                 boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0"));
13844                 if (isSecure) {
13845                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13846                         throw new SecurityException("Process not debuggable: " + proc);
13847                     }
13848                 }
13849 
13850                 proc.thread.profilerControl(start, path, fd);
13851                 fd = null;
13852                 return true;
13853             }
13854         } catch (RemoteException e) {
13855             throw new IllegalStateException("Process disappeared");
13856         } finally {
13857             if (fd != null) {
13858                 try {
13859                     fd.close();
13860                 } catch (IOException e) {
13861                 }
13862             }
13863         }
13864     }
13865 
13866     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
monitor()13867     public void monitor() {
13868         synchronized (this) { }
13869     }
13870 }
13871