blob: 141569e054b3f5b83070b2ff9049bba326d5c5a7 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import com.android.internal.os.BatteryStatsImpl;
20import com.android.internal.os.RuntimeInit;
21import com.android.server.IntentResolver;
22import com.android.server.ProcessMap;
23import com.android.server.ProcessStats;
24import com.android.server.SystemServer;
25import com.android.server.Watchdog;
26import com.android.server.WindowManagerService;
27
28import android.app.Activity;
29import android.app.ActivityManager;
30import android.app.ActivityManagerNative;
31import android.app.ActivityThread;
32import android.app.AlertDialog;
33import android.app.Dialog;
34import android.app.IActivityWatcher;
35import android.app.IApplicationThread;
36import android.app.IInstrumentationWatcher;
37import android.app.IIntentReceiver;
38import android.app.IIntentSender;
39import android.app.IServiceConnection;
40import android.app.IThumbnailReceiver;
41import android.app.Instrumentation;
42import android.app.PendingIntent;
43import android.app.ResultInfo;
44import android.content.ComponentName;
45import android.content.ContentResolver;
46import android.content.Context;
47import android.content.Intent;
48import android.content.IntentFilter;
49import android.content.pm.ActivityInfo;
50import android.content.pm.ApplicationInfo;
51import android.content.pm.ConfigurationInfo;
52import android.content.pm.IPackageDataObserver;
53import android.content.pm.IPackageManager;
54import android.content.pm.InstrumentationInfo;
55import android.content.pm.PackageManager;
56import android.content.pm.ProviderInfo;
57import android.content.pm.ResolveInfo;
58import android.content.pm.ServiceInfo;
59import android.content.res.Configuration;
60import android.graphics.Bitmap;
61import android.net.Uri;
62import android.os.Binder;
63import android.os.Bundle;
64import android.os.Environment;
65import android.os.FileUtils;
66import android.os.Handler;
67import android.os.IBinder;
68import android.os.IPermissionController;
69import android.os.Looper;
70import android.os.Message;
71import android.os.Parcel;
72import android.os.ParcelFileDescriptor;
73import android.os.PowerManager;
74import android.os.Process;
75import android.os.RemoteException;
76import android.os.ServiceManager;
77import android.os.SystemClock;
78import android.os.SystemProperties;
79import android.provider.Checkin;
80import android.provider.Settings;
81import android.text.TextUtils;
82import android.util.Config;
83import android.util.EventLog;
84import android.util.Log;
85import android.util.PrintWriterPrinter;
86import android.util.SparseArray;
87import android.view.Gravity;
88import android.view.LayoutInflater;
89import android.view.View;
90import android.view.WindowManager;
91import android.view.WindowManagerPolicy;
92
93import dalvik.system.Zygote;
94
95import java.io.File;
96import java.io.FileDescriptor;
97import java.io.FileInputStream;
98import java.io.FileNotFoundException;
99import java.io.PrintWriter;
100import java.lang.IllegalStateException;
101import java.lang.ref.WeakReference;
102import java.util.ArrayList;
103import java.util.HashMap;
104import java.util.HashSet;
105import java.util.Iterator;
106import java.util.List;
107import java.util.Locale;
108import java.util.Map;
109
110public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor {
111 static final String TAG = "ActivityManager";
112 static final boolean DEBUG = false;
113 static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
114 static final boolean DEBUG_SWITCH = localLOGV || false;
115 static final boolean DEBUG_TASKS = localLOGV || false;
116 static final boolean DEBUG_PAUSE = localLOGV || false;
117 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
118 static final boolean DEBUG_TRANSITION = localLOGV || false;
119 static final boolean DEBUG_BROADCAST = localLOGV || false;
120 static final boolean DEBUG_SERVICE = localLOGV || false;
121 static final boolean DEBUG_VISBILITY = localLOGV || false;
122 static final boolean DEBUG_PROCESSES = localLOGV || false;
123 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
124 static final boolean VALIDATE_TOKENS = false;
125 static final boolean SHOW_ACTIVITY_START_TIME = true;
126
127 // Control over CPU and battery monitoring.
128 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
129 static final boolean MONITOR_CPU_USAGE = true;
130 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
131 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
132 static final boolean MONITOR_THREAD_CPU_USAGE = false;
133
134 // Event log tags
135 static final int LOG_CONFIGURATION_CHANGED = 2719;
136 static final int LOG_CPU = 2721;
137 static final int LOG_AM_FINISH_ACTIVITY = 30001;
138 static final int LOG_TASK_TO_FRONT = 30002;
139 static final int LOG_AM_NEW_INTENT = 30003;
140 static final int LOG_AM_CREATE_TASK = 30004;
141 static final int LOG_AM_CREATE_ACTIVITY = 30005;
142 static final int LOG_AM_RESTART_ACTIVITY = 30006;
143 static final int LOG_AM_RESUME_ACTIVITY = 30007;
144 static final int LOG_ANR = 30008;
145 static final int LOG_ACTIVITY_LAUNCH_TIME = 30009;
146 static final int LOG_AM_PROCESS_BOUND = 30010;
147 static final int LOG_AM_PROCESS_DIED = 30011;
148 static final int LOG_AM_FAILED_TO_PAUSE_ACTIVITY = 30012;
149 static final int LOG_AM_PAUSE_ACTIVITY = 30013;
150 static final int LOG_AM_PROCESS_START = 30014;
151 static final int LOG_AM_PROCESS_BAD = 30015;
152 static final int LOG_AM_PROCESS_GOOD = 30016;
153 static final int LOG_AM_LOW_MEMORY = 30017;
154 static final int LOG_AM_DESTROY_ACTIVITY = 30018;
155 static final int LOG_AM_RELAUNCH_RESUME_ACTIVITY = 30019;
156 static final int LOG_AM_RELAUNCH_ACTIVITY = 30020;
157 static final int LOG_AM_KILL_FOR_MEMORY = 30023;
158 static final int LOG_AM_BROADCAST_DISCARD_FILTER = 30024;
159 static final int LOG_AM_BROADCAST_DISCARD_APP = 30025;
160 static final int LOG_AM_CREATE_SERVICE = 30030;
161 static final int LOG_AM_DESTROY_SERVICE = 30031;
162 static final int LOG_AM_PROCESS_CRASHED_TOO_MUCH = 30032;
163 static final int LOG_AM_DROP_PROCESS = 30033;
164 static final int LOG_AM_SERVICE_CRASHED_TOO_MUCH = 30034;
165 static final int LOG_AM_SCHEDULE_SERVICE_RESTART = 30035;
166 static final int LOG_AM_PROVIDER_LOST_PROCESS = 30036;
167
168 static final int LOG_BOOT_PROGRESS_AMS_READY = 3040;
169 static final int LOG_BOOT_PROGRESS_ENABLE_SCREEN = 3050;
170
171 private static final String SYSTEM_SECURE = "ro.secure";
172
173 // This is the maximum number of application processes we would like
174 // to have running. Due to the asynchronous nature of things, we can
175 // temporarily go beyond this limit.
176 static final int MAX_PROCESSES = 2;
177
178 // Set to false to leave processes running indefinitely, relying on
179 // the kernel killing them as resources are required.
180 static final boolean ENFORCE_PROCESS_LIMIT = false;
181
182 // This is the maximum number of activities that we would like to have
183 // running at a given time.
184 static final int MAX_ACTIVITIES = 20;
185
186 // Maximum number of recent tasks that we can remember.
187 static final int MAX_RECENT_TASKS = 20;
188
189 // How long until we reset a task when the user returns to it. Currently
190 // 30 minutes.
191 static final long ACTIVITY_INACTIVE_RESET_TIME = 1000*60*30;
192
193 // Set to true to disable the icon that is shown while a new activity
194 // is being started.
195 static final boolean SHOW_APP_STARTING_ICON = true;
196
197 // How long we wait until giving up on the last activity to pause. This
198 // is short because it directly impacts the responsiveness of starting the
199 // next activity.
200 static final int PAUSE_TIMEOUT = 500;
201
202 /**
203 * How long we can hold the launch wake lock before giving up.
204 */
205 static final int LAUNCH_TIMEOUT = 10*1000;
206
207 // How long we wait for a launched process to attach to the activity manager
208 // before we decide it's never going to come up for real.
209 static final int PROC_START_TIMEOUT = 10*1000;
210
211 // How long we wait until giving up on the last activity telling us it
212 // is idle.
213 static final int IDLE_TIMEOUT = 10*1000;
214
215 // How long to wait after going idle before forcing apps to GC.
216 static final int GC_TIMEOUT = 5*1000;
217
218 // How long we wait until giving up on an activity telling us it has
219 // finished destroying itself.
220 static final int DESTROY_TIMEOUT = 10*1000;
221
222 // How long we allow a receiver to run before giving up on it.
223 static final int BROADCAST_TIMEOUT = 10*1000;
224
225 // How long we wait for a service to finish executing.
226 static final int SERVICE_TIMEOUT = 20*1000;
227
228 // How long a service needs to be running until restarting its process
229 // is no longer considered to be a relaunch of the service.
230 static final int SERVICE_RESTART_DURATION = 5*1000;
231
232 // Maximum amount of time for there to be no activity on a service before
233 // we consider it non-essential and allow its process to go on the
234 // LRU background list.
235 static final int MAX_SERVICE_INACTIVITY = 10*60*1000;
236
237 // How long we wait until we timeout on key dispatching.
238 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
239
240 // The minimum time we allow between crashes, for us to consider this
241 // application to be bad and stop and its services and reject broadcasts.
242 static final int MIN_CRASH_INTERVAL = 60*1000;
243
244 // How long we wait until we timeout on key dispatching during instrumentation.
245 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
246
247 // OOM adjustments for processes in various states:
248
249 // This is a process without anything currently running in it. Definitely
250 // the first to go! Value set in system/rootdir/init.rc on startup.
251 // This value is initalized in the constructor, careful when refering to
252 // this static variable externally.
253 static int EMPTY_APP_ADJ;
254
255 // This is a process with a content provider that does not have any clients
256 // attached to it. If it did have any clients, its adjustment would be the
257 // one for the highest-priority of those processes.
258 static int CONTENT_PROVIDER_ADJ;
259
260 // This is a process only hosting activities that are not visible,
261 // so it can be killed without any disruption. Value set in
262 // system/rootdir/init.rc on startup.
263 final int HIDDEN_APP_MAX_ADJ;
264 static int HIDDEN_APP_MIN_ADJ;
265
266 // This is a process holding a secondary server -- killing it will not
267 // have much of an impact as far as the user is concerned. Value set in
268 // system/rootdir/init.rc on startup.
269 final int SECONDARY_SERVER_ADJ;
270
271 // This is a process only hosting activities that are visible to the
272 // user, so we'd prefer they don't disappear. Value set in
273 // system/rootdir/init.rc on startup.
274 final int VISIBLE_APP_ADJ;
275
276 // This is the process running the current foreground app. We'd really
277 // rather not kill it! Value set in system/rootdir/init.rc on startup.
278 final int FOREGROUND_APP_ADJ;
279
280 // This is a process running a core server, such as telephony. Definitely
281 // don't want to kill it, but doing so is not completely fatal.
282 static final int CORE_SERVER_ADJ = -12;
283
284 // The system process runs at the default adjustment.
285 static final int SYSTEM_ADJ = -16;
286
287 // Memory pages are 4K.
288 static final int PAGE_SIZE = 4*1024;
289
290 // Corresponding memory levels for above adjustments.
291 final int EMPTY_APP_MEM;
292 final int HIDDEN_APP_MEM;
293 final int SECONDARY_SERVER_MEM;
294 final int VISIBLE_APP_MEM;
295 final int FOREGROUND_APP_MEM;
296
297 final int MY_PID;
298
299 static final String[] EMPTY_STRING_ARRAY = new String[0];
300
301 enum ActivityState {
302 INITIALIZING,
303 RESUMED,
304 PAUSING,
305 PAUSED,
306 STOPPING,
307 STOPPED,
308 FINISHING,
309 DESTROYING,
310 DESTROYED
311 }
312
313 /**
314 * The back history of all previous (and possibly still
315 * running) activities. It contains HistoryRecord objects.
316 */
317 final ArrayList mHistory = new ArrayList();
318
319 /**
320 * List of all active broadcasts that are to be executed immediately
321 * (without waiting for another broadcast to finish). Currently this only
322 * contains broadcasts to registered receivers, to avoid spinning up
323 * a bunch of processes to execute IntentReceiver components.
324 */
325 final ArrayList<BroadcastRecord> mParallelBroadcasts
326 = new ArrayList<BroadcastRecord>();
327
328 /**
329 * List of all active broadcasts that are to be executed one at a time.
330 * The object at the top of the list is the currently activity broadcasts;
331 * those after it are waiting for the top to finish..
332 */
333 final ArrayList<BroadcastRecord> mOrderedBroadcasts
334 = new ArrayList<BroadcastRecord>();
335
336 /**
337 * Set when we current have a BROADCAST_INTENT_MSG in flight.
338 */
339 boolean mBroadcastsScheduled = false;
340
341 /**
342 * Set to indicate whether to issue an onUserLeaving callback when a
343 * newly launched activity is being brought in front of us.
344 */
345 boolean mUserLeaving = false;
346
347 /**
348 * When we are in the process of pausing an activity, before starting the
349 * next one, this variable holds the activity that is currently being paused.
350 */
351 HistoryRecord mPausingActivity = null;
352
353 /**
354 * Current activity that is resumed, or null if there is none.
355 */
356 HistoryRecord mResumedActivity = null;
357
358 /**
359 * Activity we have told the window manager to have key focus.
360 */
361 HistoryRecord mFocusedActivity = null;
362
363 /**
364 * This is the last activity that we put into the paused state. This is
365 * used to determine if we need to do an activity transition while sleeping,
366 * when we normally hold the top activity paused.
367 */
368 HistoryRecord mLastPausedActivity = null;
369
370 /**
371 * List of activities that are waiting for a new activity
372 * to become visible before completing whatever operation they are
373 * supposed to do.
374 */
375 final ArrayList mWaitingVisibleActivities = new ArrayList();
376
377 /**
378 * List of activities that are ready to be stopped, but waiting
379 * for the next activity to settle down before doing so. It contains
380 * HistoryRecord objects.
381 */
382 final ArrayList<HistoryRecord> mStoppingActivities
383 = new ArrayList<HistoryRecord>();
384
385 /**
386 * List of intents that were used to start the most recent tasks.
387 */
388 final ArrayList<TaskRecord> mRecentTasks
389 = new ArrayList<TaskRecord>();
390
391 /**
392 * List of activities that are ready to be finished, but waiting
393 * for the previous activity to settle down before doing so. It contains
394 * HistoryRecord objects.
395 */
396 final ArrayList mFinishingActivities = new ArrayList();
397
398 /**
399 * All of the applications we currently have running organized by name.
400 * The keys are strings of the application package name (as
401 * returned by the package manager), and the keys are ApplicationRecord
402 * objects.
403 */
404 final ProcessMap<ProcessRecord> mProcessNames
405 = new ProcessMap<ProcessRecord>();
406
407 /**
408 * The last time that various processes have crashed.
409 */
410 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
411
412 /**
413 * Set of applications that we consider to be bad, and will reject
414 * incoming broadcasts from (which the user has no control over).
415 * Processes are added to this set when they have crashed twice within
416 * a minimum amount of time; they are removed from it when they are
417 * later restarted (hopefully due to some user action). The value is the
418 * time it was added to the list.
419 */
420 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
421
422 /**
423 * All of the processes we currently have running organized by pid.
424 * The keys are the pid running the application.
425 *
426 * <p>NOTE: This object is protected by its own lock, NOT the global
427 * activity manager lock!
428 */
429 final SparseArray<ProcessRecord> mPidsSelfLocked
430 = new SparseArray<ProcessRecord>();
431
432 /**
433 * All of the processes that have been forced to be foreground. The key
434 * is the pid of the caller who requested it (we hold a death
435 * link on it).
436 */
437 abstract class ForegroundToken implements IBinder.DeathRecipient {
438 int pid;
439 IBinder token;
440 }
441 final SparseArray<ForegroundToken> mForegroundProcesses
442 = new SparseArray<ForegroundToken>();
443
444 /**
445 * List of records for processes that someone had tried to start before the
446 * system was ready. We don't start them at that point, but ensure they
447 * are started by the time booting is complete.
448 */
449 final ArrayList<ProcessRecord> mProcessesOnHold
450 = new ArrayList<ProcessRecord>();
451
452 /**
453 * List of records for processes that we have started and are waiting
454 * for them to call back. This is really only needed when running in
455 * single processes mode, in which case we do not have a unique pid for
456 * each process.
457 */
458 final ArrayList<ProcessRecord> mStartingProcesses
459 = new ArrayList<ProcessRecord>();
460
461 /**
462 * List of persistent applications that are in the process
463 * of being started.
464 */
465 final ArrayList<ProcessRecord> mPersistentStartingProcesses
466 = new ArrayList<ProcessRecord>();
467
468 /**
469 * Processes that are being forcibly torn down.
470 */
471 final ArrayList<ProcessRecord> mRemovedProcesses
472 = new ArrayList<ProcessRecord>();
473
474 /**
475 * List of running applications, sorted by recent usage.
476 * The first entry in the list is the least recently used.
477 * It contains ApplicationRecord objects. This list does NOT include
478 * any persistent application records (since we never want to exit them).
479 */
480 final ArrayList<ProcessRecord> mLRUProcesses
481 = new ArrayList<ProcessRecord>();
482
483 /**
484 * List of processes that should gc as soon as things are idle.
485 */
486 final ArrayList<ProcessRecord> mProcessesToGc
487 = new ArrayList<ProcessRecord>();
488
489 /**
490 * List of running activities, sorted by recent usage.
491 * The first entry in the list is the least recently used.
492 * It contains HistoryRecord objects.
493 */
494 private final ArrayList mLRUActivities = new ArrayList();
495
496 /**
497 * Set of PendingResultRecord objects that are currently active.
498 */
499 final HashSet mPendingResultRecords = new HashSet();
500
501 /**
502 * Set of IntentSenderRecord objects that are currently active.
503 */
504 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
505 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
506
507 /**
508 * Intent broadcast that we have tried to start, but are
509 * waiting for its application's process to be created. We only
510 * need one (instead of a list) because we always process broadcasts
511 * one at a time, so no others can be started while waiting for this
512 * one.
513 */
514 BroadcastRecord mPendingBroadcast = null;
515
516 /**
517 * Keeps track of all IIntentReceivers that have been registered for
518 * broadcasts. Hash keys are the receiver IBinder, hash value is
519 * a ReceiverList.
520 */
521 final HashMap mRegisteredReceivers = new HashMap();
522
523 /**
524 * Resolver for broadcast intents to registered receivers.
525 * Holds BroadcastFilter (subclass of IntentFilter).
526 */
527 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
528 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
529 @Override
530 protected boolean allowFilterResult(
531 BroadcastFilter filter, List<BroadcastFilter> dest) {
532 IBinder target = filter.receiverList.receiver.asBinder();
533 for (int i=dest.size()-1; i>=0; i--) {
534 if (dest.get(i).receiverList.receiver.asBinder() == target) {
535 return false;
536 }
537 }
538 return true;
539 }
540 };
541
542 /**
543 * State of all active sticky broadcasts. Keys are the action of the
544 * sticky Intent, values are an ArrayList of all broadcasted intents with
545 * that action (which should usually be one).
546 */
547 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
548 new HashMap<String, ArrayList<Intent>>();
549
550 /**
551 * All currently running services.
552 */
553 final HashMap<ComponentName, ServiceRecord> mServices =
554 new HashMap<ComponentName, ServiceRecord>();
555
556 /**
557 * All currently running services indexed by the Intent used to start them.
558 */
559 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
560 new HashMap<Intent.FilterComparison, ServiceRecord>();
561
562 /**
563 * All currently bound service connections. Keys are the IBinder of
564 * the client's IServiceConnection.
565 */
566 final HashMap<IBinder, ConnectionRecord> mServiceConnections
567 = new HashMap<IBinder, ConnectionRecord>();
568
569 /**
570 * List of services that we have been asked to start,
571 * but haven't yet been able to. It is used to hold start requests
572 * while waiting for their corresponding application thread to get
573 * going.
574 */
575 final ArrayList<ServiceRecord> mPendingServices
576 = new ArrayList<ServiceRecord>();
577
578 /**
579 * List of services that are scheduled to restart following a crash.
580 */
581 final ArrayList<ServiceRecord> mRestartingServices
582 = new ArrayList<ServiceRecord>();
583
584 /**
585 * List of services that are in the process of being stopped.
586 */
587 final ArrayList<ServiceRecord> mStoppingServices
588 = new ArrayList<ServiceRecord>();
589
590 /**
591 * List of PendingThumbnailsRecord objects of clients who are still
592 * waiting to receive all of the thumbnails for a task.
593 */
594 final ArrayList mPendingThumbnails = new ArrayList();
595
596 /**
597 * List of HistoryRecord objects that have been finished and must
598 * still report back to a pending thumbnail receiver.
599 */
600 final ArrayList mCancelledThumbnails = new ArrayList();
601
602 /**
603 * All of the currently running global content providers. Keys are a
604 * string containing the provider name and values are a
605 * ContentProviderRecord object containing the data about it. Note
606 * that a single provider may be published under multiple names, so
607 * there may be multiple entries here for a single one in mProvidersByClass.
608 */
609 final HashMap mProvidersByName = new HashMap();
610
611 /**
612 * All of the currently running global content providers. Keys are a
613 * string containing the provider's implementation class and values are a
614 * ContentProviderRecord object containing the data about it.
615 */
616 final HashMap mProvidersByClass = new HashMap();
617
618 /**
619 * List of content providers who have clients waiting for them. The
620 * application is currently being launched and the provider will be
621 * removed from this list once it is published.
622 */
623 final ArrayList mLaunchingProviders = new ArrayList();
624
625 /**
626 * Global set of specific Uri permissions that have been granted.
627 */
628 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
629 = new SparseArray<HashMap<Uri, UriPermission>>();
630
631 /**
632 * Thread-local storage used to carry caller permissions over through
633 * indirect content-provider access.
634 * @see #ActivityManagerService.openContentUri()
635 */
636 private class Identity {
637 public int pid;
638 public int uid;
639
640 Identity(int _pid, int _uid) {
641 pid = _pid;
642 uid = _uid;
643 }
644 }
645 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
646
647 /**
648 * All information we have collected about the runtime performance of
649 * any user id that can impact battery performance.
650 */
651 final BatteryStatsService mBatteryStatsService;
652
653 /**
654 * information about component usage
655 */
656 final UsageStatsService mUsageStatsService;
657
658 /**
659 * Current configuration information. HistoryRecord objects are given
660 * a reference to this object to indicate which configuration they are
661 * currently running in, so this object must be kept immutable.
662 */
663 Configuration mConfiguration = new Configuration();
664
665 /**
666 * List of initialization arguments to pass to all processes when binding applications to them.
667 * For example, references to the commonly used services.
668 */
669 HashMap<String, IBinder> mAppBindArgs;
670
671 /**
672 * Used to control how we initialize the service.
673 */
674 boolean mStartRunning = false;
675 ComponentName mTopComponent;
676 String mTopAction;
677 String mTopData;
678 boolean mSystemReady = false;
679 boolean mBooting = false;
680
681 Context mContext;
682
683 int mFactoryTest;
684
685 /**
686 * Set while we are wanting to sleep, to prevent any
687 * activities from being started/resumed.
688 */
689 boolean mSleeping = false;
690
691 /**
692 * Set when the system is going to sleep, until we have
693 * successfully paused the current activity and released our wake lock.
694 * At that point the system is allowed to actually sleep.
695 */
696 PowerManager.WakeLock mGoingToSleep;
697
698 /**
699 * We don't want to allow the device to go to sleep while in the process
700 * of launching an activity. This is primarily to allow alarm intent
701 * receivers to launch an activity and get that to run before the device
702 * goes back to sleep.
703 */
704 PowerManager.WakeLock mLaunchingActivity;
705
706 /**
707 * Task identifier that activities are currently being started
708 * in. Incremented each time a new task is created.
709 * todo: Replace this with a TokenSpace class that generates non-repeating
710 * integers that won't wrap.
711 */
712 int mCurTask = 1;
713
714 /**
715 * Current sequence id for oom_adj computation traversal.
716 */
717 int mAdjSeq = 0;
718
719 /**
720 * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar
721 * is set, indicating the user wants processes started in such a way
722 * that they can use ANDROID_PROCESS_WRAPPER and know what will be
723 * running in each process (thus no pre-initialized process, etc).
724 */
725 boolean mSimpleProcessManagement = false;
726
727 /**
728 * System monitoring: number of processes that died since the last
729 * N procs were started.
730 */
731 int[] mProcDeaths = new int[20];
732
733 String mDebugApp = null;
734 boolean mWaitForDebugger = false;
735 boolean mDebugTransient = false;
736 String mOrigDebugApp = null;
737 boolean mOrigWaitForDebugger = false;
738 boolean mAlwaysFinishActivities = false;
739 IActivityWatcher mWatcher = null;
740
741 /**
742 * Callback of last caller to {@link #requestPss}.
743 */
744 Runnable mRequestPssCallback;
745
746 /**
747 * Remaining processes for which we are waiting results from the last
748 * call to {@link #requestPss}.
749 */
750 final ArrayList<ProcessRecord> mRequestPssList
751 = new ArrayList<ProcessRecord>();
752
753 /**
754 * Runtime statistics collection thread. This object's lock is used to
755 * protect all related state.
756 */
757 final Thread mProcessStatsThread;
758
759 /**
760 * Used to collect process stats when showing not responding dialog.
761 * Protected by mProcessStatsThread.
762 */
763 final ProcessStats mProcessStats = new ProcessStats(
764 MONITOR_THREAD_CPU_USAGE);
765 long mLastCpuTime = 0;
766 long mLastWriteTime = 0;
767
768 /**
769 * Set to true after the system has finished booting.
770 */
771 boolean mBooted = false;
772
773 int mProcessLimit = 0;
774
775 WindowManagerService mWindowManager;
776
777 static ActivityManagerService mSelf;
778 static ActivityThread mSystemThread;
779
780 private final class AppDeathRecipient implements IBinder.DeathRecipient {
781 final ProcessRecord mApp;
782 final int mPid;
783 final IApplicationThread mAppThread;
784
785 AppDeathRecipient(ProcessRecord app, int pid,
786 IApplicationThread thread) {
787 if (localLOGV) Log.v(
788 TAG, "New death recipient " + this
789 + " for thread " + thread.asBinder());
790 mApp = app;
791 mPid = pid;
792 mAppThread = thread;
793 }
794
795 public void binderDied() {
796 if (localLOGV) Log.v(
797 TAG, "Death received in " + this
798 + " for thread " + mAppThread.asBinder());
799 removeRequestedPss(mApp);
800 synchronized(ActivityManagerService.this) {
801 appDiedLocked(mApp, mPid, mAppThread);
802 }
803 }
804 }
805
806 static final int SHOW_ERROR_MSG = 1;
807 static final int SHOW_NOT_RESPONDING_MSG = 2;
808 static final int SHOW_FACTORY_ERROR_MSG = 3;
809 static final int UPDATE_CONFIGURATION_MSG = 4;
810 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
811 static final int WAIT_FOR_DEBUGGER_MSG = 6;
812 static final int BROADCAST_INTENT_MSG = 7;
813 static final int BROADCAST_TIMEOUT_MSG = 8;
814 static final int PAUSE_TIMEOUT_MSG = 9;
815 static final int IDLE_TIMEOUT_MSG = 10;
816 static final int IDLE_NOW_MSG = 11;
817 static final int SERVICE_TIMEOUT_MSG = 12;
818 static final int UPDATE_TIME_ZONE = 13;
819 static final int SHOW_UID_ERROR_MSG = 14;
820 static final int IM_FEELING_LUCKY_MSG = 15;
821 static final int LAUNCH_TIMEOUT_MSG = 16;
822 static final int DESTROY_TIMEOUT_MSG = 17;
823 static final int SERVICE_ERROR_MSG = 18;
824 static final int RESUME_TOP_ACTIVITY_MSG = 19;
825 static final int PROC_START_TIMEOUT_MSG = 20;
826
827 AlertDialog mUidAlert;
828
829 final Handler mHandler = new Handler() {
830 //public Handler() {
831 // if (localLOGV) Log.v(TAG, "Handler started!");
832 //}
833
834 public void handleMessage(Message msg) {
835 switch (msg.what) {
836 case SHOW_ERROR_MSG: {
837 HashMap data = (HashMap) msg.obj;
838 byte[] crashData = (byte[])data.get("crashData");
839 if (crashData != null) {
840 // This needs to be *un*synchronized to avoid deadlock.
841 ContentResolver resolver = mContext.getContentResolver();
842 Checkin.reportCrash(resolver, crashData);
843 }
844 synchronized (ActivityManagerService.this) {
845 ProcessRecord proc = (ProcessRecord)data.get("app");
846 if (proc != null && proc.crashDialog != null) {
847 Log.e(TAG, "App already has crash dialog: " + proc);
848 return;
849 }
850 AppErrorResult res = (AppErrorResult) data.get("result");
851 if (!mSleeping) {
852 Dialog d = new AppErrorDialog(
853 mContext, res, proc,
854 (Integer)data.get("flags"),
855 (String)data.get("shortMsg"),
856 (String)data.get("longMsg"));
857 d.show();
858 proc.crashDialog = d;
859 } else {
860 // The device is asleep, so just pretend that the user
861 // saw a crash dialog and hit "force quit".
862 res.set(0);
863 }
864 }
865 } break;
866 case SHOW_NOT_RESPONDING_MSG: {
867 synchronized (ActivityManagerService.this) {
868 HashMap data = (HashMap) msg.obj;
869 ProcessRecord proc = (ProcessRecord)data.get("app");
870 if (proc != null && proc.anrDialog != null) {
871 Log.e(TAG, "App already has anr dialog: " + proc);
872 return;
873 }
874 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
875 mContext, proc, (HistoryRecord)data.get("activity"));
876 d.show();
877 proc.anrDialog = d;
878 }
879 } break;
880 case SHOW_FACTORY_ERROR_MSG: {
881 Dialog d = new FactoryErrorDialog(
882 mContext, msg.getData().getCharSequence("msg"));
883 d.show();
884 enableScreenAfterBoot();
885 } break;
886 case UPDATE_CONFIGURATION_MSG: {
887 final ContentResolver resolver = mContext.getContentResolver();
888 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
889 } break;
890 case GC_BACKGROUND_PROCESSES_MSG: {
891 synchronized (ActivityManagerService.this) {
892 performAppGcsIfAppropriateLocked();
893 }
894 } break;
895 case WAIT_FOR_DEBUGGER_MSG: {
896 synchronized (ActivityManagerService.this) {
897 ProcessRecord app = (ProcessRecord)msg.obj;
898 if (msg.arg1 != 0) {
899 if (!app.waitedForDebugger) {
900 Dialog d = new AppWaitingForDebuggerDialog(
901 ActivityManagerService.this,
902 mContext, app);
903 app.waitDialog = d;
904 app.waitedForDebugger = true;
905 d.show();
906 }
907 } else {
908 if (app.waitDialog != null) {
909 app.waitDialog.dismiss();
910 app.waitDialog = null;
911 }
912 }
913 }
914 } break;
915 case BROADCAST_INTENT_MSG: {
916 if (DEBUG_BROADCAST) Log.v(
917 TAG, "Received BROADCAST_INTENT_MSG");
918 processNextBroadcast(true);
919 } break;
920 case BROADCAST_TIMEOUT_MSG: {
921 broadcastTimeout();
922 } break;
923 case PAUSE_TIMEOUT_MSG: {
924 IBinder token = (IBinder)msg.obj;
925 // We don't at this point know if the activity is fullscreen,
926 // so we need to be conservative and assume it isn't.
927 Log.w(TAG, "Activity pause timeout for " + token);
928 activityPaused(token, null, true);
929 } break;
930 case IDLE_TIMEOUT_MSG: {
931 IBinder token = (IBinder)msg.obj;
932 // We don't at this point know if the activity is fullscreen,
933 // so we need to be conservative and assume it isn't.
934 Log.w(TAG, "Activity idle timeout for " + token);
935 activityIdleInternal(token, true);
936 } break;
937 case DESTROY_TIMEOUT_MSG: {
938 IBinder token = (IBinder)msg.obj;
939 // We don't at this point know if the activity is fullscreen,
940 // so we need to be conservative and assume it isn't.
941 Log.w(TAG, "Activity destroy timeout for " + token);
942 activityDestroyed(token);
943 } break;
944 case IDLE_NOW_MSG: {
945 IBinder token = (IBinder)msg.obj;
946 activityIdle(token);
947 } break;
948 case SERVICE_TIMEOUT_MSG: {
949 serviceTimeout((ProcessRecord)msg.obj);
950 } break;
951 case UPDATE_TIME_ZONE: {
952 synchronized (ActivityManagerService.this) {
953 for (int i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) {
954 ProcessRecord r = mLRUProcesses.get(i);
955 if (r.thread != null) {
956 try {
957 r.thread.updateTimeZone();
958 } catch (RemoteException ex) {
959 Log.w(TAG, "Failed to update time zone for: " + r.info.processName);
960 }
961 }
962 }
963 }
964 break;
965 }
966 case SHOW_UID_ERROR_MSG: {
967 // XXX This is a temporary dialog, no need to localize.
968 AlertDialog d = new BaseErrorDialog(mContext);
969 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
970 d.setCancelable(false);
971 d.setTitle("System UIDs Inconsistent");
972 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
973 d.setButton("I'm Feeling Lucky",
974 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
975 mUidAlert = d;
976 d.show();
977 } break;
978 case IM_FEELING_LUCKY_MSG: {
979 if (mUidAlert != null) {
980 mUidAlert.dismiss();
981 mUidAlert = null;
982 }
983 } break;
984 case LAUNCH_TIMEOUT_MSG: {
985 synchronized (ActivityManagerService.this) {
986 if (mLaunchingActivity.isHeld()) {
987 Log.w(TAG, "Launch timeout has expired, giving up wake lock!");
988 mLaunchingActivity.release();
989 }
990 }
991 } break;
992 case SERVICE_ERROR_MSG: {
993 ServiceRecord srv = (ServiceRecord)msg.obj;
994 // This needs to be *un*synchronized to avoid deadlock.
995 Checkin.logEvent(mContext.getContentResolver(),
996 Checkin.Events.Tag.SYSTEM_SERVICE_LOOPING,
997 srv.name.toShortString());
998 } break;
999 case RESUME_TOP_ACTIVITY_MSG: {
1000 synchronized (ActivityManagerService.this) {
1001 resumeTopActivityLocked(null);
1002 }
1003 }
1004 case PROC_START_TIMEOUT_MSG: {
1005 ProcessRecord app = (ProcessRecord)msg.obj;
1006 synchronized (ActivityManagerService.this) {
1007 processStartTimedOutLocked(app);
1008 }
1009 }
1010 }
1011 }
1012 };
1013
1014 public static void setSystemProcess() {
1015 try {
1016 ActivityManagerService m = mSelf;
1017
1018 ServiceManager.addService("activity", m);
1019 ServiceManager.addService("meminfo", new MemBinder(m));
1020 if (MONITOR_CPU_USAGE) {
1021 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1022 }
1023 ServiceManager.addService("activity.broadcasts", new BroadcastsBinder(m));
1024 ServiceManager.addService("activity.services", new ServicesBinder(m));
1025 ServiceManager.addService("activity.senders", new SendersBinder(m));
1026 ServiceManager.addService("activity.providers", new ProvidersBinder(m));
1027 ServiceManager.addService("permission", new PermissionController(m));
1028
1029 ApplicationInfo info =
1030 mSelf.mContext.getPackageManager().getApplicationInfo(
1031 "android", PackageManager.GET_SHARED_LIBRARY_FILES);
1032 synchronized (mSelf) {
1033 ProcessRecord app = mSelf.newProcessRecordLocked(
1034 mSystemThread.getApplicationThread(), info,
1035 info.processName);
1036 app.persistent = true;
1037 app.pid = Process.myPid();
1038 app.maxAdj = SYSTEM_ADJ;
1039 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1040 synchronized (mSelf.mPidsSelfLocked) {
1041 mSelf.mPidsSelfLocked.put(app.pid, app);
1042 }
1043 mSelf.updateLRUListLocked(app, true);
1044 }
1045 } catch (PackageManager.NameNotFoundException e) {
1046 throw new RuntimeException(
1047 "Unable to find android system package", e);
1048 }
1049 }
1050
1051 public void setWindowManager(WindowManagerService wm) {
1052 mWindowManager = wm;
1053 }
1054
1055 public static final Context main(int factoryTest) {
1056 AThread thr = new AThread();
1057 thr.start();
1058
1059 synchronized (thr) {
1060 while (thr.mService == null) {
1061 try {
1062 thr.wait();
1063 } catch (InterruptedException e) {
1064 }
1065 }
1066 }
1067
1068 ActivityManagerService m = thr.mService;
1069 mSelf = m;
1070 ActivityThread at = ActivityThread.systemMain();
1071 mSystemThread = at;
1072 Context context = at.getSystemContext();
1073 m.mContext = context;
1074 m.mFactoryTest = factoryTest;
1075 PowerManager pm =
1076 (PowerManager)context.getSystemService(Context.POWER_SERVICE);
1077 m.mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
1078 m.mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
1079 m.mLaunchingActivity.setReferenceCounted(false);
1080
1081 m.mBatteryStatsService.publish(context);
1082 m.mUsageStatsService.publish(context);
1083
1084 synchronized (thr) {
1085 thr.mReady = true;
1086 thr.notifyAll();
1087 }
1088
1089 m.startRunning(null, null, null, null);
1090
1091 return context;
1092 }
1093
1094 public static ActivityManagerService self() {
1095 return mSelf;
1096 }
1097
1098 static class AThread extends Thread {
1099 ActivityManagerService mService;
1100 boolean mReady = false;
1101
1102 public AThread() {
1103 super("ActivityManager");
1104 }
1105
1106 public void run() {
1107 Looper.prepare();
1108
1109 android.os.Process.setThreadPriority(
1110 android.os.Process.THREAD_PRIORITY_FOREGROUND);
1111
1112 ActivityManagerService m = new ActivityManagerService();
1113
1114 synchronized (this) {
1115 mService = m;
1116 notifyAll();
1117 }
1118
1119 synchronized (this) {
1120 while (!mReady) {
1121 try {
1122 wait();
1123 } catch (InterruptedException e) {
1124 }
1125 }
1126 }
1127
1128 Looper.loop();
1129 }
1130 }
1131
1132 static class BroadcastsBinder extends Binder {
1133 ActivityManagerService mActivityManagerService;
1134 BroadcastsBinder(ActivityManagerService activityManagerService) {
1135 mActivityManagerService = activityManagerService;
1136 }
1137
1138 @Override
1139 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1140 mActivityManagerService.dumpBroadcasts(pw);
1141 }
1142 }
1143
1144 static class ServicesBinder extends Binder {
1145 ActivityManagerService mActivityManagerService;
1146 ServicesBinder(ActivityManagerService activityManagerService) {
1147 mActivityManagerService = activityManagerService;
1148 }
1149
1150 @Override
1151 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1152 mActivityManagerService.dumpServices(pw);
1153 }
1154 }
1155
1156 static class SendersBinder extends Binder {
1157 ActivityManagerService mActivityManagerService;
1158 SendersBinder(ActivityManagerService activityManagerService) {
1159 mActivityManagerService = activityManagerService;
1160 }
1161
1162 @Override
1163 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1164 mActivityManagerService.dumpSenders(pw);
1165 }
1166 }
1167
1168 static class ProvidersBinder extends Binder {
1169 ActivityManagerService mActivityManagerService;
1170 ProvidersBinder(ActivityManagerService activityManagerService) {
1171 mActivityManagerService = activityManagerService;
1172 }
1173
1174 @Override
1175 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1176 mActivityManagerService.dumpProviders(pw);
1177 }
1178 }
1179
1180 static class MemBinder extends Binder {
1181 ActivityManagerService mActivityManagerService;
1182 MemBinder(ActivityManagerService activityManagerService) {
1183 mActivityManagerService = activityManagerService;
1184 }
1185
1186 @Override
1187 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1188 ActivityManagerService service = mActivityManagerService;
1189 ArrayList<ProcessRecord> procs;
1190 synchronized (mActivityManagerService) {
1191 if (args != null && args.length > 0
1192 && args[0].charAt(0) != '-') {
1193 procs = new ArrayList<ProcessRecord>();
1194 int pid = -1;
1195 try {
1196 pid = Integer.parseInt(args[0]);
1197 } catch (NumberFormatException e) {
1198
1199 }
1200 for (int i=0; i<service.mLRUProcesses.size(); i++) {
1201 ProcessRecord proc = service.mLRUProcesses.get(i);
1202 if (proc.pid == pid) {
1203 procs.add(proc);
1204 } else if (proc.processName.equals(args[0])) {
1205 procs.add(proc);
1206 }
1207 }
1208 if (procs.size() <= 0) {
1209 pw.println("No process found for: " + args[0]);
1210 return;
1211 }
1212 } else {
1213 procs = service.mLRUProcesses;
1214 }
1215 }
1216 dumpApplicationMemoryUsage(fd, pw, procs, " ", args);
1217 }
1218 }
1219
1220 static class CpuBinder extends Binder {
1221 ActivityManagerService mActivityManagerService;
1222 CpuBinder(ActivityManagerService activityManagerService) {
1223 mActivityManagerService = activityManagerService;
1224 }
1225
1226 @Override
1227 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1228 synchronized (mActivityManagerService.mProcessStatsThread) {
1229 pw.print(mActivityManagerService.mProcessStats.printCurrentState());
1230 }
1231 }
1232 }
1233
1234 private ActivityManagerService() {
1235 String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT");
1236 if (v != null && Integer.getInteger(v) != 0) {
1237 mSimpleProcessManagement = true;
1238 }
1239 v = System.getenv("ANDROID_DEBUG_APP");
1240 if (v != null) {
1241 mSimpleProcessManagement = true;
1242 }
1243
1244 MY_PID = Process.myPid();
1245
1246 File dataDir = Environment.getDataDirectory();
1247 File systemDir = new File(dataDir, "system");
1248 systemDir.mkdirs();
1249 mBatteryStatsService = new BatteryStatsService(new File(
1250 systemDir, "batterystats.bin").toString());
1251 mBatteryStatsService.getActiveStatistics().readLocked();
1252 mBatteryStatsService.getActiveStatistics().writeLocked();
1253
1254 mUsageStatsService = new UsageStatsService( new File(
1255 systemDir, "usagestats.bin").toString());
1256
1257 mConfiguration.makeDefault();
1258 mProcessStats.init();
1259
1260 // Add ourself to the Watchdog monitors.
1261 Watchdog.getInstance().addMonitor(this);
1262
1263 // These values are set in system/rootdir/init.rc on startup.
1264 FOREGROUND_APP_ADJ =
1265 Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_ADJ"));
1266 VISIBLE_APP_ADJ =
1267 Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_ADJ"));
1268 SECONDARY_SERVER_ADJ =
1269 Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_ADJ"));
1270 HIDDEN_APP_MIN_ADJ =
1271 Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MIN_ADJ"));
1272 CONTENT_PROVIDER_ADJ =
1273 Integer.valueOf(SystemProperties.get("ro.CONTENT_PROVIDER_ADJ"));
1274 HIDDEN_APP_MAX_ADJ = CONTENT_PROVIDER_ADJ-1;
1275 EMPTY_APP_ADJ =
1276 Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_ADJ"));
1277 FOREGROUND_APP_MEM =
1278 Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_MEM"))*PAGE_SIZE;
1279 VISIBLE_APP_MEM =
1280 Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_MEM"))*PAGE_SIZE;
1281 SECONDARY_SERVER_MEM =
1282 Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_MEM"))*PAGE_SIZE;
1283 HIDDEN_APP_MEM =
1284 Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MEM"))*PAGE_SIZE;
1285 EMPTY_APP_MEM =
1286 Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_MEM"))*PAGE_SIZE;
1287
1288 mProcessStatsThread = new Thread("ProcessStats") {
1289 public void run() {
1290 while (true) {
1291 try {
1292 try {
1293 synchronized(this) {
1294 final long now = SystemClock.uptimeMillis();
1295 long nextCpuDelay = (mLastCpuTime+MONITOR_CPU_MAX_TIME)-now;
1296 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1297 //Log.i(TAG, "Cpu delay=" + nextCpuDelay
1298 // + ", write delay=" + nextWriteDelay);
1299 if (nextWriteDelay < nextCpuDelay) {
1300 nextCpuDelay = nextWriteDelay;
1301 }
1302 if (nextCpuDelay > 0) {
1303 this.wait(nextCpuDelay);
1304 }
1305 }
1306 } catch (InterruptedException e) {
1307 }
1308
1309 updateCpuStatsNow();
1310 } catch (Exception e) {
1311 Log.e(TAG, "Unexpected exception collecting process stats", e);
1312 }
1313 }
1314 }
1315 };
1316 mProcessStatsThread.start();
1317 }
1318
1319 @Override
1320 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1321 throws RemoteException {
1322 try {
1323 return super.onTransact(code, data, reply, flags);
1324 } catch (RuntimeException e) {
1325 // The activity manager only throws security exceptions, so let's
1326 // log all others.
1327 if (!(e instanceof SecurityException)) {
1328 Log.e(TAG, "Activity Manager Crash", e);
1329 }
1330 throw e;
1331 }
1332 }
1333
1334 void updateCpuStats() {
1335 synchronized (mProcessStatsThread) {
1336 final long now = SystemClock.uptimeMillis();
1337 if (mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) {
1338 mProcessStatsThread.notify();
1339 }
1340 }
1341 }
1342
1343 void updateCpuStatsNow() {
1344 synchronized (mProcessStatsThread) {
1345 final long now = SystemClock.uptimeMillis();
1346 boolean haveNewCpuStats = false;
1347
1348 if (MONITOR_CPU_USAGE &&
1349 mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) {
1350 mLastCpuTime = now;
1351 haveNewCpuStats = true;
1352 mProcessStats.update();
1353 //Log.i(TAG, mProcessStats.printCurrentState());
1354 //Log.i(TAG, "Total CPU usage: "
1355 // + mProcessStats.getTotalCpuPercent() + "%");
1356
1357 // Log the cpu usage if the property is set.
1358 if ("true".equals(SystemProperties.get("events.cpu"))) {
1359 int user = mProcessStats.getLastUserTime();
1360 int system = mProcessStats.getLastSystemTime();
1361 int iowait = mProcessStats.getLastIoWaitTime();
1362 int irq = mProcessStats.getLastIrqTime();
1363 int softIrq = mProcessStats.getLastSoftIrqTime();
1364 int idle = mProcessStats.getLastIdleTime();
1365
1366 int total = user + system + iowait + irq + softIrq + idle;
1367 if (total == 0) total = 1;
1368
1369 EventLog.writeEvent(LOG_CPU,
1370 ((user+system+iowait+irq+softIrq) * 100) / total,
1371 (user * 100) / total,
1372 (system * 100) / total,
1373 (iowait * 100) / total,
1374 (irq * 100) / total,
1375 (softIrq * 100) / total);
1376 }
1377 }
1378
1379 synchronized(mBatteryStatsService.getActiveStatistics()) {
1380 synchronized(mPidsSelfLocked) {
1381 if (haveNewCpuStats) {
1382 if (mBatteryStatsService.isOnBattery()) {
1383 final int N = mProcessStats.countWorkingStats();
1384 for (int i=0; i<N; i++) {
1385 ProcessStats.Stats st
1386 = mProcessStats.getWorkingStats(i);
1387 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1388 if (pr != null) {
1389 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1390 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
1391 }
1392 }
1393 }
1394 }
1395 }
1396
1397 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1398 mLastWriteTime = now;
1399 mBatteryStatsService.getActiveStatistics().writeLocked();
1400 }
1401 }
1402 }
1403 }
1404
1405 /**
1406 * Initialize the application bind args. These are passed to each
1407 * process when the bindApplication() IPC is sent to the process. They're
1408 * lazily setup to make sure the services are running when they're asked for.
1409 */
1410 private HashMap<String, IBinder> getCommonServicesLocked() {
1411 if (mAppBindArgs == null) {
1412 mAppBindArgs = new HashMap<String, IBinder>();
1413
1414 // Setup the application init args
1415 mAppBindArgs.put("package", ServiceManager.getService("package"));
1416 mAppBindArgs.put("window", ServiceManager.getService("window"));
1417 mAppBindArgs.put(Context.ALARM_SERVICE,
1418 ServiceManager.getService(Context.ALARM_SERVICE));
1419 }
1420 return mAppBindArgs;
1421 }
1422
1423 private final void setFocusedActivityLocked(HistoryRecord r) {
1424 if (mFocusedActivity != r) {
1425 mFocusedActivity = r;
1426 mWindowManager.setFocusedApp(r, true);
1427 }
1428 }
1429
1430 private final void updateLRUListLocked(ProcessRecord app,
1431 boolean oomAdj) {
1432 // put it on the LRU to keep track of when it should be exited.
1433 int lrui = mLRUProcesses.indexOf(app);
1434 if (lrui >= 0) mLRUProcesses.remove(lrui);
1435 mLRUProcesses.add(app);
1436 //Log.i(TAG, "Putting proc to front: " + app.processName);
1437 if (oomAdj) {
1438 updateOomAdjLocked();
1439 }
1440 }
1441
1442 private final boolean updateLRUListLocked(HistoryRecord r) {
1443 final boolean hadit = mLRUActivities.remove(r);
1444 mLRUActivities.add(r);
1445 return hadit;
1446 }
1447
1448 private final HistoryRecord topRunningActivityLocked(HistoryRecord notTop) {
1449 int i = mHistory.size()-1;
1450 while (i >= 0) {
1451 HistoryRecord r = (HistoryRecord)mHistory.get(i);
1452 if (!r.finishing && r != notTop) {
1453 return r;
1454 }
1455 i--;
1456 }
1457 return null;
1458 }
1459
1460 /**
1461 * This is a simplified version of topRunningActivityLocked that provides a number of
1462 * optional skip-over modes. It is intended for use with the ActivityWatcher hook only.
1463 *
1464 * @param token If non-null, any history records matching this token will be skipped.
1465 * @param taskId If non-zero, we'll attempt to skip over records with the same task ID.
1466 *
1467 * @return Returns the HistoryRecord of the next activity on the stack.
1468 */
1469 private final HistoryRecord topRunningActivityLocked(IBinder token, int taskId) {
1470 int i = mHistory.size()-1;
1471 while (i >= 0) {
1472 HistoryRecord r = (HistoryRecord)mHistory.get(i);
1473 // Note: the taskId check depends on real taskId fields being non-zero
1474 if (!r.finishing && (token != r) && (taskId != r.task.taskId)) {
1475 return r;
1476 }
1477 i--;
1478 }
1479 return null;
1480 }
1481
1482 private final ProcessRecord getProcessRecordLocked(
1483 String processName, int uid) {
1484 if (uid == Process.SYSTEM_UID) {
1485 // The system gets to run in any process. If there are multiple
1486 // processes with the same uid, just pick the first (this
1487 // should never happen).
1488 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1489 processName);
1490 return procs != null ? procs.valueAt(0) : null;
1491 }
1492 ProcessRecord proc = mProcessNames.get(processName, uid);
1493 return proc;
1494 }
1495
1496 private boolean isNextTransitionForward() {
1497 int transit = mWindowManager.getPendingAppTransition();
1498 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1499 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1500 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1501 }
1502
1503 private final boolean realStartActivityLocked(HistoryRecord r,
1504 ProcessRecord app, boolean andResume, boolean checkConfig)
1505 throws RemoteException {
1506
1507 r.startFreezingScreenLocked(app, 0);
1508 mWindowManager.setAppVisibility(r, true);
1509
1510 // Have the window manager re-evaluate the orientation of
1511 // the screen based on the new activity order. Note that
1512 // as a result of this, it can call back into the activity
1513 // manager with a new orientation. We don't care about that,
1514 // because the activity is not currently running so we are
1515 // just restarting it anyway.
1516 if (checkConfig) {
1517 Configuration config = mWindowManager.updateOrientationFromAppTokens(
1518 r.mayFreezeScreenLocked(app) ? r : null);
1519 updateConfigurationLocked(config, r);
1520 }
1521
1522 r.app = app;
1523
1524 if (localLOGV) Log.v(TAG, "Launching: " + r);
1525
1526 int idx = app.activities.indexOf(r);
1527 if (idx < 0) {
1528 app.activities.add(r);
1529 }
1530 updateLRUListLocked(app, true);
1531
1532 try {
1533 if (app.thread == null) {
1534 throw new RemoteException();
1535 }
1536 List<ResultInfo> results = null;
1537 List<Intent> newIntents = null;
1538 if (andResume) {
1539 results = r.results;
1540 newIntents = r.newIntents;
1541 }
1542 if (DEBUG_SWITCH) Log.v(TAG, "Launching: " + r
1543 + " icicle=" + r.icicle
1544 + " with results=" + results + " newIntents=" + newIntents
1545 + " andResume=" + andResume);
1546 if (andResume) {
1547 EventLog.writeEvent(LOG_AM_RESTART_ACTIVITY,
1548 System.identityHashCode(r),
1549 r.task.taskId, r.shortComponentName);
1550 }
1551 app.thread.scheduleLaunchActivity(new Intent(r.intent), r,
1552 r.info, r.icicle, results, newIntents, !andResume,
1553 isNextTransitionForward());
1554 // Update usage stats for launched activity
1555 updateUsageStats(r, true);
1556 } catch (RemoteException e) {
1557 if (r.launchFailed) {
1558 // This is the second time we failed -- finish activity
1559 // and give up.
1560 Log.e(TAG, "Second failure launching "
1561 + r.intent.getComponent().flattenToShortString()
1562 + ", giving up", e);
1563 appDiedLocked(app, app.pid, app.thread);
1564 requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null,
1565 "2nd-crash");
1566 return false;
1567 }
1568
1569 // This is the first time we failed -- restart process and
1570 // retry.
1571 app.activities.remove(r);
1572 throw e;
1573 }
1574
1575 r.launchFailed = false;
1576 if (updateLRUListLocked(r)) {
1577 Log.w(TAG, "Activity " + r
1578 + " being launched, but already in LRU list");
1579 }
1580
1581 if (andResume) {
1582 // As part of the process of launching, ActivityThread also performs
1583 // a resume.
1584 r.state = ActivityState.RESUMED;
1585 r.icicle = null;
1586 r.haveState = false;
1587 r.stopped = false;
1588 mResumedActivity = r;
1589 r.task.touchActiveTime();
1590 completeResumeLocked(r);
1591 pauseIfSleepingLocked();
1592 } else {
1593 // This activity is not starting in the resumed state... which
1594 // should look like we asked it to pause+stop (but remain visible),
1595 // and it has done so and reported back the current icicle and
1596 // other state.
1597 r.state = ActivityState.STOPPED;
1598 r.stopped = true;
1599 }
1600
1601 return true;
1602 }
1603
1604 private final void startSpecificActivityLocked(HistoryRecord r,
1605 boolean andResume, boolean checkConfig) {
1606 // Is this activity's application already running?
1607 ProcessRecord app = getProcessRecordLocked(r.processName,
1608 r.info.applicationInfo.uid);
1609
1610 if (r.startTime == 0) {
1611 r.startTime = SystemClock.uptimeMillis();
1612 }
1613
1614 if (app != null && app.thread != null) {
1615 try {
1616 realStartActivityLocked(r, app, andResume, checkConfig);
1617 return;
1618 } catch (RemoteException e) {
1619 Log.w(TAG, "Exception when starting activity "
1620 + r.intent.getComponent().flattenToShortString(), e);
1621 }
1622
1623 // If a dead object exception was thrown -- fall through to
1624 // restart the application.
1625 }
1626
1627 startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
1628 "activity", r.intent.getComponent());
1629 }
1630
1631 private final ProcessRecord startProcessLocked(String processName,
1632 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1633 String hostingType, ComponentName hostingName) {
1634 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1635 // We don't have to do anything more if:
1636 // (1) There is an existing application record; and
1637 // (2) The caller doesn't think it is dead, OR there is no thread
1638 // object attached to it so we know it couldn't have crashed; and
1639 // (3) There is a pid assigned to it, so it is either starting or
1640 // already running.
1641 if (DEBUG_PROCESSES) Log.v(TAG, "startProcess: name=" + processName
1642 + " app=" + app + " knownToBeDead=" + knownToBeDead
1643 + " thread=" + (app != null ? app.thread : null)
1644 + " pid=" + (app != null ? app.pid : -1));
1645 if (app != null &&
1646 (!knownToBeDead || app.thread == null) && app.pid > 0) {
1647 return app;
1648 }
1649
1650 String hostingNameStr = hostingName != null
1651 ? hostingName.flattenToShortString() : null;
1652
1653 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1654 // If we are in the background, then check to see if this process
1655 // is bad. If so, we will just silently fail.
1656 if (mBadProcesses.get(info.processName, info.uid) != null) {
1657 return null;
1658 }
1659 } else {
1660 // When the user is explicitly starting a process, then clear its
1661 // crash count so that we won't make it bad until they see at
1662 // least one crash dialog again, and make the process good again
1663 // if it had been bad.
1664 mProcessCrashTimes.remove(info.processName, info.uid);
1665 if (mBadProcesses.get(info.processName, info.uid) != null) {
1666 EventLog.writeEvent(LOG_AM_PROCESS_GOOD, info.uid,
1667 info.processName);
1668 mBadProcesses.remove(info.processName, info.uid);
1669 if (app != null) {
1670 app.bad = false;
1671 }
1672 }
1673 }
1674
1675 if (app == null) {
1676 app = newProcessRecordLocked(null, info, processName);
1677 mProcessNames.put(processName, info.uid, app);
1678 } else {
1679 // If this is a new package in the process, add the package to the list
1680 app.addPackage(info.packageName);
1681 }
1682
1683 // If the system is not ready yet, then hold off on starting this
1684 // process until it is.
1685 if (!mSystemReady
1686 && (info.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) {
1687 if (!mProcessesOnHold.contains(app)) {
1688 mProcessesOnHold.add(app);
1689 }
1690 return app;
1691 }
1692
1693 startProcessLocked(app, hostingType, hostingNameStr);
1694 return (app.pid != 0) ? app : null;
1695 }
1696
1697 private final void startProcessLocked(ProcessRecord app,
1698 String hostingType, String hostingNameStr) {
1699 if (app.pid > 0 && app.pid != MY_PID) {
1700 synchronized (mPidsSelfLocked) {
1701 mPidsSelfLocked.remove(app.pid);
1702 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1703 }
1704 app.pid = 0;
1705 }
1706
1707 mProcessesOnHold.remove(app);
1708
1709 updateCpuStats();
1710
1711 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1712 mProcDeaths[0] = 0;
1713
1714 try {
1715 int uid = app.info.uid;
1716 int[] gids = null;
1717 try {
1718 gids = mContext.getPackageManager().getPackageGids(
1719 app.info.packageName);
1720 } catch (PackageManager.NameNotFoundException e) {
1721 Log.w(TAG, "Unable to retrieve gids", e);
1722 }
1723 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1724 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1725 && mTopComponent != null
1726 && app.processName.equals(mTopComponent.getPackageName())) {
1727 uid = 0;
1728 }
1729 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1730 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1731 uid = 0;
1732 }
1733 }
1734 int debugFlags = 0;
1735 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1736 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
1737 }
1738 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1739 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1740 }
1741 if ("1".equals(SystemProperties.get("debug.assert"))) {
1742 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1743 }
1744 int pid = Process.start("android.app.ActivityThread",
1745 mSimpleProcessManagement ? app.processName : null, uid, uid,
1746 gids, debugFlags, null);
1747 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1748 synchronized (bs) {
1749 if (bs.isOnBattery()) {
1750 app.batteryStats.incStartsLocked();
1751 }
1752 }
1753
1754 EventLog.writeEvent(LOG_AM_PROCESS_START, pid, uid,
1755 app.processName, hostingType,
1756 hostingNameStr != null ? hostingNameStr : "");
1757
1758 if (app.persistent) {
1759 Watchdog.getInstance().processStarted(app, app.processName, pid);
1760 }
1761
1762 StringBuilder buf = new StringBuilder(128);
1763 buf.append("Start proc ");
1764 buf.append(app.processName);
1765 buf.append(" for ");
1766 buf.append(hostingType);
1767 if (hostingNameStr != null) {
1768 buf.append(" ");
1769 buf.append(hostingNameStr);
1770 }
1771 buf.append(": pid=");
1772 buf.append(pid);
1773 buf.append(" uid=");
1774 buf.append(uid);
1775 buf.append(" gids={");
1776 if (gids != null) {
1777 for (int gi=0; gi<gids.length; gi++) {
1778 if (gi != 0) buf.append(", ");
1779 buf.append(gids[gi]);
1780
1781 }
1782 }
1783 buf.append("}");
1784 Log.i(TAG, buf.toString());
1785 if (pid == 0 || pid == MY_PID) {
1786 // Processes are being emulated with threads.
1787 app.pid = MY_PID;
1788 app.removed = false;
1789 mStartingProcesses.add(app);
1790 } else if (pid > 0) {
1791 app.pid = pid;
1792 app.removed = false;
1793 synchronized (mPidsSelfLocked) {
1794 this.mPidsSelfLocked.put(pid, app);
1795 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1796 msg.obj = app;
1797 mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
1798 }
1799 } else {
1800 app.pid = 0;
1801 RuntimeException e = new RuntimeException(
1802 "Failure starting process " + app.processName
1803 + ": returned pid=" + pid);
1804 Log.e(TAG, e.getMessage(), e);
1805 }
1806 } catch (RuntimeException e) {
1807 // XXX do better error recovery.
1808 app.pid = 0;
1809 Log.e(TAG, "Failure starting process " + app.processName, e);
1810 }
1811 }
1812
1813 private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) {
1814 if (mPausingActivity != null) {
1815 RuntimeException e = new RuntimeException();
1816 Log.e(TAG, "Trying to pause when pause is already pending for "
1817 + mPausingActivity, e);
1818 }
1819 HistoryRecord prev = mResumedActivity;
1820 if (prev == null) {
1821 RuntimeException e = new RuntimeException();
1822 Log.e(TAG, "Trying to pause when nothing is resumed", e);
1823 resumeTopActivityLocked(null);
1824 return;
1825 }
1826 if (DEBUG_PAUSE) Log.v(TAG, "Start pausing: " + prev);
1827 mResumedActivity = null;
1828 mPausingActivity = prev;
1829 mLastPausedActivity = prev;
1830 prev.state = ActivityState.PAUSING;
1831 prev.task.touchActiveTime();
1832
1833 updateCpuStats();
1834
1835 if (prev.app != null && prev.app.thread != null) {
1836 if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending pause: " + prev);
1837 try {
1838 EventLog.writeEvent(LOG_AM_PAUSE_ACTIVITY,
1839 System.identityHashCode(prev),
1840 prev.shortComponentName);
1841 prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving,
1842 prev.configChangeFlags);
1843 updateUsageStats(prev, false);
1844 } catch (Exception e) {
1845 // Ignore exception, if process died other code will cleanup.
1846 Log.w(TAG, "Exception thrown during pause", e);
1847 mPausingActivity = null;
1848 mLastPausedActivity = null;
1849 }
1850 } else {
1851 mPausingActivity = null;
1852 mLastPausedActivity = null;
1853 }
1854
1855 // If we are not going to sleep, we want to ensure the device is
1856 // awake until the next activity is started.
1857 if (!mSleeping) {
1858 mLaunchingActivity.acquire();
1859 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1860 // To be safe, don't allow the wake lock to be held for too long.
1861 Message msg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG);
1862 mHandler.sendMessageDelayed(msg, LAUNCH_TIMEOUT);
1863 }
1864 }
1865
1866
1867 if (mPausingActivity != null) {
1868 // Have the window manager pause its key dispatching until the new
1869 // activity has started. If we're pausing the activity just because
1870 // the screen is being turned off and the UI is sleeping, don't interrupt
1871 // key dispatch; the same activity will pick it up again on wakeup.
1872 if (!uiSleeping) {
1873 prev.pauseKeyDispatchingLocked();
1874 } else {
1875 if (DEBUG_PAUSE) Log.v(TAG, "Key dispatch not paused for screen off");
1876 }
1877
1878 // Schedule a pause timeout in case the app doesn't respond.
1879 // We don't give it much time because this directly impacts the
1880 // responsiveness seen by the user.
1881 Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
1882 msg.obj = prev;
1883 mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
1884 if (DEBUG_PAUSE) Log.v(TAG, "Waiting for pause to complete...");
1885 } else {
1886 // This activity failed to schedule the
1887 // pause, so just treat it as being paused now.
1888 if (DEBUG_PAUSE) Log.v(TAG, "Activity not running, resuming next.");
1889 resumeTopActivityLocked(null);
1890 }
1891 }
1892
1893 private final void completePauseLocked() {
1894 HistoryRecord prev = mPausingActivity;
1895 if (DEBUG_PAUSE) Log.v(TAG, "Complete pause: " + prev);
1896
1897 if (prev != null) {
1898 if (prev.finishing) {
1899 if (DEBUG_PAUSE) Log.v(TAG, "Executing finish of activity: " + prev);
1900 prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE);
1901 } else if (prev.app != null) {
1902 if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending stop: " + prev);
1903 if (prev.waitingVisible) {
1904 prev.waitingVisible = false;
1905 mWaitingVisibleActivities.remove(prev);
1906 if (DEBUG_SWITCH || DEBUG_PAUSE) Log.v(
1907 TAG, "Complete pause, no longer waiting: " + prev);
1908 }
1909 if (prev.configDestroy) {
1910 // The previous is being paused because the configuration
1911 // is changing, which means it is actually stopping...
1912 // To juggle the fact that we are also starting a new
1913 // instance right now, we need to first completely stop
1914 // the current instance before starting the new one.
1915 if (DEBUG_PAUSE) Log.v(TAG, "Destroying after pause: " + prev);
1916 destroyActivityLocked(prev, true);
1917 } else {
1918 mStoppingActivities.add(prev);
1919 if (mStoppingActivities.size() > 3) {
1920 // If we already have a few activities waiting to stop,
1921 // then give up on things going idle and start clearing
1922 // them out.
1923 if (DEBUG_PAUSE) Log.v(TAG, "To many pending stops, forcing idle");
1924 Message msg = Message.obtain();
1925 msg.what = ActivityManagerService.IDLE_NOW_MSG;
1926 mHandler.sendMessage(msg);
1927 }
1928 }
1929 } else {
1930 if (DEBUG_PAUSE) Log.v(TAG, "App died during pause, not stopping: " + prev);
1931 prev = null;
1932 }
1933 mPausingActivity = null;
1934 }
1935
1936 if (!mSleeping) {
1937 resumeTopActivityLocked(prev);
1938 } else {
1939 if (mGoingToSleep.isHeld()) {
1940 mGoingToSleep.release();
1941 }
1942 }
1943
1944 if (prev != null) {
1945 prev.resumeKeyDispatchingLocked();
1946 }
1947 }
1948
1949 /**
1950 * Once we know that we have asked an application to put an activity in
1951 * the resumed state (either by launching it or explicitly telling it),
1952 * this function updates the rest of our state to match that fact.
1953 */
1954 private final void completeResumeLocked(HistoryRecord next) {
1955 next.idle = false;
1956 next.results = null;
1957 next.newIntents = null;
1958
1959 // schedule an idle timeout in case the app doesn't do it for us.
1960 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
1961 msg.obj = next;
1962 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
1963
1964 if (false) {
1965 // The activity was never told to pause, so just keep
1966 // things going as-is. To maintain our own state,
1967 // we need to emulate it coming back and saying it is
1968 // idle.
1969 msg = mHandler.obtainMessage(IDLE_NOW_MSG);
1970 msg.obj = next;
1971 mHandler.sendMessage(msg);
1972 }
1973
1974 next.thumbnail = null;
1975 setFocusedActivityLocked(next);
1976 next.resumeKeyDispatchingLocked();
1977 ensureActivitiesVisibleLocked(null, 0);
1978 mWindowManager.executeAppTransition();
1979 }
1980
1981 /**
1982 * Make sure that all activities that need to be visible (that is, they
1983 * currently can be seen by the user) actually are.
1984 */
1985 private final void ensureActivitiesVisibleLocked(HistoryRecord top,
1986 HistoryRecord starting, String onlyThisProcess, int configChanges) {
1987 if (DEBUG_VISBILITY) Log.v(
1988 TAG, "ensureActivitiesVisible behind " + top
1989 + " configChanges=0x" + Integer.toHexString(configChanges));
1990
1991 // If the top activity is not fullscreen, then we need to
1992 // make sure any activities under it are now visible.
1993 final int count = mHistory.size();
1994 int i = count-1;
1995 while (mHistory.get(i) != top) {
1996 i--;
1997 }
1998 HistoryRecord r;
1999 boolean behindFullscreen = false;
2000 for (; i>=0; i--) {
2001 r = (HistoryRecord)mHistory.get(i);
2002 if (DEBUG_VISBILITY) Log.v(
2003 TAG, "Make visible? " + r + " finishing=" + r.finishing
2004 + " state=" + r.state);
2005 if (r.finishing) {
2006 continue;
2007 }
2008
2009 final boolean doThisProcess = onlyThisProcess == null
2010 || onlyThisProcess.equals(r.processName);
2011
2012 // First: if this is not the current activity being started, make
2013 // sure it matches the current configuration.
2014 if (r != starting && doThisProcess) {
2015 ensureActivityConfigurationLocked(r, 0);
2016 }
2017
2018 if (r.app == null || r.app.thread == null) {
2019 if (onlyThisProcess == null
2020 || onlyThisProcess.equals(r.processName)) {
2021 // This activity needs to be visible, but isn't even
2022 // running... get it started, but don't resume it
2023 // at this point.
2024 if (DEBUG_VISBILITY) Log.v(
2025 TAG, "Start and freeze screen for " + r);
2026 if (r != starting) {
2027 r.startFreezingScreenLocked(r.app, configChanges);
2028 }
2029 if (!r.visible) {
2030 if (DEBUG_VISBILITY) Log.v(
2031 TAG, "Starting and making visible: " + r);
2032 mWindowManager.setAppVisibility(r, true);
2033 }
2034 if (r != starting) {
2035 startSpecificActivityLocked(r, false, false);
2036 }
2037 }
2038
2039 } else if (r.visible) {
2040 // If this activity is already visible, then there is nothing
2041 // else to do here.
2042 if (DEBUG_VISBILITY) Log.v(
2043 TAG, "Skipping: already visible at " + r);
2044 r.stopFreezingScreenLocked(false);
2045
2046 } else if (onlyThisProcess == null) {
2047 // This activity is not currently visible, but is running.
2048 // Tell it to become visible.
2049 r.visible = true;
2050 if (r.state != ActivityState.RESUMED && r != starting) {
2051 // If this activity is paused, tell it
2052 // to now show its window.
2053 if (DEBUG_VISBILITY) Log.v(
2054 TAG, "Making visible and scheduling visibility: " + r);
2055 try {
2056 mWindowManager.setAppVisibility(r, true);
2057 r.app.thread.scheduleWindowVisibility(r, true);
2058 r.stopFreezingScreenLocked(false);
2059 } catch (Exception e) {
2060 // Just skip on any failure; we'll make it
2061 // visible when it next restarts.
2062 Log.w(TAG, "Exception thrown making visibile: "
2063 + r.intent.getComponent(), e);
2064 }
2065 }
2066 }
2067
2068 // Aggregate current change flags.
2069 configChanges |= r.configChangeFlags;
2070
2071 if (r.fullscreen) {
2072 // At this point, nothing else needs to be shown
2073 if (DEBUG_VISBILITY) Log.v(
2074 TAG, "Stopping: fullscreen at " + r);
2075 behindFullscreen = true;
2076 i--;
2077 break;
2078 }
2079 }
2080
2081 // Now for any activities that aren't visible to the user, make
2082 // sure they no longer are keeping the screen frozen.
2083 while (i >= 0) {
2084 r = (HistoryRecord)mHistory.get(i);
2085 if (DEBUG_VISBILITY) Log.v(
2086 TAG, "Make invisible? " + r + " finishing=" + r.finishing
2087 + " state=" + r.state
2088 + " behindFullscreen=" + behindFullscreen);
2089 if (!r.finishing) {
2090 if (behindFullscreen) {
2091 if (r.visible) {
2092 if (DEBUG_VISBILITY) Log.v(
2093 TAG, "Making invisible: " + r);
2094 r.visible = false;
2095 try {
2096 mWindowManager.setAppVisibility(r, false);
2097 if ((r.state == ActivityState.STOPPING
2098 || r.state == ActivityState.STOPPED)
2099 && r.app != null && r.app.thread != null) {
2100 if (DEBUG_VISBILITY) Log.v(
2101 TAG, "Scheduling invisibility: " + r);
2102 r.app.thread.scheduleWindowVisibility(r, false);
2103 }
2104 } catch (Exception e) {
2105 // Just skip on any failure; we'll make it
2106 // visible when it next restarts.
2107 Log.w(TAG, "Exception thrown making hidden: "
2108 + r.intent.getComponent(), e);
2109 }
2110 } else {
2111 if (DEBUG_VISBILITY) Log.v(
2112 TAG, "Already invisible: " + r);
2113 }
2114 } else if (r.fullscreen) {
2115 if (DEBUG_VISBILITY) Log.v(
2116 TAG, "Now behindFullscreen: " + r);
2117 behindFullscreen = true;
2118 }
2119 }
2120 i--;
2121 }
2122 }
2123
2124 /**
2125 * Version of ensureActivitiesVisible that can easily be called anywhere.
2126 */
2127 private final void ensureActivitiesVisibleLocked(HistoryRecord starting,
2128 int configChanges) {
2129 HistoryRecord r = topRunningActivityLocked(null);
2130 if (r != null) {
2131 ensureActivitiesVisibleLocked(r, starting, null, configChanges);
2132 }
2133 }
2134
2135 private void updateUsageStats(HistoryRecord resumedComponent, boolean resumed) {
2136 if (resumed) {
2137 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2138 } else {
2139 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2140 }
2141 }
2142
2143 /**
2144 * Ensure that the top activity in the stack is resumed.
2145 *
2146 * @param prev The previously resumed activity, for when in the process
2147 * of pausing; can be null to call from elsewhere.
2148 *
2149 * @return Returns true if something is being resumed, or false if
2150 * nothing happened.
2151 */
2152 private final boolean resumeTopActivityLocked(HistoryRecord prev) {
2153 // Find the first activity that is not finishing.
2154 HistoryRecord next = topRunningActivityLocked(null);
2155
2156 // Remember how we'll process this pause/resume situation, and ensure
2157 // that the state is reset however we wind up proceeding.
2158 final boolean userLeaving = mUserLeaving;
2159 mUserLeaving = false;
2160
2161 if (next == null) {
2162 // There are no more activities! Let's just start up the
2163 // Launcher...
2164 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2165 && mTopAction == null) {
2166 // We are running in factory test mode, but unable to find
2167 // the factory test app, so just sit around displaying the
2168 // error message and don't try to start anything.
2169 return false;
2170 }
2171 Intent intent = new Intent(
2172 mTopAction,
2173 mTopData != null ? Uri.parse(mTopData) : null);
2174 intent.setComponent(mTopComponent);
2175 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2176 intent.addCategory(Intent.CATEGORY_HOME);
2177 }
2178 ActivityInfo aInfo =
2179 intent.resolveActivityInfo(mContext.getPackageManager(),
2180 PackageManager.GET_SHARED_LIBRARY_FILES);
2181 if (aInfo != null) {
2182 intent.setComponent(new ComponentName(
2183 aInfo.applicationInfo.packageName, aInfo.name));
2184 // Don't do this if the home app is currently being
2185 // instrumented.
2186 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2187 aInfo.applicationInfo.uid);
2188 if (app == null || app.instrumentationClass == null) {
2189 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2190 startActivityLocked(null, intent, null, null, 0, aInfo,
2191 null, null, 0, 0, 0, false);
2192 }
2193 }
2194 return true;
2195 }
2196
2197 // If the top activity is the resumed one, nothing to do.
2198 if (mResumedActivity == next && next.state == ActivityState.RESUMED) {
2199 // Make sure we have executed any pending transitions, since there
2200 // should be nothing left to do at this point.
2201 mWindowManager.executeAppTransition();
2202 return false;
2203 }
2204
2205 // If we are sleeping, and there is no resumed activity, and the top
2206 // activity is paused, well that is the state we want.
2207 if (mSleeping && mLastPausedActivity == next && next.state == ActivityState.PAUSED) {
2208 // Make sure we have executed any pending transitions, since there
2209 // should be nothing left to do at this point.
2210 mWindowManager.executeAppTransition();
2211 return false;
2212 }
2213
2214 // The activity may be waiting for stop, but that is no longer
2215 // appropriate for it.
2216 mStoppingActivities.remove(next);
2217 mWaitingVisibleActivities.remove(next);
2218
2219 if (DEBUG_SWITCH) Log.v(TAG, "Resuming " + next);
2220
2221 // If we are currently pausing an activity, then don't do anything
2222 // until that is done.
2223 if (mPausingActivity != null) {
2224 if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: pausing=" + mPausingActivity);
2225 return false;
2226 }
2227
2228 // We need to start pausing the current activity so the top one
2229 // can be resumed...
2230 if (mResumedActivity != null) {
2231 if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: need to start pausing");
2232 startPausingLocked(userLeaving, false);
2233 return true;
2234 }
2235
2236 if (prev != null && prev != next) {
2237 if (!prev.waitingVisible && next != null && !next.nowVisible) {
2238 prev.waitingVisible = true;
2239 mWaitingVisibleActivities.add(prev);
2240 if (DEBUG_SWITCH) Log.v(
2241 TAG, "Resuming top, waiting visible to hide: " + prev);
2242 } else {
2243 // The next activity is already visible, so hide the previous
2244 // activity's windows right now so we can show the new one ASAP.
2245 // We only do this if the previous is finishing, which should mean
2246 // it is on top of the one being resumed so hiding it quickly
2247 // is good. Otherwise, we want to do the normal route of allowing
2248 // the resumed activity to be shown so we can decide if the
2249 // previous should actually be hidden depending on whether the
2250 // new one is found to be full-screen or not.
2251 if (prev.finishing) {
2252 mWindowManager.setAppVisibility(prev, false);
2253 if (DEBUG_SWITCH) Log.v(TAG, "Not waiting for visible to hide: "
2254 + prev + ", waitingVisible="
2255 + (prev != null ? prev.waitingVisible : null)
2256 + ", nowVisible=" + next.nowVisible);
2257 } else {
2258 if (DEBUG_SWITCH) Log.v(TAG, "Previous already visible but still waiting to hide: "
2259 + prev + ", waitingVisible="
2260 + (prev != null ? prev.waitingVisible : null)
2261 + ", nowVisible=" + next.nowVisible);
2262 }
2263 }
2264 }
2265
2266 // We are starting up the next activity, so tell the window manager
2267 // that the previous one will be hidden soon. This way it can know
2268 // to ignore it when computing the desired screen orientation.
2269 if (prev != null) {
2270 if (prev.finishing) {
2271 if (DEBUG_TRANSITION) Log.v(TAG,
2272 "Prepare close transition: prev=" + prev);
2273 mWindowManager.prepareAppTransition(prev.task == next.task
2274 ? WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE
2275 : WindowManagerPolicy.TRANSIT_TASK_CLOSE);
2276 mWindowManager.setAppWillBeHidden(prev);
2277 mWindowManager.setAppVisibility(prev, false);
2278 } else {
2279 if (DEBUG_TRANSITION) Log.v(TAG,
2280 "Prepare open transition: prev=" + prev);
2281 mWindowManager.prepareAppTransition(prev.task == next.task
2282 ? WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
2283 : WindowManagerPolicy.TRANSIT_TASK_OPEN);
2284 }
2285 if (false) {
2286 mWindowManager.setAppWillBeHidden(prev);
2287 mWindowManager.setAppVisibility(prev, false);
2288 }
2289 } else if (mHistory.size() > 1) {
2290 if (DEBUG_TRANSITION) Log.v(TAG,
2291 "Prepare open transition: no previous");
2292 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
2293 }
2294
2295 if (next.app != null && next.app.thread != null) {
2296 if (DEBUG_SWITCH) Log.v(TAG, "Resume running: " + next);
2297
2298 // This activity is now becoming visible.
2299 mWindowManager.setAppVisibility(next, true);
2300
2301 HistoryRecord lastResumedActivity = mResumedActivity;
2302 ActivityState lastState = next.state;
2303
2304 updateCpuStats();
2305
2306 next.state = ActivityState.RESUMED;
2307 mResumedActivity = next;
2308 next.task.touchActiveTime();
2309 updateLRUListLocked(next.app, true);
2310 updateLRUListLocked(next);
2311
2312 // Have the window manager re-evaluate the orientation of
2313 // the screen based on the new activity order.
2314 Configuration config = mWindowManager.updateOrientationFromAppTokens(
2315 next.mayFreezeScreenLocked(next.app) ? next : null);
2316 if (config != null) {
2317 next.frozenBeforeDestroy = true;
2318 }
2319 if (!updateConfigurationLocked(config, next)) {
2320 // The configuration update wasn't able to keep the existing
2321 // instance of the activity, and instead started a new one.
2322 // We should be all done, but let's just make sure our activity
2323 // is still at the top and schedule another run if something
2324 // weird happened.
2325 HistoryRecord nextNext = topRunningActivityLocked(null);
2326 if (DEBUG_SWITCH) Log.i(TAG,
2327 "Activity config changed during resume: " + next
2328 + ", new next: " + nextNext);
2329 if (nextNext != next) {
2330 // Do over!
2331 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2332 }
2333 mWindowManager.executeAppTransition();
2334 return true;
2335 }
2336
2337 try {
2338 // Deliver all pending results.
2339 ArrayList a = next.results;
2340 if (a != null) {
2341 final int N = a.size();
2342 if (!next.finishing && N > 0) {
2343 if (localLOGV) Log.v(
2344 TAG, "Delivering results to " + next
2345 + ": " + a);
2346 next.app.thread.scheduleSendResult(next, a);
2347 }
2348 }
2349
2350 if (next.newIntents != null) {
2351 next.app.thread.scheduleNewIntent(next.newIntents, next);
2352 }
2353
2354 EventLog.writeEvent(LOG_AM_RESUME_ACTIVITY,
2355 System.identityHashCode(next),
2356 next.task.taskId, next.shortComponentName);
2357 updateUsageStats(next, true);
2358
2359 next.app.thread.scheduleResumeActivity(next,
2360 isNextTransitionForward());
2361 pauseIfSleepingLocked();
2362
2363 } catch (Exception e) {
2364 // Whoops, need to restart this activity!
2365 next.state = lastState;
2366 mResumedActivity = lastResumedActivity;
2367 if (Config.LOGD) Log.d(TAG,
2368 "Restarting because process died: " + next);
2369 if (!next.hasBeenLaunched) {
2370 next.hasBeenLaunched = true;
2371 } else {
2372 if (SHOW_APP_STARTING_ICON) {
2373 mWindowManager.setAppStartingWindow(
2374 next, next.packageName, next.theme,
2375 next.nonLocalizedLabel,
2376 next.labelRes, next.icon, null, true);
2377 }
2378 }
2379 startSpecificActivityLocked(next, true, false);
2380 return true;
2381 }
2382
2383 // From this point on, if something goes wrong there is no way
2384 // to recover the activity.
2385 try {
2386 next.visible = true;
2387 completeResumeLocked(next);
2388 } catch (Exception e) {
2389 // If any exception gets thrown, toss away this
2390 // activity and try the next one.
2391 Log.w(TAG, "Exception thrown during resume of " + next, e);
2392 requestFinishActivityLocked(next, Activity.RESULT_CANCELED, null,
2393 "resume-exception");
2394 return true;
2395 }
2396
2397 // Didn't need to use the icicle, and it is now out of date.
2398 next.icicle = null;
2399 next.haveState = false;
2400 next.stopped = false;
2401
2402 } else {
2403 // Whoops, need to restart this activity!
2404 if (!next.hasBeenLaunched) {
2405 next.hasBeenLaunched = true;
2406 } else {
2407 if (SHOW_APP_STARTING_ICON) {
2408 mWindowManager.setAppStartingWindow(
2409 next, next.packageName, next.theme,
2410 next.nonLocalizedLabel,
2411 next.labelRes, next.icon, null, true);
2412 }
2413 if (DEBUG_SWITCH) Log.v(TAG, "Restarting: " + next);
2414 }
2415 startSpecificActivityLocked(next, true, true);
2416 }
2417
2418 return true;
2419 }
2420
2421 private final void startActivityLocked(HistoryRecord r, boolean newTask) {
2422 final int NH = mHistory.size();
2423
2424 int addPos = -1;
2425
2426 if (!newTask) {
2427 // If starting in an existing task, find where that is...
2428 HistoryRecord next = null;
2429 boolean startIt = true;
2430 for (int i = NH-1; i >= 0; i--) {
2431 HistoryRecord p = (HistoryRecord)mHistory.get(i);
2432 if (p.finishing) {
2433 continue;
2434 }
2435 if (p.task == r.task) {
2436 // Here it is! Now, if this is not yet visible to the
2437 // user, then just add it without starting; it will
2438 // get started when the user navigates back to it.
2439 addPos = i+1;
2440 if (!startIt) {
2441 mHistory.add(addPos, r);
2442 r.inHistory = true;
2443 r.task.numActivities++;
2444 mWindowManager.addAppToken(addPos, r, r.task.taskId,
2445 r.info.screenOrientation, r.fullscreen);
2446 if (VALIDATE_TOKENS) {
2447 mWindowManager.validateAppTokens(mHistory);
2448 }
2449 return;
2450 }
2451 break;
2452 }
2453 if (p.fullscreen) {
2454 startIt = false;
2455 }
2456 next = p;
2457 }
2458 }
2459
2460 // Place a new activity at top of stack, so it is next to interact
2461 // with the user.
2462 if (addPos < 0) {
2463 addPos = mHistory.size();
2464 }
2465
2466 // If we are not placing the new activity frontmost, we do not want
2467 // to deliver the onUserLeaving callback to the actual frontmost
2468 // activity
2469 if (addPos < NH) {
2470 mUserLeaving = false;
2471 if (DEBUG_USER_LEAVING) Log.v(TAG, "startActivity() behind front, mUserLeaving=false");
2472 }
2473
2474 // Slot the activity into the history stack and proceed
2475 mHistory.add(addPos, r);
2476 r.inHistory = true;
2477 r.frontOfTask = newTask;
2478 r.task.numActivities++;
2479 if (NH > 0) {
2480 // We want to show the starting preview window if we are
2481 // switching to a new task, or the next activity's process is
2482 // not currently running.
2483 boolean showStartingIcon = newTask;
2484 ProcessRecord proc = r.app;
2485 if (proc == null) {
2486 proc = mProcessNames.get(r.processName, r.info.applicationInfo.uid);
2487 }
2488 if (proc == null || proc.thread == null) {
2489 showStartingIcon = true;
2490 }
2491 if (DEBUG_TRANSITION) Log.v(TAG,
2492 "Prepare open transition: starting " + r);
2493 mWindowManager.prepareAppTransition(newTask
2494 ? WindowManagerPolicy.TRANSIT_TASK_OPEN
2495 : WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
2496 mWindowManager.addAppToken(
2497 addPos, r, r.task.taskId, r.info.screenOrientation, r.fullscreen);
2498 boolean doShow = true;
2499 if (newTask) {
2500 // Even though this activity is starting fresh, we still need
2501 // to reset it to make sure we apply affinities to move any
2502 // existing activities from other tasks in to it.
2503 // If the caller has requested that the target task be
2504 // reset, then do so.
2505 if ((r.intent.getFlags()
2506 &Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
2507 resetTaskIfNeededLocked(r, r);
2508 doShow = topRunningActivityLocked(null) == r;
2509 }
2510 }
2511 if (SHOW_APP_STARTING_ICON && doShow) {
2512 // Figure out if we are transitioning from another activity that is
2513 // "has the same starting icon" as the next one. This allows the
2514 // window manager to keep the previous window it had previously
2515 // created, if it still had one.
2516 HistoryRecord prev = mResumedActivity;
2517 if (prev != null) {
2518 // We don't want to reuse the previous starting preview if:
2519 // (1) The current activity is in a different task.
2520 if (prev.task != r.task) prev = null;
2521 // (2) The current activity is already displayed.
2522 else if (prev.nowVisible) prev = null;
2523 }
2524 mWindowManager.setAppStartingWindow(
2525 r, r.packageName, r.theme, r.nonLocalizedLabel,
2526 r.labelRes, r.icon, prev, showStartingIcon);
2527 }
2528 } else {
2529 // If this is the first activity, don't do any fancy animations,
2530 // because there is nothing for it to animate on top of.
2531 mWindowManager.addAppToken(addPos, r, r.task.taskId,
2532 r.info.screenOrientation, r.fullscreen);
2533 }
2534 if (VALIDATE_TOKENS) {
2535 mWindowManager.validateAppTokens(mHistory);
2536 }
2537
2538 resumeTopActivityLocked(null);
2539 }
2540
2541 /**
2542 * Perform clear operation as requested by
2543 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: assuming the top task on the
2544 * stack is the one that the new activity is being launched in, look for
2545 * an instance of that activity in the stack and, if found, finish all
2546 * activities on top of it and return the instance.
2547 *
2548 * @param newR Description of the new activity being started.
2549 * @return Returns the old activity that should be continue to be used,
2550 * or null if none was found.
2551 */
2552 private final HistoryRecord performClearTopTaskLocked(int taskId,
2553 HistoryRecord newR, boolean doClear) {
2554 int i = mHistory.size();
2555 while (i > 0) {
2556 i--;
2557 HistoryRecord r = (HistoryRecord)mHistory.get(i);
2558 if (r.finishing) {
2559 continue;
2560 }
2561 if (r.task.taskId != taskId) {
2562 return null;
2563 }
2564 if (r.realActivity.equals(newR.realActivity)) {
2565 // Here it is! Now finish everything in front...
2566 HistoryRecord ret = r;
2567 if (doClear) {
2568 while (i < (mHistory.size()-1)) {
2569 i++;
2570 r = (HistoryRecord)mHistory.get(i);
2571 if (r.finishing) {
2572 continue;
2573 }
2574 if (finishActivityLocked(r, i, Activity.RESULT_CANCELED,
2575 null, "clear")) {
2576 i--;
2577 }
2578 }
2579 }
2580
2581 // Finally, if this is a normal launch mode (that is, not
2582 // expecting onNewIntent()), then we will finish the current
2583 // instance of the activity so a new fresh one can be started.
2584 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE) {
2585 if (!ret.finishing) {
2586 int index = indexOfTokenLocked(ret, false);
2587 if (index >= 0) {
2588 finishActivityLocked(ret, 0, Activity.RESULT_CANCELED,
2589 null, "clear");
2590 }
2591 return null;
2592 }
2593 }
2594
2595 return ret;
2596 }
2597 }
2598
2599 return null;
2600 }
2601
2602 /**
2603 * Find the activity in the history stack within the given task. Returns
2604 * the index within the history at which it's found, or < 0 if not found.
2605 */
2606 private final int findActivityInHistoryLocked(HistoryRecord r, int task) {
2607 int i = mHistory.size();
2608 while (i > 0) {
2609 i--;
2610 HistoryRecord candidate = (HistoryRecord)mHistory.get(i);
2611 if (candidate.task.taskId != task) {
2612 break;
2613 }
2614 if (candidate.realActivity.equals(r.realActivity)) {
2615 return i;
2616 }
2617 }
2618
2619 return -1;
2620 }
2621
2622 /**
2623 * Reorder the history stack so that the activity at the given index is
2624 * brought to the front.
2625 */
2626 private final HistoryRecord moveActivityToFrontLocked(int where) {
2627 HistoryRecord newTop = (HistoryRecord)mHistory.remove(where);
2628 int top = mHistory.size();
2629 HistoryRecord oldTop = (HistoryRecord)mHistory.get(top-1);
2630 mHistory.add(top, newTop);
2631 oldTop.frontOfTask = false;
2632 newTop.frontOfTask = true;
2633 return newTop;
2634 }
2635
2636 /**
2637 * Deliver a new Intent to an existing activity, so that its onNewIntent()
2638 * method will be called at the proper time.
2639 */
2640 private final void deliverNewIntentLocked(HistoryRecord r, Intent intent) {
2641 boolean sent = false;
2642 if (r.state == ActivityState.RESUMED
2643 && r.app != null && r.app.thread != null) {
2644 try {
2645 ArrayList<Intent> ar = new ArrayList<Intent>();
2646 ar.add(new Intent(intent));
2647 r.app.thread.scheduleNewIntent(ar, r);
2648 sent = true;
2649 } catch (Exception e) {
2650 Log.w(TAG, "Exception thrown sending new intent to " + r, e);
2651 }
2652 }
2653 if (!sent) {
2654 r.addNewIntentLocked(new Intent(intent));
2655 }
2656 }
2657
2658 private final void logStartActivity(int tag, HistoryRecord r,
2659 TaskRecord task) {
2660 EventLog.writeEvent(tag,
2661 System.identityHashCode(r), task.taskId,
2662 r.shortComponentName, r.intent.getAction(),
2663 r.intent.getType(), r.intent.getDataString(),
2664 r.intent.getFlags());
2665 }
2666
2667 private final int startActivityLocked(IApplicationThread caller,
2668 Intent intent, String resolvedType,
2669 Uri[] grantedUriPermissions,
2670 int grantedMode, ActivityInfo aInfo, IBinder resultTo,
2671 String resultWho, int requestCode,
2672 int callingPid, int callingUid, boolean onlyIfNeeded) {
2673 Log.i(TAG, "Starting activity: " + intent);
2674
2675 HistoryRecord sourceRecord = null;
2676 HistoryRecord resultRecord = null;
2677 if (resultTo != null) {
2678 int index = indexOfTokenLocked(resultTo, false);
2679 if (localLOGV) Log.v(
2680 TAG, "Sending result to " + resultTo + " (index " + index + ")");
2681 if (index >= 0) {
2682 sourceRecord = (HistoryRecord)mHistory.get(index);
2683 if (requestCode >= 0 && !sourceRecord.finishing) {
2684 resultRecord = sourceRecord;
2685 }
2686 }
2687 }
2688
2689 int launchFlags = intent.getFlags();
2690
2691 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
2692 && sourceRecord != null) {
2693 // Transfer the result target from the source activity to the new
2694 // one being started, including any failures.
2695 if (requestCode >= 0) {
2696 return START_FORWARD_AND_REQUEST_CONFLICT;
2697 }
2698 resultRecord = sourceRecord.resultTo;
2699 resultWho = sourceRecord.resultWho;
2700 requestCode = sourceRecord.requestCode;
2701 sourceRecord.resultTo = null;
2702 if (resultRecord != null) {
2703 resultRecord.removeResultsLocked(
2704 sourceRecord, resultWho, requestCode);
2705 }
2706 }
2707
2708 int err = START_SUCCESS;
2709
2710 if (intent.getComponent() == null) {
2711 // We couldn't find a class that can handle the given Intent.
2712 // That's the end of that!
2713 err = START_INTENT_NOT_RESOLVED;
2714 }
2715
2716 if (err == START_SUCCESS && aInfo == null) {
2717 // We couldn't find the specific class specified in the Intent.
2718 // Also the end of the line.
2719 err = START_CLASS_NOT_FOUND;
2720 }
2721
2722 ProcessRecord callerApp = null;
2723 if (err == START_SUCCESS && caller != null) {
2724 callerApp = getRecordForAppLocked(caller);
2725 if (callerApp != null) {
2726 callingPid = callerApp.pid;
2727 callingUid = callerApp.info.uid;
2728 } else {
2729 Log.w(TAG, "Unable to find app for caller " + caller
2730 + " (pid=" + callingPid + ") when starting: "
2731 + intent.toString());
2732 err = START_PERMISSION_DENIED;
2733 }
2734 }
2735
2736 if (err != START_SUCCESS) {
2737 if (resultRecord != null) {
2738 sendActivityResultLocked(-1,
2739 resultRecord, resultWho, requestCode,
2740 Activity.RESULT_CANCELED, null);
2741 }
2742 return err;
2743 }
2744
2745 final int perm = checkComponentPermission(aInfo.permission, callingPid,
2746 callingUid, aInfo.exported ? -1 : aInfo.applicationInfo.uid);
2747 if (perm != PackageManager.PERMISSION_GRANTED) {
2748 if (resultRecord != null) {
2749 sendActivityResultLocked(-1,
2750 resultRecord, resultWho, requestCode,
2751 Activity.RESULT_CANCELED, null);
2752 }
2753 String msg = "Permission Denial: starting " + intent.toString()
2754 + " from " + callerApp + " (pid=" + callingPid
2755 + ", uid=" + callingUid + ")"
2756 + " requires " + aInfo.permission;
2757 Log.w(TAG, msg);
2758 throw new SecurityException(msg);
2759 }
2760
2761 if (mWatcher != null) {
2762 boolean abort = false;
2763 try {
2764 // The Intent we give to the watcher has the extra data
2765 // stripped off, since it can contain private information.
2766 Intent watchIntent = intent.cloneFilter();
2767 abort = !mWatcher.activityStarting(watchIntent,
2768 aInfo.applicationInfo.packageName);
2769 } catch (RemoteException e) {
2770 mWatcher = null;
2771 }
2772
2773 if (abort) {
2774 if (resultRecord != null) {
2775 sendActivityResultLocked(-1,
2776 resultRecord, resultWho, requestCode,
2777 Activity.RESULT_CANCELED, null);
2778 }
2779 // We pretend to the caller that it was really started, but
2780 // they will just get a cancel result.
2781 return START_SUCCESS;
2782 }
2783 }
2784
2785 HistoryRecord r = new HistoryRecord(this, callerApp, callingUid,
2786 intent, resolvedType, aInfo, mConfiguration,
2787 resultRecord, resultWho, requestCode);
2788 r.startTime = SystemClock.uptimeMillis();
2789
2790 HistoryRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
2791 != 0 ? r : null;
2792
2793 // We'll invoke onUserLeaving before onPause only if the launching
2794 // activity did not explicitly state that this is an automated launch.
2795 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
2796 if (DEBUG_USER_LEAVING) Log.v(TAG,
2797 "startActivity() => mUserLeaving=" + mUserLeaving);
2798
2799 // If the onlyIfNeeded flag is set, then we can do this if the activity
2800 // being launched is the same as the one making the call... or, as
2801 // a special case, if we do not know the caller then we count the
2802 // current top activity as the caller.
2803 if (onlyIfNeeded) {
2804 HistoryRecord checkedCaller = sourceRecord;
2805 if (checkedCaller == null) {
2806 checkedCaller = topRunningActivityLocked(notTop);
2807 }
2808 if (!checkedCaller.realActivity.equals(r.realActivity)) {
2809 // Caller is not the same as launcher, so always needed.
2810 onlyIfNeeded = false;
2811 }
2812 }
2813
2814 if (grantedUriPermissions != null && callingUid > 0) {
2815 for (int i=0; i<grantedUriPermissions.length; i++) {
2816 grantUriPermissionLocked(callingUid, r.packageName,
2817 grantedUriPermissions[i], grantedMode, r);
2818 }
2819 }
2820
2821 grantUriPermissionFromIntentLocked(callingUid, r.packageName,
2822 intent, r);
2823
2824 if (sourceRecord == null) {
2825 // This activity is not being started from another... in this
2826 // case we -always- start a new task.
2827 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
2828 Log.w(TAG, "startActivity called from non-Activity context; forcing Intent.FLAG_ACTIVITY_NEW_TASK for: "
2829 + intent);
2830 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
2831 }
2832 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
2833 // The original activity who is starting us is running as a single
2834 // instance... this new activity it is starting must go on its
2835 // own task.
2836 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
2837 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
2838 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
2839 // The activity being started is a single instance... it always
2840 // gets launched into its own task.
2841 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
2842 }
2843
2844 if (resultRecord != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
2845 // For whatever reason this activity is being launched into a new
2846 // task... yet the caller has requested a result back. Well, that
2847 // is pretty messed up, so instead immediately send back a cancel
2848 // and let the new task continue launched as normal without a
2849 // dependency on its originator.
2850 Log.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
2851 sendActivityResultLocked(-1,
2852 resultRecord, resultWho, requestCode,
2853 Activity.RESULT_CANCELED, null);
2854 r.resultTo = null;
2855 resultRecord = null;
2856 }
2857
2858 boolean addingToTask = false;
2859 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
2860 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
2861 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
2862 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
2863 // If bring to front is requested, and no result is requested, and
2864 // we can find a task that was started with this same
2865 // component, then instead of launching bring that one to the front.
2866 if (resultRecord == null) {
2867 // See if there is a task to bring to the front. If this is
2868 // a SINGLE_INSTANCE activity, there can be one and only one
2869 // instance of it in the history, and it is always in its own
2870 // unique task, so we do a special search.
2871 HistoryRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
2872 ? findTaskLocked(intent, r.info)
2873 : findActivityLocked(intent, r.info);
2874 if (taskTop != null) {
2875 if (taskTop.task.intent == null) {
2876 // This task was started because of movement of
2877 // the activity based on affinity... now that we
2878 // are actually launching it, we can assign the
2879 // base intent.
2880 taskTop.task.setIntent(intent, r.info);
2881 }
2882 // If the target task is not in the front, then we need
2883 // to bring it to the front... except... well, with
2884 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like
2885 // to have the same behavior as if a new instance was
2886 // being started, which means not bringing it to the front
2887 // if the caller is not itself in the front.
2888 HistoryRecord curTop = topRunningActivityLocked(notTop);
2889 if (curTop.task != taskTop.task) {
2890 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
2891 boolean callerAtFront = sourceRecord == null
2892 || curTop.task == sourceRecord.task;
2893 if (callerAtFront) {
2894 // We really do want to push this one into the
2895 // user's face, right now.
2896 moveTaskToFrontLocked(taskTop.task);
2897 }
2898 }
2899 // If the caller has requested that the target task be
2900 // reset, then do so.
2901 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
2902 taskTop = resetTaskIfNeededLocked(taskTop, r);
2903 }
2904 if (onlyIfNeeded) {
2905 // We don't need to start a new activity, and
2906 // the client said not to do anything if that
2907 // is the case, so this is it! And for paranoia, make
2908 // sure we have correctly resumed the top activity.
2909 resumeTopActivityLocked(null);
2910 return START_RETURN_INTENT_TO_CALLER;
2911 }
2912 if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
2913 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
2914 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
2915 // In this situation we want to remove all activities
2916 // from the task up to the one being started. In most
2917 // cases this means we are resetting the task to its
2918 // initial state.
2919 HistoryRecord top = performClearTopTaskLocked(
2920 taskTop.task.taskId, r, true);
2921 if (top != null) {
2922 if (top.frontOfTask) {
2923 // Activity aliases may mean we use different
2924 // intents for the top activity, so make sure
2925 // the task now has the identity of the new
2926 // intent.
2927 top.task.setIntent(r.intent, r.info);
2928 }
2929 logStartActivity(LOG_AM_NEW_INTENT, r, top.task);
2930 deliverNewIntentLocked(top, r.intent);
2931 } else {
2932 // A special case: we need to
2933 // start the activity because it is not currently
2934 // running, and the caller has asked to clear the
2935 // current task to have this activity at the top.
2936 addingToTask = true;
2937 // Now pretend like this activity is being started
2938 // by the top of its task, so it is put in the
2939 // right place.
2940 sourceRecord = taskTop;
2941 }
2942 } else if (r.realActivity.equals(taskTop.task.realActivity)) {
2943 // In this case the top activity on the task is the
2944 // same as the one being launched, so we take that
2945 // as a request to bring the task to the foreground.
2946 // If the top activity in the task is the root
2947 // activity, deliver this new intent to it if it
2948 // desires.
2949 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
2950 && taskTop.realActivity.equals(r.realActivity)) {
2951 logStartActivity(LOG_AM_NEW_INTENT, r, taskTop.task);
2952 if (taskTop.frontOfTask) {
2953 taskTop.task.setIntent(r.intent, r.info);
2954 }
2955 deliverNewIntentLocked(taskTop, r.intent);
2956 } else if (!r.intent.filterEquals(taskTop.task.intent)) {
2957 // In this case we are launching the root activity
2958 // of the task, but with a different intent. We
2959 // should start a new instance on top.
2960 addingToTask = true;
2961 sourceRecord = taskTop;
2962 }
2963 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
2964 // In this case an activity is being launched in to an
2965 // existing task, without resetting that task. This
2966 // is typically the situation of launching an activity
2967 // from a notification or shortcut. We want to place
2968 // the new activity on top of the current task.
2969 addingToTask = true;
2970 sourceRecord = taskTop;
2971 } else if (!taskTop.task.rootWasReset) {
2972 // In this case we are launching in to an existing task
2973 // that has not yet been started from its front door.
2974 // The current task has been brought to the front.
2975 // Ideally, we'd probably like to place this new task
2976 // at the bottom of its stack, but that's a little hard
2977 // to do with the current organization of the code so
2978 // for now we'll just drop it.
2979 taskTop.task.setIntent(r.intent, r.info);
2980 }
2981 if (!addingToTask) {
2982 // We didn't do anything... but it was needed (a.k.a., client
2983 // don't use that intent!) And for paranoia, make
2984 // sure we have correctly resumed the top activity.
2985 resumeTopActivityLocked(null);
2986 return START_TASK_TO_FRONT;
2987 }
2988 }
2989 }
2990 }
2991
2992 //String uri = r.intent.toURI();
2993 //Intent intent2 = new Intent(uri);
2994 //Log.i(TAG, "Given intent: " + r.intent);
2995 //Log.i(TAG, "URI is: " + uri);
2996 //Log.i(TAG, "To intent: " + intent2);
2997
2998 if (r.packageName != null) {
2999 // If the activity being launched is the same as the one currently
3000 // at the top, then we need to check if it should only be launched
3001 // once.
3002 HistoryRecord top = topRunningActivityLocked(notTop);
3003 if (top != null && resultRecord == null) {
3004 if (top.realActivity.equals(r.realActivity)) {
3005 if (top.app != null && top.app.thread != null) {
3006 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
3007 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
3008 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
3009 logStartActivity(LOG_AM_NEW_INTENT, top, top.task);
3010 // For paranoia, make sure we have correctly
3011 // resumed the top activity.
3012 resumeTopActivityLocked(null);
3013 if (onlyIfNeeded) {
3014 // We don't need to start a new activity, and
3015 // the client said not to do anything if that
3016 // is the case, so this is it!
3017 return START_RETURN_INTENT_TO_CALLER;
3018 }
3019 deliverNewIntentLocked(top, r.intent);
3020 return START_DELIVERED_TO_TOP;
3021 }
3022 }
3023 }
3024 }
3025
3026 } else {
3027 if (resultRecord != null) {
3028 sendActivityResultLocked(-1,
3029 resultRecord, resultWho, requestCode,
3030 Activity.RESULT_CANCELED, null);
3031 }
3032 return START_CLASS_NOT_FOUND;
3033 }
3034
3035 boolean newTask = false;
3036
3037 // Should this be considered a new task?
3038 if (resultRecord == null && !addingToTask
3039 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
3040 // todo: should do better management of integers.
3041 mCurTask++;
3042 if (mCurTask <= 0) {
3043 mCurTask = 1;
3044 }
3045 r.task = new TaskRecord(mCurTask, r.info, intent,
3046 (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
3047 if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r
3048 + " in new task " + r.task);
3049 newTask = true;
3050 addRecentTask(r.task);
3051
3052 } else if (sourceRecord != null) {
3053 if (!addingToTask &&
3054 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
3055 // In this case, we are adding the activity to an existing
3056 // task, but the caller has asked to clear that task if the
3057 // activity is already running.
3058 HistoryRecord top = performClearTopTaskLocked(
3059 sourceRecord.task.taskId, r, true);
3060 if (top != null) {
3061 logStartActivity(LOG_AM_NEW_INTENT, r, top.task);
3062 deliverNewIntentLocked(top, r.intent);
3063 // For paranoia, make sure we have correctly
3064 // resumed the top activity.
3065 resumeTopActivityLocked(null);
3066 return START_DELIVERED_TO_TOP;
3067 }
3068 } else if (!addingToTask &&
3069 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
3070 // In this case, we are launching an activity in our own task
3071 // that may already be running somewhere in the history, and
3072 // we want to shuffle it to the front of the stack if so.
3073 int where = findActivityInHistoryLocked(r, sourceRecord.task.taskId);
3074 if (where >= 0) {
3075 HistoryRecord top = moveActivityToFrontLocked(where);
3076 logStartActivity(LOG_AM_NEW_INTENT, r, top.task);
3077 deliverNewIntentLocked(top, r.intent);
3078 resumeTopActivityLocked(null);
3079 return START_DELIVERED_TO_TOP;
3080 }
3081 }
3082 // An existing activity is starting this new activity, so we want
3083 // to keep the new one in the same task as the one that is starting
3084 // it.
3085 r.task = sourceRecord.task;
3086 if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r
3087 + " in existing task " + r.task);
3088
3089 } else {
3090 // This not being started from an existing activity, and not part
3091 // of a new task... just put it in the top task, though these days
3092 // this case should never happen.
3093 final int N = mHistory.size();
3094 HistoryRecord prev =
3095 N > 0 ? (HistoryRecord)mHistory.get(N-1) : null;
3096 r.task = prev != null
3097 ? prev.task
3098 : new TaskRecord(mCurTask, r.info, intent,
3099 (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
3100 if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r
3101 + " in new guessed " + r.task);
3102 }
3103 if (newTask) {
3104 EventLog.writeEvent(LOG_AM_CREATE_TASK, r.task.taskId);
3105 }
3106 logStartActivity(LOG_AM_CREATE_ACTIVITY, r, r.task);
3107 startActivityLocked(r, newTask);
3108 return START_SUCCESS;
3109 }
3110
3111 public final int startActivity(IApplicationThread caller,
3112 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
3113 int grantedMode, IBinder resultTo,
3114 String resultWho, int requestCode, boolean onlyIfNeeded,
3115 boolean debug) {
3116 // Refuse possible leaked file descriptors
3117 if (intent != null && intent.hasFileDescriptors()) {
3118 throw new IllegalArgumentException("File descriptors passed in Intent");
3119 }
3120
3121 // Don't modify the client's object!
3122 intent = new Intent(intent);
3123
3124 // Collect information about the target of the Intent.
3125 // Must do this before locking, because resolving the intent
3126 // may require launching a process to run its content provider.
3127 ActivityInfo aInfo;
3128 try {
3129 ResolveInfo rInfo =
3130 ActivityThread.getPackageManager().resolveIntent(
3131 intent, resolvedType,
3132 PackageManager.MATCH_DEFAULT_ONLY
3133 | PackageManager.GET_SHARED_LIBRARY_FILES);
3134 aInfo = rInfo != null ? rInfo.activityInfo : null;
3135 } catch (RemoteException e) {
3136 aInfo = null;
3137 }
3138
3139 if (aInfo != null) {
3140 // Store the found target back into the intent, because now that
3141 // we have it we never want to do this again. For example, if the
3142 // user navigates back to this point in the history, we should
3143 // always restart the exact same activity.
3144 intent.setComponent(new ComponentName(
3145 aInfo.applicationInfo.packageName, aInfo.name));
3146
3147 // Don't debug things in the system process
3148 if (debug) {
3149 if (!aInfo.processName.equals("system")) {
3150 setDebugApp(aInfo.processName, true, false);
3151 }
3152 }
3153 }
3154
3155 synchronized(this) {
3156 final long origId = Binder.clearCallingIdentity();
3157 int res = startActivityLocked(caller, intent, resolvedType,
3158 grantedUriPermissions, grantedMode, aInfo,
3159 resultTo, resultWho, requestCode, -1, -1,
3160 onlyIfNeeded);
3161 Binder.restoreCallingIdentity(origId);
3162 return res;
3163 }
3164 }
3165
3166 public boolean startNextMatchingActivity(IBinder callingActivity,
3167 Intent intent) {
3168 // Refuse possible leaked file descriptors
3169 if (intent != null && intent.hasFileDescriptors() == true) {
3170 throw new IllegalArgumentException("File descriptors passed in Intent");
3171 }
3172
3173 synchronized (this) {
3174 int index = indexOfTokenLocked(callingActivity, false);
3175 if (index < 0) {
3176 return false;
3177 }
3178 HistoryRecord r = (HistoryRecord)mHistory.get(index);
3179 if (r.app == null || r.app.thread == null) {
3180 // The caller is not running... d'oh!
3181 return false;
3182 }
3183 intent = new Intent(intent);
3184 // The caller is not allowed to change the data.
3185 intent.setDataAndType(r.intent.getData(), r.intent.getType());
3186 // And we are resetting to find the next component...
3187 intent.setComponent(null);
3188
3189 ActivityInfo aInfo = null;
3190 try {
3191 List<ResolveInfo> resolves =
3192 ActivityThread.getPackageManager().queryIntentActivities(
3193 intent, r.resolvedType,
3194 PackageManager.MATCH_DEFAULT_ONLY
3195 | PackageManager.GET_SHARED_LIBRARY_FILES);
3196
3197 // Look for the original activity in the list...
3198 final int N = resolves != null ? resolves.size() : 0;
3199 for (int i=0; i<N; i++) {
3200 ResolveInfo rInfo = resolves.get(i);
3201 if (rInfo.activityInfo.packageName.equals(r.packageName)
3202 && rInfo.activityInfo.name.equals(r.info.name)) {
3203 // We found the current one... the next matching is
3204 // after it.
3205 i++;
3206 if (i<N) {
3207 aInfo = resolves.get(i).activityInfo;
3208 }
3209 break;
3210 }
3211 }
3212 } catch (RemoteException e) {
3213 }
3214
3215 if (aInfo == null) {
3216 // Nobody who is next!
3217 return false;
3218 }
3219
3220 intent.setComponent(new ComponentName(
3221 aInfo.applicationInfo.packageName, aInfo.name));
3222 intent.setFlags(intent.getFlags()&~(
3223 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3224 Intent.FLAG_ACTIVITY_CLEAR_TOP|
3225 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3226 Intent.FLAG_ACTIVITY_NEW_TASK));
3227
3228 // Okay now we need to start the new activity, replacing the
3229 // currently running activity. This is a little tricky because
3230 // we want to start the new one as if the current one is finished,
3231 // but not finish the current one first so that there is no flicker.
3232 // And thus...
3233 final boolean wasFinishing = r.finishing;
3234 r.finishing = true;
3235
3236 // Propagate reply information over to the new activity.
3237 final HistoryRecord resultTo = r.resultTo;
3238 final String resultWho = r.resultWho;
3239 final int requestCode = r.requestCode;
3240 r.resultTo = null;
3241 if (resultTo != null) {
3242 resultTo.removeResultsLocked(r, resultWho, requestCode);
3243 }
3244
3245 final long origId = Binder.clearCallingIdentity();
3246 // XXX we are not dealing with propagating grantedUriPermissions...
3247 // those are not yet exposed to user code, so there is no need.
3248 int res = startActivityLocked(r.app.thread, intent,
3249 r.resolvedType, null, 0, aInfo, resultTo, resultWho,
3250 requestCode, -1, r.launchedFromUid, false);
3251 Binder.restoreCallingIdentity(origId);
3252
3253 r.finishing = wasFinishing;
3254 if (res != START_SUCCESS) {
3255 return false;
3256 }
3257 return true;
3258 }
3259 }
3260
3261 final int startActivityInPackage(int uid,
3262 Intent intent, String resolvedType, IBinder resultTo,
3263 String resultWho, int requestCode, boolean onlyIfNeeded) {
3264 // Don't modify the client's object!
3265 intent = new Intent(intent);
3266
3267 // Collect information about the target of the Intent.
3268 // Must do this before locking, because resolving the intent
3269 // may require launching a process to run its content provider.
3270 ActivityInfo aInfo;
3271 try {
3272 ResolveInfo rInfo =
3273 ActivityThread.getPackageManager().resolveIntent(
3274 intent, resolvedType,
3275 PackageManager.MATCH_DEFAULT_ONLY
3276 | PackageManager.GET_SHARED_LIBRARY_FILES);
3277 aInfo = rInfo != null ? rInfo.activityInfo : null;
3278 } catch (RemoteException e) {
3279 aInfo = null;
3280 }
3281
3282 if (aInfo != null) {
3283 // Store the found target back into the intent, because now that
3284 // we have it we never want to do this again. For example, if the
3285 // user navigates back to this point in the history, we should
3286 // always restart the exact same activity.
3287 intent.setComponent(new ComponentName(
3288 aInfo.applicationInfo.packageName, aInfo.name));
3289 }
3290
3291 synchronized(this) {
3292 return startActivityLocked(null, intent, resolvedType,
3293 null, 0, aInfo, resultTo, resultWho, requestCode, -1, uid,
3294 onlyIfNeeded);
3295 }
3296 }
3297
3298 private final void addRecentTask(TaskRecord task) {
3299 // Remove any existing entries that are the same kind of task.
3300 int N = mRecentTasks.size();
3301 for (int i=0; i<N; i++) {
3302 TaskRecord tr = mRecentTasks.get(i);
3303 if ((task.affinity != null && task.affinity.equals(tr.affinity))
3304 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
3305 mRecentTasks.remove(i);
3306 i--;
3307 N--;
3308 if (task.intent == null) {
3309 // If the new recent task we are adding is not fully
3310 // specified, then replace it with the existing recent task.
3311 task = tr;
3312 }
3313 }
3314 }
3315 if (N >= MAX_RECENT_TASKS) {
3316 mRecentTasks.remove(N-1);
3317 }
3318 mRecentTasks.add(0, task);
3319 }
3320
3321 public void setRequestedOrientation(IBinder token,
3322 int requestedOrientation) {
3323 synchronized (this) {
3324 int index = indexOfTokenLocked(token, false);
3325 if (index < 0) {
3326 return;
3327 }
3328 HistoryRecord r = (HistoryRecord)mHistory.get(index);
3329 final long origId = Binder.clearCallingIdentity();
3330 mWindowManager.setAppOrientation(r, requestedOrientation);
3331 Configuration config = mWindowManager.updateOrientationFromAppTokens(
3332 r.mayFreezeScreenLocked(r.app) ? r : null);
3333 if (config != null) {
3334 r.frozenBeforeDestroy = true;
3335 if (!updateConfigurationLocked(config, r)) {
3336 resumeTopActivityLocked(null);
3337 }
3338 }
3339 Binder.restoreCallingIdentity(origId);
3340 }
3341 }
3342
3343 public int getRequestedOrientation(IBinder token) {
3344 synchronized (this) {
3345 int index = indexOfTokenLocked(token, false);
3346 if (index < 0) {
3347 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3348 }
3349 HistoryRecord r = (HistoryRecord)mHistory.get(index);
3350 return mWindowManager.getAppOrientation(r);
3351 }
3352 }
3353
3354 private final void stopActivityLocked(HistoryRecord r) {
3355 if (DEBUG_SWITCH) Log.d(TAG, "Stopping: " + r);
3356 if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
3357 || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
3358 if (!r.finishing) {
3359 requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null,
3360 "no-history");
3361 }
3362 } else if (r.app != null && r.app.thread != null) {
3363 if (mFocusedActivity == r) {
3364 setFocusedActivityLocked(topRunningActivityLocked(null));
3365 }
3366 r.resumeKeyDispatchingLocked();
3367 try {
3368 r.stopped = false;
3369 r.state = ActivityState.STOPPING;
3370 if (DEBUG_VISBILITY) Log.v(
3371 TAG, "Stopping visible=" + r.visible + " for " + r);
3372 if (!r.visible) {
3373 mWindowManager.setAppVisibility(r, false);
3374 }
3375 r.app.thread.scheduleStopActivity(r, r.visible, r.configChangeFlags);
3376 } catch (Exception e) {
3377 // Maybe just ignore exceptions here... if the process
3378 // has crashed, our death notification will clean things
3379 // up.
3380 Log.w(TAG, "Exception thrown during pause", e);
3381 // Just in case, assume it to be stopped.
3382 r.stopped = true;
3383 r.state = ActivityState.STOPPED;
3384 if (r.configDestroy) {
3385 destroyActivityLocked(r, true);
3386 }
3387 }
3388 }
3389 }
3390
3391 /**
3392 * @return Returns true if the activity is being finished, false if for
3393 * some reason it is being left as-is.
3394 */
3395 private final boolean requestFinishActivityLocked(IBinder token, int resultCode,
3396 Intent resultData, String reason) {
3397 if (localLOGV) Log.v(
3398 TAG, "Finishing activity: token=" + token
3399 + ", result=" + resultCode + ", data=" + resultData);
3400
3401 int index = indexOfTokenLocked(token, false);
3402 if (index < 0) {
3403 return false;
3404 }
3405 HistoryRecord r = (HistoryRecord)mHistory.get(index);
3406
3407 // Is this the last activity left?
3408 boolean lastActivity = true;
3409 for (int i=mHistory.size()-1; i>=0; i--) {
3410 HistoryRecord p = (HistoryRecord)mHistory.get(i);
3411 if (!p.finishing && p != r) {
3412 lastActivity = false;
3413 break;
3414 }
3415 }
3416
3417 // If this is the last activity, but it is the home activity, then
3418 // just don't finish it.
3419 if (lastActivity) {
3420 if (r.intent.hasCategory(Intent.CATEGORY_HOME)) {
3421 return false;
3422 }
3423 }
3424
3425 finishActivityLocked(r, index, resultCode, resultData, reason);
3426 return true;
3427 }
3428
3429 /**
3430 * @return Returns true if this activity has been removed from the history
3431 * list, or false if it is still in the list and will be removed later.
3432 */
3433 private final boolean finishActivityLocked(HistoryRecord r, int index,
3434 int resultCode, Intent resultData, String reason) {
3435 if (r.finishing) {
3436 Log.w(TAG, "Duplicate finish request for " + r);
3437 return false;
3438 }
3439
3440 r.finishing = true;
3441 EventLog.writeEvent(LOG_AM_FINISH_ACTIVITY,
3442 System.identityHashCode(r),
3443 r.task.taskId, r.shortComponentName, reason);
3444 r.task.numActivities--;
3445 if (r.frontOfTask && index < (mHistory.size()-1)) {
3446 HistoryRecord next = (HistoryRecord)mHistory.get(index+1);
3447 if (next.task == r.task) {
3448 next.frontOfTask = true;
3449 }
3450 }
3451
3452 r.pauseKeyDispatchingLocked();
3453 if (mFocusedActivity == r) {
3454 setFocusedActivityLocked(topRunningActivityLocked(null));
3455 }
3456
3457 // send the result
3458 HistoryRecord resultTo = r.resultTo;
3459 if (resultTo != null) {
3460 if (localLOGV) Log.v(TAG, "Adding result to " + resultTo);
3461 if (r.info.applicationInfo.uid > 0) {
3462 grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid,
3463 r.packageName, resultData, r);
3464 }
3465 resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode,
3466 resultData);
3467 r.resultTo = null;
3468 }
3469
3470 // Make sure this HistoryRecord is not holding on to other resources,
3471 // because clients have remote IPC references to this object so we
3472 // can't assume that will go away and want to avoid circular IPC refs.
3473 r.results = null;
3474 r.pendingResults = null;
3475 r.newIntents = null;
3476 r.icicle = null;
3477
3478 if (mPendingThumbnails.size() > 0) {
3479 // There are clients waiting to receive thumbnails so, in case
3480 // this is an activity that someone is waiting for, add it
3481 // to the pending list so we can correctly update the clients.
3482 mCancelledThumbnails.add(r);
3483 }
3484
3485 if (mResumedActivity == r) {
3486 boolean endTask = index <= 0
3487 || ((HistoryRecord)mHistory.get(index-1)).task != r.task;
3488 if (DEBUG_TRANSITION) Log.v(TAG,
3489 "Prepare close transition: finishing " + r);
3490 mWindowManager.prepareAppTransition(endTask
3491 ? WindowManagerPolicy.TRANSIT_TASK_CLOSE
3492 : WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE);
3493
3494 // Tell window manager to prepare for this one to be removed.
3495 mWindowManager.setAppVisibility(r, false);
3496
3497 if (mPausingActivity == null) {
3498 if (DEBUG_PAUSE) Log.v(TAG, "Finish needs to pause: " + r);
3499 if (DEBUG_USER_LEAVING) Log.v(TAG, "finish() => pause with userLeaving=false");
3500 startPausingLocked(false, false);
3501 }
3502
3503 } else if (r.state != ActivityState.PAUSING) {
3504 // If the activity is PAUSING, we will complete the finish once
3505 // it is done pausing; else we can just directly finish it here.
3506 if (DEBUG_PAUSE) Log.v(TAG, "Finish not pausing: " + r);
3507 return finishCurrentActivityLocked(r, index,
3508 FINISH_AFTER_PAUSE) == null;
3509 } else {
3510 if (DEBUG_PAUSE) Log.v(TAG, "Finish waiting for pause of: " + r);
3511 }
3512
3513 return false;
3514 }
3515
3516 private static final int FINISH_IMMEDIATELY = 0;
3517 private static final int FINISH_AFTER_PAUSE = 1;
3518 private static final int FINISH_AFTER_VISIBLE = 2;
3519
3520 private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r,
3521 int mode) {
3522 final int index = indexOfTokenLocked(r, false);
3523 if (index < 0) {
3524 return null;
3525 }
3526
3527 return finishCurrentActivityLocked(r, index, mode);
3528 }
3529
3530 private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r,
3531 int index, int mode) {
3532 // First things first: if this activity is currently visible,
3533 // and the resumed activity is not yet visible, then hold off on
3534 // finishing until the resumed one becomes visible.
3535 if (mode == FINISH_AFTER_VISIBLE && r.nowVisible) {
3536 if (!mStoppingActivities.contains(r)) {
3537 mStoppingActivities.add(r);
3538 if (mStoppingActivities.size() > 3) {
3539 // If we already have a few activities waiting to stop,
3540 // then give up on things going idle and start clearing
3541 // them out.
3542 Message msg = Message.obtain();
3543 msg.what = ActivityManagerService.IDLE_NOW_MSG;
3544 mHandler.sendMessage(msg);
3545 }
3546 }
3547 r.state = ActivityState.STOPPING;
3548 updateOomAdjLocked();
3549 return r;
3550 }
3551
3552 // make sure the record is cleaned out of other places.
3553 mStoppingActivities.remove(r);
3554 mWaitingVisibleActivities.remove(r);
3555 if (mResumedActivity == r) {
3556 mResumedActivity = null;
3557 }
3558 final ActivityState prevState = r.state;
3559 r.state = ActivityState.FINISHING;
3560
3561 if (mode == FINISH_IMMEDIATELY
3562 || prevState == ActivityState.STOPPED
3563 || prevState == ActivityState.INITIALIZING) {
3564 // If this activity is already stopped, we can just finish
3565 // it right now.
3566 return destroyActivityLocked(r, true) ? null : r;
3567 } else {
3568 // Need to go through the full pause cycle to get this
3569 // activity into the stopped state and then finish it.
3570 if (localLOGV) Log.v(TAG, "Enqueueing pending finish: " + r);
3571 mFinishingActivities.add(r);
3572 resumeTopActivityLocked(null);
3573 }
3574 return r;
3575 }
3576
3577 /**
3578 * This is the internal entry point for handling Activity.finish().
3579 *
3580 * @param token The Binder token referencing the Activity we want to finish.
3581 * @param resultCode Result code, if any, from this Activity.
3582 * @param resultData Result data (Intent), if any, from this Activity.
3583 *
3584 * @result Returns true if the activity successfully finished, or false if it is still running.
3585 */
3586 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3587 // Refuse possible leaked file descriptors
3588 if (resultData != null && resultData.hasFileDescriptors() == true) {
3589 throw new IllegalArgumentException("File descriptors passed in Intent");
3590 }
3591
3592 synchronized(this) {
3593 if (mWatcher != null) {
3594 // Find the first activity that is not finishing.
3595 HistoryRecord next = topRunningActivityLocked(token, 0);
3596 if (next != null) {
3597 // ask watcher if this is allowed
3598 boolean resumeOK = true;
3599 try {
3600 resumeOK = mWatcher.activityResuming(next.packageName);
3601 } catch (RemoteException e) {
3602 mWatcher = null;
3603 }
3604
3605 if (!resumeOK) {
3606 return false;
3607 }
3608 }
3609 }
3610 final long origId = Binder.clearCallingIdentity();
3611 boolean res = requestFinishActivityLocked(token, resultCode,
3612 resultData, "app-request");
3613 Binder.restoreCallingIdentity(origId);
3614 return res;
3615 }
3616 }
3617
3618 void sendActivityResultLocked(int callingUid, HistoryRecord r,
3619 String resultWho, int requestCode, int resultCode, Intent data) {
3620
3621 if (callingUid > 0) {
3622 grantUriPermissionFromIntentLocked(callingUid, r.packageName,
3623 data, r);
3624 }
3625
3626 if (mResumedActivity == r && r.app != null && r.app.thread != null) {
3627 try {
3628 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
3629 list.add(new ResultInfo(resultWho, requestCode,
3630 resultCode, data));
3631 r.app.thread.scheduleSendResult(r, list);
3632 return;
3633 } catch (Exception e) {
3634 Log.w(TAG, "Exception thrown sending result to " + r, e);
3635 }
3636 }
3637
3638 r.addResultLocked(null, resultWho, requestCode, resultCode, data);
3639 }
3640
3641 public final void finishSubActivity(IBinder token, String resultWho,
3642 int requestCode) {
3643 synchronized(this) {
3644 int index = indexOfTokenLocked(token, false);
3645 if (index < 0) {
3646 return;
3647 }
3648 HistoryRecord self = (HistoryRecord)mHistory.get(index);
3649
3650 final long origId = Binder.clearCallingIdentity();
3651
3652 int i;
3653 for (i=mHistory.size()-1; i>=0; i--) {
3654 HistoryRecord r = (HistoryRecord)mHistory.get(i);
3655 if (r.resultTo == self && r.requestCode == requestCode) {
3656 if ((r.resultWho == null && resultWho == null) ||
3657 (r.resultWho != null && r.resultWho.equals(resultWho))) {
3658 finishActivityLocked(r, i,
3659 Activity.RESULT_CANCELED, null, "request-sub");
3660 }
3661 }
3662 }
3663
3664 Binder.restoreCallingIdentity(origId);
3665 }
3666 }
3667
3668 /**
3669 * Perform clean-up of service connections in an activity record.
3670 */
3671 private final void cleanUpActivityServicesLocked(HistoryRecord r) {
3672 // Throw away any services that have been bound by this activity.
3673 if (r.connections != null) {
3674 Iterator<ConnectionRecord> it = r.connections.iterator();
3675 while (it.hasNext()) {
3676 ConnectionRecord c = it.next();
3677 removeConnectionLocked(c, null, r);
3678 }
3679 r.connections = null;
3680 }
3681 }
3682
3683 /**
3684 * Perform the common clean-up of an activity record. This is called both
3685 * as part of destroyActivityLocked() (when destroying the client-side
3686 * representation) and cleaning things up as a result of its hosting
3687 * processing going away, in which case there is no remaining client-side
3688 * state to destroy so only the cleanup here is needed.
3689 */
3690 private final void cleanUpActivityLocked(HistoryRecord r, boolean cleanServices) {
3691 if (mResumedActivity == r) {
3692 mResumedActivity = null;
3693 }
3694 if (mFocusedActivity == r) {
3695 mFocusedActivity = null;
3696 }
3697
3698 r.configDestroy = false;
3699 r.frozenBeforeDestroy = false;
3700
3701 // Make sure this record is no longer in the pending finishes list.
3702 // This could happen, for example, if we are trimming activities
3703 // down to the max limit while they are still waiting to finish.
3704 mFinishingActivities.remove(r);
3705 mWaitingVisibleActivities.remove(r);
3706
3707 // Remove any pending results.
3708 if (r.finishing && r.pendingResults != null) {
3709 for (WeakReference<PendingIntentRecord> apr : r.pendingResults) {
3710 PendingIntentRecord rec = apr.get();
3711 if (rec != null) {
3712 cancelIntentSenderLocked(rec, false);
3713 }
3714 }
3715 r.pendingResults = null;
3716 }
3717
3718 if (cleanServices) {
3719 cleanUpActivityServicesLocked(r);
3720 }
3721
3722 if (mPendingThumbnails.size() > 0) {
3723 // There are clients waiting to receive thumbnails so, in case
3724 // this is an activity that someone is waiting for, add it
3725 // to the pending list so we can correctly update the clients.
3726 mCancelledThumbnails.add(r);
3727 }
3728
3729 // Get rid of any pending idle timeouts.
3730 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
3731 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
3732 }
3733
3734 private final void removeActivityFromHistoryLocked(HistoryRecord r) {
3735 if (r.state != ActivityState.DESTROYED) {
3736 mHistory.remove(r);
3737 r.inHistory = false;
3738 r.state = ActivityState.DESTROYED;
3739 mWindowManager.removeAppToken(r);
3740 if (VALIDATE_TOKENS) {
3741 mWindowManager.validateAppTokens(mHistory);
3742 }
3743 cleanUpActivityServicesLocked(r);
3744 removeActivityUriPermissionsLocked(r);
3745 }
3746 }
3747
3748 /**
3749 * Destroy the current CLIENT SIDE instance of an activity. This may be
3750 * called both when actually finishing an activity, or when performing
3751 * a configuration switch where we destroy the current client-side object
3752 * but then create a new client-side object for this same HistoryRecord.
3753 */
3754 private final boolean destroyActivityLocked(HistoryRecord r,
3755 boolean removeFromApp) {
3756 if (DEBUG_SWITCH) Log.v(
3757 TAG, "Removing activity: token=" + r
3758 + ", app=" + (r.app != null ? r.app.processName : "(null)"));
3759 EventLog.writeEvent(LOG_AM_DESTROY_ACTIVITY,
3760 System.identityHashCode(r),
3761 r.task.taskId, r.shortComponentName);
3762
3763 boolean removedFromHistory = false;
3764
3765 cleanUpActivityLocked(r, false);
3766
3767 if (r.app != null) {
3768 if (removeFromApp) {
3769 int idx = r.app.activities.indexOf(r);
3770 if (idx >= 0) {
3771 r.app.activities.remove(idx);
3772 }
3773 if (r.persistent) {
3774 decPersistentCountLocked(r.app);
3775 }
3776 }
3777
3778 boolean skipDestroy = false;
3779
3780 try {
3781 if (DEBUG_SWITCH) Log.i(TAG, "Destroying: " + r);
3782 r.app.thread.scheduleDestroyActivity(r, r.finishing,
3783 r.configChangeFlags);
3784 } catch (Exception e) {
3785 // We can just ignore exceptions here... if the process
3786 // has crashed, our death notification will clean things
3787 // up.
3788 //Log.w(TAG, "Exception thrown during finish", e);
3789 if (r.finishing) {
3790 removeActivityFromHistoryLocked(r);
3791 removedFromHistory = true;
3792 skipDestroy = true;
3793 }
3794 }
3795
3796 r.app = null;
3797 r.nowVisible = false;
3798
3799 if (r.finishing && !skipDestroy) {
3800 r.state = ActivityState.DESTROYING;
3801 Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG);
3802 msg.obj = r;
3803 mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT);
3804 } else {
3805 r.state = ActivityState.DESTROYED;
3806 }
3807 } else {
3808 // remove this record from the history.
3809 if (r.finishing) {
3810 removeActivityFromHistoryLocked(r);
3811 removedFromHistory = true;
3812 } else {
3813 r.state = ActivityState.DESTROYED;
3814 }
3815 }
3816
3817 r.configChangeFlags = 0;
3818
3819 if (!mLRUActivities.remove(r)) {
3820 Log.w(TAG, "Activity " + r + " being finished, but not in LRU list");
3821 }
3822
3823 return removedFromHistory;
3824 }
3825
3826 private static void removeHistoryRecordsForAppLocked(ArrayList list,
3827 ProcessRecord app)
3828 {
3829 int i = list.size();
3830 if (localLOGV) Log.v(
3831 TAG, "Removing app " + app + " from list " + list
3832 + " with " + i + " entries");
3833 while (i > 0) {
3834 i--;
3835 HistoryRecord r = (HistoryRecord)list.get(i);
3836 if (localLOGV) Log.v(
3837 TAG, "Record #" + i + " " + r + ": app=" + r.app);
3838 if (r.app == app) {
3839 if (localLOGV) Log.v(TAG, "Removing this entry!");
3840 list.remove(i);
3841 }
3842 }
3843 }
3844
3845 /**
3846 * Main function for removing an existing process from the activity manager
3847 * as a result of that process going away. Clears out all connections
3848 * to the process.
3849 */
3850 private final void handleAppDiedLocked(ProcessRecord app,
3851 boolean restarting) {
3852 cleanUpApplicationRecordLocked(app, restarting, -1);
3853 if (!restarting) {
3854 mLRUProcesses.remove(app);
3855 }
3856
3857 // Just in case...
3858 if (mPausingActivity != null && mPausingActivity.app == app) {
3859 if (DEBUG_PAUSE) Log.v(TAG, "App died while pausing: " + mPausingActivity);
3860 mPausingActivity = null;
3861 }
3862 if (mLastPausedActivity != null && mLastPausedActivity.app == app) {
3863 mLastPausedActivity = null;
3864 }
3865
3866 // Remove this application's activities from active lists.
3867 removeHistoryRecordsForAppLocked(mLRUActivities, app);
3868 removeHistoryRecordsForAppLocked(mStoppingActivities, app);
3869 removeHistoryRecordsForAppLocked(mWaitingVisibleActivities, app);
3870 removeHistoryRecordsForAppLocked(mFinishingActivities, app);
3871
3872 boolean atTop = true;
3873 boolean hasVisibleActivities = false;
3874
3875 // Clean out the history list.
3876 int i = mHistory.size();
3877 if (localLOGV) Log.v(
3878 TAG, "Removing app " + app + " from history with " + i + " entries");
3879 while (i > 0) {
3880 i--;
3881 HistoryRecord r = (HistoryRecord)mHistory.get(i);
3882 if (localLOGV) Log.v(
3883 TAG, "Record #" + i + " " + r + ": app=" + r.app);
3884 if (r.app == app) {
3885 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
3886 if (localLOGV) Log.v(
3887 TAG, "Removing this entry! frozen=" + r.haveState
3888 + " finishing=" + r.finishing);
3889 mHistory.remove(i);
3890
3891 r.inHistory = false;
3892 mWindowManager.removeAppToken(r);
3893 if (VALIDATE_TOKENS) {
3894 mWindowManager.validateAppTokens(mHistory);
3895 }
3896 removeActivityUriPermissionsLocked(r);
3897
3898 } else {
3899 // We have the current state for this activity, so
3900 // it can be restarted later when needed.
3901 if (localLOGV) Log.v(
3902 TAG, "Keeping entry, setting app to null");
3903 if (r.visible) {
3904 hasVisibleActivities = true;
3905 }
3906 r.app = null;
3907 r.nowVisible = false;
3908 if (!r.haveState) {
3909 r.icicle = null;
3910 }
3911 }
3912
3913 cleanUpActivityLocked(r, true);
3914 r.state = ActivityState.STOPPED;
3915 }
3916 atTop = false;
3917 }
3918
3919 app.activities.clear();
3920
3921 if (app.instrumentationClass != null) {
3922 Log.w(TAG, "Crash of app " + app.processName
3923 + " running instrumentation " + app.instrumentationClass);
3924 Bundle info = new Bundle();
3925 info.putString("shortMsg", "Process crashed.");
3926 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3927 }
3928
3929 if (!restarting) {
3930 if (!resumeTopActivityLocked(null)) {
3931 // If there was nothing to resume, and we are not already
3932 // restarting this process, but there is a visible activity that
3933 // is hosted by the process... then make sure all visible
3934 // activities are running, taking care of restarting this
3935 // process.
3936 if (hasVisibleActivities) {
3937 ensureActivitiesVisibleLocked(null, 0);
3938 }
3939 }
3940 }
3941 }
3942
3943 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3944 IBinder threadBinder = thread.asBinder();
3945
3946 // Find the application record.
3947 int count = mLRUProcesses.size();
3948 int i;
3949 for (i=0; i<count; i++) {
3950 ProcessRecord rec = mLRUProcesses.get(i);
3951 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3952 return i;
3953 }
3954 }
3955 return -1;
3956 }
3957
3958 private final ProcessRecord getRecordForAppLocked(
3959 IApplicationThread thread) {
3960 if (thread == null) {
3961 return null;
3962 }
3963
3964 int appIndex = getLRURecordIndexForAppLocked(thread);
3965 return appIndex >= 0 ? mLRUProcesses.get(appIndex) : null;
3966 }
3967
3968 private final void appDiedLocked(ProcessRecord app, int pid,
3969 IApplicationThread thread) {
3970
3971 mProcDeaths[0]++;
3972
3973 if (app.thread != null && app.thread.asBinder() == thread.asBinder()) {
3974 Log.i(TAG, "Process " + app.processName + " (pid " + pid
3975 + ") has died.");
3976 EventLog.writeEvent(LOG_AM_PROCESS_DIED, app.pid, app.processName);
3977 if (localLOGV) Log.v(
3978 TAG, "Dying app: " + app + ", pid: " + pid
3979 + ", thread: " + thread.asBinder());
3980 boolean doLowMem = app.instrumentationClass == null;
3981 handleAppDiedLocked(app, false);
3982
3983 if (doLowMem) {
3984 // If there are no longer any background processes running,
3985 // and the app that died was not running instrumentation,
3986 // then tell everyone we are now low on memory.
3987 boolean haveBg = false;
3988 int count = mLRUProcesses.size();
3989 int i;
3990 for (i=0; i<count; i++) {
3991 ProcessRecord rec = mLRUProcesses.get(i);
3992 if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
3993 haveBg = true;
3994 break;
3995 }
3996 }
3997
3998 if (!haveBg) {
3999 Log.i(TAG, "Low Memory: No more background processes.");
4000 EventLog.writeEvent(LOG_AM_LOW_MEMORY, mLRUProcesses.size());
4001 for (i=0; i<count; i++) {
4002 ProcessRecord rec = mLRUProcesses.get(i);
4003 if (rec.thread != null) {
4004 rec.lastRequestedGc = SystemClock.uptimeMillis();
4005 try {
4006 rec.thread.scheduleLowMemory();
4007 } catch (RemoteException e) {
4008 // Don't care if the process is gone.
4009 }
4010 }
4011 }
4012 }
4013 }
4014 } else if (Config.LOGD) {
4015 Log.d(TAG, "Received spurious death notification for thread "
4016 + thread.asBinder());
4017 }
4018 }
4019
4020 final String readFile(String filename) {
4021 try {
4022 FileInputStream fs = new FileInputStream(filename);
4023 byte[] inp = new byte[8192];
4024 int size = fs.read(inp);
4025 fs.close();
4026 return new String(inp, 0, 0, size);
4027 } catch (java.io.IOException e) {
4028 }
4029 return "";
4030 }
4031
4032 final void appNotRespondingLocked(ProcessRecord app, HistoryRecord activity,
4033 final String annotation) {
4034 if (app.notResponding || app.crashing) {
4035 return;
4036 }
4037
4038 // Log the ANR to the event log.
4039 EventLog.writeEvent(LOG_ANR, app.pid, app.processName, annotation);
4040
4041 // If we are on a secure build and the application is not interesting to the user (it is
4042 // not visible or in the background), just kill it instead of displaying a dialog.
4043 boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0"));
4044 if (isSecure && !app.isInterestingToUserLocked() && Process.myPid() != app.pid) {
4045 Process.killProcess(app.pid);
4046 return;
4047 }
4048
4049 // DeviceMonitor.start();
4050
4051 String processInfo = null;
4052 if (MONITOR_CPU_USAGE) {
4053 updateCpuStatsNow();
4054 synchronized (mProcessStatsThread) {
4055 processInfo = mProcessStats.printCurrentState();
4056 }
4057 }
4058
4059 StringBuilder info = new StringBuilder();
4060 info.append("ANR (application not responding) in process: ");
4061 info.append(app.processName);
4062 if (annotation != null) {
4063 info.append("\nAnnotation: ");
4064 info.append(annotation);
4065 }
4066 if (MONITOR_CPU_USAGE) {
4067 info.append("\nCPU usage:\n");
4068 info.append(processInfo);
4069 }
4070 Log.i(TAG, info.toString());
4071
4072 // The application is not responding. Dump as many thread traces as we can.
4073 boolean fileDump = prepareTraceFile(true);
4074 if (!fileDump) {
4075 // Dumping traces to the log, just dump the process that isn't responding so
4076 // we don't overflow the log
4077 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4078 } else {
4079 // Dumping traces to a file so dump all active processes we know about
4080 synchronized (this) {
4081 for (int i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) {
4082 ProcessRecord r = mLRUProcesses.get(i);
4083 if (r.thread != null) {
4084 Process.sendSignal(r.pid, Process.SIGNAL_QUIT);
4085 }
4086 }
4087 }
4088 }
4089
4090 if (mWatcher != null) {
4091 try {
4092 int res = mWatcher.appNotResponding(app.processName,
4093 app.pid, info.toString());
4094 if (res != 0) {
4095 if (res < 0) {
4096 // wait until the SIGQUIT has had a chance to process before killing the
4097 // process.
4098 try {
4099 wait(2000);
4100 } catch (InterruptedException e) {
4101 }
4102
4103 Process.killProcess(app.pid);
4104 return;
4105 }
4106 }
4107 } catch (RemoteException e) {
4108 mWatcher = null;
4109 }
4110 }
4111
4112 makeAppNotRespondingLocked(app,
4113 activity != null ? activity.shortComponentName : null,
4114 annotation != null ? "ANR " + annotation : "ANR",
4115 info.toString(), null);
4116 Message msg = Message.obtain();
4117 HashMap map = new HashMap();
4118 msg.what = SHOW_NOT_RESPONDING_MSG;
4119 msg.obj = map;
4120 map.put("app", app);
4121 if (activity != null) {
4122 map.put("activity", activity);
4123 }
4124
4125 mHandler.sendMessage(msg);
4126 return;
4127 }
4128
4129 /**
4130 * If a stack trace file has been configured, prepare the filesystem
4131 * by creating the directory if it doesn't exist and optionally
4132 * removing the old trace file.
4133 *
4134 * @param removeExisting If set, the existing trace file will be removed.
4135 * @return Returns true if the trace file preparations succeeded
4136 */
4137 public static boolean prepareTraceFile(boolean removeExisting) {
4138 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4139 boolean fileReady = false;
4140 if (!TextUtils.isEmpty(tracesPath)) {
4141 File f = new File(tracesPath);
4142 if (!f.exists()) {
4143 // Ensure the enclosing directory exists
4144 File dir = f.getParentFile();
4145 if (!dir.exists()) {
4146 fileReady = dir.mkdirs();
4147 FileUtils.setPermissions(dir.getAbsolutePath(),
4148 FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IRWXO, -1, -1);
4149 } else if (dir.isDirectory()) {
4150 fileReady = true;
4151 }
4152 } else if (removeExisting) {
4153 // Remove the previous traces file, so we don't fill the disk.
4154 // The VM will recreate it
4155 Log.i(TAG, "Removing old ANR trace file from " + tracesPath);
4156 fileReady = f.delete();
4157 }
4158 }
4159
4160 return fileReady;
4161 }
4162
4163
4164 private final void decPersistentCountLocked(ProcessRecord app)
4165 {
4166 app.persistentActivities--;
4167 if (app.persistentActivities > 0) {
4168 // Still more of 'em...
4169 return;
4170 }
4171 if (app.persistent) {
4172 // Ah, but the application itself is persistent. Whatever!
4173 return;
4174 }
4175
4176 // App is no longer persistent... make sure it and the ones
4177 // following it in the LRU list have the correc oom_adj.
4178 updateOomAdjLocked();
4179 }
4180
4181 public void setPersistent(IBinder token, boolean isPersistent) {
4182 if (checkCallingPermission(android.Manifest.permission.PERSISTENT_ACTIVITY)
4183 != PackageManager.PERMISSION_GRANTED) {
4184 String msg = "Permission Denial: setPersistent() from pid="
4185 + Binder.getCallingPid()
4186 + ", uid=" + Binder.getCallingUid()
4187 + " requires " + android.Manifest.permission.PERSISTENT_ACTIVITY;
4188 Log.w(TAG, msg);
4189 throw new SecurityException(msg);
4190 }
4191
4192 synchronized(this) {
4193 int index = indexOfTokenLocked(token, true);
4194 if (index < 0) {
4195 return;
4196 }
4197 HistoryRecord r = (HistoryRecord)mHistory.get(index);
4198 ProcessRecord app = r.app;
4199
4200 if (localLOGV) Log.v(
4201 TAG, "Setting persistence " + isPersistent + ": " + r);
4202
4203 if (isPersistent) {
4204 if (r.persistent) {
4205 // Okay okay, I heard you already!
4206 if (localLOGV) Log.v(TAG, "Already persistent!");
4207 return;
4208 }
4209 r.persistent = true;
4210 app.persistentActivities++;
4211 if (localLOGV) Log.v(TAG, "Num persistent now: " + app.persistentActivities);
4212 if (app.persistentActivities > 1) {
4213 // We aren't the first...
4214 if (localLOGV) Log.v(TAG, "Not the first!");
4215 return;
4216 }
4217 if (app.persistent) {
4218 // This would be redundant.
4219 if (localLOGV) Log.v(TAG, "App is persistent!");
4220 return;
4221 }
4222
4223 // App is now persistent... make sure it and the ones
4224 // following it now have the correct oom_adj.
4225 final long origId = Binder.clearCallingIdentity();
4226 updateOomAdjLocked();
4227 Binder.restoreCallingIdentity(origId);
4228
4229 } else {
4230 if (!r.persistent) {
4231 // Okay okay, I heard you already!
4232 return;
4233 }
4234 r.persistent = false;
4235 final long origId = Binder.clearCallingIdentity();
4236 decPersistentCountLocked(app);
4237 Binder.restoreCallingIdentity(origId);
4238
4239 }
4240 }
4241 }
4242
4243 public boolean clearApplicationUserData(final String packageName,
4244 final IPackageDataObserver observer) {
4245 int uid = Binder.getCallingUid();
4246 int pid = Binder.getCallingPid();
4247 long callingId = Binder.clearCallingIdentity();
4248 try {
4249 IPackageManager pm = ActivityThread.getPackageManager();
4250 int pkgUid = -1;
4251 synchronized(this) {
4252 try {
4253 pkgUid = pm.getPackageUid(packageName);
4254 } catch (RemoteException e) {
4255 }
4256 if (pkgUid == -1) {
4257 Log.w(TAG, "Invalid packageName:" + packageName);
4258 return false;
4259 }
4260 if (uid == pkgUid || checkComponentPermission(
4261 android.Manifest.permission.CLEAR_APP_USER_DATA,
4262 pid, uid, -1)
4263 == PackageManager.PERMISSION_GRANTED) {
4264 restartPackageLocked(packageName, pkgUid);
4265 } else {
4266 throw new SecurityException(pid+" does not have permission:"+
4267 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
4268 "for process:"+packageName);
4269 }
4270 }
4271
4272 try {
4273 //clear application user data
4274 pm.clearApplicationUserData(packageName, observer);
4275 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4276 Uri.fromParts("package", packageName, null));
4277 intent.putExtra(Intent.EXTRA_UID, pkgUid);
4278 broadcastIntentLocked(null, null, intent,
4279 null, null, 0, null, null, null,
4280 false, false, MY_PID, Process.SYSTEM_UID);
4281 } catch (RemoteException e) {
4282 }
4283 } finally {
4284 Binder.restoreCallingIdentity(callingId);
4285 }
4286 return true;
4287 }
4288
4289 public void restartPackage(final String packageName) {
4290 if (checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4291 != PackageManager.PERMISSION_GRANTED) {
4292 String msg = "Permission Denial: restartPackage() from pid="
4293 + Binder.getCallingPid()
4294 + ", uid=" + Binder.getCallingUid()
4295 + " requires " + android.Manifest.permission.RESTART_PACKAGES;
4296 Log.w(TAG, msg);
4297 throw new SecurityException(msg);
4298 }
4299
4300 long callingId = Binder.clearCallingIdentity();
4301 try {
4302 IPackageManager pm = ActivityThread.getPackageManager();
4303 int pkgUid = -1;
4304 synchronized(this) {
4305 try {
4306 pkgUid = pm.getPackageUid(packageName);
4307 } catch (RemoteException e) {
4308 }
4309 if (pkgUid == -1) {
4310 Log.w(TAG, "Invalid packageName: " + packageName);
4311 return;
4312 }
4313 restartPackageLocked(packageName, pkgUid);
4314 }
4315 } finally {
4316 Binder.restoreCallingIdentity(callingId);
4317 }
4318 }
4319
4320 private void restartPackageLocked(final String packageName, int uid) {
4321 uninstallPackageLocked(packageName, uid, false);
4322 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4323 Uri.fromParts("package", packageName, null));
4324 intent.putExtra(Intent.EXTRA_UID, uid);
4325 broadcastIntentLocked(null, null, intent,
4326 null, null, 0, null, null, null,
4327 false, false, MY_PID, Process.SYSTEM_UID);
4328 }
4329
4330 private final void uninstallPackageLocked(String name, int uid,
4331 boolean callerWillRestart) {
4332 if (Config.LOGD) Log.d(TAG, "Uninstalling process " + name);
4333
4334 int i, N;
4335
4336 final String procNamePrefix = name + ":";
4337 if (uid < 0) {
4338 try {
4339 uid = ActivityThread.getPackageManager().getPackageUid(name);
4340 } catch (RemoteException e) {
4341 }
4342 }
4343
4344 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
4345 while (badApps.hasNext()) {
4346 SparseArray<Long> ba = badApps.next();
4347 if (ba.get(uid) != null) {
4348 badApps.remove();
4349 }
4350 }
4351
4352 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4353
4354 // Remove all processes this package may have touched: all with the
4355 // same UID (except for the system or root user), and all whose name
4356 // matches the package name.
4357 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
4358 final int NA = apps.size();
4359 for (int ia=0; ia<NA; ia++) {
4360 ProcessRecord app = apps.valueAt(ia);
4361 if (app.removed) {
4362 procs.add(app);
4363 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
4364 || app.processName.equals(name)
4365 || app.processName.startsWith(procNamePrefix)) {
4366 app.removed = true;
4367 procs.add(app);
4368 }
4369 }
4370 }
4371
4372 N = procs.size();
4373 for (i=0; i<N; i++) {
4374 removeProcessLocked(procs.get(i), callerWillRestart);
4375 }
4376
4377 for (i=mHistory.size()-1; i>=0; i--) {
4378 HistoryRecord r = (HistoryRecord)mHistory.get(i);
4379 if (r.packageName.equals(name)) {
4380 if (Config.LOGD) Log.d(
4381 TAG, " Force finishing activity "
4382 + r.intent.getComponent().flattenToShortString());
4383 if (r.app != null) {
4384 r.app.removed = true;
4385 }
4386 r.app = null;
4387 finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
4388 }
4389 }
4390
4391 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
4392 for (ServiceRecord service : mServices.values()) {
4393 if (service.packageName.equals(name)) {
4394 if (service.app != null) {
4395 service.app.removed = true;
4396 }
4397 service.app = null;
4398 services.add(service);
4399 }
4400 }
4401
4402 N = services.size();
4403 for (i=0; i<N; i++) {
4404 bringDownServiceLocked(services.get(i), true);
4405 }
4406
4407 resumeTopActivityLocked(null);
4408 }
4409
4410 private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) {
4411 final String name = app.processName;
4412 final int uid = app.info.uid;
4413 if (Config.LOGD) Log.d(
4414 TAG, "Force removing process " + app + " (" + name
4415 + "/" + uid + ")");
4416
4417 mProcessNames.remove(name, uid);
4418 boolean needRestart = false;
4419 if (app.pid > 0 && app.pid != MY_PID) {
4420 int pid = app.pid;
4421 synchronized (mPidsSelfLocked) {
4422 mPidsSelfLocked.remove(pid);
4423 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4424 }
4425 handleAppDiedLocked(app, true);
4426 mLRUProcesses.remove(app);
4427 Process.killProcess(pid);
4428
4429 if (app.persistent) {
4430 if (!callerWillRestart) {
4431 addAppLocked(app.info);
4432 } else {
4433 needRestart = true;
4434 }
4435 }
4436 } else {
4437 mRemovedProcesses.add(app);
4438 }
4439
4440 return needRestart;
4441 }
4442
4443 private final void processStartTimedOutLocked(ProcessRecord app) {
4444 final int pid = app.pid;
4445 boolean gone = false;
4446 synchronized (mPidsSelfLocked) {
4447 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4448 if (knownApp != null && knownApp.thread == null) {
4449 mPidsSelfLocked.remove(pid);
4450 gone = true;
4451 }
4452 }
4453
4454 if (gone) {
4455 Log.w(TAG, "Process " + app + " failed to attach");
4456 mProcessNames.remove(app.processName, app.info.uid);
4457 Process.killProcess(pid);
4458 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
4459 Log.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4460 mPendingBroadcast = null;
4461 scheduleBroadcastsLocked();
4462 }
4463 } else {
4464 Log.w(TAG, "Spurious process start timeout - pid not known for " + app);
4465 }
4466 }
4467
4468 private final boolean attachApplicationLocked(IApplicationThread thread,
4469 int pid) {
4470
4471 // Find the application record that is being attached... either via
4472 // the pid if we are running in multiple processes, or just pull the
4473 // next app record if we are emulating process with anonymous threads.
4474 ProcessRecord app;
4475 if (pid != MY_PID && pid >= 0) {
4476 synchronized (mPidsSelfLocked) {
4477 app = mPidsSelfLocked.get(pid);
4478 }
4479 } else if (mStartingProcesses.size() > 0) {
4480 app = mStartingProcesses.remove(0);
4481 app.pid = pid;
4482 } else {
4483 app = null;
4484 }
4485
4486 if (app == null) {
4487 Log.w(TAG, "No pending application record for pid " + pid
4488 + " (IApplicationThread " + thread + "); dropping process");
4489 EventLog.writeEvent(LOG_AM_DROP_PROCESS, pid);
4490 if (pid > 0 && pid != MY_PID) {
4491 Process.killProcess(pid);
4492 } else {
4493 try {
4494 thread.scheduleExit();
4495 } catch (Exception e) {
4496 // Ignore exceptions.
4497 }
4498 }
4499 return false;
4500 }
4501
4502 // If this application record is still attached to a previous
4503 // process, clean it up now.
4504 if (app.thread != null) {
4505 handleAppDiedLocked(app, true);
4506 }
4507
4508 // Tell the process all about itself.
4509
4510 if (localLOGV) Log.v(
4511 TAG, "Binding process pid " + pid + " to record " + app);
4512
4513 String processName = app.processName;
4514 try {
4515 thread.asBinder().linkToDeath(new AppDeathRecipient(
4516 app, pid, thread), 0);
4517 } catch (RemoteException e) {
4518 app.resetPackageList();
4519 startProcessLocked(app, "link fail", processName);
4520 return false;
4521 }
4522
4523 EventLog.writeEvent(LOG_AM_PROCESS_BOUND, app.pid, app.processName);
4524
4525 app.thread = thread;
4526 app.curAdj = app.setAdj = -100;
4527 app.forcingToForeground = null;
4528 app.foregroundServices = false;
4529 app.debugging = false;
4530
4531 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4532
4533 List providers = generateApplicationProvidersLocked(app);
4534
4535 if (localLOGV) Log.v(
4536 TAG, "New app record " + app
4537 + " thread=" + thread.asBinder() + " pid=" + pid);
4538 try {
4539 int testMode = IApplicationThread.DEBUG_OFF;
4540 if (mDebugApp != null && mDebugApp.equals(processName)) {
4541 testMode = mWaitForDebugger
4542 ? IApplicationThread.DEBUG_WAIT
4543 : IApplicationThread.DEBUG_ON;
4544 app.debugging = true;
4545 if (mDebugTransient) {
4546 mDebugApp = mOrigDebugApp;
4547 mWaitForDebugger = mOrigWaitForDebugger;
4548 }
4549 }
4550 thread.bindApplication(processName, app.info, providers,
4551 app.instrumentationClass, app.instrumentationProfileFile,
4552 app.instrumentationArguments, app.instrumentationWatcher, testMode,
4553 mConfiguration, getCommonServicesLocked());
4554 updateLRUListLocked(app, false);
4555 app.lastRequestedGc = SystemClock.uptimeMillis();
4556 } catch (Exception e) {
4557 // todo: Yikes! What should we do? For now we will try to
4558 // start another process, but that could easily get us in
4559 // an infinite loop of restarting processes...
4560 Log.w(TAG, "Exception thrown during bind!", e);
4561
4562 app.resetPackageList();
4563 startProcessLocked(app, "bind fail", processName);
4564 return false;
4565 }
4566
4567 // Remove this record from the list of starting applications.
4568 mPersistentStartingProcesses.remove(app);
4569 mProcessesOnHold.remove(app);
4570
4571 boolean badApp = false;
4572 boolean didSomething = false;
4573
4574 // See if the top visible activity is waiting to run in this process...
4575 HistoryRecord hr = topRunningActivityLocked(null);
4576 if (hr != null) {
4577 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
4578 && processName.equals(hr.processName)) {
4579 try {
4580 if (realStartActivityLocked(hr, app, true, true)) {
4581 didSomething = true;
4582 }
4583 } catch (Exception e) {
4584 Log.w(TAG, "Exception in new application when starting activity "
4585 + hr.intent.getComponent().flattenToShortString(), e);
4586 badApp = true;
4587 }
4588 } else {
4589 ensureActivitiesVisibleLocked(hr, null, processName, 0);
4590 }
4591 }
4592
4593 // Find any services that should be running in this process...
4594 if (!badApp && mPendingServices.size() > 0) {
4595 ServiceRecord sr = null;
4596 try {
4597 for (int i=0; i<mPendingServices.size(); i++) {
4598 sr = mPendingServices.get(i);
4599 if (app.info.uid != sr.appInfo.uid
4600 || !processName.equals(sr.processName)) {
4601 continue;
4602 }
4603
4604 mPendingServices.remove(i);
4605 i--;
4606 realStartServiceLocked(sr, app);
4607 didSomething = true;
4608 }
4609 } catch (Exception e) {
4610 Log.w(TAG, "Exception in new application when starting service "
4611 + sr.shortName, e);
4612 badApp = true;
4613 }
4614 }
4615
4616 // Check if the next broadcast receiver is in this process...
4617 BroadcastRecord br = mPendingBroadcast;
4618 if (!badApp && br != null && br.curApp == app) {
4619 try {
4620 mPendingBroadcast = null;
4621 processCurBroadcastLocked(br, app);
4622 didSomething = true;
4623 } catch (Exception e) {
4624 Log.w(TAG, "Exception in new application when starting receiver "
4625 + br.curComponent.flattenToShortString(), e);
4626 badApp = true;
4627 logBroadcastReceiverDiscard(br);
4628 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
4629 br.resultExtras, br.resultAbort, true);
4630 scheduleBroadcastsLocked();
4631 }
4632 }
4633
4634 if (badApp) {
4635 // todo: Also need to kill application to deal with all
4636 // kinds of exceptions.
4637 handleAppDiedLocked(app, false);
4638 return false;
4639 }
4640
4641 if (!didSomething) {
4642 updateOomAdjLocked();
4643 }
4644
4645 return true;
4646 }
4647
4648 public final void attachApplication(IApplicationThread thread) {
4649 synchronized (this) {
4650 int callingPid = Binder.getCallingPid();
4651 final long origId = Binder.clearCallingIdentity();
4652 attachApplicationLocked(thread, callingPid);
4653 Binder.restoreCallingIdentity(origId);
4654 }
4655 }
4656
4657 public final void activityIdle(IBinder token) {
4658 final long origId = Binder.clearCallingIdentity();
4659 activityIdleInternal(token, false);
4660 Binder.restoreCallingIdentity(origId);
4661 }
4662
4663 final ArrayList<HistoryRecord> processStoppingActivitiesLocked(
4664 boolean remove) {
4665 int N = mStoppingActivities.size();
4666 if (N <= 0) return null;
4667
4668 ArrayList<HistoryRecord> stops = null;
4669
4670 final boolean nowVisible = mResumedActivity != null
4671 && mResumedActivity.nowVisible
4672 && !mResumedActivity.waitingVisible;
4673 for (int i=0; i<N; i++) {
4674 HistoryRecord s = mStoppingActivities.get(i);
4675 if (localLOGV) Log.v(TAG, "Stopping " + s + ": nowVisible="
4676 + nowVisible + " waitingVisible=" + s.waitingVisible
4677 + " finishing=" + s.finishing);
4678 if (s.waitingVisible && nowVisible) {
4679 mWaitingVisibleActivities.remove(s);
4680 s.waitingVisible = false;
4681 if (s.finishing) {
4682 // If this activity is finishing, it is sitting on top of
4683 // everyone else but we now know it is no longer needed...
4684 // so get rid of it. Otherwise, we need to go through the
4685 // normal flow and hide it once we determine that it is
4686 // hidden by the activities in front of it.
4687 if (localLOGV) Log.v(TAG, "Before stopping, can hide: " + s);
4688 mWindowManager.setAppVisibility(s, false);
4689 }
4690 }
4691 if (!s.waitingVisible && remove) {
4692 if (localLOGV) Log.v(TAG, "Ready to stop: " + s);
4693 if (stops == null) {
4694 stops = new ArrayList<HistoryRecord>();
4695 }
4696 stops.add(s);
4697 mStoppingActivities.remove(i);
4698 N--;
4699 i--;
4700 }
4701 }
4702
4703 return stops;
4704 }
4705
4706 void enableScreenAfterBoot() {
4707 mWindowManager.enableScreenAfterBoot();
4708 }
4709
4710 final void activityIdleInternal(IBinder token, boolean fromTimeout) {
4711 if (localLOGV) Log.v(TAG, "Activity idle: " + token);
4712
4713 ArrayList<HistoryRecord> stops = null;
4714 ArrayList<HistoryRecord> finishes = null;
4715 ArrayList<HistoryRecord> thumbnails = null;
4716 int NS = 0;
4717 int NF = 0;
4718 int NT = 0;
4719 IApplicationThread sendThumbnail = null;
4720 boolean booting = false;
4721 boolean enableScreen = false;
4722
4723 synchronized (this) {
4724 if (token != null) {
4725 mHandler.removeMessages(IDLE_TIMEOUT_MSG, token);
4726 }
4727
4728 // Get the activity record.
4729 int index = indexOfTokenLocked(token, false);
4730 if (index >= 0) {
4731 HistoryRecord r = (HistoryRecord)mHistory.get(index);
4732
4733 // No longer need to keep the device awake.
4734 if (mResumedActivity == r && mLaunchingActivity.isHeld()) {
4735 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
4736 mLaunchingActivity.release();
4737 }
4738
4739 // We are now idle. If someone is waiting for a thumbnail from
4740 // us, we can now deliver.
4741 r.idle = true;
4742 scheduleAppGcsLocked();
4743 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
4744 sendThumbnail = r.app.thread;
4745 r.thumbnailNeeded = false;
4746 }
4747
4748 // If this activity is fullscreen, set up to hide those under it.
4749
4750 if (DEBUG_VISBILITY) Log.v(TAG, "Idle activity for " + r);
4751 ensureActivitiesVisibleLocked(null, 0);
4752
4753 //Log.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
4754 if (!mBooted && !fromTimeout) {
4755 mBooted = true;
4756 enableScreen = true;
4757 }
4758 }
4759
4760 // Atomically retrieve all of the other things to do.
4761 stops = processStoppingActivitiesLocked(true);
4762 NS = stops != null ? stops.size() : 0;
4763 if ((NF=mFinishingActivities.size()) > 0) {
4764 finishes = new ArrayList<HistoryRecord>(mFinishingActivities);
4765 mFinishingActivities.clear();
4766 }
4767 if ((NT=mCancelledThumbnails.size()) > 0) {
4768 thumbnails = new ArrayList<HistoryRecord>(mCancelledThumbnails);
4769 mCancelledThumbnails.clear();
4770 }
4771
4772 booting = mBooting;
4773 mBooting = false;
4774 }
4775
4776 int i;
4777
4778 // Send thumbnail if requested.
4779 if (sendThumbnail != null) {
4780 try {
4781 sendThumbnail.requestThumbnail(token);
4782 } catch (Exception e) {
4783 Log.w(TAG, "Exception thrown when requesting thumbnail", e);
4784 sendPendingThumbnail(null, token, null, null, true);
4785 }
4786 }
4787
4788 // Stop any activities that are scheduled to do so but have been
4789 // waiting for the next one to start.
4790 for (i=0; i<NS; i++) {
4791 HistoryRecord r = (HistoryRecord)stops.get(i);
4792 synchronized (this) {
4793 if (r.finishing) {
4794 finishCurrentActivityLocked(r, FINISH_IMMEDIATELY);
4795 } else {
4796 stopActivityLocked(r);
4797 }
4798 }
4799 }
4800
4801 // Finish any activities that are scheduled to do so but have been
4802 // waiting for the next one to start.
4803 for (i=0; i<NF; i++) {
4804 HistoryRecord r = (HistoryRecord)finishes.get(i);
4805 synchronized (this) {
4806 destroyActivityLocked(r, true);
4807 }
4808 }
4809
4810 // Report back to any thumbnail receivers.
4811 for (i=0; i<NT; i++) {
4812 HistoryRecord r = (HistoryRecord)thumbnails.get(i);
4813 sendPendingThumbnail(r, null, null, null, true);
4814 }
4815
4816 if (booting) {
4817 // Ensure that any processes we had put on hold are now started
4818 // up.
4819 final int NP = mProcessesOnHold.size();
4820 if (NP > 0) {
4821 ArrayList<ProcessRecord> procs =
4822 new ArrayList<ProcessRecord>(mProcessesOnHold);
4823 for (int ip=0; ip<NP; ip++) {
4824 this.startProcessLocked(procs.get(ip), "on-hold", null);
4825 }
4826 }
4827 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4828 // Tell anyone interested that we are done booting!
4829 synchronized (this) {
4830 broadcastIntentLocked(null, null,
4831 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4832 null, null, 0, null, null,
4833 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4834 false, false, MY_PID, Process.SYSTEM_UID);
4835 }
4836 }
4837 }
4838
4839 trimApplications();
4840 //dump();
4841 //mWindowManager.dump();
4842
4843 if (enableScreen) {
4844 EventLog.writeEvent(LOG_BOOT_PROGRESS_ENABLE_SCREEN,
4845 SystemClock.uptimeMillis());
4846 enableScreenAfterBoot();
4847 }
4848 }
4849
4850 public final void activityPaused(IBinder token, Bundle icicle) {
4851 // Refuse possible leaked file descriptors
4852 if (icicle != null && icicle.hasFileDescriptors()) {
4853 throw new IllegalArgumentException("File descriptors passed in Bundle");
4854 }
4855
4856 final long origId = Binder.clearCallingIdentity();
4857 activityPaused(token, icicle, false);
4858 Binder.restoreCallingIdentity(origId);
4859 }
4860
4861 final void activityPaused(IBinder token, Bundle icicle, boolean timeout) {
4862 if (DEBUG_PAUSE) Log.v(
4863 TAG, "Activity paused: token=" + token + ", icicle=" + icicle
4864 + ", timeout=" + timeout);
4865
4866 HistoryRecord r = null;
4867
4868 synchronized (this) {
4869 int index = indexOfTokenLocked(token, false);
4870 if (index >= 0) {
4871 r = (HistoryRecord)mHistory.get(index);
4872 if (!timeout) {
4873 r.icicle = icicle;
4874 r.haveState = true;
4875 }
4876 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
4877 if (mPausingActivity == r) {
4878 r.state = ActivityState.PAUSED;
4879 completePauseLocked();
4880 } else {
4881 EventLog.writeEvent(LOG_AM_FAILED_TO_PAUSE_ACTIVITY,
4882 System.identityHashCode(r), r.shortComponentName,
4883 mPausingActivity != null
4884 ? mPausingActivity.shortComponentName : "(none)");
4885 }
4886 }
4887 }
4888 }
4889
4890 public final void activityStopped(IBinder token, Bitmap thumbnail,
4891 CharSequence description) {
4892 if (localLOGV) Log.v(
4893 TAG, "Activity stopped: token=" + token);
4894
4895 HistoryRecord r = null;
4896
4897 final long origId = Binder.clearCallingIdentity();
4898
4899 synchronized (this) {
4900 int index = indexOfTokenLocked(token, false);
4901 if (index >= 0) {
4902 r = (HistoryRecord)mHistory.get(index);
4903 r.thumbnail = thumbnail;
4904 r.description = description;
4905 r.stopped = true;
4906 r.state = ActivityState.STOPPED;
4907 if (!r.finishing) {
4908 if (r.configDestroy) {
4909 destroyActivityLocked(r, true);
4910 resumeTopActivityLocked(null);
4911 }
4912 }
4913 }
4914 }
4915
4916 if (r != null) {
4917 sendPendingThumbnail(r, null, null, null, false);
4918 }
4919
4920 trimApplications();
4921
4922 Binder.restoreCallingIdentity(origId);
4923 }
4924
4925 public final void activityDestroyed(IBinder token) {
4926 if (DEBUG_SWITCH) Log.v(TAG, "ACTIVITY DESTROYED: " + token);
4927 synchronized (this) {
4928 mHandler.removeMessages(DESTROY_TIMEOUT_MSG, token);
4929
4930 int index = indexOfTokenLocked(token, false);
4931 if (index >= 0) {
4932 HistoryRecord r = (HistoryRecord)mHistory.get(index);
4933 if (r.state == ActivityState.DESTROYING) {
4934 final long origId = Binder.clearCallingIdentity();
4935 removeActivityFromHistoryLocked(r);
4936 Binder.restoreCallingIdentity(origId);
4937 }
4938 }
4939 }
4940 }
4941
4942 public String getCallingPackage(IBinder token) {
4943 synchronized (this) {
4944 HistoryRecord r = getCallingRecordLocked(token);
4945 return r != null && r.app != null ? r.app.processName : null;
4946 }
4947 }
4948
4949 public ComponentName getCallingActivity(IBinder token) {
4950 synchronized (this) {
4951 HistoryRecord r = getCallingRecordLocked(token);
4952 return r != null ? r.intent.getComponent() : null;
4953 }
4954 }
4955
4956 private HistoryRecord getCallingRecordLocked(IBinder token) {
4957 int index = indexOfTokenLocked(token, true);
4958 if (index >= 0) {
4959 HistoryRecord r = (HistoryRecord)mHistory.get(index);
4960 if (r != null) {
4961 return r.resultTo;
4962 }
4963 }
4964 return null;
4965 }
4966
4967 public ComponentName getActivityClassForToken(IBinder token) {
4968 synchronized(this) {
4969 int index = indexOfTokenLocked(token, false);
4970 if (index >= 0) {
4971 HistoryRecord r = (HistoryRecord)mHistory.get(index);
4972 return r.intent.getComponent();
4973 }
4974 return null;
4975 }
4976 }
4977
4978 public String getPackageForToken(IBinder token) {
4979 synchronized(this) {
4980 int index = indexOfTokenLocked(token, false);
4981 if (index >= 0) {
4982 HistoryRecord r = (HistoryRecord)mHistory.get(index);
4983 return r.packageName;
4984 }
4985 return null;
4986 }
4987 }
4988
4989 public IIntentSender getIntentSender(int type,
4990 String packageName, IBinder token, String resultWho,
4991 int requestCode, Intent intent, String resolvedType, int flags) {
4992 // Refuse possible leaked file descriptors
4993 if (intent != null && intent.hasFileDescriptors() == true) {
4994 throw new IllegalArgumentException("File descriptors passed in Intent");
4995 }
4996
4997 synchronized(this) {
4998 int callingUid = Binder.getCallingUid();
4999 try {
5000 if (callingUid != 0 && callingUid != Process.SYSTEM_UID &&
5001 Process.supportsProcesses()) {
5002 int uid = ActivityThread.getPackageManager()
5003 .getPackageUid(packageName);
5004 if (uid != Binder.getCallingUid()) {
5005 String msg = "Permission Denial: getIntentSender() from pid="
5006 + Binder.getCallingPid()
5007 + ", uid=" + Binder.getCallingUid()
5008 + ", (need uid=" + uid + ")"
5009 + " is not allowed to send as package " + packageName;
5010 Log.w(TAG, msg);
5011 throw new SecurityException(msg);
5012 }
5013 }
5014 } catch (RemoteException e) {
5015 throw new SecurityException(e);
5016 }
5017 HistoryRecord activity = null;
5018 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
5019 int index = indexOfTokenLocked(token, false);
5020 if (index < 0) {
5021 return null;
5022 }
5023 activity = (HistoryRecord)mHistory.get(index);
5024 if (activity.finishing) {
5025 return null;
5026 }
5027 }
5028
5029 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5030 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5031 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5032 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5033 |PendingIntent.FLAG_UPDATE_CURRENT);
5034
5035 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5036 type, packageName, activity, resultWho,
5037 requestCode, intent, resolvedType, flags);
5038 WeakReference<PendingIntentRecord> ref;
5039 ref = mIntentSenderRecords.get(key);
5040 PendingIntentRecord rec = ref != null ? ref.get() : null;
5041 if (rec != null) {
5042 if (!cancelCurrent) {
5043 if (updateCurrent) {
5044 rec.key.requestIntent.replaceExtras(intent);
5045 }
5046 return rec;
5047 }
5048 rec.canceled = true;
5049 mIntentSenderRecords.remove(key);
5050 }
5051 if (noCreate) {
5052 return rec;
5053 }
5054 rec = new PendingIntentRecord(this, key, callingUid);
5055 mIntentSenderRecords.put(key, rec.ref);
5056 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
5057 if (activity.pendingResults == null) {
5058 activity.pendingResults
5059 = new HashSet<WeakReference<PendingIntentRecord>>();
5060 }
5061 activity.pendingResults.add(rec.ref);
5062 }
5063 return rec;
5064 }
5065 }
5066
5067 public void cancelIntentSender(IIntentSender sender) {
5068 if (!(sender instanceof PendingIntentRecord)) {
5069 return;
5070 }
5071 synchronized(this) {
5072 PendingIntentRecord rec = (PendingIntentRecord)sender;
5073 try {
5074 int uid = ActivityThread.getPackageManager()
5075 .getPackageUid(rec.key.packageName);
5076 if (uid != Binder.getCallingUid()) {
5077 String msg = "Permission Denial: cancelIntentSender() from pid="
5078 + Binder.getCallingPid()
5079 + ", uid=" + Binder.getCallingUid()
5080 + " is not allowed to cancel packges "
5081 + rec.key.packageName;
5082 Log.w(TAG, msg);
5083 throw new SecurityException(msg);
5084 }
5085 } catch (RemoteException e) {
5086 throw new SecurityException(e);
5087 }
5088 cancelIntentSenderLocked(rec, true);
5089 }
5090 }
5091
5092 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5093 rec.canceled = true;
5094 mIntentSenderRecords.remove(rec.key);
5095 if (cleanActivity && rec.key.activity != null) {
5096 rec.key.activity.pendingResults.remove(rec.ref);
5097 }
5098 }
5099
5100 public String getPackageForIntentSender(IIntentSender pendingResult) {
5101 if (!(pendingResult instanceof PendingIntentRecord)) {
5102 return null;
5103 }
5104 synchronized(this) {
5105 try {
5106 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5107 return res.key.packageName;
5108 } catch (ClassCastException e) {
5109 }
5110 }
5111 return null;
5112 }
5113
5114 public void setProcessLimit(int max) {
5115 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5116 "setProcessLimit()");
5117 mProcessLimit = max;
5118 }
5119
5120 public int getProcessLimit() {
5121 return mProcessLimit;
5122 }
5123
5124 void foregroundTokenDied(ForegroundToken token) {
5125 synchronized (ActivityManagerService.this) {
5126 synchronized (mPidsSelfLocked) {
5127 ForegroundToken cur
5128 = mForegroundProcesses.get(token.pid);
5129 if (cur != token) {
5130 return;
5131 }
5132 mForegroundProcesses.remove(token.pid);
5133 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5134 if (pr == null) {
5135 return;
5136 }
5137 pr.forcingToForeground = null;
5138 pr.foregroundServices = false;
5139 }
5140 updateOomAdjLocked();
5141 }
5142 }
5143
5144 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5145 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5146 "setProcessForeground()");
5147 synchronized(this) {
5148 boolean changed = false;
5149
5150 synchronized (mPidsSelfLocked) {
5151 ProcessRecord pr = mPidsSelfLocked.get(pid);
5152 if (pr == null) {
5153 Log.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5154 return;
5155 }
5156 ForegroundToken oldToken = mForegroundProcesses.get(pid);
5157 if (oldToken != null) {
5158 oldToken.token.unlinkToDeath(oldToken, 0);
5159 mForegroundProcesses.remove(pid);
5160 pr.forcingToForeground = null;
5161 changed = true;
5162 }
5163 if (isForeground && token != null) {
5164 ForegroundToken newToken = new ForegroundToken() {
5165 public void binderDied() {
5166 foregroundTokenDied(this);
5167 }
5168 };
5169 newToken.pid = pid;
5170 newToken.token = token;
5171 try {
5172 token.linkToDeath(newToken, 0);
5173 mForegroundProcesses.put(pid, newToken);
5174 pr.forcingToForeground = token;
5175 changed = true;
5176 } catch (RemoteException e) {
5177 // If the process died while doing this, we will later
5178 // do the cleanup with the process death link.
5179 }
5180 }
5181 }
5182
5183 if (changed) {
5184 updateOomAdjLocked();
5185 }
5186 }
5187 }
5188
5189 // =========================================================
5190 // PERMISSIONS
5191 // =========================================================
5192
5193 static class PermissionController extends IPermissionController.Stub {
5194 ActivityManagerService mActivityManagerService;
5195 PermissionController(ActivityManagerService activityManagerService) {
5196 mActivityManagerService = activityManagerService;
5197 }
5198
5199 public boolean checkPermission(String permission, int pid, int uid) {
5200 return mActivityManagerService.checkPermission(permission, pid,
5201 uid) == PackageManager.PERMISSION_GRANTED;
5202 }
5203 }
5204
5205 /**
5206 * This can be called with or without the global lock held.
5207 */
5208 int checkComponentPermission(String permission, int pid, int uid,
5209 int reqUid) {
5210 // We might be performing an operation on behalf of an indirect binder
5211 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
5212 // client identity accordingly before proceeding.
5213 Identity tlsIdentity = sCallerIdentity.get();
5214 if (tlsIdentity != null) {
5215 Log.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5216 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5217 uid = tlsIdentity.uid;
5218 pid = tlsIdentity.pid;
5219 }
5220
5221 // Root, system server and our own process get to do everything.
5222 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID ||
5223 !Process.supportsProcesses()) {
5224 return PackageManager.PERMISSION_GRANTED;
5225 }
5226 // If the target requires a specific UID, always fail for others.
5227 if (reqUid >= 0 && uid != reqUid) {
5228 return PackageManager.PERMISSION_DENIED;
5229 }
5230 if (permission == null) {
5231 return PackageManager.PERMISSION_GRANTED;
5232 }
5233 try {
5234 return ActivityThread.getPackageManager()
5235 .checkUidPermission(permission, uid);
5236 } catch (RemoteException e) {
5237 // Should never happen, but if it does... deny!
5238 Log.e(TAG, "PackageManager is dead?!?", e);
5239 }
5240 return PackageManager.PERMISSION_DENIED;
5241 }
5242
5243 /**
5244 * As the only public entry point for permissions checking, this method
5245 * can enforce the semantic that requesting a check on a null global
5246 * permission is automatically denied. (Internally a null permission
5247 * string is used when calling {@link #checkComponentPermission} in cases
5248 * when only uid-based security is needed.)
5249 *
5250 * This can be called with or without the global lock held.
5251 */
5252 public int checkPermission(String permission, int pid, int uid) {
5253 if (permission == null) {
5254 return PackageManager.PERMISSION_DENIED;
5255 }
5256 return checkComponentPermission(permission, pid, uid, -1);
5257 }
5258
5259 /**
5260 * Binder IPC calls go through the public entry point.
5261 * This can be called with or without the global lock held.
5262 */
5263 int checkCallingPermission(String permission) {
5264 return checkPermission(permission,
5265 Binder.getCallingPid(),
5266 Binder.getCallingUid());
5267 }
5268
5269 /**
5270 * This can be called with or without the global lock held.
5271 */
5272 void enforceCallingPermission(String permission, String func) {
5273 if (checkCallingPermission(permission)
5274 == PackageManager.PERMISSION_GRANTED) {
5275 return;
5276 }
5277
5278 String msg = "Permission Denial: " + func + " from pid="
5279 + Binder.getCallingPid()
5280 + ", uid=" + Binder.getCallingUid()
5281 + " requires " + permission;
5282 Log.w(TAG, msg);
5283 throw new SecurityException(msg);
5284 }
5285
5286 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
5287 ProviderInfo pi, int uid, int modeFlags) {
5288 try {
5289 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5290 if ((pi.readPermission != null) &&
5291 (pm.checkUidPermission(pi.readPermission, uid)
5292 != PackageManager.PERMISSION_GRANTED)) {
5293 return false;
5294 }
5295 }
5296 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5297 if ((pi.writePermission != null) &&
5298 (pm.checkUidPermission(pi.writePermission, uid)
5299 != PackageManager.PERMISSION_GRANTED)) {
5300 return false;
5301 }
5302 }
5303 return true;
5304 } catch (RemoteException e) {
5305 return false;
5306 }
5307 }
5308
5309 private final boolean checkUriPermissionLocked(Uri uri, int uid,
5310 int modeFlags) {
5311 // Root gets to do everything.
5312 if (uid == 0 || !Process.supportsProcesses()) {
5313 return true;
5314 }
5315 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5316 if (perms == null) return false;
5317 UriPermission perm = perms.get(uri);
5318 if (perm == null) return false;
5319 return (modeFlags&perm.modeFlags) == modeFlags;
5320 }
5321
5322 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5323 // Another redirected-binder-call permissions check as in
5324 // {@link checkComponentPermission}.
5325 Identity tlsIdentity = sCallerIdentity.get();
5326 if (tlsIdentity != null) {
5327 uid = tlsIdentity.uid;
5328 pid = tlsIdentity.pid;
5329 }
5330
5331 // Our own process gets to do everything.
5332 if (pid == MY_PID) {
5333 return PackageManager.PERMISSION_GRANTED;
5334 }
5335 synchronized(this) {
5336 return checkUriPermissionLocked(uri, uid, modeFlags)
5337 ? PackageManager.PERMISSION_GRANTED
5338 : PackageManager.PERMISSION_DENIED;
5339 }
5340 }
5341
5342 private void grantUriPermissionLocked(int callingUid,
5343 String targetPkg, Uri uri, int modeFlags, HistoryRecord activity) {
5344 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5345 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5346 if (modeFlags == 0) {
5347 return;
5348 }
5349
5350 final IPackageManager pm = ActivityThread.getPackageManager();
5351
5352 // If this is not a content: uri, we can't do anything with it.
5353 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5354 return;
5355 }
5356
5357 String name = uri.getAuthority();
5358 ProviderInfo pi = null;
5359 ContentProviderRecord cpr
5360 = (ContentProviderRecord)mProvidersByName.get(name);
5361 if (cpr != null) {
5362 pi = cpr.info;
5363 } else {
5364 try {
5365 pi = pm.resolveContentProvider(name,
5366 PackageManager.GET_URI_PERMISSION_PATTERNS);
5367 } catch (RemoteException ex) {
5368 }
5369 }
5370 if (pi == null) {
5371 Log.w(TAG, "No content provider found for: " + name);
5372 return;
5373 }
5374
5375 int targetUid;
5376 try {
5377 targetUid = pm.getPackageUid(targetPkg);
5378 if (targetUid < 0) {
5379 return;
5380 }
5381 } catch (RemoteException ex) {
5382 return;
5383 }
5384
5385 // First... does the target actually need this permission?
5386 if (checkHoldingPermissionsLocked(pm, pi, targetUid, modeFlags)) {
5387 // No need to grant the target this permission.
5388 return;
5389 }
5390
5391 // Second... maybe someone else has already granted the
5392 // permission?
5393 if (checkUriPermissionLocked(uri, targetUid, modeFlags)) {
5394 // No need to grant the target this permission.
5395 return;
5396 }
5397
5398 // Third... is the provider allowing granting of URI permissions?
5399 if (!pi.grantUriPermissions) {
5400 throw new SecurityException("Provider " + pi.packageName
5401 + "/" + pi.name
5402 + " does not allow granting of Uri permissions (uri "
5403 + uri + ")");
5404 }
5405 if (pi.uriPermissionPatterns != null) {
5406 final int N = pi.uriPermissionPatterns.length;
5407 boolean allowed = false;
5408 for (int i=0; i<N; i++) {
5409 if (pi.uriPermissionPatterns[i] != null
5410 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5411 allowed = true;
5412 break;
5413 }
5414 }
5415 if (!allowed) {
5416 throw new SecurityException("Provider " + pi.packageName
5417 + "/" + pi.name
5418 + " does not allow granting of permission to path of Uri "
5419 + uri);
5420 }
5421 }
5422
5423 // Fourth... does the caller itself have permission to access
5424 // this uri?
5425 if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) {
5426 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5427 throw new SecurityException("Uid " + callingUid
5428 + " does not have permission to uri " + uri);
5429 }
5430 }
5431
5432 // Okay! So here we are: the caller has the assumed permission
5433 // to the uri, and the target doesn't. Let's now give this to
5434 // the target.
5435
5436 HashMap<Uri, UriPermission> targetUris
5437 = mGrantedUriPermissions.get(targetUid);
5438 if (targetUris == null) {
5439 targetUris = new HashMap<Uri, UriPermission>();
5440 mGrantedUriPermissions.put(targetUid, targetUris);
5441 }
5442
5443 UriPermission perm = targetUris.get(uri);
5444 if (perm == null) {
5445 perm = new UriPermission(targetUid, uri);
5446 targetUris.put(uri, perm);
5447
5448 }
5449 perm.modeFlags |= modeFlags;
5450 if (activity == null) {
5451 perm.globalModeFlags |= modeFlags;
5452 } else if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5453 perm.readActivities.add(activity);
5454 if (activity.readUriPermissions == null) {
5455 activity.readUriPermissions = new HashSet<UriPermission>();
5456 }
5457 activity.readUriPermissions.add(perm);
5458 } else if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5459 perm.writeActivities.add(activity);
5460 if (activity.writeUriPermissions == null) {
5461 activity.writeUriPermissions = new HashSet<UriPermission>();
5462 }
5463 activity.writeUriPermissions.add(perm);
5464 }
5465 }
5466
5467 private void grantUriPermissionFromIntentLocked(int callingUid,
5468 String targetPkg, Intent intent, HistoryRecord activity) {
5469 if (intent == null) {
5470 return;
5471 }
5472 Uri data = intent.getData();
5473 if (data == null) {
5474 return;
5475 }
5476 grantUriPermissionLocked(callingUid, targetPkg, data,
5477 intent.getFlags(), activity);
5478 }
5479
5480 public void grantUriPermission(IApplicationThread caller, String targetPkg,
5481 Uri uri, int modeFlags) {
5482 synchronized(this) {
5483 final ProcessRecord r = getRecordForAppLocked(caller);
5484 if (r == null) {
5485 throw new SecurityException("Unable to find app for caller "
5486 + caller
5487 + " when granting permission to uri " + uri);
5488 }
5489 if (targetPkg == null) {
5490 Log.w(TAG, "grantUriPermission: null target");
5491 return;
5492 }
5493 if (uri == null) {
5494 Log.w(TAG, "grantUriPermission: null uri");
5495 return;
5496 }
5497
5498 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
5499 null);
5500 }
5501 }
5502
5503 private void removeUriPermissionIfNeededLocked(UriPermission perm) {
5504 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5505 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5506 HashMap<Uri, UriPermission> perms
5507 = mGrantedUriPermissions.get(perm.uid);
5508 if (perms != null) {
5509 perms.remove(perm.uri);
5510 if (perms.size() == 0) {
5511 mGrantedUriPermissions.remove(perm.uid);
5512 }
5513 }
5514 }
5515 }
5516
5517 private void removeActivityUriPermissionsLocked(HistoryRecord activity) {
5518 if (activity.readUriPermissions != null) {
5519 for (UriPermission perm : activity.readUriPermissions) {
5520 perm.readActivities.remove(activity);
5521 if (perm.readActivities.size() == 0 && (perm.globalModeFlags
5522 &Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0) {
5523 perm.modeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
5524 removeUriPermissionIfNeededLocked(perm);
5525 }
5526 }
5527 }
5528 if (activity.writeUriPermissions != null) {
5529 for (UriPermission perm : activity.writeUriPermissions) {
5530 perm.writeActivities.remove(activity);
5531 if (perm.writeActivities.size() == 0 && (perm.globalModeFlags
5532 &Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0) {
5533 perm.modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
5534 removeUriPermissionIfNeededLocked(perm);
5535 }
5536 }
5537 }
5538 }
5539
5540 private void revokeUriPermissionLocked(int callingUid, Uri uri,
5541 int modeFlags) {
5542 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5543 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5544 if (modeFlags == 0) {
5545 return;
5546 }
5547
5548 final IPackageManager pm = ActivityThread.getPackageManager();
5549
5550 final String authority = uri.getAuthority();
5551 ProviderInfo pi = null;
5552 ContentProviderRecord cpr
5553 = (ContentProviderRecord)mProvidersByName.get(authority);
5554 if (cpr != null) {
5555 pi = cpr.info;
5556 } else {
5557 try {
5558 pi = pm.resolveContentProvider(authority,
5559 PackageManager.GET_URI_PERMISSION_PATTERNS);
5560 } catch (RemoteException ex) {
5561 }
5562 }
5563 if (pi == null) {
5564 Log.w(TAG, "No content provider found for: " + authority);
5565 return;
5566 }
5567
5568 // Does the caller have this permission on the URI?
5569 if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) {
5570 // Right now, if you are not the original owner of the permission,
5571 // you are not allowed to revoke it.
5572 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5573 throw new SecurityException("Uid " + callingUid
5574 + " does not have permission to uri " + uri);
5575 //}
5576 }
5577
5578 // Go through all of the permissions and remove any that match.
5579 final List<String> SEGMENTS = uri.getPathSegments();
5580 if (SEGMENTS != null) {
5581 final int NS = SEGMENTS.size();
5582 int N = mGrantedUriPermissions.size();
5583 for (int i=0; i<N; i++) {
5584 HashMap<Uri, UriPermission> perms
5585 = mGrantedUriPermissions.valueAt(i);
5586 Iterator<UriPermission> it = perms.values().iterator();
5587 toploop:
5588 while (it.hasNext()) {
5589 UriPermission perm = it.next();
5590 Uri targetUri = perm.uri;
5591 if (!authority.equals(targetUri.getAuthority())) {
5592 continue;
5593 }
5594 List<String> targetSegments = targetUri.getPathSegments();
5595 if (targetSegments == null) {
5596 continue;
5597 }
5598 if (targetSegments.size() < NS) {
5599 continue;
5600 }
5601 for (int j=0; j<NS; j++) {
5602 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5603 continue toploop;
5604 }
5605 }
5606 perm.clearModes(modeFlags);
5607 if (perm.modeFlags == 0) {
5608 it.remove();
5609 }
5610 }
5611 if (perms.size() == 0) {
5612 mGrantedUriPermissions.remove(
5613 mGrantedUriPermissions.keyAt(i));
5614 N--;
5615 i--;
5616 }
5617 }
5618 }
5619 }
5620
5621 public void revokeUriPermission(IApplicationThread caller, Uri uri,
5622 int modeFlags) {
5623 synchronized(this) {
5624 final ProcessRecord r = getRecordForAppLocked(caller);
5625 if (r == null) {
5626 throw new SecurityException("Unable to find app for caller "
5627 + caller
5628 + " when revoking permission to uri " + uri);
5629 }
5630 if (uri == null) {
5631 Log.w(TAG, "revokeUriPermission: null uri");
5632 return;
5633 }
5634
5635 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5636 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5637 if (modeFlags == 0) {
5638 return;
5639 }
5640
5641 final IPackageManager pm = ActivityThread.getPackageManager();
5642
5643 final String authority = uri.getAuthority();
5644 ProviderInfo pi = null;
5645 ContentProviderRecord cpr
5646 = (ContentProviderRecord)mProvidersByName.get(authority);
5647 if (cpr != null) {
5648 pi = cpr.info;
5649 } else {
5650 try {
5651 pi = pm.resolveContentProvider(authority,
5652 PackageManager.GET_URI_PERMISSION_PATTERNS);
5653 } catch (RemoteException ex) {
5654 }
5655 }
5656 if (pi == null) {
5657 Log.w(TAG, "No content provider found for: " + authority);
5658 return;
5659 }
5660
5661 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
5662 }
5663 }
5664
5665 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5666 synchronized (this) {
5667 ProcessRecord app =
5668 who != null ? getRecordForAppLocked(who) : null;
5669 if (app == null) return;
5670
5671 Message msg = Message.obtain();
5672 msg.what = WAIT_FOR_DEBUGGER_MSG;
5673 msg.obj = app;
5674 msg.arg1 = waiting ? 1 : 0;
5675 mHandler.sendMessage(msg);
5676 }
5677 }
5678
5679 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5680 outInfo.availMem = Process.getFreeMemory();
5681 outInfo.threshold = SECONDARY_SERVER_MEM;
5682 outInfo.lowMemory = outInfo.availMem <
5683 (SECONDARY_SERVER_MEM + ((HIDDEN_APP_MEM-SECONDARY_SERVER_MEM)/2));
5684 }
5685
5686 // =========================================================
5687 // TASK MANAGEMENT
5688 // =========================================================
5689
5690 public List getTasks(int maxNum, int flags,
5691 IThumbnailReceiver receiver) {
5692 ArrayList list = new ArrayList();
5693
5694 PendingThumbnailsRecord pending = null;
5695 IApplicationThread topThumbnail = null;
5696 HistoryRecord topRecord = null;
5697
5698 synchronized(this) {
5699 if (localLOGV) Log.v(
5700 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5701 + ", receiver=" + receiver);
5702
5703 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5704 != PackageManager.PERMISSION_GRANTED) {
5705 if (receiver != null) {
5706 // If the caller wants to wait for pending thumbnails,
5707 // it ain't gonna get them.
5708 try {
5709 receiver.finished();
5710 } catch (RemoteException ex) {
5711 }
5712 }
5713 String msg = "Permission Denial: getTasks() from pid="
5714 + Binder.getCallingPid()
5715 + ", uid=" + Binder.getCallingUid()
5716 + " requires " + android.Manifest.permission.GET_TASKS;
5717 Log.w(TAG, msg);
5718 throw new SecurityException(msg);
5719 }
5720
5721 int pos = mHistory.size()-1;
5722 HistoryRecord next =
5723 pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null;
5724 HistoryRecord top = null;
5725 CharSequence topDescription = null;
5726 TaskRecord curTask = null;
5727 int numActivities = 0;
5728 int numRunning = 0;
5729 while (pos >= 0 && maxNum > 0) {
5730 final HistoryRecord r = next;
5731 pos--;
5732 next = pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null;
5733
5734 // Initialize state for next task if needed.
5735 if (top == null ||
5736 (top.state == ActivityState.INITIALIZING
5737 && top.task == r.task)) {
5738 top = r;
5739 topDescription = r.description;
5740 curTask = r.task;
5741 numActivities = numRunning = 0;
5742 }
5743
5744 // Add 'r' into the current task.
5745 numActivities++;
5746 if (r.app != null && r.app.thread != null) {
5747 numRunning++;
5748 }
5749 if (topDescription == null) {
5750 topDescription = r.description;
5751 }
5752
5753 if (localLOGV) Log.v(
5754 TAG, r.intent.getComponent().flattenToShortString()
5755 + ": task=" + r.task);
5756
5757 // If the next one is a different task, generate a new
5758 // TaskInfo entry for what we have.
5759 if (next == null || next.task != curTask) {
5760 ActivityManager.RunningTaskInfo ci
5761 = new ActivityManager.RunningTaskInfo();
5762 ci.id = curTask.taskId;
5763 ci.baseActivity = r.intent.getComponent();
5764 ci.topActivity = top.intent.getComponent();
5765 ci.thumbnail = top.thumbnail;
5766 ci.description = topDescription;
5767 ci.numActivities = numActivities;
5768 ci.numRunning = numRunning;
5769 //System.out.println(
5770 // "#" + maxNum + ": " + " descr=" + ci.description);
5771 if (ci.thumbnail == null && receiver != null) {
5772 if (localLOGV) Log.v(
5773 TAG, "State=" + top.state + "Idle=" + top.idle
5774 + " app=" + top.app
5775 + " thr=" + (top.app != null ? top.app.thread : null));
5776 if (top.state == ActivityState.RESUMED
5777 || top.state == ActivityState.PAUSING) {
5778 if (top.idle && top.app != null
5779 && top.app.thread != null) {
5780 topRecord = top;
5781 topThumbnail = top.app.thread;
5782 } else {
5783 top.thumbnailNeeded = true;
5784 }
5785 }
5786 if (pending == null) {
5787 pending = new PendingThumbnailsRecord(receiver);
5788 }
5789 pending.pendingRecords.add(top);
5790 }
5791 list.add(ci);
5792 maxNum--;
5793 top = null;
5794 }
5795 }
5796
5797 if (pending != null) {
5798 mPendingThumbnails.add(pending);
5799 }
5800 }
5801
5802 if (localLOGV) Log.v(TAG, "We have pending thumbnails: " + pending);
5803
5804 if (topThumbnail != null) {
5805 if (localLOGV) Log.v(TAG, "Requesting top thumbnail");
5806 try {
5807 topThumbnail.requestThumbnail(topRecord);
5808 } catch (Exception e) {
5809 Log.w(TAG, "Exception thrown when requesting thumbnail", e);
5810 sendPendingThumbnail(null, topRecord, null, null, true);
5811 }
5812 }
5813
5814 if (pending == null && receiver != null) {
5815 // In this case all thumbnails were available and the client
5816 // is being asked to be told when the remaining ones come in...
5817 // which is unusually, since the top-most currently running
5818 // activity should never have a canned thumbnail! Oh well.
5819 try {
5820 receiver.finished();
5821 } catch (RemoteException ex) {
5822 }
5823 }
5824
5825 return list;
5826 }
5827
5828 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5829 int flags) {
5830 synchronized (this) {
5831 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5832 "getRecentTasks()");
5833
5834 final int N = mRecentTasks.size();
5835 ArrayList<ActivityManager.RecentTaskInfo> res
5836 = new ArrayList<ActivityManager.RecentTaskInfo>(
5837 maxNum < N ? maxNum : N);
5838 for (int i=0; i<N && maxNum > 0; i++) {
5839 TaskRecord tr = mRecentTasks.get(i);
5840 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5841 || (tr.intent == null)
5842 || ((tr.intent.getFlags()
5843 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5844 ActivityManager.RecentTaskInfo rti
5845 = new ActivityManager.RecentTaskInfo();
5846 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5847 rti.baseIntent = new Intent(
5848 tr.intent != null ? tr.intent : tr.affinityIntent);
5849 rti.origActivity = tr.origActivity;
5850 res.add(rti);
5851 maxNum--;
5852 }
5853 }
5854 return res;
5855 }
5856 }
5857
5858 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5859 int j;
5860 TaskRecord startTask = ((HistoryRecord)mHistory.get(startIndex)).task;
5861 TaskRecord jt = startTask;
5862
5863 // First look backwards
5864 for (j=startIndex-1; j>=0; j--) {
5865 HistoryRecord r = (HistoryRecord)mHistory.get(j);
5866 if (r.task != jt) {
5867 jt = r.task;
5868 if (affinity.equals(jt.affinity)) {
5869 return j;
5870 }
5871 }
5872 }
5873
5874 // Now look forwards
5875 final int N = mHistory.size();
5876 jt = startTask;
5877 for (j=startIndex+1; j<N; j++) {
5878 HistoryRecord r = (HistoryRecord)mHistory.get(j);
5879 if (r.task != jt) {
5880 if (affinity.equals(jt.affinity)) {
5881 return j;
5882 }
5883 jt = r.task;
5884 }
5885 }
5886
5887 // Might it be at the top?
5888 if (affinity.equals(((HistoryRecord)mHistory.get(N-1)).task.affinity)) {
5889 return N-1;
5890 }
5891
5892 return -1;
5893 }
5894
5895 /**
5896 * Perform a reset of the given task, if needed as part of launching it.
5897 * Returns the new HistoryRecord at the top of the task.
5898 */
5899 private final HistoryRecord resetTaskIfNeededLocked(HistoryRecord taskTop,
5900 HistoryRecord newActivity) {
5901 boolean forceReset = (newActivity.info.flags
5902 &ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0;
5903 if (taskTop.task.getInactiveDuration() > ACTIVITY_INACTIVE_RESET_TIME) {
5904 if ((newActivity.info.flags
5905 &ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE) == 0) {
5906 forceReset = true;
5907 }
5908 }
5909
5910 final TaskRecord task = taskTop.task;
5911
5912 // We are going to move through the history list so that we can look
5913 // at each activity 'target' with 'below' either the interesting
5914 // activity immediately below it in the stack or null.
5915 HistoryRecord target = null;
5916 int targetI = 0;
5917 int taskTopI = -1;
5918 int replyChainEnd = -1;
5919 int lastReparentPos = -1;
5920 for (int i=mHistory.size()-1; i>=-1; i--) {
5921 HistoryRecord below = i >= 0 ? (HistoryRecord)mHistory.get(i) : null;
5922
5923 if (below != null && below.finishing) {
5924 continue;
5925 }
5926 if (target == null) {
5927 target = below;
5928 targetI = i;
5929 // If we were in the middle of a reply chain before this
5930 // task, it doesn't appear like the root of the chain wants
5931 // anything interesting, so drop it.
5932 replyChainEnd = -1;
5933 continue;
5934 }
5935
5936 final int flags = target.info.flags;
5937
5938 final boolean finishOnTaskLaunch =
5939 (flags&ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0;
5940 final boolean allowTaskReparenting =
5941 (flags&ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0;
5942
5943 if (target.task == task) {
5944 // We are inside of the task being reset... we'll either
5945 // finish this activity, push it out for another task,
5946 // or leave it as-is. We only do this
5947 // for activities that are not the root of the task (since
5948 // if we finish the root, we may no longer have the task!).
5949 if (taskTopI < 0) {
5950 taskTopI = targetI;
5951 }
5952 if (below != null && below.task == task) {
5953 final boolean clearWhenTaskReset =
5954 (target.intent.getFlags()
5955 &Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0;
5956 if (!finishOnTaskLaunch && target.resultTo != null) {
5957 // If this activity is sending a reply to a previous
5958 // activity, we can't do anything with it now until
5959 // we reach the start of the reply chain.
5960 // XXX note that we are assuming the result is always
5961 // to the previous activity, which is almost always
5962 // the case but we really shouldn't count on.
5963 if (replyChainEnd < 0) {
5964 replyChainEnd = targetI;
5965 }
5966 } else if (!finishOnTaskLaunch && allowTaskReparenting
5967 && target.taskAffinity != null
5968 && !target.taskAffinity.equals(task.affinity)) {
5969 // If this activity has an affinity for another
5970 // task, then we need to move it out of here. We will
5971 // move it as far out of the way as possible, to the
5972 // bottom of the activity stack. This also keeps it
5973 // correctly ordered with any activities we previously
5974 // moved.
5975 HistoryRecord p = (HistoryRecord)mHistory.get(0);
5976 if (target.taskAffinity != null
5977 && target.taskAffinity.equals(p.task.affinity)) {
5978 // If the activity currently at the bottom has the
5979 // same task affinity as the one we are moving,
5980 // then merge it into the same task.
5981 target.task = p.task;
5982 if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target
5983 + " out to bottom task " + p.task);
5984 } else {
5985 mCurTask++;
5986 if (mCurTask <= 0) {
5987 mCurTask = 1;
5988 }
5989 target.task = new TaskRecord(mCurTask, target.info, null,
5990 (target.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
5991 target.task.affinityIntent = target.intent;
5992 if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target
5993 + " out to new task " + target.task);
5994 }
5995 mWindowManager.setAppGroupId(target, task.taskId);
5996 if (replyChainEnd < 0) {
5997 replyChainEnd = targetI;
5998 }
5999 int dstPos = 0;
6000 for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
6001 p = (HistoryRecord)mHistory.get(srcPos);
6002 if (p.finishing) {
6003 continue;
6004 }
6005 if (DEBUG_TASKS) Log.v(TAG, "Pushing next activity " + p
6006 + " out to target's task " + target.task);
6007 task.numActivities--;
6008 p.task = target.task;
6009 target.task.numActivities++;
6010 mHistory.remove(srcPos);
6011 mHistory.add(dstPos, p);
6012 mWindowManager.moveAppToken(dstPos, p);
6013 mWindowManager.setAppGroupId(p, p.task.taskId);
6014 dstPos++;
6015 if (VALIDATE_TOKENS) {
6016 mWindowManager.validateAppTokens(mHistory);
6017 }
6018 i++;
6019 }
6020 if (taskTop == p) {
6021 taskTop = below;
6022 }
6023 if (taskTopI == replyChainEnd) {
6024 taskTopI = -1;
6025 }
6026 replyChainEnd = -1;
6027 addRecentTask(target.task);
6028 } else if (forceReset || finishOnTaskLaunch
6029 || clearWhenTaskReset) {
6030 // If the activity should just be removed -- either
6031 // because it asks for it, or the task should be
6032 // cleared -- then finish it and anything that is
6033 // part of its reply chain.
6034 if (clearWhenTaskReset) {
6035 // In this case, we want to finish this activity
6036 // and everything above it, so be sneaky and pretend
6037 // like these are all in the reply chain.
6038 replyChainEnd = targetI+1;
6039 while (replyChainEnd < mHistory.size() &&
6040 ((HistoryRecord)mHistory.get(
6041 replyChainEnd)).task == task) {
6042 replyChainEnd++;
6043 }
6044 replyChainEnd--;
6045 } else if (replyChainEnd < 0) {
6046 replyChainEnd = targetI;
6047 }
6048 HistoryRecord p = null;
6049 for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
6050 p = (HistoryRecord)mHistory.get(srcPos);
6051 if (p.finishing) {
6052 continue;
6053 }
6054 if (finishActivityLocked(p, srcPos,
6055 Activity.RESULT_CANCELED, null, "reset")) {
6056 replyChainEnd--;
6057 srcPos--;
6058 }
6059 }
6060 if (taskTop == p) {
6061 taskTop = below;
6062 }
6063 if (taskTopI == replyChainEnd) {
6064 taskTopI = -1;
6065 }
6066 replyChainEnd = -1;
6067 } else {
6068 // If we were in the middle of a chain, well the
6069 // activity that started it all doesn't want anything
6070 // special, so leave it all as-is.
6071 replyChainEnd = -1;
6072 }
6073 } else {
6074 // Reached the bottom of the task -- any reply chain
6075 // should be left as-is.
6076 replyChainEnd = -1;
6077 }
6078
6079 } else if (target.resultTo != null) {
6080 // If this activity is sending a reply to a previous
6081 // activity, we can't do anything with it now until
6082 // we reach the start of the reply chain.
6083 // XXX note that we are assuming the result is always
6084 // to the previous activity, which is almost always
6085 // the case but we really shouldn't count on.
6086 if (replyChainEnd < 0) {
6087 replyChainEnd = targetI;
6088 }
6089
6090 } else if (taskTopI >= 0 && allowTaskReparenting
6091 && task.affinity != null
6092 && task.affinity.equals(target.taskAffinity)) {
6093 // We are inside of another task... if this activity has
6094 // an affinity for our task, then either remove it if we are
6095 // clearing or move it over to our task. Note that
6096 // we currently punt on the case where we are resetting a
6097 // task that is not at the top but who has activities above
6098 // with an affinity to it... this is really not a normal
6099 // case, and we will need to later pull that task to the front
6100 // and usually at that point we will do the reset and pick
6101 // up those remaining activities. (This only happens if
6102 // someone starts an activity in a new task from an activity
6103 // in a task that is not currently on top.)
6104 if (forceReset || finishOnTaskLaunch) {
6105 if (replyChainEnd < 0) {
6106 replyChainEnd = targetI;
6107 }
6108 HistoryRecord p = null;
6109 for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
6110 p = (HistoryRecord)mHistory.get(srcPos);
6111 if (p.finishing) {
6112 continue;
6113 }
6114 if (finishActivityLocked(p, srcPos,
6115 Activity.RESULT_CANCELED, null, "reset")) {
6116 taskTopI--;
6117 lastReparentPos--;
6118 replyChainEnd--;
6119 srcPos--;
6120 }
6121 }
6122 replyChainEnd = -1;
6123 } else {
6124 if (replyChainEnd < 0) {
6125 replyChainEnd = targetI;
6126 }
6127 for (int srcPos=replyChainEnd; srcPos>=targetI; srcPos--) {
6128 HistoryRecord p = (HistoryRecord)mHistory.get(srcPos);
6129 if (p.finishing) {
6130 continue;
6131 }
6132 if (lastReparentPos < 0) {
6133 lastReparentPos = taskTopI;
6134 taskTop = p;
6135 } else {
6136 lastReparentPos--;
6137 }
6138 mHistory.remove(srcPos);
6139 p.task.numActivities--;
6140 p.task = task;
6141 mHistory.add(lastReparentPos, p);
6142 if (DEBUG_TASKS) Log.v(TAG, "Pulling activity " + p
6143 + " in to resetting task " + task);
6144 task.numActivities++;
6145 mWindowManager.moveAppToken(lastReparentPos, p);
6146 mWindowManager.setAppGroupId(p, p.task.taskId);
6147 if (VALIDATE_TOKENS) {
6148 mWindowManager.validateAppTokens(mHistory);
6149 }
6150 }
6151 replyChainEnd = -1;
6152
6153 // Now we've moved it in to place... but what if this is
6154 // a singleTop activity and we have put it on top of another
6155 // instance of the same activity? Then we drop the instance
6156 // below so it remains singleTop.
6157 if (target.info.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
6158 for (int j=lastReparentPos-1; j>=0; j--) {
6159 HistoryRecord p = (HistoryRecord)mHistory.get(j);
6160 if (p.finishing) {
6161 continue;
6162 }
6163 if (p.intent.getComponent().equals(target.intent.getComponent())) {
6164 if (finishActivityLocked(p, j,
6165 Activity.RESULT_CANCELED, null, "replace")) {
6166 taskTopI--;
6167 lastReparentPos--;
6168 }
6169 }
6170 }
6171 }
6172 }
6173 }
6174
6175 target = below;
6176 targetI = i;
6177 }
6178
6179 return taskTop;
6180 }
6181
6182 /**
6183 * TODO: Add mWatcher hook
6184 */
6185 public void moveTaskToFront(int task) {
6186 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6187 "moveTaskToFront()");
6188
6189 synchronized(this) {
6190 final long origId = Binder.clearCallingIdentity();
6191 try {
6192 int N = mRecentTasks.size();
6193 for (int i=0; i<N; i++) {
6194 TaskRecord tr = mRecentTasks.get(i);
6195 if (tr.taskId == task) {
6196 moveTaskToFrontLocked(tr);
6197 return;
6198 }
6199 }
6200 for (int i=mHistory.size()-1; i>=0; i--) {
6201 HistoryRecord hr = (HistoryRecord)mHistory.get(i);
6202 if (hr.task.taskId == task) {
6203 moveTaskToFrontLocked(hr.task);
6204 return;
6205 }
6206 }
6207 } finally {
6208 Binder.restoreCallingIdentity(origId);
6209 }
6210 }
6211 }
6212
6213 private final void moveTaskToFrontLocked(TaskRecord tr) {
6214 if (DEBUG_SWITCH) Log.v(TAG, "moveTaskToFront: " + tr);
6215
6216 final int task = tr.taskId;
6217 int top = mHistory.size()-1;
6218
6219 if (top < 0 || ((HistoryRecord)mHistory.get(top)).task.taskId == task) {
6220 // nothing to do!
6221 return;
6222 }
6223
6224 if (DEBUG_TRANSITION) Log.v(TAG,
6225 "Prepare to front transition: task=" + tr);
6226 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT);
6227
6228 ArrayList moved = new ArrayList();
6229
6230 // Applying the affinities may have removed entries from the history,
6231 // so get the size again.
6232 top = mHistory.size()-1;
6233 int pos = top;
6234
6235 // Shift all activities with this task up to the top
6236 // of the stack, keeping them in the same internal order.
6237 while (pos >= 0) {
6238 HistoryRecord r = (HistoryRecord)mHistory.get(pos);
6239 if (localLOGV) Log.v(
6240 TAG, "At " + pos + " ckp " + r.task + ": " + r);
6241 boolean first = true;
6242 if (r.task.taskId == task) {
6243 if (localLOGV) Log.v(TAG, "Removing and adding at " + top);
6244 mHistory.remove(pos);
6245 mHistory.add(top, r);
6246 moved.add(0, r);
6247 top--;
6248 if (first) {
6249 addRecentTask(r.task);
6250 first = false;
6251 }
6252 }
6253 pos--;
6254 }
6255
6256 mWindowManager.moveAppTokensToTop(moved);
6257 if (VALIDATE_TOKENS) {
6258 mWindowManager.validateAppTokens(mHistory);
6259 }
6260
6261 finishTaskMove(task);
6262 EventLog.writeEvent(LOG_TASK_TO_FRONT, task);
6263 }
6264
6265 private final void finishTaskMove(int task) {
6266 resumeTopActivityLocked(null);
6267 }
6268
6269 public void moveTaskToBack(int task) {
6270 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6271 "moveTaskToBack()");
6272
6273 synchronized(this) {
6274 final long origId = Binder.clearCallingIdentity();
6275 moveTaskToBackLocked(task);
6276 Binder.restoreCallingIdentity(origId);
6277 }
6278 }
6279
6280 /**
6281 * Moves an activity, and all of the other activities within the same task, to the bottom
6282 * of the history stack. The activity's order within the task is unchanged.
6283 *
6284 * @param token A reference to the activity we wish to move
6285 * @param nonRoot If false then this only works if the activity is the root
6286 * of a task; if true it will work for any activity in a task.
6287 * @return Returns true if the move completed, false if not.
6288 */
6289 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
6290 synchronized(this) {
6291 final long origId = Binder.clearCallingIdentity();
6292 int taskId = getTaskForActivityLocked(token, !nonRoot);
6293 if (taskId >= 0) {
6294 return moveTaskToBackLocked(taskId);
6295 }
6296 Binder.restoreCallingIdentity(origId);
6297 }
6298 return false;
6299 }
6300
6301 /**
6302 * Worker method for rearranging history stack. Implements the function of moving all
6303 * activities for a specific task (gathering them if disjoint) into a single group at the
6304 * bottom of the stack.
6305 *
6306 * If a watcher is installed, the action is preflighted and the watcher has an opportunity
6307 * to premeptively cancel the move.
6308 *
6309 * @param task The taskId to collect and move to the bottom.
6310 * @return Returns true if the move completed, false if not.
6311 */
6312 private final boolean moveTaskToBackLocked(int task) {
6313 Log.i(TAG, "moveTaskToBack: " + task);
6314
6315 // If we have a watcher, preflight the move before committing to it. First check
6316 // for *other* available tasks, but if none are available, then try again allowing the
6317 // current task to be selected.
6318 if (mWatcher != null) {
6319 HistoryRecord next = topRunningActivityLocked(null, task);
6320 if (next == null) {
6321 next = topRunningActivityLocked(null, 0);
6322 }
6323 if (next != null) {
6324 // ask watcher if this is allowed
6325 boolean moveOK = true;
6326 try {
6327 moveOK = mWatcher.activityResuming(next.packageName);
6328 } catch (RemoteException e) {
6329 mWatcher = null;
6330 }
6331 if (!moveOK) {
6332 return false;
6333 }
6334 }
6335 }
6336
6337 ArrayList moved = new ArrayList();
6338
6339 if (DEBUG_TRANSITION) Log.v(TAG,
6340 "Prepare to back transition: task=" + task);
6341 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_BACK);
6342
6343 final int N = mHistory.size();
6344 int bottom = 0;
6345 int pos = 0;
6346
6347 // Shift all activities with this task down to the bottom
6348 // of the stack, keeping them in the same internal order.
6349 while (pos < N) {
6350 HistoryRecord r = (HistoryRecord)mHistory.get(pos);
6351 if (localLOGV) Log.v(
6352 TAG, "At " + pos + " ckp " + r.task + ": " + r);
6353 if (r.task.taskId == task) {
6354 if (localLOGV) Log.v(TAG, "Removing and adding at " + (N-1));
6355 mHistory.remove(pos);
6356 mHistory.add(bottom, r);
6357 moved.add(r);
6358 bottom++;
6359 }
6360 pos++;
6361 }
6362
6363 mWindowManager.moveAppTokensToBottom(moved);
6364 if (VALIDATE_TOKENS) {
6365 mWindowManager.validateAppTokens(mHistory);
6366 }
6367
6368 finishTaskMove(task);
6369 return true;
6370 }
6371
6372 public void moveTaskBackwards(int task) {
6373 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6374 "moveTaskBackwards()");
6375
6376 synchronized(this) {
6377 final long origId = Binder.clearCallingIdentity();
6378 moveTaskBackwardsLocked(task);
6379 Binder.restoreCallingIdentity(origId);
6380 }
6381 }
6382
6383 private final void moveTaskBackwardsLocked(int task) {
6384 Log.e(TAG, "moveTaskBackwards not yet implemented!");
6385 }
6386
6387 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6388 synchronized(this) {
6389 return getTaskForActivityLocked(token, onlyRoot);
6390 }
6391 }
6392
6393 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
6394 final int N = mHistory.size();
6395 TaskRecord lastTask = null;
6396 for (int i=0; i<N; i++) {
6397 HistoryRecord r = (HistoryRecord)mHistory.get(i);
6398 if (r == token) {
6399 if (!onlyRoot || lastTask != r.task) {
6400 return r.task.taskId;
6401 }
6402 return -1;
6403 }
6404 lastTask = r.task;
6405 }
6406
6407 return -1;
6408 }
6409
6410 /**
6411 * Returns the top activity in any existing task matching the given
6412 * Intent. Returns null if no such task is found.
6413 */
6414 private HistoryRecord findTaskLocked(Intent intent, ActivityInfo info) {
6415 ComponentName cls = intent.getComponent();
6416 if (info.targetActivity != null) {
6417 cls = new ComponentName(info.packageName, info.targetActivity);
6418 }
6419
6420 TaskRecord cp = null;
6421
6422 final int N = mHistory.size();
6423 for (int i=(N-1); i>=0; i--) {
6424 HistoryRecord r = (HistoryRecord)mHistory.get(i);
6425 if (!r.finishing && r.task != cp
6426 && r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
6427 cp = r.task;
6428 //Log.i(TAG, "Comparing existing cls=" + r.task.intent.getComponent().flattenToShortString()
6429 // + "/aff=" + r.task.affinity + " to new cls="
6430 // + intent.getComponent().flattenToShortString() + "/aff=" + taskAffinity);
6431 if (r.task.affinity != null) {
6432 if (r.task.affinity.equals(info.taskAffinity)) {
6433 //Log.i(TAG, "Found matching affinity!");
6434 return r;
6435 }
6436 } else if (r.task.intent != null
6437 && r.task.intent.getComponent().equals(cls)) {
6438 //Log.i(TAG, "Found matching class!");
6439 //dump();
6440 //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
6441 return r;
6442 } else if (r.task.affinityIntent != null
6443 && r.task.affinityIntent.getComponent().equals(cls)) {
6444 //Log.i(TAG, "Found matching class!");
6445 //dump();
6446 //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
6447 return r;
6448 }
6449 }
6450 }
6451
6452 return null;
6453 }
6454
6455 /**
6456 * Returns the first activity (starting from the top of the stack) that
6457 * is the same as the given activity. Returns null if no such activity
6458 * is found.
6459 */
6460 private HistoryRecord findActivityLocked(Intent intent, ActivityInfo info) {
6461 ComponentName cls = intent.getComponent();
6462 if (info.targetActivity != null) {
6463 cls = new ComponentName(info.packageName, info.targetActivity);
6464 }
6465
6466 final int N = mHistory.size();
6467 for (int i=(N-1); i>=0; i--) {
6468 HistoryRecord r = (HistoryRecord)mHistory.get(i);
6469 if (!r.finishing) {
6470 if (r.intent.getComponent().equals(cls)) {
6471 //Log.i(TAG, "Found matching class!");
6472 //dump();
6473 //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
6474 return r;
6475 }
6476 }
6477 }
6478
6479 return null;
6480 }
6481
6482 public void finishOtherInstances(IBinder token, ComponentName className) {
6483 synchronized(this) {
6484 final long origId = Binder.clearCallingIdentity();
6485
6486 int N = mHistory.size();
6487 TaskRecord lastTask = null;
6488 for (int i=0; i<N; i++) {
6489 HistoryRecord r = (HistoryRecord)mHistory.get(i);
6490 if (r.realActivity.equals(className)
6491 && r != token && lastTask != r.task) {
6492 if (finishActivityLocked(r, i, Activity.RESULT_CANCELED,
6493 null, "others")) {
6494 i--;
6495 N--;
6496 }
6497 }
6498 lastTask = r.task;
6499 }
6500
6501 Binder.restoreCallingIdentity(origId);
6502 }
6503 }
6504
6505 // =========================================================
6506 // THUMBNAILS
6507 // =========================================================
6508
6509 public void reportThumbnail(IBinder token,
6510 Bitmap thumbnail, CharSequence description) {
6511 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6512 final long origId = Binder.clearCallingIdentity();
6513 sendPendingThumbnail(null, token, thumbnail, description, true);
6514 Binder.restoreCallingIdentity(origId);
6515 }
6516
6517 final void sendPendingThumbnail(HistoryRecord r, IBinder token,
6518 Bitmap thumbnail, CharSequence description, boolean always) {
6519 TaskRecord task = null;
6520 ArrayList receivers = null;
6521
6522 //System.out.println("Send pending thumbnail: " + r);
6523
6524 synchronized(this) {
6525 if (r == null) {
6526 int index = indexOfTokenLocked(token, false);
6527 if (index < 0) {
6528 return;
6529 }
6530 r = (HistoryRecord)mHistory.get(index);
6531 }
6532 if (thumbnail == null) {
6533 thumbnail = r.thumbnail;
6534 description = r.description;
6535 }
6536 if (thumbnail == null && !always) {
6537 // If there is no thumbnail, and this entry is not actually
6538 // going away, then abort for now and pick up the next
6539 // thumbnail we get.
6540 return;
6541 }
6542 task = r.task;
6543
6544 int N = mPendingThumbnails.size();
6545 int i=0;
6546 while (i<N) {
6547 PendingThumbnailsRecord pr =
6548 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6549 //System.out.println("Looking in " + pr.pendingRecords);
6550 if (pr.pendingRecords.remove(r)) {
6551 if (receivers == null) {
6552 receivers = new ArrayList();
6553 }
6554 receivers.add(pr);
6555 if (pr.pendingRecords.size() == 0) {
6556 pr.finished = true;
6557 mPendingThumbnails.remove(i);
6558 N--;
6559 continue;
6560 }
6561 }
6562 i++;
6563 }
6564 }
6565
6566 if (receivers != null) {
6567 final int N = receivers.size();
6568 for (int i=0; i<N; i++) {
6569 try {
6570 PendingThumbnailsRecord pr =
6571 (PendingThumbnailsRecord)receivers.get(i);
6572 pr.receiver.newThumbnail(
6573 task != null ? task.taskId : -1, thumbnail, description);
6574 if (pr.finished) {
6575 pr.receiver.finished();
6576 }
6577 } catch (Exception e) {
6578 Log.w(TAG, "Exception thrown when sending thumbnail", e);
6579 }
6580 }
6581 }
6582 }
6583
6584 // =========================================================
6585 // CONTENT PROVIDERS
6586 // =========================================================
6587
6588 private final List generateApplicationProvidersLocked(ProcessRecord app) {
6589 List providers = null;
6590 try {
6591 providers = ActivityThread.getPackageManager().
6592 queryContentProviders(app.processName, app.info.uid,
6593 PackageManager.GET_SHARED_LIBRARY_FILES
6594 | PackageManager.GET_URI_PERMISSION_PATTERNS);
6595 } catch (RemoteException ex) {
6596 }
6597 if (providers != null) {
6598 final int N = providers.size();
6599 for (int i=0; i<N; i++) {
6600 ProviderInfo cpi =
6601 (ProviderInfo)providers.get(i);
6602 ContentProviderRecord cpr =
6603 (ContentProviderRecord)mProvidersByClass.get(cpi.name);
6604 if (cpr == null) {
6605 cpr = new ContentProviderRecord(cpi, app.info);
6606 mProvidersByClass.put(cpi.name, cpr);
6607 }
6608 app.pubProviders.put(cpi.name, cpr);
6609 app.addPackage(cpi.applicationInfo.packageName);
6610 }
6611 }
6612 return providers;
6613 }
6614
6615 private final String checkContentProviderPermissionLocked(
6616 ProviderInfo cpi, ProcessRecord r, int mode) {
6617 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6618 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
6619 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6620 cpi.exported ? -1 : cpi.applicationInfo.uid)
6621 == PackageManager.PERMISSION_GRANTED
6622 && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) {
6623 return null;
6624 }
6625 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6626 cpi.exported ? -1 : cpi.applicationInfo.uid)
6627 == PackageManager.PERMISSION_GRANTED) {
6628 return null;
6629 }
6630 String msg = "Permission Denial: opening provider " + cpi.name
6631 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6632 + ", uid=" + callingUid + ") requires "
6633 + cpi.readPermission + " or " + cpi.writePermission;
6634 Log.w(TAG, msg);
6635 return msg;
6636 }
6637
6638 private final ContentProviderHolder getContentProviderImpl(
6639 IApplicationThread caller, String name) {
6640 ContentProviderRecord cpr;
6641 ProviderInfo cpi = null;
6642
6643 synchronized(this) {
6644 ProcessRecord r = null;
6645 if (caller != null) {
6646 r = getRecordForAppLocked(caller);
6647 if (r == null) {
6648 throw new SecurityException(
6649 "Unable to find app for caller " + caller
6650 + " (pid=" + Binder.getCallingPid()
6651 + ") when getting content provider " + name);
6652 }
6653 }
6654
6655 // First check if this content provider has been published...
6656 cpr = (ContentProviderRecord)mProvidersByName.get(name);
6657 if (cpr != null) {
6658 cpi = cpr.info;
6659 if (checkContentProviderPermissionLocked(cpi, r, -1) != null) {
6660 return new ContentProviderHolder(cpi,
6661 cpi.readPermission != null
6662 ? cpi.readPermission : cpi.writePermission);
6663 }
6664
6665 if (r != null && cpr.canRunHere(r)) {
6666 // This provider has been published or is in the process
6667 // of being published... but it is also allowed to run
6668 // in the caller's process, so don't make a connection
6669 // and just let the caller instantiate its own instance.
6670 if (cpr.provider != null) {
6671 // don't give caller the provider object, it needs
6672 // to make its own.
6673 cpr = new ContentProviderRecord(cpr);
6674 }
6675 return cpr;
6676 }
6677
6678 final long origId = Binder.clearCallingIdentity();
6679
6680 // In this case the provider is a single instance, so we can
6681 // return it right away.
6682 if (r != null) {
6683 r.conProviders.add(cpr);
6684 cpr.clients.add(r);
6685 } else {
6686 cpr.externals++;
6687 }
6688
6689 if (cpr.app != null) {
6690 updateOomAdjLocked(cpr.app);
6691 }
6692
6693 Binder.restoreCallingIdentity(origId);
6694
6695 } else {
6696 try {
6697 cpi = ActivityThread.getPackageManager().
6698 resolveContentProvider(name, PackageManager.GET_URI_PERMISSION_PATTERNS);
6699 } catch (RemoteException ex) {
6700 }
6701 if (cpi == null) {
6702 return null;
6703 }
6704
6705 if (checkContentProviderPermissionLocked(cpi, r, -1) != null) {
6706 return new ContentProviderHolder(cpi,
6707 cpi.readPermission != null
6708 ? cpi.readPermission : cpi.writePermission);
6709 }
6710
6711 cpr = (ContentProviderRecord)mProvidersByClass.get(cpi.name);
6712 final boolean firstClass = cpr == null;
6713 if (firstClass) {
6714 try {
6715 ApplicationInfo ai =
6716 ActivityThread.getPackageManager().
6717 getApplicationInfo(
6718 cpi.applicationInfo.packageName,
6719 PackageManager.GET_SHARED_LIBRARY_FILES);
6720 if (ai == null) {
6721 Log.w(TAG, "No package info for content provider "
6722 + cpi.name);
6723 return null;
6724 }
6725 cpr = new ContentProviderRecord(cpi, ai);
6726 } catch (RemoteException ex) {
6727 // pm is in same process, this will never happen.
6728 }
6729 }
6730
6731 if (r != null && cpr.canRunHere(r)) {
6732 // If this is a multiprocess provider, then just return its
6733 // info and allow the caller to instantiate it. Only do
6734 // this if the provider is the same user as the caller's
6735 // process, or can run as root (so can be in any process).
6736 return cpr;
6737 }
6738
6739 if (false) {
6740 RuntimeException e = new RuntimeException("foo");
6741 //Log.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
6742 // + " pruid " + ai.uid + "): " + cpi.className, e);
6743 }
6744
6745 // This is single process, and our app is now connecting to it.
6746 // See if we are already in the process of launching this
6747 // provider.
6748 final int N = mLaunchingProviders.size();
6749 int i;
6750 for (i=0; i<N; i++) {
6751 if (mLaunchingProviders.get(i) == cpr) {
6752 break;
6753 }
6754 if (false) {
6755 final ContentProviderRecord rec =
6756 (ContentProviderRecord)mLaunchingProviders.get(i);
6757 if (rec.info.name.equals(cpr.info.name)) {
6758 cpr = rec;
6759 break;
6760 }
6761 }
6762 }
6763
6764 // If the provider is not already being launched, then get it
6765 // started.
6766 if (i >= N) {
6767 final long origId = Binder.clearCallingIdentity();
6768 ProcessRecord proc = startProcessLocked(cpi.processName,
6769 cpr.appInfo, false, 0, "content provider",
6770 new ComponentName(cpi.applicationInfo.packageName,
6771 cpi.name));
6772 if (proc == null) {
6773 Log.w(TAG, "Unable to launch app "
6774 + cpi.applicationInfo.packageName + "/"
6775 + cpi.applicationInfo.uid + " for provider "
6776 + name + ": process is bad");
6777 return null;
6778 }
6779 cpr.launchingApp = proc;
6780 mLaunchingProviders.add(cpr);
6781 Binder.restoreCallingIdentity(origId);
6782 }
6783
6784 // Make sure the provider is published (the same provider class
6785 // may be published under multiple names).
6786 if (firstClass) {
6787 mProvidersByClass.put(cpi.name, cpr);
6788 }
6789 mProvidersByName.put(name, cpr);
6790
6791 if (r != null) {
6792 r.conProviders.add(cpr);
6793 cpr.clients.add(r);
6794 } else {
6795 cpr.externals++;
6796 }
6797 }
6798 }
6799
6800 // Wait for the provider to be published...
6801 synchronized (cpr) {
6802 while (cpr.provider == null) {
6803 if (cpr.launchingApp == null) {
6804 Log.w(TAG, "Unable to launch app "
6805 + cpi.applicationInfo.packageName + "/"
6806 + cpi.applicationInfo.uid + " for provider "
6807 + name + ": launching app became null");
6808 EventLog.writeEvent(LOG_AM_PROVIDER_LOST_PROCESS,
6809 cpi.applicationInfo.packageName,
6810 cpi.applicationInfo.uid, name);
6811 return null;
6812 }
6813 try {
6814 cpr.wait();
6815 } catch (InterruptedException ex) {
6816 }
6817 }
6818 }
6819 return cpr;
6820 }
6821
6822 public final ContentProviderHolder getContentProvider(
6823 IApplicationThread caller, String name) {
6824 if (caller == null) {
6825 String msg = "null IApplicationThread when getting content provider "
6826 + name;
6827 Log.w(TAG, msg);
6828 throw new SecurityException(msg);
6829 }
6830
6831 return getContentProviderImpl(caller, name);
6832 }
6833
6834 private ContentProviderHolder getContentProviderExternal(String name) {
6835 return getContentProviderImpl(null, name);
6836 }
6837
6838 /**
6839 * Drop a content provider from a ProcessRecord's bookkeeping
6840 * @param cpr
6841 */
6842 public void removeContentProvider(IApplicationThread caller, String name) {
6843 synchronized (this) {
6844 ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name);
6845 if(cpr == null) {
6846 //remove from mProvidersByClass
6847 if(localLOGV) Log.v(TAG, name+" content provider not found in providers list");
6848 return;
6849 }
6850 final ProcessRecord r = getRecordForAppLocked(caller);
6851 if (r == null) {
6852 throw new SecurityException(
6853 "Unable to find app for caller " + caller +
6854 " when removing content provider " + name);
6855 }
6856 //update content provider record entry info
6857 ContentProviderRecord localCpr = (ContentProviderRecord) mProvidersByClass.get(cpr.info.name);
6858 if(localLOGV) Log.v(TAG, "Removing content provider requested by "+
6859 r.info.processName+" from process "+localCpr.appInfo.processName);
6860 if(localCpr.appInfo.processName == r.info.processName) {
6861 //should not happen. taken care of as a local provider
6862 if(localLOGV) Log.v(TAG, "local provider doing nothing Ignoring other names");
6863 return;
6864 } else {
6865 localCpr.clients.remove(r);
6866 r.conProviders.remove(localCpr);
6867 }
6868 updateOomAdjLocked();
6869 }
6870 }
6871
6872 private void removeContentProviderExternal(String name) {
6873 synchronized (this) {
6874 ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name);
6875 if(cpr == null) {
6876 //remove from mProvidersByClass
6877 if(localLOGV) Log.v(TAG, name+" content provider not found in providers list");
6878 return;
6879 }
6880
6881 //update content provider record entry info
6882 ContentProviderRecord localCpr = (ContentProviderRecord) mProvidersByClass.get(cpr.info.name);
6883 localCpr.externals--;
6884 if (localCpr.externals < 0) {
6885 Log.e(TAG, "Externals < 0 for content provider " + localCpr);
6886 }
6887 updateOomAdjLocked();
6888 }
6889 }
6890
6891 public final void publishContentProviders(IApplicationThread caller,
6892 List<ContentProviderHolder> providers) {
6893 if (providers == null) {
6894 return;
6895 }
6896
6897 synchronized(this) {
6898 final ProcessRecord r = getRecordForAppLocked(caller);
6899 if (r == null) {
6900 throw new SecurityException(
6901 "Unable to find app for caller " + caller
6902 + " (pid=" + Binder.getCallingPid()
6903 + ") when publishing content providers");
6904 }
6905
6906 final long origId = Binder.clearCallingIdentity();
6907
6908 final int N = providers.size();
6909 for (int i=0; i<N; i++) {
6910 ContentProviderHolder src = providers.get(i);
6911 if (src == null || src.info == null || src.provider == null) {
6912 continue;
6913 }
6914 ContentProviderRecord dst =
6915 (ContentProviderRecord)r.pubProviders.get(src.info.name);
6916 if (dst != null) {
6917 mProvidersByClass.put(dst.info.name, dst);
6918 String names[] = dst.info.authority.split(";");
6919 for (int j = 0; j < names.length; j++) {
6920 mProvidersByName.put(names[j], dst);
6921 }
6922
6923 int NL = mLaunchingProviders.size();
6924 int j;
6925 for (j=0; j<NL; j++) {
6926 if (mLaunchingProviders.get(j) == dst) {
6927 mLaunchingProviders.remove(j);
6928 j--;
6929 NL--;
6930 }
6931 }
6932 synchronized (dst) {
6933 dst.provider = src.provider;
6934 dst.app = r;
6935 dst.notifyAll();
6936 }
6937 updateOomAdjLocked(r);
6938 }
6939 }
6940
6941 Binder.restoreCallingIdentity(origId);
6942 }
6943 }
6944
6945 public static final void installSystemProviders() {
6946 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6947 List providers = mSelf.generateApplicationProvidersLocked(app);
6948 mSystemThread.installSystemProviders(providers);
6949 }
6950
6951 // =========================================================
6952 // GLOBAL MANAGEMENT
6953 // =========================================================
6954
6955 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6956 ApplicationInfo info, String customProcess) {
6957 String proc = customProcess != null ? customProcess : info.processName;
6958 BatteryStatsImpl.Uid.Proc ps = null;
6959 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6960 synchronized (stats) {
6961 ps = stats.getProcessStatsLocked(info.uid, proc);
6962 }
6963 return new ProcessRecord(ps, thread, info, proc);
6964 }
6965
6966 final ProcessRecord addAppLocked(ApplicationInfo info) {
6967 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
6968
6969 if (app == null) {
6970 app = newProcessRecordLocked(null, info, null);
6971 mProcessNames.put(info.processName, info.uid, app);
6972 updateLRUListLocked(app, true);
6973 }
6974
6975 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6976 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6977 app.persistent = true;
6978 app.maxAdj = CORE_SERVER_ADJ;
6979 }
6980 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6981 mPersistentStartingProcesses.add(app);
6982 startProcessLocked(app, "added application", app.processName);
6983 }
6984
6985 return app;
6986 }
6987
6988 public void unhandledBack() {
6989 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6990 "unhandledBack()");
6991
6992 synchronized(this) {
6993 int count = mHistory.size();
6994 if (Config.LOGD) Log.d(
6995 TAG, "Performing unhandledBack(): stack size = " + count);
6996 if (count > 1) {
6997 final long origId = Binder.clearCallingIdentity();
6998 finishActivityLocked((HistoryRecord)mHistory.get(count-1),
6999 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
7000 Binder.restoreCallingIdentity(origId);
7001 }
7002 }
7003 }
7004
7005 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
7006 String name = uri.getAuthority();
7007 ContentProviderHolder cph = getContentProviderExternal(name);
7008 ParcelFileDescriptor pfd = null;
7009 if (cph != null) {
7010 // We record the binder invoker's uid in thread-local storage before
7011 // going to the content provider to open the file. Later, in the code
7012 // that handles all permissions checks, we look for this uid and use
7013 // that rather than the Activity Manager's own uid. The effect is that
7014 // we do the check against the caller's permissions even though it looks
7015 // to the content provider like the Activity Manager itself is making
7016 // the request.
7017 sCallerIdentity.set(new Identity(
7018 Binder.getCallingPid(), Binder.getCallingUid()));
7019 try {
7020 pfd = cph.provider.openFile(uri, "r");
7021 } catch (FileNotFoundException e) {
7022 // do nothing; pfd will be returned null
7023 } finally {
7024 // Ensure that whatever happens, we clean up the identity state
7025 sCallerIdentity.remove();
7026 }
7027
7028 // We've got the fd now, so we're done with the provider.
7029 removeContentProviderExternal(name);
7030 } else {
7031 Log.d(TAG, "Failed to get provider for authority '" + name + "'");
7032 }
7033 return pfd;
7034 }
7035
7036 public void goingToSleep() {
7037 synchronized(this) {
7038 mSleeping = true;
7039 mWindowManager.setEventDispatching(false);
7040
7041 if (mResumedActivity != null) {
7042 pauseIfSleepingLocked();
7043 } else {
7044 Log.w(TAG, "goingToSleep with no resumed activity!");
7045 }
7046 }
7047 }
7048
7049 void pauseIfSleepingLocked() {
7050 if (mSleeping) {
7051 if (!mGoingToSleep.isHeld()) {
7052 mGoingToSleep.acquire();
7053 if (mLaunchingActivity.isHeld()) {
7054 mLaunchingActivity.release();
7055 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
7056 }
7057 }
7058
7059 // If we are not currently pausing an activity, get the current
7060 // one to pause. If we are pausing one, we will just let that stuff
7061 // run and release the wake lock when all done.
7062 if (mPausingActivity == null) {
7063 if (DEBUG_PAUSE) Log.v(TAG, "Sleep needs to pause...");
7064 if (DEBUG_USER_LEAVING) Log.v(TAG, "Sleep => pause with userLeaving=false");
7065 startPausingLocked(false, true);
7066 }
7067 }
7068 }
7069
7070 public void wakingUp() {
7071 synchronized(this) {
7072 if (mGoingToSleep.isHeld()) {
7073 mGoingToSleep.release();
7074 }
7075 mWindowManager.setEventDispatching(true);
7076 mSleeping = false;
7077 resumeTopActivityLocked(null);
7078 }
7079 }
7080
7081 public void setDebugApp(String packageName, boolean waitForDebugger,
7082 boolean persistent) {
7083 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7084 "setDebugApp()");
7085
7086 // Note that this is not really thread safe if there are multiple
7087 // callers into it at the same time, but that's not a situation we
7088 // care about.
7089 if (persistent) {
7090 final ContentResolver resolver = mContext.getContentResolver();
7091 Settings.System.putString(
7092 resolver, Settings.System.DEBUG_APP,
7093 packageName);
7094 Settings.System.putInt(
7095 resolver, Settings.System.WAIT_FOR_DEBUGGER,
7096 waitForDebugger ? 1 : 0);
7097 }
7098
7099 synchronized (this) {
7100 if (!persistent) {
7101 mOrigDebugApp = mDebugApp;
7102 mOrigWaitForDebugger = mWaitForDebugger;
7103 }
7104 mDebugApp = packageName;
7105 mWaitForDebugger = waitForDebugger;
7106 mDebugTransient = !persistent;
7107 if (packageName != null) {
7108 final long origId = Binder.clearCallingIdentity();
7109 uninstallPackageLocked(packageName, -1, false);
7110 Binder.restoreCallingIdentity(origId);
7111 }
7112 }
7113 }
7114
7115 public void setAlwaysFinish(boolean enabled) {
7116 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7117 "setAlwaysFinish()");
7118
7119 Settings.System.putInt(
7120 mContext.getContentResolver(),
7121 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7122
7123 synchronized (this) {
7124 mAlwaysFinishActivities = enabled;
7125 }
7126 }
7127
7128 public void setActivityWatcher(IActivityWatcher watcher) {
7129 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7130 "setActivityWatcher()");
7131 synchronized (this) {
7132 mWatcher = watcher;
7133 }
7134 }
7135
7136 public final void enterSafeMode() {
7137 synchronized(this) {
7138 // It only makes sense to do this before the system is ready
7139 // and started launching other packages.
7140 if (!mSystemReady) {
7141 try {
7142 ActivityThread.getPackageManager().enterSafeMode();
7143 } catch (RemoteException e) {
7144 }
7145
7146 View v = LayoutInflater.from(mContext).inflate(
7147 com.android.internal.R.layout.safe_mode, null);
7148 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7149 lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
7150 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7151 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7152 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
7153 lp.format = v.getBackground().getOpacity();
7154 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7155 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7156 ((WindowManager)mContext.getSystemService(
7157 Context.WINDOW_SERVICE)).addView(v, lp);
7158 }
7159 }
7160 }
7161
7162 public void noteWakeupAlarm(IIntentSender sender) {
7163 if (!(sender instanceof PendingIntentRecord)) {
7164 return;
7165 }
7166 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7167 synchronized (stats) {
7168 if (mBatteryStatsService.isOnBattery()) {
7169 mBatteryStatsService.enforceCallingPermission();
7170 PendingIntentRecord rec = (PendingIntentRecord)sender;
7171 int MY_UID = Binder.getCallingUid();
7172 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7173 BatteryStatsImpl.Uid.Pkg pkg =
7174 stats.getPackageStatsLocked(uid, rec.key.packageName);
7175 pkg.incWakeupsLocked();
7176 }
7177 }
7178 }
7179
7180 public boolean killPidsForMemory(int[] pids) {
7181 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7182 throw new SecurityException("killPidsForMemory only available to the system");
7183 }
7184
7185 // XXX Note: don't acquire main activity lock here, because the window
7186 // manager calls in with its locks held.
7187
7188 boolean killed = false;
7189 synchronized (mPidsSelfLocked) {
7190 int[] types = new int[pids.length];
7191 int worstType = 0;
7192 for (int i=0; i<pids.length; i++) {
7193 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7194 if (proc != null) {
7195 int type = proc.setAdj;
7196 types[i] = type;
7197 if (type > worstType) {
7198 worstType = type;
7199 }
7200 }
7201 }
7202
7203 // If the worse oom_adj is somewhere in the hidden proc LRU range,
7204 // then constrain it so we will kill all hidden procs.
7205 if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
7206 worstType = HIDDEN_APP_MIN_ADJ;
7207 }
7208 Log.w(TAG, "Killing processes for memory at adjustment " + worstType);
7209 for (int i=0; i<pids.length; i++) {
7210 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7211 if (proc == null) {
7212 continue;
7213 }
7214 int adj = proc.setAdj;
7215 if (adj >= worstType) {
7216 Log.w(TAG, "Killing for memory: " + proc + " (adj "
7217 + adj + ")");
7218 EventLog.writeEvent(LOG_AM_KILL_FOR_MEMORY, proc.pid,
7219 proc.processName, adj);
7220 killed = true;
7221 Process.killProcess(pids[i]);
7222 }
7223 }
7224 }
7225 return killed;
7226 }
7227
7228 public void reportPss(IApplicationThread caller, int pss) {
7229 Watchdog.PssRequestor req;
7230 String name;
7231 ProcessRecord callerApp;
7232 synchronized (this) {
7233 if (caller == null) {
7234 return;
7235 }
7236 callerApp = getRecordForAppLocked(caller);
7237 if (callerApp == null) {
7238 return;
7239 }
7240 callerApp.lastPss = pss;
7241 req = callerApp;
7242 name = callerApp.processName;
7243 }
7244 Watchdog.getInstance().reportPss(req, name, pss);
7245 if (!callerApp.persistent) {
7246 removeRequestedPss(callerApp);
7247 }
7248 }
7249
7250 public void requestPss(Runnable completeCallback) {
7251 ArrayList<ProcessRecord> procs;
7252 synchronized (this) {
7253 mRequestPssCallback = completeCallback;
7254 mRequestPssList.clear();
7255 for (int i=mLRUProcesses.size()-1; i>=0; i--) {
7256 ProcessRecord proc = mLRUProcesses.get(i);
7257 if (!proc.persistent) {
7258 mRequestPssList.add(proc);
7259 }
7260 }
7261 procs = new ArrayList<ProcessRecord>(mRequestPssList);
7262 }
7263
7264 int oldPri = Process.getThreadPriority(Process.myTid());
7265 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
7266 for (int i=procs.size()-1; i>=0; i--) {
7267 ProcessRecord proc = procs.get(i);
7268 proc.lastPss = 0;
7269 proc.requestPss();
7270 }
7271 Process.setThreadPriority(oldPri);
7272 }
7273
7274 void removeRequestedPss(ProcessRecord proc) {
7275 Runnable callback = null;
7276 synchronized (this) {
7277 if (mRequestPssList.remove(proc)) {
7278 if (mRequestPssList.size() == 0) {
7279 callback = mRequestPssCallback;
7280 mRequestPssCallback = null;
7281 }
7282 }
7283 }
7284
7285 if (callback != null) {
7286 callback.run();
7287 }
7288 }
7289
7290 public void collectPss(Watchdog.PssStats stats) {
7291 stats.mEmptyPss = 0;
7292 stats.mEmptyCount = 0;
7293 stats.mBackgroundPss = 0;
7294 stats.mBackgroundCount = 0;
7295 stats.mServicePss = 0;
7296 stats.mServiceCount = 0;
7297 stats.mVisiblePss = 0;
7298 stats.mVisibleCount = 0;
7299 stats.mForegroundPss = 0;
7300 stats.mForegroundCount = 0;
7301 stats.mNoPssCount = 0;
7302 synchronized (this) {
7303 int i;
7304 int NPD = mProcDeaths.length < stats.mProcDeaths.length
7305 ? mProcDeaths.length : stats.mProcDeaths.length;
7306 int aggr = 0;
7307 for (i=0; i<NPD; i++) {
7308 aggr += mProcDeaths[i];
7309 stats.mProcDeaths[i] = aggr;
7310 }
7311 while (i<stats.mProcDeaths.length) {
7312 stats.mProcDeaths[i] = 0;
7313 i++;
7314 }
7315
7316 for (i=mLRUProcesses.size()-1; i>=0; i--) {
7317 ProcessRecord proc = mLRUProcesses.get(i);
7318 if (proc.persistent) {
7319 continue;
7320 }
7321 //Log.i(TAG, "Proc " + proc + ": pss=" + proc.lastPss);
7322 if (proc.lastPss == 0) {
7323 stats.mNoPssCount++;
7324 continue;
7325 }
7326 if (proc.setAdj == EMPTY_APP_ADJ) {
7327 stats.mEmptyPss += proc.lastPss;
7328 stats.mEmptyCount++;
7329 } else if (proc.setAdj == CONTENT_PROVIDER_ADJ) {
7330 stats.mEmptyPss += proc.lastPss;
7331 stats.mEmptyCount++;
7332 } else if (proc.setAdj >= HIDDEN_APP_MIN_ADJ) {
7333 stats.mBackgroundPss += proc.lastPss;
7334 stats.mBackgroundCount++;
7335 } else if (proc.setAdj >= VISIBLE_APP_ADJ) {
7336 stats.mVisiblePss += proc.lastPss;
7337 stats.mVisibleCount++;
7338 } else {
7339 stats.mForegroundPss += proc.lastPss;
7340 stats.mForegroundCount++;
7341 }
7342 }
7343 }
7344 }
7345
7346 public final void startRunning(String pkg, String cls, String action,
7347 String data) {
7348 synchronized(this) {
7349 if (mStartRunning) {
7350 return;
7351 }
7352 mStartRunning = true;
7353 mTopComponent = pkg != null && cls != null
7354 ? new ComponentName(pkg, cls) : null;
7355 mTopAction = action != null ? action : Intent.ACTION_MAIN;
7356 mTopData = data;
7357 if (!mSystemReady) {
7358 return;
7359 }
7360 }
7361
7362 systemReady();
7363 }
7364
7365 private void retrieveSettings() {
7366 final ContentResolver resolver = mContext.getContentResolver();
7367 String debugApp = Settings.System.getString(
7368 resolver, Settings.System.DEBUG_APP);
7369 boolean waitForDebugger = Settings.System.getInt(
7370 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7371 boolean alwaysFinishActivities = Settings.System.getInt(
7372 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7373
7374 Configuration configuration = new Configuration();
7375 Settings.System.getConfiguration(resolver, configuration);
7376
7377 synchronized (this) {
7378 mDebugApp = mOrigDebugApp = debugApp;
7379 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7380 mAlwaysFinishActivities = alwaysFinishActivities;
7381 // This happens before any activities are started, so we can
7382 // change mConfiguration in-place.
7383 mConfiguration.updateFrom(configuration);
7384 }
7385 }
7386
7387 public boolean testIsSystemReady() {
7388 // no need to synchronize(this) just to read & return the value
7389 return mSystemReady;
7390 }
7391
7392 public void systemReady() {
7393 // In the simulator, startRunning will never have been called, which
7394 // normally sets a few crucial variables. Do it here instead.
7395 if (!Process.supportsProcesses()) {
7396 mStartRunning = true;
7397 mTopAction = Intent.ACTION_MAIN;
7398 }
7399
7400 synchronized(this) {
7401 if (mSystemReady) {
7402 return;
7403 }
7404 mSystemReady = true;
7405 if (!mStartRunning) {
7406 return;
7407 }
7408 }
7409
7410 if (Config.LOGD) Log.d(TAG, "Start running!");
7411 EventLog.writeEvent(LOG_BOOT_PROGRESS_AMS_READY,
7412 SystemClock.uptimeMillis());
7413
7414 synchronized(this) {
7415 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7416 ResolveInfo ri = mContext.getPackageManager()
7417 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7418 0);
7419 CharSequence errorMsg = null;
7420 if (ri != null) {
7421 ActivityInfo ai = ri.activityInfo;
7422 ApplicationInfo app = ai.applicationInfo;
7423 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7424 mTopAction = Intent.ACTION_FACTORY_TEST;
7425 mTopData = null;
7426 mTopComponent = new ComponentName(app.packageName,
7427 ai.name);
7428 } else {
7429 errorMsg = mContext.getResources().getText(
7430 com.android.internal.R.string.factorytest_not_system);
7431 }
7432 } else {
7433 errorMsg = mContext.getResources().getText(
7434 com.android.internal.R.string.factorytest_no_action);
7435 }
7436 if (errorMsg != null) {
7437 mTopAction = null;
7438 mTopData = null;
7439 mTopComponent = null;
7440 Message msg = Message.obtain();
7441 msg.what = SHOW_FACTORY_ERROR_MSG;
7442 msg.getData().putCharSequence("msg", errorMsg);
7443 mHandler.sendMessage(msg);
7444 }
7445 }
7446 }
7447
7448 retrieveSettings();
7449
7450 synchronized (this) {
7451 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7452 try {
7453 List apps = ActivityThread.getPackageManager().
7454 getPersistentApplications(PackageManager.GET_SHARED_LIBRARY_FILES);
7455 if (apps != null) {
7456 int N = apps.size();
7457 int i;
7458 for (i=0; i<N; i++) {
7459 ApplicationInfo info
7460 = (ApplicationInfo)apps.get(i);
7461 if (info != null &&
7462 !info.packageName.equals("android")) {
7463 addAppLocked(info);
7464 }
7465 }
7466 }
7467 } catch (RemoteException ex) {
7468 // pm is in same process, this will never happen.
7469 }
7470 }
7471
7472 try {
7473 if (ActivityThread.getPackageManager().hasSystemUidErrors()) {
7474 Message msg = Message.obtain();
7475 msg.what = SHOW_UID_ERROR_MSG;
7476 mHandler.sendMessage(msg);
7477 }
7478 } catch (RemoteException e) {
7479 }
7480
7481 // Start up initial activity.
7482 mBooting = true;
7483 resumeTopActivityLocked(null);
7484 }
7485 }
7486
7487 boolean makeAppCrashingLocked(ProcessRecord app,
7488 String tag, String shortMsg, String longMsg, byte[] crashData) {
7489 app.crashing = true;
7490 app.crashingReport = generateProcessError(app,
7491 ActivityManager.ProcessErrorStateInfo.CRASHED, tag, shortMsg, longMsg, crashData);
7492 startAppProblemLocked(app);
7493 app.stopFreezingAllLocked();
7494 return handleAppCrashLocked(app);
7495 }
7496
7497 void makeAppNotRespondingLocked(ProcessRecord app,
7498 String tag, String shortMsg, String longMsg, byte[] crashData) {
7499 app.notResponding = true;
7500 app.notRespondingReport = generateProcessError(app,
7501 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, tag, shortMsg, longMsg,
7502 crashData);
7503 startAppProblemLocked(app);
7504 app.stopFreezingAllLocked();
7505 }
7506
7507 /**
7508 * Generate a process error record, suitable for attachment to a ProcessRecord.
7509 *
7510 * @param app The ProcessRecord in which the error occurred.
7511 * @param condition Crashing, Application Not Responding, etc. Values are defined in
7512 * ActivityManager.AppErrorStateInfo
7513 * @param tag The tag that was passed into handleApplicationError(). Typically the classname.
7514 * @param shortMsg Short message describing the crash.
7515 * @param longMsg Long message describing the crash.
7516 * @param crashData Raw data passed into handleApplicationError(). Typically a stack trace.
7517 *
7518 * @return Returns a fully-formed AppErrorStateInfo record.
7519 */
7520 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7521 int condition, String tag, String shortMsg, String longMsg, byte[] crashData) {
7522 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7523
7524 report.condition = condition;
7525 report.processName = app.processName;
7526 report.pid = app.pid;
7527 report.uid = app.info.uid;
7528 report.tag = tag;
7529 report.shortMsg = shortMsg;
7530 report.longMsg = longMsg;
7531 report.crashData = crashData;
7532
7533 return report;
7534 }
7535
7536 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog,
7537 boolean crashed) {
7538 synchronized (this) {
7539 app.crashing = false;
7540 app.crashingReport = null;
7541 app.notResponding = false;
7542 app.notRespondingReport = null;
7543 if (app.anrDialog == fromDialog) {
7544 app.anrDialog = null;
7545 }
7546 if (app.waitDialog == fromDialog) {
7547 app.waitDialog = null;
7548 }
7549 if (app.pid > 0 && app.pid != MY_PID) {
7550 if (crashed) {
7551 handleAppCrashLocked(app);
7552 }
7553 Log.i(ActivityManagerService.TAG, "Killing process "
7554 + app.processName
7555 + " (pid=" + app.pid + ") at user's request");
7556 Process.killProcess(app.pid);
7557 }
7558
7559 }
7560 }
7561
7562 boolean handleAppCrashLocked(ProcessRecord app) {
7563 long now = SystemClock.uptimeMillis();
7564
7565 Long crashTime = mProcessCrashTimes.get(app.info.processName,
7566 app.info.uid);
7567 if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
7568 // This process loses!
7569 Log.w(TAG, "Process " + app.info.processName
7570 + " has crashed too many times: killing!");
7571 EventLog.writeEvent(LOG_AM_PROCESS_CRASHED_TOO_MUCH,
7572 app.info.processName, app.info.uid);
7573 killServicesLocked(app, false);
7574 for (int i=mHistory.size()-1; i>=0; i--) {
7575 HistoryRecord r = (HistoryRecord)mHistory.get(i);
7576 if (r.app == app) {
7577 if (Config.LOGD) Log.d(
7578 TAG, " Force finishing activity "
7579 + r.intent.getComponent().flattenToShortString());
7580 finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
7581 }
7582 }
7583 if (!app.persistent) {
7584 // We don't want to start this process again until the user
7585 // explicitly does so... but for persistent process, we really
7586 // need to keep it running. If a persistent process is actually
7587 // repeatedly crashing, then badness for everyone.
7588 EventLog.writeEvent(LOG_AM_PROCESS_BAD, app.info.uid,
7589 app.info.processName);
7590 mBadProcesses.put(app.info.processName, app.info.uid, now);
7591 app.bad = true;
7592 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
7593 app.removed = true;
7594 removeProcessLocked(app, false);
7595 return false;
7596 }
7597 }
7598
7599 // Bump up the crash count of any services currently running in the proc.
7600 if (app.services.size() != 0) {
7601 // Any services running in the application need to be placed
7602 // back in the pending list.
7603 Iterator it = app.services.iterator();
7604 while (it.hasNext()) {
7605 ServiceRecord sr = (ServiceRecord)it.next();
7606 sr.crashCount++;
7607 }
7608 }
7609
7610 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
7611 return true;
7612 }
7613
7614 void startAppProblemLocked(ProcessRecord app) {
7615 skipCurrentReceiverLocked(app);
7616 }
7617
7618 void skipCurrentReceiverLocked(ProcessRecord app) {
7619 boolean reschedule = false;
7620 BroadcastRecord r = app.curReceiver;
7621 if (r != null) {
7622 // The current broadcast is waiting for this app's receiver
7623 // to be finished. Looks like that's not going to happen, so
7624 // let the broadcast continue.
7625 logBroadcastReceiverDiscard(r);
7626 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7627 r.resultExtras, r.resultAbort, true);
7628 reschedule = true;
7629 }
7630 r = mPendingBroadcast;
7631 if (r != null && r.curApp == app) {
7632 if (DEBUG_BROADCAST) Log.v(TAG,
7633 "skip & discard pending app " + r);
7634 logBroadcastReceiverDiscard(r);
7635 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7636 r.resultExtras, r.resultAbort, true);
7637 reschedule = true;
7638 }
7639 if (reschedule) {
7640 scheduleBroadcastsLocked();
7641 }
7642 }
7643
7644 public int handleApplicationError(IBinder app, int flags,
7645 String tag, String shortMsg, String longMsg, byte[] crashData) {
7646 AppErrorResult result = new AppErrorResult();
7647
7648 ProcessRecord r = null;
7649 synchronized (this) {
7650 if (app != null) {
7651 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7652 final int NA = apps.size();
7653 for (int ia=0; ia<NA; ia++) {
7654 ProcessRecord p = apps.valueAt(ia);
7655 if (p.thread != null && p.thread.asBinder() == app) {
7656 r = p;
7657 break;
7658 }
7659 }
7660 }
7661 }
7662
7663 if (r != null) {
7664 // The application has crashed. Send the SIGQUIT to the process so
7665 // that it can dump its state.
7666 Process.sendSignal(r.pid, Process.SIGNAL_QUIT);
7667 //Log.i(TAG, "Current system threads:");
7668 //Process.sendSignal(MY_PID, Process.SIGNAL_QUIT);
7669 }
7670
7671 if (mWatcher != null) {
7672 try {
7673 String name = r != null ? r.processName : null;
7674 int pid = r != null ? r.pid : Binder.getCallingPid();
7675 if (!mWatcher.appCrashed(name, pid,
7676 shortMsg, longMsg, crashData)) {
7677 Log.w(TAG, "Force-killing crashed app " + name
7678 + " at watcher's request");
7679 Process.killProcess(pid);
7680 return 0;
7681 }
7682 } catch (RemoteException e) {
7683 mWatcher = null;
7684 }
7685 }
7686
7687 final long origId = Binder.clearCallingIdentity();
7688
7689 // If this process is running instrumentation, finish it.
7690 if (r != null && r.instrumentationClass != null) {
7691 Log.w(TAG, "Error in app " + r.processName
7692 + " running instrumentation " + r.instrumentationClass + ":");
7693 if (shortMsg != null) Log.w(TAG, " " + shortMsg);
7694 if (longMsg != null) Log.w(TAG, " " + longMsg);
7695 Bundle info = new Bundle();
7696 info.putString("shortMsg", shortMsg);
7697 info.putString("longMsg", longMsg);
7698 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7699 Binder.restoreCallingIdentity(origId);
7700 return 0;
7701 }
7702
7703 if (r != null) {
7704 if (!makeAppCrashingLocked(r, tag, shortMsg, longMsg, crashData)) {
7705 return 0;
7706 }
7707 } else {
7708 Log.w(TAG, "Some application object " + app + " tag " + tag
7709 + " has crashed, but I don't know who it is.");
7710 Log.w(TAG, "ShortMsg:" + shortMsg);
7711 Log.w(TAG, "LongMsg:" + longMsg);
7712 Binder.restoreCallingIdentity(origId);
7713 return 0;
7714 }
7715
7716 Message msg = Message.obtain();
7717 msg.what = SHOW_ERROR_MSG;
7718 HashMap data = new HashMap();
7719 data.put("result", result);
7720 data.put("app", r);
7721 data.put("flags", flags);
7722 data.put("shortMsg", shortMsg);
7723 data.put("longMsg", longMsg);
7724 if (r != null && (r.info.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7725 // For system processes, submit crash data to the server.
7726 data.put("crashData", crashData);
7727 }
7728 msg.obj = data;
7729 mHandler.sendMessage(msg);
7730
7731 Binder.restoreCallingIdentity(origId);
7732 }
7733
7734 int res = result.get();
7735
7736 synchronized (this) {
7737 if (r != null) {
7738 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7739 SystemClock.uptimeMillis());
7740 }
7741 }
7742
7743 return res;
7744 }
7745
7746 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7747 // assume our apps are happy - lazy create the list
7748 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7749
7750 synchronized (this) {
7751
7752 // iterate across all processes
7753 final int N = mLRUProcesses.size();
7754 for (int i = 0; i < N; i++) {
7755 ProcessRecord app = mLRUProcesses.get(i);
7756 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7757 // This one's in trouble, so we'll generate a report for it
7758 // crashes are higher priority (in case there's a crash *and* an anr)
7759 ActivityManager.ProcessErrorStateInfo report = null;
7760 if (app.crashing) {
7761 report = app.crashingReport;
7762 } else if (app.notResponding) {
7763 report = app.notRespondingReport;
7764 }
7765
7766 if (report != null) {
7767 if (errList == null) {
7768 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7769 }
7770 errList.add(report);
7771 } else {
7772 Log.w(TAG, "Missing app error report, app = " + app.processName +
7773 " crashing = " + app.crashing +
7774 " notResponding = " + app.notResponding);
7775 }
7776 }
7777 }
7778 }
7779
7780 return errList;
7781 }
7782
7783 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7784 // Lazy instantiation of list
7785 List<ActivityManager.RunningAppProcessInfo> runList = null;
7786 synchronized (this) {
7787 // Iterate across all processes
7788 final int N = mLRUProcesses.size();
7789 for (int i = 0; i < N; i++) {
7790 ProcessRecord app = mLRUProcesses.get(i);
7791 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7792 // Generate process state info for running application
7793 ActivityManager.RunningAppProcessInfo currApp =
7794 new ActivityManager.RunningAppProcessInfo(app.processName,
7795 app.pid, app.getPackageList());
7796 int adj = app.curAdj;
7797 if (adj >= CONTENT_PROVIDER_ADJ) {
7798 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
7799 } else if (adj >= HIDDEN_APP_MIN_ADJ) {
7800 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7801 currApp.lru = adj - HIDDEN_APP_MIN_ADJ;
7802 } else if (adj >= SECONDARY_SERVER_ADJ) {
7803 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
7804 } else if (adj >= VISIBLE_APP_ADJ) {
7805 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7806 } else {
7807 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7808 }
7809 //Log.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
7810 // + " lru=" + currApp.lru);
7811 if (runList == null) {
7812 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7813 }
7814 runList.add(currApp);
7815 }
7816 }
7817 }
7818 return runList;
7819 }
7820
7821 @Override
7822 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
7823 synchronized (this) {
7824 if (checkCallingPermission(android.Manifest.permission.DUMP)
7825 != PackageManager.PERMISSION_GRANTED) {
7826 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7827 + Binder.getCallingPid()
7828 + ", uid=" + Binder.getCallingUid()
7829 + " without permission "
7830 + android.Manifest.permission.DUMP);
7831 return;
7832 }
7833 if (args.length != 0 && "service".equals(args[0])) {
7834 dumpService(fd, pw, args);
7835 return;
7836 }
7837 pw.println("Activities in Current Activity Manager State:");
7838 dumpHistoryList(pw, mHistory, " ", "History");
7839 pw.println(" ");
7840 pw.println(" Running activities (most recent first):");
7841 dumpHistoryList(pw, mLRUActivities, " ", "Running");
7842 if (mWaitingVisibleActivities.size() > 0) {
7843 pw.println(" ");
7844 pw.println(" Activities waiting for another to become visible:");
7845 dumpHistoryList(pw, mWaitingVisibleActivities, " ", "Waiting");
7846 }
7847 if (mStoppingActivities.size() > 0) {
7848 pw.println(" ");
7849 pw.println(" Activities waiting to stop:");
7850 dumpHistoryList(pw, mStoppingActivities, " ", "Stopping");
7851 }
7852 if (mFinishingActivities.size() > 0) {
7853 pw.println(" ");
7854 pw.println(" Activities waiting to finish:");
7855 dumpHistoryList(pw, mFinishingActivities, " ", "Finishing");
7856 }
7857
7858 pw.println(" ");
7859 pw.println(" mPausingActivity: " + mPausingActivity);
7860 pw.println(" mResumedActivity: " + mResumedActivity);
7861 pw.println(" mFocusedActivity: " + mFocusedActivity);
7862 pw.println(" mLastPausedActivity: " + mLastPausedActivity);
7863
7864 if (mRecentTasks.size() > 0) {
7865 pw.println(" ");
7866 pw.println("Recent tasks in Current Activity Manager State:");
7867
7868 final int N = mRecentTasks.size();
7869 for (int i=0; i<N; i++) {
7870 pw.println(" Recent Task #" + i);
7871 mRecentTasks.get(i).dump(pw, " ");
7872 }
7873 }
7874
7875 pw.println(" ");
7876 pw.println(" mCurTask: " + mCurTask);
7877
7878 pw.println(" ");
7879 pw.println("Processes in Current Activity Manager State:");
7880
7881 boolean needSep = false;
7882 int numPers = 0;
7883
7884 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7885 final int NA = procs.size();
7886 for (int ia=0; ia<NA; ia++) {
7887 if (!needSep) {
7888 pw.println(" All known processes:");
7889 needSep = true;
7890 }
7891 ProcessRecord r = procs.valueAt(ia);
7892 pw.println((r.persistent ? " *PERSISTENT* Process [" : " Process [")
7893 + r.processName + "] UID " + procs.keyAt(ia));
7894 r.dump(pw, " ");
7895 if (r.persistent) {
7896 numPers++;
7897 }
7898 }
7899 }
7900
7901 if (mLRUProcesses.size() > 0) {
7902 if (needSep) pw.println(" ");
7903 needSep = true;
7904 pw.println(" Running processes (most recent first):");
7905 dumpProcessList(pw, mLRUProcesses, " ",
7906 "Running Norm Proc", "Running PERS Proc", true);
7907 needSep = true;
7908 }
7909
7910 synchronized (mPidsSelfLocked) {
7911 if (mPidsSelfLocked.size() > 0) {
7912 if (needSep) pw.println(" ");
7913 needSep = true;
7914 pw.println(" PID mappings:");
7915 for (int i=0; i<mPidsSelfLocked.size(); i++) {
7916 pw.println(" PID #" + mPidsSelfLocked.keyAt(i)
7917 + ": " + mPidsSelfLocked.valueAt(i));
7918 }
7919 }
7920 }
7921
7922 if (mForegroundProcesses.size() > 0) {
7923 if (needSep) pw.println(" ");
7924 needSep = true;
7925 pw.println(" Foreground Processes:");
7926 for (int i=0; i<mForegroundProcesses.size(); i++) {
7927 pw.println(" PID #" + mForegroundProcesses.keyAt(i)
7928 + ": " + mForegroundProcesses.valueAt(i));
7929 }
7930 }
7931
7932 if (mPersistentStartingProcesses.size() > 0) {
7933 if (needSep) pw.println(" ");
7934 needSep = true;
7935 pw.println(" Persisent processes that are starting:");
7936 dumpProcessList(pw, mPersistentStartingProcesses, " ",
7937 "Starting Initial Proc", "Restarting PERS Proc", false);
7938 }
7939
7940 if (mStartingProcesses.size() > 0) {
7941 if (needSep) pw.println(" ");
7942 needSep = true;
7943 pw.println(" Processes that are starting:");
7944 dumpProcessList(pw, mStartingProcesses, " ",
7945 "Starting Norm Proc", "Starting PERS Proc", false);
7946 }
7947
7948 if (mRemovedProcesses.size() > 0) {
7949 if (needSep) pw.println(" ");
7950 needSep = true;
7951 pw.println(" Processes that are being removed:");
7952 dumpProcessList(pw, mRemovedProcesses, " ",
7953 "Removed Norm Proc", "Removed PERS Proc", false);
7954 }
7955
7956 if (mProcessesOnHold.size() > 0) {
7957 if (needSep) pw.println(" ");
7958 needSep = true;
7959 pw.println(" Processes that are on old until the system is ready:");
7960 dumpProcessList(pw, mProcessesOnHold, " ",
7961 "OnHold Norm Proc", "OnHold PERS Proc", false);
7962 }
7963
7964 if (mProcessCrashTimes.getMap().size() > 0) {
7965 if (needSep) pw.println(" ");
7966 needSep = true;
7967 pw.println(" Time since processes crashed:");
7968 long now = SystemClock.uptimeMillis();
7969 for (Map.Entry<String, SparseArray<Long>> procs
7970 : mProcessCrashTimes.getMap().entrySet()) {
7971 SparseArray<Long> uids = procs.getValue();
7972 final int N = uids.size();
7973 for (int i=0; i<N; i++) {
7974 pw.println(" Process " + procs.getKey()
7975 + " uid " + uids.keyAt(i)
7976 + ": last crashed "
7977 + (now-uids.valueAt(i)) + " ms ago");
7978 }
7979 }
7980 }
7981
7982 if (mBadProcesses.getMap().size() > 0) {
7983 if (needSep) pw.println(" ");
7984 needSep = true;
7985 pw.println(" Bad processes:");
7986 for (Map.Entry<String, SparseArray<Long>> procs
7987 : mBadProcesses.getMap().entrySet()) {
7988 SparseArray<Long> uids = procs.getValue();
7989 final int N = uids.size();
7990 for (int i=0; i<N; i++) {
7991 pw.println(" Bad process " + procs.getKey()
7992 + " uid " + uids.keyAt(i)
7993 + ": crashed at time " + uids.valueAt(i));
7994 }
7995 }
7996 }
7997
7998 pw.println(" ");
7999 pw.println(" Total persistent processes: " + numPers);
8000 pw.println(" mConfiguration: " + mConfiguration);
8001 pw.println(" mStartRunning=" + mStartRunning
8002 + " mSystemReady=" + mSystemReady
8003 + " mBooting=" + mBooting
8004 + " mBooted=" + mBooted
8005 + " mFactoryTest=" + mFactoryTest);
8006 pw.println(" mSleeping=" + mSleeping);
8007 pw.println(" mGoingToSleep=" + mGoingToSleep);
8008 pw.println(" mLaunchingActivity=" + mLaunchingActivity);
8009 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
8010 + " mDebugTransient=" + mDebugTransient
8011 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
8012 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
8013 + " mWatcher=" + mWatcher);
8014 }
8015 }
8016
8017 /**
8018 * There are three ways to call this:
8019 * - no service specified: dump all the services
8020 * - a flattened component name that matched an existing service was specified as the
8021 * first arg: dump that one service
8022 * - the first arg isn't the flattened component name of an existing service:
8023 * dump all services whose component contains the first arg as a substring
8024 */
8025 protected void dumpService(FileDescriptor fd, PrintWriter pw, String[] args) {
8026 String[] newArgs;
8027 String componentNameString;
8028 ServiceRecord r;
8029 if (args.length == 1) {
8030 componentNameString = null;
8031 newArgs = EMPTY_STRING_ARRAY;
8032 r = null;
8033 } else {
8034 componentNameString = args[1];
8035 ComponentName componentName = ComponentName.unflattenFromString(componentNameString);
8036 r = componentName != null ? mServices.get(componentName) : null;
8037 newArgs = new String[args.length - 2];
8038 if (args.length > 2) System.arraycopy(args, 2, newArgs, 0, args.length - 2);
8039 }
8040
8041 if (r != null) {
8042 dumpService(fd, pw, r, newArgs);
8043 } else {
8044 for (ServiceRecord r1 : mServices.values()) {
8045 if (componentNameString == null
8046 || r1.name.flattenToString().contains(componentNameString)) {
8047 dumpService(fd, pw, r1, newArgs);
8048 }
8049 }
8050 }
8051 }
8052
8053 /**
8054 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8055 * there is a thread associated with the service.
8056 */
8057 private void dumpService(FileDescriptor fd, PrintWriter pw, ServiceRecord r, String[] args) {
8058 pw.println(" Service " + r.name.flattenToString());
8059 if (r.app != null && r.app.thread != null) {
8060 try {
8061 // flush anything that is already in the PrintWriter since the thread is going
8062 // to write to the file descriptor directly
8063 pw.flush();
8064 r.app.thread.dumpService(fd, r, args);
8065 pw.print("\n");
8066 } catch (RemoteException e) {
8067 pw.println("got a RemoteException while dumping the service");
8068 }
8069 }
8070 }
8071
8072 void dumpBroadcasts(PrintWriter pw) {
8073 synchronized (this) {
8074 if (checkCallingPermission(android.Manifest.permission.DUMP)
8075 != PackageManager.PERMISSION_GRANTED) {
8076 pw.println("Permission Denial: can't dump ActivityManager from from pid="
8077 + Binder.getCallingPid()
8078 + ", uid=" + Binder.getCallingUid()
8079 + " without permission "
8080 + android.Manifest.permission.DUMP);
8081 return;
8082 }
8083 pw.println("Broadcasts in Current Activity Manager State:");
8084
8085 if (mRegisteredReceivers.size() > 0) {
8086 pw.println(" ");
8087 pw.println(" Registered Receivers:");
8088 Iterator it = mRegisteredReceivers.values().iterator();
8089 while (it.hasNext()) {
8090 ReceiverList r = (ReceiverList)it.next();
8091 pw.println(" Receiver " + r.receiver);
8092 r.dump(pw, " ");
8093 }
8094 }
8095
8096 pw.println(" ");
8097 pw.println("Receiver Resolver Table:");
8098 mReceiverResolver.dump(new PrintWriterPrinter(pw), " ");
8099
8100 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8101 || mPendingBroadcast != null) {
8102 if (mParallelBroadcasts.size() > 0) {
8103 pw.println(" ");
8104 pw.println(" Active broadcasts:");
8105 }
8106 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8107 pw.println(" Broadcast #" + i + ":");
8108 mParallelBroadcasts.get(i).dump(pw, " ");
8109 }
8110 if (mOrderedBroadcasts.size() > 0) {
8111 pw.println(" ");
8112 pw.println(" Active serialized broadcasts:");
8113 }
8114 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8115 pw.println(" Serialized Broadcast #" + i + ":");
8116 mOrderedBroadcasts.get(i).dump(pw, " ");
8117 }
8118 pw.println(" ");
8119 pw.println(" Pending broadcast:");
8120 if (mPendingBroadcast != null) {
8121 mPendingBroadcast.dump(pw, " ");
8122 } else {
8123 pw.println(" (null)");
8124 }
8125 }
8126
8127 pw.println(" ");
8128 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
8129 if (mStickyBroadcasts != null) {
8130 pw.println(" ");
8131 pw.println(" Sticky broadcasts:");
8132 for (Map.Entry<String, ArrayList<Intent>> ent
8133 : mStickyBroadcasts.entrySet()) {
8134 pw.println(" Sticky action " + ent.getKey() + ":");
8135 ArrayList<Intent> intents = ent.getValue();
8136 final int N = intents.size();
8137 for (int i=0; i<N; i++) {
8138 pw.println(" " + intents.get(i));
8139 }
8140 }
8141 }
8142
8143 pw.println(" ");
8144 pw.println(" mHandler:");
8145 mHandler.dump(new PrintWriterPrinter(pw), " ");
8146 }
8147 }
8148
8149 void dumpServices(PrintWriter pw) {
8150 synchronized (this) {
8151 if (checkCallingPermission(android.Manifest.permission.DUMP)
8152 != PackageManager.PERMISSION_GRANTED) {
8153 pw.println("Permission Denial: can't dump ActivityManager from from pid="
8154 + Binder.getCallingPid()
8155 + ", uid=" + Binder.getCallingUid()
8156 + " without permission "
8157 + android.Manifest.permission.DUMP);
8158 return;
8159 }
8160 pw.println("Services in Current Activity Manager State:");
8161
8162 boolean needSep = false;
8163
8164 if (mServices.size() > 0) {
8165 pw.println(" Active services:");
8166 Iterator<ServiceRecord> it = mServices.values().iterator();
8167 while (it.hasNext()) {
8168 ServiceRecord r = it.next();
8169 pw.println(" Service " + r.shortName);
8170 r.dump(pw, " ");
8171 }
8172 needSep = true;
8173 }
8174
8175 if (mPendingServices.size() > 0) {
8176 if (needSep) pw.println(" ");
8177 pw.println(" Pending services:");
8178 for (int i=0; i<mPendingServices.size(); i++) {
8179 ServiceRecord r = mPendingServices.get(i);
8180 pw.println(" Pending Service " + r.shortName);
8181 r.dump(pw, " ");
8182 }
8183 needSep = true;
8184 }
8185
8186 if (mRestartingServices.size() > 0) {
8187 if (needSep) pw.println(" ");
8188 pw.println(" Restarting services:");
8189 for (int i=0; i<mRestartingServices.size(); i++) {
8190 ServiceRecord r = mRestartingServices.get(i);
8191 pw.println(" Restarting Service " + r.shortName);
8192 r.dump(pw, " ");
8193 }
8194 needSep = true;
8195 }
8196
8197 if (mStoppingServices.size() > 0) {
8198 if (needSep) pw.println(" ");
8199 pw.println(" Stopping services:");
8200 for (int i=0; i<mStoppingServices.size(); i++) {
8201 ServiceRecord r = mStoppingServices.get(i);
8202 pw.println(" Stopping Service " + r.shortName);
8203 r.dump(pw, " ");
8204 }
8205 needSep = true;
8206 }
8207
8208 if (mServiceConnections.size() > 0) {
8209 if (needSep) pw.println(" ");
8210 pw.println(" Connection bindings to services:");
8211 Iterator<ConnectionRecord> it
8212 = mServiceConnections.values().iterator();
8213 while (it.hasNext()) {
8214 ConnectionRecord r = it.next();
8215 pw.println(" " + r.binding.service.shortName
8216 + " -> " + r.conn.asBinder());
8217 r.dump(pw, " ");
8218 }
8219 }
8220 }
8221 }
8222
8223 void dumpProviders(PrintWriter pw) {
8224 synchronized (this) {
8225 if (checkCallingPermission(android.Manifest.permission.DUMP)
8226 != PackageManager.PERMISSION_GRANTED) {
8227 pw.println("Permission Denial: can't dump ActivityManager from from pid="
8228 + Binder.getCallingPid()
8229 + ", uid=" + Binder.getCallingUid()
8230 + " without permission "
8231 + android.Manifest.permission.DUMP);
8232 return;
8233 }
8234
8235 pw.println("Content Providers in Current Activity Manager State:");
8236
8237 boolean needSep = false;
8238
8239 if (mProvidersByName.size() > 0) {
8240 pw.println(" Published content providers (by name):");
8241 Iterator it = mProvidersByName.entrySet().iterator();
8242 while (it.hasNext()) {
8243 Map.Entry e = (Map.Entry)it.next();
8244 ContentProviderRecord r = (ContentProviderRecord)e.getValue();
8245 pw.println(" Provider " + (String)e.getKey());
8246 r.dump(pw, " ");
8247 }
8248 needSep = true;
8249 }
8250
8251 if (mProvidersByClass.size() > 0) {
8252 if (needSep) pw.println(" ");
8253 pw.println(" Published content providers (by class):");
8254 Iterator it = mProvidersByClass.entrySet().iterator();
8255 while (it.hasNext()) {
8256 Map.Entry e = (Map.Entry)it.next();
8257 ContentProviderRecord r = (ContentProviderRecord)e.getValue();
8258 pw.println(" Provider " + (String)e.getKey());
8259 r.dump(pw, " ");
8260 }
8261 needSep = true;
8262 }
8263
8264 if (mLaunchingProviders.size() > 0) {
8265 if (needSep) pw.println(" ");
8266 pw.println(" Launching content providers:");
8267 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8268 pw.println(" Provider #" + i + ":");
8269 ((ContentProviderRecord)mLaunchingProviders.get(i)).dump(pw, " ");
8270 }
8271 needSep = true;
8272 }
8273
8274 pw.println();
8275 pw.println("Granted Uri Permissions:");
8276 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8277 int uid = mGrantedUriPermissions.keyAt(i);
8278 HashMap<Uri, UriPermission> perms
8279 = mGrantedUriPermissions.valueAt(i);
8280 pw.println(" Uris granted to uid " + uid + ":");
8281 for (UriPermission perm : perms.values()) {
8282 perm.dump(pw, " ");
8283 }
8284 }
8285 }
8286 }
8287
8288 void dumpSenders(PrintWriter pw) {
8289 synchronized (this) {
8290 if (checkCallingPermission(android.Manifest.permission.DUMP)
8291 != PackageManager.PERMISSION_GRANTED) {
8292 pw.println("Permission Denial: can't dump ActivityManager from from pid="
8293 + Binder.getCallingPid()
8294 + ", uid=" + Binder.getCallingUid()
8295 + " without permission "
8296 + android.Manifest.permission.DUMP);
8297 return;
8298 }
8299
8300 pw.println("Intent Senders in Current Activity Manager State:");
8301
8302 if (this.mIntentSenderRecords.size() > 0) {
8303 Iterator<WeakReference<PendingIntentRecord>> it
8304 = mIntentSenderRecords.values().iterator();
8305 while (it.hasNext()) {
8306 WeakReference<PendingIntentRecord> ref = it.next();
8307 PendingIntentRecord rec = ref != null ? ref.get(): null;
8308 if (rec != null) {
8309 pw.println(" IntentSender " + rec);
8310 rec.dump(pw, " ");
8311 } else {
8312 pw.println(" IntentSender " + ref);
8313 }
8314 }
8315 }
8316 }
8317 }
8318
8319 private static final void dumpHistoryList(PrintWriter pw, List list,
8320 String prefix, String label) {
8321 TaskRecord lastTask = null;
8322 for (int i=list.size()-1; i>=0; i--) {
8323 HistoryRecord r = (HistoryRecord)list.get(i);
8324 if (lastTask != r.task) {
8325 lastTask = r.task;
8326 lastTask.dump(pw, prefix + " ");
8327 }
8328 pw.println(prefix + " " + label + " #" + i + ":");
8329 r.dump(pw, prefix + " ");
8330 }
8331 }
8332
8333 private static final int dumpProcessList(PrintWriter pw, List list,
8334 String prefix, String normalLabel, String persistentLabel,
8335 boolean inclOomAdj) {
8336 int numPers = 0;
8337 for (int i=list.size()-1; i>=0; i--) {
8338 ProcessRecord r = (ProcessRecord)list.get(i);
8339 if (false) {
8340 pw.println(prefix + (r.persistent ? persistentLabel : normalLabel)
8341 + " #" + i + ":");
8342 r.dump(pw, prefix + " ");
8343 } else if (inclOomAdj) {
8344 pw.println(String.format("%s%s #%2d: oom_adj=%3d %s",
8345 prefix, (r.persistent ? persistentLabel : normalLabel),
8346 i, r.setAdj, r.toString()));
8347 } else {
8348 pw.println(String.format("%s%s #%2d: %s",
8349 prefix, (r.persistent ? persistentLabel : normalLabel),
8350 i, r.toString()));
8351 }
8352 if (r.persistent) {
8353 numPers++;
8354 }
8355 }
8356 return numPers;
8357 }
8358
8359 private static final void dumpApplicationMemoryUsage(FileDescriptor fd,
8360 PrintWriter pw, List list, String prefix, String[] args) {
8361 final boolean isCheckinRequest = scanArgs(args, "-c");
8362 long uptime = SystemClock.uptimeMillis();
8363 long realtime = SystemClock.elapsedRealtime();
8364
8365 if (isCheckinRequest) {
8366 // short checkin version
8367 pw.println(uptime + "," + realtime);
8368 pw.flush();
8369 } else {
8370 pw.println("Applications Memory Usage (kB):");
8371 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8372 }
8373 for (int i = list.size() - 1 ; i >= 0 ; i--) {
8374 ProcessRecord r = (ProcessRecord)list.get(i);
8375 if (r.thread != null) {
8376 if (!isCheckinRequest) {
8377 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
8378 pw.flush();
8379 }
8380 try {
8381 r.thread.asBinder().dump(fd, args);
8382 } catch (RemoteException e) {
8383 if (!isCheckinRequest) {
8384 pw.println("Got RemoteException!");
8385 pw.flush();
8386 }
8387 }
8388 }
8389 }
8390 }
8391
8392 /**
8393 * Searches array of arguments for the specified string
8394 * @param args array of argument strings
8395 * @param value value to search for
8396 * @return true if the value is contained in the array
8397 */
8398 private static boolean scanArgs(String[] args, String value) {
8399 if (args != null) {
8400 for (String arg : args) {
8401 if (value.equals(arg)) {
8402 return true;
8403 }
8404 }
8405 }
8406 return false;
8407 }
8408
8409 private final int indexOfTokenLocked(IBinder token, boolean required) {
8410 int count = mHistory.size();
8411
8412 // convert the token to an entry in the history.
8413 HistoryRecord r = null;
8414 int index = -1;
8415 for (int i=count-1; i>=0; i--) {
8416 Object o = mHistory.get(i);
8417 if (o == token) {
8418 r = (HistoryRecord)o;
8419 index = i;
8420 break;
8421 }
8422 }
8423 if (index < 0 && required) {
8424 RuntimeInit.crash(TAG, new InvalidTokenException(token));
8425 }
8426
8427 return index;
8428 }
8429
8430 static class InvalidTokenException extends Exception {
8431 InvalidTokenException(IBinder token) {
8432 super("Bad activity token: " + token);
8433 }
8434 }
8435
8436 private final void killServicesLocked(ProcessRecord app,
8437 boolean allowRestart) {
8438 // Report disconnected services.
8439 if (false) {
8440 // XXX we are letting the client link to the service for
8441 // death notifications.
8442 if (app.services.size() > 0) {
8443 Iterator it = app.services.iterator();
8444 while (it.hasNext()) {
8445 ServiceRecord r = (ServiceRecord)it.next();
8446 if (r.connections.size() > 0) {
8447 Iterator<ConnectionRecord> jt
8448 = r.connections.values().iterator();
8449 while (jt.hasNext()) {
8450 ConnectionRecord c = jt.next();
8451 if (c.binding.client != app) {
8452 try {
8453 //c.conn.connected(r.className, null);
8454 } catch (Exception e) {
8455 // todo: this should be asynchronous!
8456 Log.w(TAG, "Exception thrown disconnected servce "
8457 + r.shortName
8458 + " from app " + app.processName, e);
8459 }
8460 }
8461 }
8462 }
8463 }
8464 }
8465 }
8466
8467 // Clean up any connections this application has to other services.
8468 if (app.connections.size() > 0) {
8469 Iterator<ConnectionRecord> it = app.connections.iterator();
8470 while (it.hasNext()) {
8471 ConnectionRecord r = it.next();
8472 removeConnectionLocked(r, app, null);
8473 }
8474 }
8475 app.connections.clear();
8476
8477 if (app.services.size() != 0) {
8478 // Any services running in the application need to be placed
8479 // back in the pending list.
8480 Iterator it = app.services.iterator();
8481 while (it.hasNext()) {
8482 ServiceRecord sr = (ServiceRecord)it.next();
8483 synchronized (sr.stats.getBatteryStats()) {
8484 sr.stats.stopLaunchedLocked();
8485 }
8486 sr.app = null;
8487 sr.executeNesting = 0;
8488 mStoppingServices.remove(sr);
8489 if (sr.bindings.size() > 0) {
8490 Iterator<IntentBindRecord> bindings
8491 = sr.bindings.values().iterator();
8492 while (bindings.hasNext()) {
8493 IntentBindRecord b = bindings.next();
8494 if (DEBUG_SERVICE) Log.v(TAG, "Killing binding " + b
8495 + ": shouldUnbind=" + b.hasBound);
8496 b.binder = null;
8497 b.requested = b.received = b.hasBound = false;
8498 }
8499 }
8500
8501 if (sr.crashCount >= 2) {
8502 Log.w(TAG, "Service crashed " + sr.crashCount
8503 + " times, stopping: " + sr);
8504 EventLog.writeEvent(LOG_AM_SERVICE_CRASHED_TOO_MUCH,
8505 sr.crashCount, sr.shortName, app.pid);
8506 bringDownServiceLocked(sr, true);
8507 } else if (!allowRestart) {
8508 bringDownServiceLocked(sr, true);
8509 } else {
8510 scheduleServiceRestartLocked(sr);
8511 }
8512 }
8513
8514 if (!allowRestart) {
8515 app.services.clear();
8516 }
8517 }
8518
8519 app.executingServices.clear();
8520 }
8521
8522 private final void removeDyingProviderLocked(ProcessRecord proc,
8523 ContentProviderRecord cpr) {
8524 synchronized (cpr) {
8525 cpr.launchingApp = null;
8526 cpr.notifyAll();
8527 }
8528
8529 mProvidersByClass.remove(cpr.info.name);
8530 String names[] = cpr.info.authority.split(";");
8531 for (int j = 0; j < names.length; j++) {
8532 mProvidersByName.remove(names[j]);
8533 }
8534
8535 Iterator<ProcessRecord> cit = cpr.clients.iterator();
8536 while (cit.hasNext()) {
8537 ProcessRecord capp = cit.next();
8538 if (!capp.persistent && capp.thread != null
8539 && capp.pid != 0
8540 && capp.pid != MY_PID) {
8541 Log.i(TAG, "Killing app " + capp.processName
8542 + " (pid " + capp.pid
8543 + ") because provider " + cpr.info.name
8544 + " is in dying process " + proc.processName);
8545 Process.killProcess(capp.pid);
8546 }
8547 }
8548
8549 mLaunchingProviders.remove(cpr);
8550 }
8551
8552 /**
8553 * Main code for cleaning up a process when it has gone away. This is
8554 * called both as a result of the process dying, or directly when stopping
8555 * a process when running in single process mode.
8556 */
8557 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
8558 boolean restarting, int index) {
8559 if (index >= 0) {
8560 mLRUProcesses.remove(index);
8561 }
8562
8563 // Dismiss any open dialogs.
8564 if (app.crashDialog != null) {
8565 app.crashDialog.dismiss();
8566 app.crashDialog = null;
8567 }
8568 if (app.anrDialog != null) {
8569 app.anrDialog.dismiss();
8570 app.anrDialog = null;
8571 }
8572 if (app.waitDialog != null) {
8573 app.waitDialog.dismiss();
8574 app.waitDialog = null;
8575 }
8576
8577 app.crashing = false;
8578 app.notResponding = false;
8579
8580 app.resetPackageList();
8581 app.thread = null;
8582 app.forcingToForeground = null;
8583 app.foregroundServices = false;
8584
8585 killServicesLocked(app, true);
8586
8587 boolean restart = false;
8588
8589 int NL = mLaunchingProviders.size();
8590
8591 // Remove published content providers.
8592 if (!app.pubProviders.isEmpty()) {
8593 Iterator it = app.pubProviders.values().iterator();
8594 while (it.hasNext()) {
8595 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
8596 cpr.provider = null;
8597 cpr.app = null;
8598
8599 // See if someone is waiting for this provider... in which
8600 // case we don't remove it, but just let it restart.
8601 int i = 0;
8602 if (!app.bad) {
8603 for (; i<NL; i++) {
8604 if (mLaunchingProviders.get(i) == cpr) {
8605 restart = true;
8606 break;
8607 }
8608 }
8609 } else {
8610 i = NL;
8611 }
8612
8613 if (i >= NL) {
8614 removeDyingProviderLocked(app, cpr);
8615 NL = mLaunchingProviders.size();
8616 }
8617 }
8618 app.pubProviders.clear();
8619 }
8620
8621 // Look through the content providers we are waiting to have launched,
8622 // and if any run in this process then either schedule a restart of
8623 // the process or kill the client waiting for it if this process has
8624 // gone bad.
8625 for (int i=0; i<NL; i++) {
8626 ContentProviderRecord cpr = (ContentProviderRecord)
8627 mLaunchingProviders.get(i);
8628 if (cpr.launchingApp == app) {
8629 if (!app.bad) {
8630 restart = true;
8631 } else {
8632 removeDyingProviderLocked(app, cpr);
8633 NL = mLaunchingProviders.size();
8634 }
8635 }
8636 }
8637
8638 // Unregister from connected content providers.
8639 if (!app.conProviders.isEmpty()) {
8640 Iterator it = app.conProviders.iterator();
8641 while (it.hasNext()) {
8642 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
8643 cpr.clients.remove(app);
8644 }
8645 app.conProviders.clear();
8646 }
8647
8648 skipCurrentReceiverLocked(app);
8649
8650 // Unregister any receivers.
8651 if (app.receivers.size() > 0) {
8652 Iterator<ReceiverList> it = app.receivers.iterator();
8653 while (it.hasNext()) {
8654 removeReceiverLocked(it.next());
8655 }
8656 app.receivers.clear();
8657 }
8658
8659 // If the caller is restarting this app, then leave it in its
8660 // current lists and let the caller take care of it.
8661 if (restarting) {
8662 return;
8663 }
8664
8665 if (!app.persistent) {
8666 if (DEBUG_PROCESSES) Log.v(TAG,
8667 "Removing non-persistent process during cleanup: " + app);
8668 mProcessNames.remove(app.processName, app.info.uid);
8669 } else if (!app.removed) {
8670 // This app is persistent, so we need to keep its record around.
8671 // If it is not already on the pending app list, add it there
8672 // and start a new process for it.
8673 app.thread = null;
8674 app.forcingToForeground = null;
8675 app.foregroundServices = false;
8676 if (mPersistentStartingProcesses.indexOf(app) < 0) {
8677 mPersistentStartingProcesses.add(app);
8678 restart = true;
8679 }
8680 }
8681 mProcessesOnHold.remove(app);
8682
8683 if (restart) {
8684 // We have components that still need to be running in the
8685 // process, so re-launch it.
8686 mProcessNames.put(app.processName, app.info.uid, app);
8687 startProcessLocked(app, "restart", app.processName);
8688 } else if (app.pid > 0 && app.pid != MY_PID) {
8689 // Goodbye!
8690 synchronized (mPidsSelfLocked) {
8691 mPidsSelfLocked.remove(app.pid);
8692 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
8693 }
8694 app.pid = 0;
8695 }
8696 }
8697
8698 // =========================================================
8699 // SERVICES
8700 // =========================================================
8701
8702 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
8703 ActivityManager.RunningServiceInfo info =
8704 new ActivityManager.RunningServiceInfo();
8705 info.service = r.name;
8706 if (r.app != null) {
8707 info.pid = r.app.pid;
8708 }
8709 info.process = r.processName;
8710 info.foreground = r.isForeground;
8711 info.activeSince = r.createTime;
8712 info.started = r.startRequested;
8713 info.clientCount = r.connections.size();
8714 info.crashCount = r.crashCount;
8715 info.lastActivityTime = r.lastActivity;
8716 return info;
8717 }
8718
8719 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
8720 int flags) {
8721 synchronized (this) {
8722 ArrayList<ActivityManager.RunningServiceInfo> res
8723 = new ArrayList<ActivityManager.RunningServiceInfo>();
8724
8725 if (mServices.size() > 0) {
8726 Iterator<ServiceRecord> it = mServices.values().iterator();
8727 while (it.hasNext() && res.size() < maxNum) {
8728 res.add(makeRunningServiceInfoLocked(it.next()));
8729 }
8730 }
8731
8732 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
8733 ServiceRecord r = mRestartingServices.get(i);
8734 ActivityManager.RunningServiceInfo info =
8735 makeRunningServiceInfoLocked(r);
8736 info.restarting = r.nextRestartTime;
8737 res.add(info);
8738 }
8739
8740 return res;
8741 }
8742 }
8743
8744 private final ServiceRecord findServiceLocked(ComponentName name,
8745 IBinder token) {
8746 ServiceRecord r = mServices.get(name);
8747 return r == token ? r : null;
8748 }
8749
8750 private final class ServiceLookupResult {
8751 final ServiceRecord record;
8752 final String permission;
8753
8754 ServiceLookupResult(ServiceRecord _record, String _permission) {
8755 record = _record;
8756 permission = _permission;
8757 }
8758 };
8759
8760 private ServiceLookupResult findServiceLocked(Intent service,
8761 String resolvedType) {
8762 ServiceRecord r = null;
8763 if (service.getComponent() != null) {
8764 r = mServices.get(service.getComponent());
8765 }
8766 if (r == null) {
8767 Intent.FilterComparison filter = new Intent.FilterComparison(service);
8768 r = mServicesByIntent.get(filter);
8769 }
8770
8771 if (r == null) {
8772 try {
8773 ResolveInfo rInfo =
8774 ActivityThread.getPackageManager().resolveService(
8775 service, resolvedType, 0);
8776 ServiceInfo sInfo =
8777 rInfo != null ? rInfo.serviceInfo : null;
8778 if (sInfo == null) {
8779 return null;
8780 }
8781
8782 ComponentName name = new ComponentName(
8783 sInfo.applicationInfo.packageName, sInfo.name);
8784 r = mServices.get(name);
8785 } catch (RemoteException ex) {
8786 // pm is in same process, this will never happen.
8787 }
8788 }
8789 if (r != null) {
8790 int callingPid = Binder.getCallingPid();
8791 int callingUid = Binder.getCallingUid();
8792 if (checkComponentPermission(r.permission,
8793 callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
8794 != PackageManager.PERMISSION_GRANTED) {
8795 Log.w(TAG, "Permission Denial: Accessing service " + r.name
8796 + " from pid=" + callingPid
8797 + ", uid=" + callingUid
8798 + " requires " + r.permission);
8799 return new ServiceLookupResult(null, r.permission);
8800 }
8801 return new ServiceLookupResult(r, null);
8802 }
8803 return null;
8804 }
8805
8806 private class ServiceRestarter implements Runnable {
8807 private ServiceRecord mService;
8808
8809 void setService(ServiceRecord service) {
8810 mService = service;
8811 }
8812
8813 public void run() {
8814 synchronized(ActivityManagerService.this) {
8815 performServiceRestartLocked(mService);
8816 }
8817 }
8818 }
8819
8820 private ServiceLookupResult retrieveServiceLocked(Intent service,
8821 String resolvedType, int callingPid, int callingUid) {
8822 ServiceRecord r = null;
8823 if (service.getComponent() != null) {
8824 r = mServices.get(service.getComponent());
8825 }
8826 Intent.FilterComparison filter = new Intent.FilterComparison(service);
8827 r = mServicesByIntent.get(filter);
8828 if (r == null) {
8829 try {
8830 ResolveInfo rInfo =
8831 ActivityThread.getPackageManager().resolveService(
8832 service, resolvedType, PackageManager.GET_SHARED_LIBRARY_FILES);
8833 ServiceInfo sInfo =
8834 rInfo != null ? rInfo.serviceInfo : null;
8835 if (sInfo == null) {
8836 Log.w(TAG, "Unable to start service " + service +
8837 ": not found");
8838 return null;
8839 }
8840
8841 ComponentName name = new ComponentName(
8842 sInfo.applicationInfo.packageName, sInfo.name);
8843 r = mServices.get(name);
8844 if (r == null) {
8845 filter = new Intent.FilterComparison(service.cloneFilter());
8846 ServiceRestarter res = new ServiceRestarter();
8847 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
8848 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8849 synchronized (stats) {
8850 ss = stats.getServiceStatsLocked(
8851 sInfo.applicationInfo.uid, sInfo.packageName,
8852 sInfo.name);
8853 }
8854 r = new ServiceRecord(ss, name, filter, sInfo, res);
8855 res.setService(r);
8856 mServices.put(name, r);
8857 mServicesByIntent.put(filter, r);
8858
8859 // Make sure this component isn't in the pending list.
8860 int N = mPendingServices.size();
8861 for (int i=0; i<N; i++) {
8862 ServiceRecord pr = mPendingServices.get(i);
8863 if (pr.name.equals(name)) {
8864 mPendingServices.remove(i);
8865 i--;
8866 N--;
8867 }
8868 }
8869 }
8870 } catch (RemoteException ex) {
8871 // pm is in same process, this will never happen.
8872 }
8873 }
8874 if (r != null) {
8875 if (checkComponentPermission(r.permission,
8876 callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
8877 != PackageManager.PERMISSION_GRANTED) {
8878 Log.w(TAG, "Permission Denial: Accessing service " + r.name
8879 + " from pid=" + Binder.getCallingPid()
8880 + ", uid=" + Binder.getCallingUid()
8881 + " requires " + r.permission);
8882 return new ServiceLookupResult(null, r.permission);
8883 }
8884 return new ServiceLookupResult(r, null);
8885 }
8886 return null;
8887 }
8888
8889 private final void bumpServiceExecutingLocked(ServiceRecord r) {
8890 long now = SystemClock.uptimeMillis();
8891 if (r.executeNesting == 0 && r.app != null) {
8892 if (r.app.executingServices.size() == 0) {
8893 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
8894 msg.obj = r.app;
8895 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
8896 }
8897 r.app.executingServices.add(r);
8898 }
8899 r.executeNesting++;
8900 r.executingStart = now;
8901 }
8902
8903 private final void sendServiceArgsLocked(ServiceRecord r,
8904 boolean oomAdjusted) {
8905 final int N = r.startArgs.size();
8906 if (N == 0) {
8907 return;
8908 }
8909
8910 final int BASEID = r.lastStartId - N + 1;
8911 int i = 0;
8912 while (i < N) {
8913 try {
8914 Intent args = r.startArgs.get(i);
8915 if (DEBUG_SERVICE) Log.v(TAG, "Sending arguments to service: "
8916 + r.name + " " + r.intent + " args=" + args);
8917 bumpServiceExecutingLocked(r);
8918 if (!oomAdjusted) {
8919 oomAdjusted = true;
8920 updateOomAdjLocked(r.app);
8921 }
8922 r.app.thread.scheduleServiceArgs(r, BASEID+i, args);
8923 i++;
8924 } catch (Exception e) {
8925 break;
8926 }
8927 }
8928 if (i == N) {
8929 r.startArgs.clear();
8930 } else {
8931 while (i > 0) {
8932 r.startArgs.remove(0);
8933 i--;
8934 }
8935 }
8936 }
8937
8938 private final boolean requestServiceBindingLocked(ServiceRecord r,
8939 IntentBindRecord i, boolean rebind) {
8940 if (r.app == null || r.app.thread == null) {
8941 // If service is not currently running, can't yet bind.
8942 return false;
8943 }
8944 if ((!i.requested || rebind) && i.apps.size() > 0) {
8945 try {
8946 bumpServiceExecutingLocked(r);
8947 if (DEBUG_SERVICE) Log.v(TAG, "Connecting binding " + i
8948 + ": shouldUnbind=" + i.hasBound);
8949 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
8950 if (!rebind) {
8951 i.requested = true;
8952 }
8953 i.hasBound = true;
8954 i.doRebind = false;
8955 } catch (RemoteException e) {
8956 return false;
8957 }
8958 }
8959 return true;
8960 }
8961
8962 private final void requestServiceBindingsLocked(ServiceRecord r) {
8963 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
8964 while (bindings.hasNext()) {
8965 IntentBindRecord i = bindings.next();
8966 if (!requestServiceBindingLocked(r, i, false)) {
8967 break;
8968 }
8969 }
8970 }
8971
8972 private final void realStartServiceLocked(ServiceRecord r,
8973 ProcessRecord app) throws RemoteException {
8974 if (app.thread == null) {
8975 throw new RemoteException();
8976 }
8977
8978 r.app = app;
8979 r.restartTime = SystemClock.uptimeMillis();
8980
8981 app.services.add(r);
8982 bumpServiceExecutingLocked(r);
8983 updateLRUListLocked(app, true);
8984
8985 boolean created = false;
8986 try {
8987 if (DEBUG_SERVICE) Log.v(TAG, "Scheduling start service: "
8988 + r.name + " " + r.intent);
8989 EventLog.writeEvent(LOG_AM_CREATE_SERVICE,
8990 System.identityHashCode(r), r.shortName,
8991 r.intent.getIntent().toString(), r.app.pid);
8992 synchronized (r.stats.getBatteryStats()) {
8993 r.stats.startLaunchedLocked();
8994 }
8995 app.thread.scheduleCreateService(r, r.serviceInfo);
8996 created = true;
8997 } finally {
8998 if (!created) {
8999 app.services.remove(r);
9000 scheduleServiceRestartLocked(r);
9001 }
9002 }
9003
9004 requestServiceBindingsLocked(r);
9005 sendServiceArgsLocked(r, true);
9006 }
9007
9008 private final void scheduleServiceRestartLocked(ServiceRecord r) {
9009 r.totalRestartCount++;
9010 if (r.restartDelay == 0) {
9011 r.restartCount++;
9012 r.restartDelay = SERVICE_RESTART_DURATION;
9013 } else {
9014 // If it has been a "reasonably long time" since the service
9015 // was started, then reset our restart duration back to
9016 // the beginning, so we don't infinitely increase the duration
9017 // on a service that just occasionally gets killed (which is
9018 // a normal case, due to process being killed to reclaim memory).
9019 long now = SystemClock.uptimeMillis();
9020 if (now > (r.restartTime+(SERVICE_RESTART_DURATION*2*2*2))) {
9021 r.restartCount = 1;
9022 r.restartDelay = SERVICE_RESTART_DURATION;
9023 } else {
9024 r.restartDelay *= 2;
9025 }
9026 }
9027 if (!mRestartingServices.contains(r)) {
9028 mRestartingServices.add(r);
9029 }
9030 mHandler.removeCallbacks(r.restarter);
9031 mHandler.postDelayed(r.restarter, r.restartDelay);
9032 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
9033 Log.w(TAG, "Scheduling restart of crashed service "
9034 + r.shortName + " in " + r.restartDelay + "ms");
9035 EventLog.writeEvent(LOG_AM_SCHEDULE_SERVICE_RESTART,
9036 r.shortName, r.restartDelay);
9037
9038 Message msg = Message.obtain();
9039 msg.what = SERVICE_ERROR_MSG;
9040 msg.obj = r;
9041 mHandler.sendMessage(msg);
9042 }
9043
9044 final void performServiceRestartLocked(ServiceRecord r) {
9045 if (!mRestartingServices.contains(r)) {
9046 return;
9047 }
9048 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
9049 }
9050
9051 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
9052 if (r.restartDelay == 0) {
9053 return false;
9054 }
9055 r.resetRestartCounter();
9056 mRestartingServices.remove(r);
9057 mHandler.removeCallbacks(r.restarter);
9058 return true;
9059 }
9060
9061 private final boolean bringUpServiceLocked(ServiceRecord r,
9062 int intentFlags, boolean whileRestarting) {
9063 //Log.i(TAG, "Bring up service:");
9064 //r.dump(" ");
9065
9066 if (r.app != null) {
9067 sendServiceArgsLocked(r, false);
9068 return true;
9069 }
9070
9071 if (!whileRestarting && r.restartDelay > 0) {
9072 // If waiting for a restart, then do nothing.
9073 return true;
9074 }
9075
9076 if (DEBUG_SERVICE) Log.v(TAG, "Bringing up service " + r.name
9077 + " " + r.intent);
9078
9079 final String appName = r.processName;
9080 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
9081 if (app != null && app.thread != null) {
9082 try {
9083 realStartServiceLocked(r, app);
9084 return true;
9085 } catch (RemoteException e) {
9086 Log.w(TAG, "Exception when starting service " + r.shortName, e);
9087 }
9088
9089 // If a dead object exception was thrown -- fall through to
9090 // restart the application.
9091 }
9092
9093 if (!mPendingServices.contains(r)) {
9094 // Not running -- get it started, and enqueue this service record
9095 // to be executed when the app comes up.
9096 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
9097 "service", r.name) == null) {
9098 Log.w(TAG, "Unable to launch app "
9099 + r.appInfo.packageName + "/"
9100 + r.appInfo.uid + " for service "
9101 + r.intent.getIntent() + ": process is bad");
9102 bringDownServiceLocked(r, true);
9103 return false;
9104 }
9105 mPendingServices.add(r);
9106 }
9107 return true;
9108 }
9109
9110 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
9111 //Log.i(TAG, "Bring down service:");
9112 //r.dump(" ");
9113
9114 // Does it still need to run?
9115 if (!force && r.startRequested) {
9116 return;
9117 }
9118 if (r.connections.size() > 0) {
9119 if (!force) {
9120 // XXX should probably keep a count of the number of auto-create
9121 // connections directly in the service.
9122 Iterator<ConnectionRecord> it = r.connections.values().iterator();
9123 while (it.hasNext()) {
9124 ConnectionRecord cr = it.next();
9125 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
9126 return;
9127 }
9128 }
9129 }
9130
9131 // Report to all of the connections that the service is no longer
9132 // available.
9133 Iterator<ConnectionRecord> it = r.connections.values().iterator();
9134 while (it.hasNext()) {
9135 ConnectionRecord c = it.next();
9136 try {
9137 // todo: shouldn't be a synchronous call!
9138 c.conn.connected(r.name, null);
9139 } catch (Exception e) {
9140 Log.w(TAG, "Failure disconnecting service " + r.name +
9141 " to connection " + c.conn.asBinder() +
9142 " (in " + c.binding.client.processName + ")", e);
9143 }
9144 }
9145 }
9146
9147 // Tell the service that it has been unbound.
9148 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
9149 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
9150 while (it.hasNext()) {
9151 IntentBindRecord ibr = it.next();
9152 if (DEBUG_SERVICE) Log.v(TAG, "Bringing down binding " + ibr
9153 + ": hasBound=" + ibr.hasBound);
9154 if (r.app != null && r.app.thread != null && ibr.hasBound) {
9155 try {
9156 bumpServiceExecutingLocked(r);
9157 updateOomAdjLocked(r.app);
9158 ibr.hasBound = false;
9159 r.app.thread.scheduleUnbindService(r,
9160 ibr.intent.getIntent());
9161 } catch (Exception e) {
9162 Log.w(TAG, "Exception when unbinding service "
9163 + r.shortName, e);
9164 serviceDoneExecutingLocked(r, true);
9165 }
9166 }
9167 }
9168 }
9169
9170 if (DEBUG_SERVICE) Log.v(TAG, "Bringing down service " + r.name
9171 + " " + r.intent);
9172 EventLog.writeEvent(LOG_AM_DESTROY_SERVICE,
9173 System.identityHashCode(r), r.shortName,
9174 (r.app != null) ? r.app.pid : -1);
9175
9176 mServices.remove(r.name);
9177 mServicesByIntent.remove(r.intent);
9178 if (localLOGV) Log.v(TAG, "BRING DOWN SERVICE: " + r.shortName);
9179 r.totalRestartCount = 0;
9180 unscheduleServiceRestartLocked(r);
9181
9182 // Also make sure it is not on the pending list.
9183 int N = mPendingServices.size();
9184 for (int i=0; i<N; i++) {
9185 if (mPendingServices.get(i) == r) {
9186 mPendingServices.remove(i);
9187 if (DEBUG_SERVICE) Log.v(
9188 TAG, "Removed pending service: " + r.shortName);
9189 i--;
9190 N--;
9191 }
9192 }
9193
9194 if (r.app != null) {
9195 synchronized (r.stats.getBatteryStats()) {
9196 r.stats.stopLaunchedLocked();
9197 }
9198 r.app.services.remove(r);
9199 if (r.app.thread != null) {
9200 updateServiceForegroundLocked(r.app, false);
9201 try {
9202 Log.i(TAG, "Stopping service: " + r.shortName);
9203 bumpServiceExecutingLocked(r);
9204 mStoppingServices.add(r);
9205 updateOomAdjLocked(r.app);
9206 r.app.thread.scheduleStopService(r);
9207 } catch (Exception e) {
9208 Log.w(TAG, "Exception when stopping service "
9209 + r.shortName, e);
9210 serviceDoneExecutingLocked(r, true);
9211 }
9212 } else {
9213 if (DEBUG_SERVICE) Log.v(
9214 TAG, "Removed service that has no process: " + r.shortName);
9215 }
9216 } else {
9217 if (DEBUG_SERVICE) Log.v(
9218 TAG, "Removed service that is not running: " + r.shortName);
9219 }
9220 }
9221
9222 ComponentName startServiceLocked(IApplicationThread caller,
9223 Intent service, String resolvedType,
9224 int callingPid, int callingUid) {
9225 synchronized(this) {
9226 if (DEBUG_SERVICE) Log.v(TAG, "startService: " + service
9227 + " type=" + resolvedType + " args=" + service.getExtras());
9228
9229 if (caller != null) {
9230 final ProcessRecord callerApp = getRecordForAppLocked(caller);
9231 if (callerApp == null) {
9232 throw new SecurityException(
9233 "Unable to find app for caller " + caller
9234 + " (pid=" + Binder.getCallingPid()
9235 + ") when starting service " + service);
9236 }
9237 }
9238
9239 ServiceLookupResult res =
9240 retrieveServiceLocked(service, resolvedType,
9241 callingPid, callingUid);
9242 if (res == null) {
9243 return null;
9244 }
9245 if (res.record == null) {
9246 return new ComponentName("!", res.permission != null
9247 ? res.permission : "private to package");
9248 }
9249 ServiceRecord r = res.record;
9250 if (unscheduleServiceRestartLocked(r)) {
9251 if (DEBUG_SERVICE) Log.v(TAG, "START SERVICE WHILE RESTART PENDING: "
9252 + r.shortName);
9253 }
9254 r.startRequested = true;
9255 r.startArgs.add(service);
9256 r.lastStartId++;
9257 if (r.lastStartId < 1) {
9258 r.lastStartId = 1;
9259 }
9260 r.lastActivity = SystemClock.uptimeMillis();
9261 synchronized (r.stats.getBatteryStats()) {
9262 r.stats.startRunningLocked();
9263 }
9264 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
9265 return new ComponentName("!", "Service process is bad");
9266 }
9267 return r.name;
9268 }
9269 }
9270
9271 public ComponentName startService(IApplicationThread caller, Intent service,
9272 String resolvedType) {
9273 // Refuse possible leaked file descriptors
9274 if (service != null && service.hasFileDescriptors() == true) {
9275 throw new IllegalArgumentException("File descriptors passed in Intent");
9276 }
9277
9278 synchronized(this) {
9279 final int callingPid = Binder.getCallingPid();
9280 final int callingUid = Binder.getCallingUid();
9281 final long origId = Binder.clearCallingIdentity();
9282 ComponentName res = startServiceLocked(caller, service,
9283 resolvedType, callingPid, callingUid);
9284 Binder.restoreCallingIdentity(origId);
9285 return res;
9286 }
9287 }
9288
9289 ComponentName startServiceInPackage(int uid,
9290 Intent service, String resolvedType) {
9291 synchronized(this) {
9292 final long origId = Binder.clearCallingIdentity();
9293 ComponentName res = startServiceLocked(null, service,
9294 resolvedType, -1, uid);
9295 Binder.restoreCallingIdentity(origId);
9296 return res;
9297 }
9298 }
9299
9300 public int stopService(IApplicationThread caller, Intent service,
9301 String resolvedType) {
9302 // Refuse possible leaked file descriptors
9303 if (service != null && service.hasFileDescriptors() == true) {
9304 throw new IllegalArgumentException("File descriptors passed in Intent");
9305 }
9306
9307 synchronized(this) {
9308 if (DEBUG_SERVICE) Log.v(TAG, "stopService: " + service
9309 + " type=" + resolvedType);
9310
9311 final ProcessRecord callerApp = getRecordForAppLocked(caller);
9312 if (caller != null && callerApp == null) {
9313 throw new SecurityException(
9314 "Unable to find app for caller " + caller
9315 + " (pid=" + Binder.getCallingPid()
9316 + ") when stopping service " + service);
9317 }
9318
9319 // If this service is active, make sure it is stopped.
9320 ServiceLookupResult r = findServiceLocked(service, resolvedType);
9321 if (r != null) {
9322 if (r.record != null) {
9323 synchronized (r.record.stats.getBatteryStats()) {
9324 r.record.stats.stopRunningLocked();
9325 }
9326 r.record.startRequested = false;
9327 final long origId = Binder.clearCallingIdentity();
9328 bringDownServiceLocked(r.record, false);
9329 Binder.restoreCallingIdentity(origId);
9330 return 1;
9331 }
9332 return -1;
9333 }
9334 }
9335
9336 return 0;
9337 }
9338
9339 public IBinder peekService(Intent service, String resolvedType) {
9340 // Refuse possible leaked file descriptors
9341 if (service != null && service.hasFileDescriptors() == true) {
9342 throw new IllegalArgumentException("File descriptors passed in Intent");
9343 }
9344
9345 IBinder ret = null;
9346
9347 synchronized(this) {
9348 ServiceLookupResult r = findServiceLocked(service, resolvedType);
9349
9350 if (r != null) {
9351 // r.record is null if findServiceLocked() failed the caller permission check
9352 if (r.record == null) {
9353 throw new SecurityException(
9354 "Permission Denial: Accessing service " + r.record.name
9355 + " from pid=" + Binder.getCallingPid()
9356 + ", uid=" + Binder.getCallingUid()
9357 + " requires " + r.permission);
9358 }
9359 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
9360 if (ib != null) {
9361 ret = ib.binder;
9362 }
9363 }
9364 }
9365
9366 return ret;
9367 }
9368
9369 public boolean stopServiceToken(ComponentName className, IBinder token,
9370 int startId) {
9371 synchronized(this) {
9372 if (DEBUG_SERVICE) Log.v(TAG, "stopServiceToken: " + className
9373 + " " + token + " startId=" + startId);
9374 ServiceRecord r = findServiceLocked(className, token);
9375 if (r != null && (startId < 0 || r.lastStartId == startId)) {
9376 synchronized (r.stats.getBatteryStats()) {
9377 r.stats.stopRunningLocked();
9378 r.startRequested = false;
9379 }
9380 final long origId = Binder.clearCallingIdentity();
9381 bringDownServiceLocked(r, false);
9382 Binder.restoreCallingIdentity(origId);
9383 return true;
9384 }
9385 }
9386 return false;
9387 }
9388
9389 public void setServiceForeground(ComponentName className, IBinder token,
9390 boolean isForeground) {
9391 synchronized(this) {
9392 ServiceRecord r = findServiceLocked(className, token);
9393 if (r != null) {
9394 if (r.isForeground != isForeground) {
9395 final long origId = Binder.clearCallingIdentity();
9396 r.isForeground = isForeground;
9397 if (r.app != null) {
9398 updateServiceForegroundLocked(r.app, true);
9399 }
9400 Binder.restoreCallingIdentity(origId);
9401 }
9402 }
9403 }
9404 }
9405
9406 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
9407 boolean anyForeground = false;
9408 for (ServiceRecord sr : (HashSet<ServiceRecord>)proc.services) {
9409 if (sr.isForeground) {
9410 anyForeground = true;
9411 break;
9412 }
9413 }
9414 if (anyForeground != proc.foregroundServices) {
9415 proc.foregroundServices = anyForeground;
9416 if (oomAdj) {
9417 updateOomAdjLocked();
9418 }
9419 }
9420 }
9421
9422 public int bindService(IApplicationThread caller, IBinder token,
9423 Intent service, String resolvedType,
9424 IServiceConnection connection, int flags) {
9425 // Refuse possible leaked file descriptors
9426 if (service != null && service.hasFileDescriptors() == true) {
9427 throw new IllegalArgumentException("File descriptors passed in Intent");
9428 }
9429
9430 synchronized(this) {
9431 if (DEBUG_SERVICE) Log.v(TAG, "bindService: " + service
9432 + " type=" + resolvedType + " conn=" + connection.asBinder()
9433 + " flags=0x" + Integer.toHexString(flags));
9434 final ProcessRecord callerApp = getRecordForAppLocked(caller);
9435 if (callerApp == null) {
9436 throw new SecurityException(
9437 "Unable to find app for caller " + caller
9438 + " (pid=" + Binder.getCallingPid()
9439 + ") when binding service " + service);
9440 }
9441
9442 HistoryRecord activity = null;
9443 if (token != null) {
9444 int aindex = indexOfTokenLocked(token, false);
9445 if (aindex < 0) {
9446 Log.w(TAG, "Binding with unknown activity: " + token);
9447 return 0;
9448 }
9449 activity = (HistoryRecord)mHistory.get(aindex);
9450 }
9451
9452 ServiceLookupResult res =
9453 retrieveServiceLocked(service, resolvedType,
9454 Binder.getCallingPid(), Binder.getCallingUid());
9455 if (res == null) {
9456 return 0;
9457 }
9458 if (res.record == null) {
9459 return -1;
9460 }
9461 ServiceRecord s = res.record;
9462
9463 final long origId = Binder.clearCallingIdentity();
9464
9465 if (unscheduleServiceRestartLocked(s)) {
9466 if (DEBUG_SERVICE) Log.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
9467 + s.shortName);
9468 }
9469
9470 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
9471 ConnectionRecord c = new ConnectionRecord(b, activity,
9472 connection, flags);
9473
9474 IBinder binder = connection.asBinder();
9475 s.connections.put(binder, c);
9476 b.connections.add(c);
9477 if (activity != null) {
9478 if (activity.connections == null) {
9479 activity.connections = new HashSet<ConnectionRecord>();
9480 }
9481 activity.connections.add(c);
9482 }
9483 b.client.connections.add(c);
9484 mServiceConnections.put(binder, c);
9485
9486 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
9487 s.lastActivity = SystemClock.uptimeMillis();
9488 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
9489 return 0;
9490 }
9491 }
9492
9493 if (s.app != null) {
9494 // This could have made the service more important.
9495 updateOomAdjLocked(s.app);
9496 }
9497
9498 if (DEBUG_SERVICE) Log.v(TAG, "Bind " + s + " with " + b
9499 + ": received=" + b.intent.received
9500 + " apps=" + b.intent.apps.size()
9501 + " doRebind=" + b.intent.doRebind);
9502
9503 if (s.app != null && b.intent.received) {
9504 // Service is already running, so we can immediately
9505 // publish the connection.
9506 try {
9507 c.conn.connected(s.name, b.intent.binder);
9508 } catch (Exception e) {
9509 Log.w(TAG, "Failure sending service " + s.shortName
9510 + " to connection " + c.conn.asBinder()
9511 + " (in " + c.binding.client.processName + ")", e);
9512 }
9513
9514 // If this is the first app connected back to this binding,
9515 // and the service had previously asked to be told when
9516 // rebound, then do so.
9517 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
9518 requestServiceBindingLocked(s, b.intent, true);
9519 }
9520 } else if (!b.intent.requested) {
9521 requestServiceBindingLocked(s, b.intent, false);
9522 }
9523
9524 Binder.restoreCallingIdentity(origId);
9525 }
9526
9527 return 1;
9528 }
9529
9530 private void removeConnectionLocked(
9531 ConnectionRecord c, ProcessRecord skipApp, HistoryRecord skipAct) {
9532 IBinder binder = c.conn.asBinder();
9533 AppBindRecord b = c.binding;
9534 ServiceRecord s = b.service;
9535 s.connections.remove(binder);
9536 b.connections.remove(c);
9537 if (c.activity != null && c.activity != skipAct) {
9538 if (c.activity.connections != null) {
9539 c.activity.connections.remove(c);
9540 }
9541 }
9542 if (b.client != skipApp) {
9543 b.client.connections.remove(c);
9544 }
9545 mServiceConnections.remove(binder);
9546
9547 if (b.connections.size() == 0) {
9548 b.intent.apps.remove(b.client);
9549 }
9550
9551 if (DEBUG_SERVICE) Log.v(TAG, "Disconnecting binding " + b.intent
9552 + ": shouldUnbind=" + b.intent.hasBound);
9553 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
9554 && b.intent.hasBound) {
9555 try {
9556 bumpServiceExecutingLocked(s);
9557 updateOomAdjLocked(s.app);
9558 b.intent.hasBound = false;
9559 // Assume the client doesn't want to know about a rebind;
9560 // we will deal with that later if it asks for one.
9561 b.intent.doRebind = false;
9562 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
9563 } catch (Exception e) {
9564 Log.w(TAG, "Exception when unbinding service " + s.shortName, e);
9565 serviceDoneExecutingLocked(s, true);
9566 }
9567 }
9568
9569 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
9570 bringDownServiceLocked(s, false);
9571 }
9572 }
9573
9574 public boolean unbindService(IServiceConnection connection) {
9575 synchronized (this) {
9576 IBinder binder = connection.asBinder();
9577 if (DEBUG_SERVICE) Log.v(TAG, "unbindService: conn=" + binder);
9578 ConnectionRecord r = mServiceConnections.get(binder);
9579 if (r == null) {
9580 Log.w(TAG, "Unbind failed: could not find connection for "
9581 + connection.asBinder());
9582 return false;
9583 }
9584
9585 final long origId = Binder.clearCallingIdentity();
9586
9587 removeConnectionLocked(r, null, null);
9588
9589 if (r.binding.service.app != null) {
9590 // This could have made the service less important.
9591 updateOomAdjLocked(r.binding.service.app);
9592 }
9593
9594 Binder.restoreCallingIdentity(origId);
9595 }
9596
9597 return true;
9598 }
9599
9600 public void publishService(IBinder token, Intent intent, IBinder service) {
9601 // Refuse possible leaked file descriptors
9602 if (intent != null && intent.hasFileDescriptors() == true) {
9603 throw new IllegalArgumentException("File descriptors passed in Intent");
9604 }
9605
9606 synchronized(this) {
9607 if (!(token instanceof ServiceRecord)) {
9608 throw new IllegalArgumentException("Invalid service token");
9609 }
9610 ServiceRecord r = (ServiceRecord)token;
9611
9612 final long origId = Binder.clearCallingIdentity();
9613
9614 if (DEBUG_SERVICE) Log.v(TAG, "PUBLISHING SERVICE " + r.name
9615 + " " + intent + ": " + service);
9616 if (r != null) {
9617 Intent.FilterComparison filter
9618 = new Intent.FilterComparison(intent);
9619 IntentBindRecord b = r.bindings.get(filter);
9620 if (b != null && !b.received) {
9621 b.binder = service;
9622 b.requested = true;
9623 b.received = true;
9624 if (r.connections.size() > 0) {
9625 Iterator<ConnectionRecord> it
9626 = r.connections.values().iterator();
9627 while (it.hasNext()) {
9628 ConnectionRecord c = it.next();
9629 if (!filter.equals(c.binding.intent.intent)) {
9630 if (DEBUG_SERVICE) Log.v(
9631 TAG, "Not publishing to: " + c);
9632 if (DEBUG_SERVICE) Log.v(
9633 TAG, "Bound intent: " + c.binding.intent.intent);
9634 if (DEBUG_SERVICE) Log.v(
9635 TAG, "Published intent: " + intent);
9636 continue;
9637 }
9638 if (DEBUG_SERVICE) Log.v(TAG, "Publishing to: " + c);
9639 try {
9640 c.conn.connected(r.name, service);
9641 } catch (Exception e) {
9642 Log.w(TAG, "Failure sending service " + r.name +
9643 " to connection " + c.conn.asBinder() +
9644 " (in " + c.binding.client.processName + ")", e);
9645 }
9646 }
9647 }
9648 }
9649
9650 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
9651
9652 Binder.restoreCallingIdentity(origId);
9653 }
9654 }
9655 }
9656
9657 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
9658 // Refuse possible leaked file descriptors
9659 if (intent != null && intent.hasFileDescriptors() == true) {
9660 throw new IllegalArgumentException("File descriptors passed in Intent");
9661 }
9662
9663 synchronized(this) {
9664 if (!(token instanceof ServiceRecord)) {
9665 throw new IllegalArgumentException("Invalid service token");
9666 }
9667 ServiceRecord r = (ServiceRecord)token;
9668
9669 final long origId = Binder.clearCallingIdentity();
9670
9671 if (r != null) {
9672 Intent.FilterComparison filter
9673 = new Intent.FilterComparison(intent);
9674 IntentBindRecord b = r.bindings.get(filter);
9675 if (DEBUG_SERVICE) Log.v(TAG, "unbindFinished in " + r
9676 + " at " + b + ": apps="
9677 + (b != null ? b.apps.size() : 0));
9678 if (b != null) {
9679 if (b.apps.size() > 0) {
9680 // Applications have already bound since the last
9681 // unbind, so just rebind right here.
9682 requestServiceBindingLocked(r, b, true);
9683 } else {
9684 // Note to tell the service the next time there is
9685 // a new client.
9686 b.doRebind = true;
9687 }
9688 }
9689
9690 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
9691
9692 Binder.restoreCallingIdentity(origId);
9693 }
9694 }
9695 }
9696
9697 public void serviceDoneExecuting(IBinder token) {
9698 synchronized(this) {
9699 if (!(token instanceof ServiceRecord)) {
9700 throw new IllegalArgumentException("Invalid service token");
9701 }
9702 ServiceRecord r = (ServiceRecord)token;
9703 boolean inStopping = mStoppingServices.contains(token);
9704 if (r != null) {
9705 if (DEBUG_SERVICE) Log.v(TAG, "DONE EXECUTING SERVICE " + r.name
9706 + ": nesting=" + r.executeNesting
9707 + ", inStopping=" + inStopping);
9708 if (r != token) {
9709 Log.w(TAG, "Done executing service " + r.name
9710 + " with incorrect token: given " + token
9711 + ", expected " + r);
9712 return;
9713 }
9714
9715 final long origId = Binder.clearCallingIdentity();
9716 serviceDoneExecutingLocked(r, inStopping);
9717 Binder.restoreCallingIdentity(origId);
9718 } else {
9719 Log.w(TAG, "Done executing unknown service " + r.name
9720 + " with token " + token);
9721 }
9722 }
9723 }
9724
9725 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
9726 r.executeNesting--;
9727 if (r.executeNesting <= 0 && r.app != null) {
9728 r.app.executingServices.remove(r);
9729 if (r.app.executingServices.size() == 0) {
9730 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
9731 }
9732 if (inStopping) {
9733 mStoppingServices.remove(r);
9734 }
9735 updateOomAdjLocked(r.app);
9736 }
9737 }
9738
9739 void serviceTimeout(ProcessRecord proc) {
9740 synchronized(this) {
9741 if (proc.executingServices.size() == 0 || proc.thread == null) {
9742 return;
9743 }
9744 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
9745 Iterator<ServiceRecord> it = proc.executingServices.iterator();
9746 ServiceRecord timeout = null;
9747 long nextTime = 0;
9748 while (it.hasNext()) {
9749 ServiceRecord sr = it.next();
9750 if (sr.executingStart < maxTime) {
9751 timeout = sr;
9752 break;
9753 }
9754 if (sr.executingStart > nextTime) {
9755 nextTime = sr.executingStart;
9756 }
9757 }
9758 if (timeout != null && mLRUProcesses.contains(proc)) {
9759 Log.w(TAG, "Timeout executing service: " + timeout);
9760 appNotRespondingLocked(proc, null, "Executing service "
9761 + timeout.name);
9762 } else {
9763 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9764 msg.obj = proc;
9765 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
9766 }
9767 }
9768 }
9769
9770 // =========================================================
9771 // BROADCASTS
9772 // =========================================================
9773
9774 private final List getStickies(String action, IntentFilter filter,
9775 List cur) {
9776 final ContentResolver resolver = mContext.getContentResolver();
9777 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
9778 if (list == null) {
9779 return cur;
9780 }
9781 int N = list.size();
9782 for (int i=0; i<N; i++) {
9783 Intent intent = list.get(i);
9784 if (filter.match(resolver, intent, true, TAG) >= 0) {
9785 if (cur == null) {
9786 cur = new ArrayList<Intent>();
9787 }
9788 cur.add(intent);
9789 }
9790 }
9791 return cur;
9792 }
9793
9794 private final void scheduleBroadcastsLocked() {
9795 if (DEBUG_BROADCAST) Log.v(TAG, "Schedule broadcasts: current="
9796 + mBroadcastsScheduled);
9797
9798 if (mBroadcastsScheduled) {
9799 return;
9800 }
9801 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
9802 mBroadcastsScheduled = true;
9803 }
9804
9805 public Intent registerReceiver(IApplicationThread caller,
9806 IIntentReceiver receiver, IntentFilter filter, String permission) {
9807 synchronized(this) {
9808 ProcessRecord callerApp = null;
9809 if (caller != null) {
9810 callerApp = getRecordForAppLocked(caller);
9811 if (callerApp == null) {
9812 throw new SecurityException(
9813 "Unable to find app for caller " + caller
9814 + " (pid=" + Binder.getCallingPid()
9815 + ") when registering receiver " + receiver);
9816 }
9817 }
9818
9819 List allSticky = null;
9820
9821 // Look for any matching sticky broadcasts...
9822 Iterator actions = filter.actionsIterator();
9823 if (actions != null) {
9824 while (actions.hasNext()) {
9825 String action = (String)actions.next();
9826 allSticky = getStickies(action, filter, allSticky);
9827 }
9828 } else {
9829 allSticky = getStickies(null, filter, allSticky);
9830 }
9831
9832 // The first sticky in the list is returned directly back to
9833 // the client.
9834 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
9835
9836 if (DEBUG_BROADCAST) Log.v(TAG, "Register receiver " + filter
9837 + ": " + sticky);
9838
9839 if (receiver == null) {
9840 return sticky;
9841 }
9842
9843 ReceiverList rl
9844 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
9845 if (rl == null) {
9846 rl = new ReceiverList(this, callerApp,
9847 Binder.getCallingPid(),
9848 Binder.getCallingUid(), receiver);
9849 if (rl.app != null) {
9850 rl.app.receivers.add(rl);
9851 } else {
9852 try {
9853 receiver.asBinder().linkToDeath(rl, 0);
9854 } catch (RemoteException e) {
9855 return sticky;
9856 }
9857 rl.linkedToDeath = true;
9858 }
9859 mRegisteredReceivers.put(receiver.asBinder(), rl);
9860 }
9861 BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
9862 rl.add(bf);
9863 if (!bf.debugCheck()) {
9864 Log.w(TAG, "==> For Dynamic broadast");
9865 }
9866 mReceiverResolver.addFilter(bf);
9867
9868 // Enqueue broadcasts for all existing stickies that match
9869 // this filter.
9870 if (allSticky != null) {
9871 ArrayList receivers = new ArrayList();
9872 receivers.add(bf);
9873
9874 int N = allSticky.size();
9875 for (int i=0; i<N; i++) {
9876 Intent intent = (Intent)allSticky.get(i);
9877 BroadcastRecord r = new BroadcastRecord(intent, null,
9878 null, -1, -1, null, receivers, null, 0, null, null,
9879 false);
9880 if (mParallelBroadcasts.size() == 0) {
9881 scheduleBroadcastsLocked();
9882 }
9883 mParallelBroadcasts.add(r);
9884 }
9885 }
9886
9887 return sticky;
9888 }
9889 }
9890
9891 public void unregisterReceiver(IIntentReceiver receiver) {
9892 if (DEBUG_BROADCAST) Log.v(TAG, "Unregister receiver: " + receiver);
9893
9894 boolean doNext = false;
9895
9896 synchronized(this) {
9897 ReceiverList rl
9898 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
9899 if (rl != null) {
9900 if (rl.curBroadcast != null) {
9901 BroadcastRecord r = rl.curBroadcast;
9902 doNext = finishReceiverLocked(
9903 receiver.asBinder(), r.resultCode, r.resultData,
9904 r.resultExtras, r.resultAbort, true);
9905 }
9906
9907 if (rl.app != null) {
9908 rl.app.receivers.remove(rl);
9909 }
9910 removeReceiverLocked(rl);
9911 if (rl.linkedToDeath) {
9912 rl.linkedToDeath = false;
9913 rl.receiver.asBinder().unlinkToDeath(rl, 0);
9914 }
9915 }
9916 }
9917
9918 if (!doNext) {
9919 return;
9920 }
9921
9922 final long origId = Binder.clearCallingIdentity();
9923 processNextBroadcast(false);
9924 trimApplications();
9925 Binder.restoreCallingIdentity(origId);
9926 }
9927
9928 void removeReceiverLocked(ReceiverList rl) {
9929 mRegisteredReceivers.remove(rl.receiver.asBinder());
9930 int N = rl.size();
9931 for (int i=0; i<N; i++) {
9932 mReceiverResolver.removeFilter(rl.get(i));
9933 }
9934 }
9935
9936 private final int broadcastIntentLocked(ProcessRecord callerApp,
9937 String callerPackage, Intent intent, String resolvedType,
9938 IIntentReceiver resultTo, int resultCode, String resultData,
9939 Bundle map, String requiredPermission,
9940 boolean ordered, boolean sticky, int callingPid, int callingUid) {
9941 intent = new Intent(intent);
9942
9943 if (DEBUG_BROADCAST) Log.v(
9944 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
9945 + " ordered=" + ordered);
9946 if ((resultTo != null) && !ordered) {
9947 Log.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
9948 }
9949
9950 // Handle special intents: if this broadcast is from the package
9951 // manager about a package being removed, we need to remove all of
9952 // its activities from the history stack.
9953 final boolean uidRemoved = intent.ACTION_UID_REMOVED.equals(
9954 intent.getAction());
9955 if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
9956 || intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
9957 || uidRemoved) {
9958 if (checkComponentPermission(
9959 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
9960 callingPid, callingUid, -1)
9961 == PackageManager.PERMISSION_GRANTED) {
9962 if (uidRemoved) {
9963 final Bundle intentExtras = intent.getExtras();
9964 final int uid = intentExtras != null
9965 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
9966 if (uid >= 0) {
9967 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
9968 synchronized (bs) {
9969 bs.removeUidStatsLocked(uid);
9970 }
9971 }
9972 } else {
9973 Uri data = intent.getData();
9974 String ssp;
9975 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
9976 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
9977 uninstallPackageLocked(ssp,
9978 intent.getIntExtra(Intent.EXTRA_UID, -1), false);
9979 }
9980 }
9981 }
9982 } else {
9983 String msg = "Permission Denial: " + intent.getAction()
9984 + " broadcast from " + callerPackage + " (pid=" + callingPid
9985 + ", uid=" + callingUid + ")"
9986 + " requires "
9987 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
9988 Log.w(TAG, msg);
9989 throw new SecurityException(msg);
9990 }
9991 }
9992
9993 /*
9994 * If this is the time zone changed action, queue up a message that will reset the timezone
9995 * of all currently running processes. This message will get queued up before the broadcast
9996 * happens.
9997 */
9998 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
9999 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
10000 }
10001
10002 // Add to the sticky list if requested.
10003 if (sticky) {
10004 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
10005 callingPid, callingUid)
10006 != PackageManager.PERMISSION_GRANTED) {
10007 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
10008 + callingPid + ", uid=" + callingUid
10009 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
10010 Log.w(TAG, msg);
10011 throw new SecurityException(msg);
10012 }
10013 if (requiredPermission != null) {
10014 Log.w(TAG, "Can't broadcast sticky intent " + intent
10015 + " and enforce permission " + requiredPermission);
10016 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
10017 }
10018 if (intent.getComponent() != null) {
10019 throw new SecurityException(
10020 "Sticky broadcasts can't target a specific component");
10021 }
10022 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
10023 if (list == null) {
10024 list = new ArrayList<Intent>();
10025 mStickyBroadcasts.put(intent.getAction(), list);
10026 }
10027 int N = list.size();
10028 int i;
10029 for (i=0; i<N; i++) {
10030 if (intent.filterEquals(list.get(i))) {
10031 // This sticky already exists, replace it.
10032 list.set(i, new Intent(intent));
10033 break;
10034 }
10035 }
10036 if (i >= N) {
10037 list.add(new Intent(intent));
10038 }
10039 }
10040
10041 final ContentResolver resolver = mContext.getContentResolver();
10042
10043 // Figure out who all will receive this broadcast.
10044 List receivers = null;
10045 List<BroadcastFilter> registeredReceivers = null;
10046 try {
10047 if (intent.getComponent() != null) {
10048 // Broadcast is going to one specific receiver class...
10049 ActivityInfo ai = ActivityThread.getPackageManager().
10050 getReceiverInfo(intent.getComponent(), 0);
10051 if (ai != null) {
10052 receivers = new ArrayList();
10053 ResolveInfo ri = new ResolveInfo();
10054 ri.activityInfo = ai;
10055 receivers.add(ri);
10056 }
10057 } else {
10058 // Need to resolve the intent to interested receivers...
10059 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
10060 == 0) {
10061 receivers =
10062 ActivityThread.getPackageManager().queryIntentReceivers(
10063 intent, resolvedType, PackageManager.GET_SHARED_LIBRARY_FILES);
10064 }
10065 registeredReceivers = mReceiverResolver.queryIntent(resolver,
10066 intent, resolvedType, false);
10067 }
10068 } catch (RemoteException ex) {
10069 // pm is in same process, this will never happen.
10070 }
10071
10072 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
10073 if (!ordered && NR > 0) {
10074 // If we are not serializing this broadcast, then send the
10075 // registered receivers separately so they don't wait for the
10076 // components to be launched.
10077 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
10078 callerPackage, callingPid, callingUid, requiredPermission,
10079 registeredReceivers, resultTo, resultCode, resultData, map,
10080 ordered);
10081 if (DEBUG_BROADCAST) Log.v(
10082 TAG, "Enqueueing parallel broadcast " + r
10083 + ": prev had " + mParallelBroadcasts.size());
10084 mParallelBroadcasts.add(r);
10085 scheduleBroadcastsLocked();
10086 registeredReceivers = null;
10087 NR = 0;
10088 }
10089
10090 // Merge into one list.
10091 int ir = 0;
10092 if (receivers != null) {
10093 // A special case for PACKAGE_ADDED: do not allow the package
10094 // being added to see this broadcast. This prevents them from
10095 // using this as a back door to get run as soon as they are
10096 // installed. Maybe in the future we want to have a special install
10097 // broadcast or such for apps, but we'd like to deliberately make
10098 // this decision.
10099 String skipPackage = (intent.ACTION_PACKAGE_ADDED.equals(
10100 intent.getAction()) && intent.getData() != null)
10101 ? intent.getData().getSchemeSpecificPart()
10102 : null;
10103 if (skipPackage != null && receivers != null) {
10104 int NT = receivers.size();
10105 for (int it=0; it<NT; it++) {
10106 ResolveInfo curt = (ResolveInfo)receivers.get(it);
10107 if (curt.activityInfo.packageName.equals(skipPackage)) {
10108 receivers.remove(it);
10109 it--;
10110 NT--;
10111 }
10112 }
10113 }
10114
10115 int NT = receivers != null ? receivers.size() : 0;
10116 int it = 0;
10117 ResolveInfo curt = null;
10118 BroadcastFilter curr = null;
10119 while (it < NT && ir < NR) {
10120 if (curt == null) {
10121 curt = (ResolveInfo)receivers.get(it);
10122 }
10123 if (curr == null) {
10124 curr = registeredReceivers.get(ir);
10125 }
10126 if (curr.getPriority() >= curt.priority) {
10127 // Insert this broadcast record into the final list.
10128 receivers.add(it, curr);
10129 ir++;
10130 curr = null;
10131 it++;
10132 NT++;
10133 } else {
10134 // Skip to the next ResolveInfo in the final list.
10135 it++;
10136 curt = null;
10137 }
10138 }
10139 }
10140 while (ir < NR) {
10141 if (receivers == null) {
10142 receivers = new ArrayList();
10143 }
10144 receivers.add(registeredReceivers.get(ir));
10145 ir++;
10146 }
10147
10148 if ((receivers != null && receivers.size() > 0)
10149 || resultTo != null) {
10150 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
10151 callerPackage, callingPid, callingUid, requiredPermission,
10152 receivers, resultTo, resultCode, resultData, map, ordered);
10153 if (DEBUG_BROADCAST) Log.v(
10154 TAG, "Enqueueing ordered broadcast " + r
10155 + ": prev had " + mOrderedBroadcasts.size());
10156 if (DEBUG_BROADCAST) {
10157 int seq = r.intent.getIntExtra("seq", -1);
10158 Log.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
10159 }
10160 mOrderedBroadcasts.add(r);
10161 scheduleBroadcastsLocked();
10162 }
10163
10164 return BROADCAST_SUCCESS;
10165 }
10166
10167 public final int broadcastIntent(IApplicationThread caller,
10168 Intent intent, String resolvedType, IIntentReceiver resultTo,
10169 int resultCode, String resultData, Bundle map,
10170 String requiredPermission, boolean serialized, boolean sticky) {
10171 // Refuse possible leaked file descriptors
10172 if (intent != null && intent.hasFileDescriptors() == true) {
10173 throw new IllegalArgumentException("File descriptors passed in Intent");
10174 }
10175
10176 synchronized(this) {
10177 if (!mSystemReady) {
10178 // if the caller really truly claims to know what they're doing, go
10179 // ahead and allow the broadcast without launching any receivers
10180 int flags = intent.getFlags();
10181 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
10182 intent = new Intent(intent);
10183 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10184 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0){
10185 Log.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
10186 + " before boot completion");
10187 throw new IllegalStateException("Cannot broadcast before boot completed");
10188 }
10189 }
10190
10191 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10192 final int callingPid = Binder.getCallingPid();
10193 final int callingUid = Binder.getCallingUid();
10194 final long origId = Binder.clearCallingIdentity();
10195 int res = broadcastIntentLocked(callerApp,
10196 callerApp != null ? callerApp.info.packageName : null,
10197 intent, resolvedType, resultTo,
10198 resultCode, resultData, map, requiredPermission, serialized,
10199 sticky, callingPid, callingUid);
10200 Binder.restoreCallingIdentity(origId);
10201 return res;
10202 }
10203 }
10204
10205 int broadcastIntentInPackage(String packageName, int uid,
10206 Intent intent, String resolvedType, IIntentReceiver resultTo,
10207 int resultCode, String resultData, Bundle map,
10208 String requiredPermission, boolean serialized, boolean sticky) {
10209 synchronized(this) {
10210 final long origId = Binder.clearCallingIdentity();
10211 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
10212 resultTo, resultCode, resultData, map, requiredPermission,
10213 serialized, sticky, -1, uid);
10214 Binder.restoreCallingIdentity(origId);
10215 return res;
10216 }
10217 }
10218
10219 public final void unbroadcastIntent(IApplicationThread caller,
10220 Intent intent) {
10221 // Refuse possible leaked file descriptors
10222 if (intent != null && intent.hasFileDescriptors() == true) {
10223 throw new IllegalArgumentException("File descriptors passed in Intent");
10224 }
10225
10226 synchronized(this) {
10227 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
10228 != PackageManager.PERMISSION_GRANTED) {
10229 String msg = "Permission Denial: unbroadcastIntent() from pid="
10230 + Binder.getCallingPid()
10231 + ", uid=" + Binder.getCallingUid()
10232 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
10233 Log.w(TAG, msg);
10234 throw new SecurityException(msg);
10235 }
10236 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
10237 if (list != null) {
10238 int N = list.size();
10239 int i;
10240 for (i=0; i<N; i++) {
10241 if (intent.filterEquals(list.get(i))) {
10242 list.remove(i);
10243 break;
10244 }
10245 }
10246 }
10247 }
10248 }
10249
10250 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
10251 String resultData, Bundle resultExtras, boolean resultAbort,
10252 boolean explicit) {
10253 if (mOrderedBroadcasts.size() == 0) {
10254 if (explicit) {
10255 Log.w(TAG, "finishReceiver called but no pending broadcasts");
10256 }
10257 return false;
10258 }
10259 BroadcastRecord r = mOrderedBroadcasts.get(0);
10260 if (r.receiver == null) {
10261 if (explicit) {
10262 Log.w(TAG, "finishReceiver called but none active");
10263 }
10264 return false;
10265 }
10266 if (r.receiver != receiver) {
10267 Log.w(TAG, "finishReceiver called but active receiver is different");
10268 return false;
10269 }
10270 int state = r.state;
10271 r.state = r.IDLE;
10272 if (state == r.IDLE) {
10273 if (explicit) {
10274 Log.w(TAG, "finishReceiver called but state is IDLE");
10275 }
10276 }
10277 r.receiver = null;
10278 r.intent.setComponent(null);
10279 if (r.curApp != null) {
10280 r.curApp.curReceiver = null;
10281 }
10282 if (r.curFilter != null) {
10283 r.curFilter.receiverList.curBroadcast = null;
10284 }
10285 r.curFilter = null;
10286 r.curApp = null;
10287 r.curComponent = null;
10288 r.curReceiver = null;
10289 mPendingBroadcast = null;
10290
10291 r.resultCode = resultCode;
10292 r.resultData = resultData;
10293 r.resultExtras = resultExtras;
10294 r.resultAbort = resultAbort;
10295
10296 // We will process the next receiver right now if this is finishing
10297 // an app receiver (which is always asynchronous) or after we have
10298 // come back from calling a receiver.
10299 return state == BroadcastRecord.APP_RECEIVE
10300 || state == BroadcastRecord.CALL_DONE_RECEIVE;
10301 }
10302
10303 public void finishReceiver(IBinder who, int resultCode, String resultData,
10304 Bundle resultExtras, boolean resultAbort) {
10305 if (DEBUG_BROADCAST) Log.v(TAG, "Finish receiver: " + who);
10306
10307 // Refuse possible leaked file descriptors
10308 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
10309 throw new IllegalArgumentException("File descriptors passed in Bundle");
10310 }
10311
10312 boolean doNext;
10313
10314 final long origId = Binder.clearCallingIdentity();
10315
10316 synchronized(this) {
10317 doNext = finishReceiverLocked(
10318 who, resultCode, resultData, resultExtras, resultAbort, true);
10319 }
10320
10321 if (doNext) {
10322 processNextBroadcast(false);
10323 }
10324 trimApplications();
10325
10326 Binder.restoreCallingIdentity(origId);
10327 }
10328
10329 private final void logBroadcastReceiverDiscard(BroadcastRecord r) {
10330 if (r.nextReceiver > 0) {
10331 Object curReceiver = r.receivers.get(r.nextReceiver-1);
10332 if (curReceiver instanceof BroadcastFilter) {
10333 BroadcastFilter bf = (BroadcastFilter) curReceiver;
10334 EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_FILTER,
10335 System.identityHashCode(r),
10336 r.intent.getAction(),
10337 r.nextReceiver - 1,
10338 System.identityHashCode(bf));
10339 } else {
10340 EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_APP,
10341 System.identityHashCode(r),
10342 r.intent.getAction(),
10343 r.nextReceiver - 1,
10344 ((ResolveInfo)curReceiver).toString());
10345 }
10346 } else {
10347 Log.w(TAG, "Discarding broadcast before first receiver is invoked: "
10348 + r);
10349 EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_APP,
10350 System.identityHashCode(r),
10351 r.intent.getAction(),
10352 r.nextReceiver,
10353 "NONE");
10354 }
10355 }
10356
10357 private final void broadcastTimeout() {
10358 synchronized (this) {
10359 if (mOrderedBroadcasts.size() == 0) {
10360 return;
10361 }
10362 long now = SystemClock.uptimeMillis();
10363 BroadcastRecord r = mOrderedBroadcasts.get(0);
10364 if ((r.startTime+BROADCAST_TIMEOUT) > now) {
10365 if (DEBUG_BROADCAST) Log.v(TAG,
10366 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
10367 + (r.startTime + BROADCAST_TIMEOUT));
10368 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
10369 mHandler.sendMessageAtTime(msg, r.startTime+BROADCAST_TIMEOUT);
10370 return;
10371 }
10372
10373 Log.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver);
10374 r.startTime = now;
10375 r.anrCount++;
10376
10377 // Current receiver has passed its expiration date.
10378 if (r.nextReceiver <= 0) {
10379 Log.w(TAG, "Timeout on receiver with nextReceiver <= 0");
10380 return;
10381 }
10382
10383 ProcessRecord app = null;
10384
10385 Object curReceiver = r.receivers.get(r.nextReceiver-1);
10386 Log.w(TAG, "Receiver during timeout: " + curReceiver);
10387 logBroadcastReceiverDiscard(r);
10388 if (curReceiver instanceof BroadcastFilter) {
10389 BroadcastFilter bf = (BroadcastFilter)curReceiver;
10390 if (bf.receiverList.pid != 0
10391 && bf.receiverList.pid != MY_PID) {
10392 synchronized (this.mPidsSelfLocked) {
10393 app = this.mPidsSelfLocked.get(
10394 bf.receiverList.pid);
10395 }
10396 }
10397 } else {
10398 app = r.curApp;
10399 }
10400
10401 if (app != null) {
10402 appNotRespondingLocked(app, null, "Broadcast of " + r.intent.toString());
10403 }
10404
10405 if (mPendingBroadcast == r) {
10406 mPendingBroadcast = null;
10407 }
10408
10409 // Move on to the next receiver.
10410 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
10411 r.resultExtras, r.resultAbort, true);
10412 scheduleBroadcastsLocked();
10413 }
10414 }
10415
10416 private final void processCurBroadcastLocked(BroadcastRecord r,
10417 ProcessRecord app) throws RemoteException {
10418 if (app.thread == null) {
10419 throw new RemoteException();
10420 }
10421 r.receiver = app.thread.asBinder();
10422 r.curApp = app;
10423 app.curReceiver = r;
10424 updateLRUListLocked(app, true);
10425
10426 // Tell the application to launch this receiver.
10427 r.intent.setComponent(r.curComponent);
10428
10429 boolean started = false;
10430 try {
10431 if (DEBUG_BROADCAST) Log.v(TAG,
10432 "Delivering to component " + r.curComponent
10433 + ": " + r);
10434 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
10435 r.resultCode, r.resultData, r.resultExtras, r.ordered);
10436 started = true;
10437 } finally {
10438 if (!started) {
10439 r.receiver = null;
10440 r.curApp = null;
10441 app.curReceiver = null;
10442 }
10443 }
10444
10445 }
10446
10447 static void performReceive(ProcessRecord app, IIntentReceiver receiver,
10448 Intent intent, int resultCode, String data,
10449 Bundle extras, boolean ordered) throws RemoteException {
10450 if (app != null && app.thread != null) {
10451 // If we have an app thread, do the call through that so it is
10452 // correctly ordered with other one-way calls.
10453 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
10454 data, extras, ordered);
10455 } else {
10456 receiver.performReceive(intent, resultCode, data, extras, ordered);
10457 }
10458 }
10459
10460 private final void deliverToRegisteredReceiver(BroadcastRecord r,
10461 BroadcastFilter filter, boolean ordered) {
10462 boolean skip = false;
10463 if (filter.requiredPermission != null) {
10464 int perm = checkComponentPermission(filter.requiredPermission,
10465 r.callingPid, r.callingUid, -1);
10466 if (perm != PackageManager.PERMISSION_GRANTED) {
10467 Log.w(TAG, "Permission Denial: broadcasting "
10468 + r.intent.toString()
10469 + " from " + r.callerPackage + " (pid="
10470 + r.callingPid + ", uid=" + r.callingUid + ")"
10471 + " requires " + filter.requiredPermission
10472 + " due to registered receiver " + filter);
10473 skip = true;
10474 }
10475 }
10476 if (r.requiredPermission != null) {
10477 int perm = checkComponentPermission(r.requiredPermission,
10478 filter.receiverList.pid, filter.receiverList.uid, -1);
10479 if (perm != PackageManager.PERMISSION_GRANTED) {
10480 Log.w(TAG, "Permission Denial: receiving "
10481 + r.intent.toString()
10482 + " to " + filter.receiverList.app
10483 + " (pid=" + filter.receiverList.pid
10484 + ", uid=" + filter.receiverList.uid + ")"
10485 + " requires " + r.requiredPermission
10486 + " due to sender " + r.callerPackage
10487 + " (uid " + r.callingUid + ")");
10488 skip = true;
10489 }
10490 }
10491
10492 if (!skip) {
10493 // If this is not being sent as an ordered broadcast, then we
10494 // don't want to touch the fields that keep track of the current
10495 // state of ordered broadcasts.
10496 if (ordered) {
10497 r.receiver = filter.receiverList.receiver.asBinder();
10498 r.curFilter = filter;
10499 filter.receiverList.curBroadcast = r;
10500 r.state = BroadcastRecord.CALL_IN_RECEIVE;
10501 }
10502 try {
10503 if (DEBUG_BROADCAST) {
10504 int seq = r.intent.getIntExtra("seq", -1);
10505 Log.i(TAG, "Sending broadcast " + r.intent.getAction() + " seq=" + seq
10506 + " app=" + filter.receiverList.app);
10507 }
10508 performReceive(filter.receiverList.app, filter.receiverList.receiver,
10509 new Intent(r.intent), r.resultCode,
10510 r.resultData, r.resultExtras, r.ordered);
10511 if (ordered) {
10512 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
10513 }
10514 } catch (RemoteException e) {
10515 Log.w(TAG, "Failure sending broadcast " + r.intent, e);
10516 if (ordered) {
10517 r.receiver = null;
10518 r.curFilter = null;
10519 filter.receiverList.curBroadcast = null;
10520 }
10521 }
10522 }
10523 }
10524
10525 private final void processNextBroadcast(boolean fromMsg) {
10526 synchronized(this) {
10527 BroadcastRecord r;
10528
10529 if (DEBUG_BROADCAST) Log.v(TAG, "processNextBroadcast: "
10530 + mParallelBroadcasts.size() + " broadcasts, "
10531 + mOrderedBroadcasts.size() + " serialized broadcasts");
10532
10533 updateCpuStats();
10534
10535 if (fromMsg) {
10536 mBroadcastsScheduled = false;
10537 }
10538
10539 // First, deliver any non-serialized broadcasts right away.
10540 while (mParallelBroadcasts.size() > 0) {
10541 r = mParallelBroadcasts.remove(0);
10542 final int N = r.receivers.size();
10543 for (int i=0; i<N; i++) {
10544 Object target = r.receivers.get(i);
10545 if (DEBUG_BROADCAST) Log.v(TAG,
10546 "Delivering non-serialized to registered "
10547 + target + ": " + r);
10548 deliverToRegisteredReceiver(r, (BroadcastFilter)target, false);
10549 }
10550 }
10551
10552 // Now take care of the next serialized one...
10553
10554 // If we are waiting for a process to come up to handle the next
10555 // broadcast, then do nothing at this point. Just in case, we
10556 // check that the process we're waiting for still exists.
10557 if (mPendingBroadcast != null) {
10558 Log.i(TAG, "processNextBroadcast: waiting for "
10559 + mPendingBroadcast.curApp);
10560
10561 boolean isDead;
10562 synchronized (mPidsSelfLocked) {
10563 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
10564 }
10565 if (!isDead) {
10566 // It's still alive, so keep waiting
10567 return;
10568 } else {
10569 Log.w(TAG, "pending app " + mPendingBroadcast.curApp
10570 + " died before responding to broadcast");
10571 mPendingBroadcast = null;
10572 }
10573 }
10574
10575 do {
10576 if (mOrderedBroadcasts.size() == 0) {
10577 // No more broadcasts pending, so all done!
10578 scheduleAppGcsLocked();
10579 return;
10580 }
10581 r = mOrderedBroadcasts.get(0);
10582 boolean forceReceive = false;
10583
10584 // Ensure that even if something goes awry with the timeout
10585 // detection, we catch "hung" broadcasts here, discard them,
10586 // and continue to make progress.
10587 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
10588 long now = SystemClock.uptimeMillis();
10589 if (r.dispatchTime > 0) {
10590 if ((numReceivers > 0) &&
10591 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
10592 Log.w(TAG, "Hung broadcast discarded after timeout failure:"
10593 + " now=" + now
10594 + " dispatchTime=" + r.dispatchTime
10595 + " startTime=" + r.startTime
10596 + " intent=" + r.intent
10597 + " numReceivers=" + numReceivers
10598 + " nextReceiver=" + r.nextReceiver
10599 + " state=" + r.state);
10600 broadcastTimeout(); // forcibly finish this broadcast
10601 forceReceive = true;
10602 r.state = BroadcastRecord.IDLE;
10603 }
10604 }
10605
10606 if (r.state != BroadcastRecord.IDLE) {
10607 if (DEBUG_BROADCAST) Log.d(TAG,
10608 "processNextBroadcast() called when not idle (state="
10609 + r.state + ")");
10610 return;
10611 }
10612
10613 if (r.receivers == null || r.nextReceiver >= numReceivers
10614 || r.resultAbort || forceReceive) {
10615 // No more receivers for this broadcast! Send the final
10616 // result if requested...
10617 if (r.resultTo != null) {
10618 try {
10619 if (DEBUG_BROADCAST) {
10620 int seq = r.intent.getIntExtra("seq", -1);
10621 Log.i(TAG, "Finishing broadcast " + r.intent.getAction()
10622 + " seq=" + seq + " app=" + r.callerApp);
10623 }
10624 performReceive(r.callerApp, r.resultTo,
10625 new Intent(r.intent), r.resultCode,
10626 r.resultData, r.resultExtras, false);
10627 } catch (RemoteException e) {
10628 Log.w(TAG, "Failure sending broadcast result of " + r.intent, e);
10629 }
10630 }
10631
10632 if (DEBUG_BROADCAST) Log.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
10633 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
10634
10635 // ... and on to the next...
10636 mOrderedBroadcasts.remove(0);
10637 r = null;
10638 continue;
10639 }
10640 } while (r == null);
10641
10642 // Get the next receiver...
10643 int recIdx = r.nextReceiver++;
10644
10645 // Keep track of when this receiver started, and make sure there
10646 // is a timeout message pending to kill it if need be.
10647 r.startTime = SystemClock.uptimeMillis();
10648 if (recIdx == 0) {
10649 r.dispatchTime = r.startTime;
10650
10651 if (DEBUG_BROADCAST) Log.v(TAG,
10652 "Submitting BROADCAST_TIMEOUT_MSG for "
10653 + (r.startTime + BROADCAST_TIMEOUT));
10654 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
10655 mHandler.sendMessageAtTime(msg, r.startTime+BROADCAST_TIMEOUT);
10656 }
10657
10658 Object nextReceiver = r.receivers.get(recIdx);
10659 if (nextReceiver instanceof BroadcastFilter) {
10660 // Simple case: this is a registered receiver who gets
10661 // a direct call.
10662 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
10663 if (DEBUG_BROADCAST) Log.v(TAG,
10664 "Delivering serialized to registered "
10665 + filter + ": " + r);
10666 deliverToRegisteredReceiver(r, filter, r.ordered);
10667 if (r.receiver == null || !r.ordered) {
10668 // The receiver has already finished, so schedule to
10669 // process the next one.
10670 r.state = BroadcastRecord.IDLE;
10671 scheduleBroadcastsLocked();
10672 }
10673 return;
10674 }
10675
10676 // Hard case: need to instantiate the receiver, possibly
10677 // starting its application process to host it.
10678
10679 ResolveInfo info =
10680 (ResolveInfo)nextReceiver;
10681
10682 boolean skip = false;
10683 int perm = checkComponentPermission(info.activityInfo.permission,
10684 r.callingPid, r.callingUid,
10685 info.activityInfo.exported
10686 ? -1 : info.activityInfo.applicationInfo.uid);
10687 if (perm != PackageManager.PERMISSION_GRANTED) {
10688 Log.w(TAG, "Permission Denial: broadcasting "
10689 + r.intent.toString()
10690 + " from " + r.callerPackage + " (pid=" + r.callingPid
10691 + ", uid=" + r.callingUid + ")"
10692 + " requires " + info.activityInfo.permission
10693 + " due to receiver " + info.activityInfo.packageName
10694 + "/" + info.activityInfo.name);
10695 skip = true;
10696 }
10697 if (r.callingUid != Process.SYSTEM_UID &&
10698 r.requiredPermission != null) {
10699 try {
10700 perm = ActivityThread.getPackageManager().
10701 checkPermission(r.requiredPermission,
10702 info.activityInfo.applicationInfo.packageName);
10703 } catch (RemoteException e) {
10704 perm = PackageManager.PERMISSION_DENIED;
10705 }
10706 if (perm != PackageManager.PERMISSION_GRANTED) {
10707 Log.w(TAG, "Permission Denial: receiving "
10708 + r.intent + " to "
10709 + info.activityInfo.applicationInfo.packageName
10710 + " requires " + r.requiredPermission
10711 + " due to sender " + r.callerPackage
10712 + " (uid " + r.callingUid + ")");
10713 skip = true;
10714 }
10715 }
10716 if (r.curApp != null && r.curApp.crashing) {
10717 // If the target process is crashing, just skip it.
10718 skip = true;
10719 }
10720
10721 if (skip) {
10722 r.receiver = null;
10723 r.curFilter = null;
10724 r.state = BroadcastRecord.IDLE;
10725 scheduleBroadcastsLocked();
10726 return;
10727 }
10728
10729 r.state = BroadcastRecord.APP_RECEIVE;
10730 String targetProcess = info.activityInfo.processName;
10731 r.curComponent = new ComponentName(
10732 info.activityInfo.applicationInfo.packageName,
10733 info.activityInfo.name);
10734 r.curReceiver = info.activityInfo;
10735
10736 // Is this receiver's application already running?
10737 ProcessRecord app = getProcessRecordLocked(targetProcess,
10738 info.activityInfo.applicationInfo.uid);
10739 if (app != null && app.thread != null) {
10740 try {
10741 processCurBroadcastLocked(r, app);
10742 return;
10743 } catch (RemoteException e) {
10744 Log.w(TAG, "Exception when sending broadcast to "
10745 + r.curComponent, e);
10746 }
10747
10748 // If a dead object exception was thrown -- fall through to
10749 // restart the application.
10750 }
10751
10752 // Not running -- get it started, and enqueue this history record
10753 // to be executed when the app comes up.
10754 if ((r.curApp=startProcessLocked(targetProcess,
10755 info.activityInfo.applicationInfo, true,
10756 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
10757 "broadcast", r.curComponent)) == null) {
10758 // Ah, this recipient is unavailable. Finish it if necessary,
10759 // and mark the broadcast record as ready for the next.
10760 Log.w(TAG, "Unable to launch app "
10761 + info.activityInfo.applicationInfo.packageName + "/"
10762 + info.activityInfo.applicationInfo.uid + " for broadcast "
10763 + r.intent + ": process is bad");
10764 logBroadcastReceiverDiscard(r);
10765 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
10766 r.resultExtras, r.resultAbort, true);
10767 scheduleBroadcastsLocked();
10768 r.state = BroadcastRecord.IDLE;
10769 return;
10770 }
10771
10772 mPendingBroadcast = r;
10773 }
10774 }
10775
10776 // =========================================================
10777 // INSTRUMENTATION
10778 // =========================================================
10779
10780 public boolean startInstrumentation(ComponentName className,
10781 String profileFile, int flags, Bundle arguments,
10782 IInstrumentationWatcher watcher) {
10783 // Refuse possible leaked file descriptors
10784 if (arguments != null && arguments.hasFileDescriptors()) {
10785 throw new IllegalArgumentException("File descriptors passed in Bundle");
10786 }
10787
10788 synchronized(this) {
10789 InstrumentationInfo ii = null;
10790 ApplicationInfo ai = null;
10791 try {
10792 ii = mContext.getPackageManager().getInstrumentationInfo(
10793 className, 0);
10794 ai = mContext.getPackageManager().getApplicationInfo(
10795 ii.targetPackage, PackageManager.GET_SHARED_LIBRARY_FILES);
10796 } catch (PackageManager.NameNotFoundException e) {
10797 }
10798 if (ii == null) {
10799 reportStartInstrumentationFailure(watcher, className,
10800 "Unable to find instrumentation info for: " + className);
10801 return false;
10802 }
10803 if (ai == null) {
10804 reportStartInstrumentationFailure(watcher, className,
10805 "Unable to find instrumentation target package: " + ii.targetPackage);
10806 return false;
10807 }
10808
10809 int match = mContext.getPackageManager().checkSignatures(
10810 ii.targetPackage, ii.packageName);
10811 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
10812 String msg = "Permission Denial: starting instrumentation "
10813 + className + " from pid="
10814 + Binder.getCallingPid()
10815 + ", uid=" + Binder.getCallingPid()
10816 + " not allowed because package " + ii.packageName
10817 + " does not have a signature matching the target "
10818 + ii.targetPackage;
10819 reportStartInstrumentationFailure(watcher, className, msg);
10820 throw new SecurityException(msg);
10821 }
10822
10823 final long origId = Binder.clearCallingIdentity();
10824 uninstallPackageLocked(ii.targetPackage, -1, true);
10825 ProcessRecord app = addAppLocked(ai);
10826 app.instrumentationClass = className;
10827 app.instrumentationProfileFile = profileFile;
10828 app.instrumentationArguments = arguments;
10829 app.instrumentationWatcher = watcher;
10830 app.instrumentationResultClass = className;
10831 Binder.restoreCallingIdentity(origId);
10832 }
10833
10834 return true;
10835 }
10836
10837 /**
10838 * Report errors that occur while attempting to start Instrumentation. Always writes the
10839 * error to the logs, but if somebody is watching, send the report there too. This enables
10840 * the "am" command to report errors with more information.
10841 *
10842 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
10843 * @param cn The component name of the instrumentation.
10844 * @param report The error report.
10845 */
10846 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
10847 ComponentName cn, String report) {
10848 Log.w(TAG, report);
10849 try {
10850 if (watcher != null) {
10851 Bundle results = new Bundle();
10852 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
10853 results.putString("Error", report);
10854 watcher.instrumentationStatus(cn, -1, results);
10855 }
10856 } catch (RemoteException e) {
10857 Log.w(TAG, e);
10858 }
10859 }
10860
10861 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
10862 if (app.instrumentationWatcher != null) {
10863 try {
10864 // NOTE: IInstrumentationWatcher *must* be oneway here
10865 app.instrumentationWatcher.instrumentationFinished(
10866 app.instrumentationClass,
10867 resultCode,
10868 results);
10869 } catch (RemoteException e) {
10870 }
10871 }
10872 app.instrumentationWatcher = null;
10873 app.instrumentationClass = null;
10874 app.instrumentationProfileFile = null;
10875 app.instrumentationArguments = null;
10876
10877 uninstallPackageLocked(app.processName, -1, false);
10878 }
10879
10880 public void finishInstrumentation(IApplicationThread target,
10881 int resultCode, Bundle results) {
10882 // Refuse possible leaked file descriptors
10883 if (results != null && results.hasFileDescriptors()) {
10884 throw new IllegalArgumentException("File descriptors passed in Intent");
10885 }
10886
10887 synchronized(this) {
10888 ProcessRecord app = getRecordForAppLocked(target);
10889 if (app == null) {
10890 Log.w(TAG, "finishInstrumentation: no app for " + target);
10891 return;
10892 }
10893 final long origId = Binder.clearCallingIdentity();
10894 finishInstrumentationLocked(app, resultCode, results);
10895 Binder.restoreCallingIdentity(origId);
10896 }
10897 }
10898
10899 // =========================================================
10900 // CONFIGURATION
10901 // =========================================================
10902
10903 public ConfigurationInfo getDeviceConfigurationInfo() {
10904 ConfigurationInfo config = new ConfigurationInfo();
10905 synchronized (this) {
10906 config.reqTouchScreen = mConfiguration.touchscreen;
10907 config.reqKeyboardType = mConfiguration.keyboard;
10908 config.reqNavigation = mConfiguration.navigation;
10909 if (mConfiguration.navigation != Configuration.NAVIGATION_NONAV) {
10910 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
10911 }
10912 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED) {
10913 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
10914 }
10915 }
10916 return config;
10917 }
10918
10919 public Configuration getConfiguration() {
10920 Configuration ci;
10921 synchronized(this) {
10922 ci = new Configuration(mConfiguration);
10923 }
10924 return ci;
10925 }
10926
10927 public void updateConfiguration(Configuration values) {
10928 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
10929 "updateConfiguration()");
10930
10931 synchronized(this) {
10932 if (values == null && mWindowManager != null) {
10933 // sentinel: fetch the current configuration from the window manager
10934 values = mWindowManager.computeNewConfiguration();
10935 }
10936
10937 final long origId = Binder.clearCallingIdentity();
10938 updateConfigurationLocked(values, null);
10939 Binder.restoreCallingIdentity(origId);
10940 }
10941 }
10942
10943 /**
10944 * Do either or both things: (1) change the current configuration, and (2)
10945 * make sure the given activity is running with the (now) current
10946 * configuration. Returns true if the activity has been left running, or
10947 * false if <var>starting</var> is being destroyed to match the new
10948 * configuration.
10949 */
10950 public boolean updateConfigurationLocked(Configuration values,
10951 HistoryRecord starting) {
10952 int changes = 0;
10953
10954 boolean kept = true;
10955
10956 if (values != null) {
10957 Configuration newConfig = new Configuration(mConfiguration);
10958 changes = newConfig.updateFrom(values);
10959 if (changes != 0) {
10960 if (DEBUG_SWITCH) {
10961 Log.i(TAG, "Updating configuration to: " + values);
10962 }
10963
10964 EventLog.writeEvent(LOG_CONFIGURATION_CHANGED, changes);
10965
10966 if (values.locale != null) {
10967 saveLocaleLocked(values.locale,
10968 !values.locale.equals(mConfiguration.locale),
10969 values.userSetLocale);
10970 }
10971
10972 mConfiguration = newConfig;
10973
10974 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
10975 msg.obj = new Configuration(mConfiguration);
10976 mHandler.sendMessage(msg);
10977
10978 final int N = mLRUProcesses.size();
10979 for (int i=0; i<N; i++) {
10980 ProcessRecord app = mLRUProcesses.get(i);
10981 try {
10982 if (app.thread != null) {
10983 app.thread.scheduleConfigurationChanged(mConfiguration);
10984 }
10985 } catch (Exception e) {
10986 }
10987 }
10988 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
10989 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
10990 null, false, false, MY_PID, Process.SYSTEM_UID);
10991 }
10992 }
10993
10994 if (changes != 0 && starting == null) {
10995 // If the configuration changed, and the caller is not already
10996 // in the process of starting an activity, then find the top
10997 // activity to check if its configuration needs to change.
10998 starting = topRunningActivityLocked(null);
10999 }
11000
11001 if (starting != null) {
11002 kept = ensureActivityConfigurationLocked(starting, changes);
11003 if (kept) {
11004 // If this didn't result in the starting activity being
11005 // destroyed, then we need to make sure at this point that all
11006 // other activities are made visible.
11007 if (DEBUG_SWITCH) Log.i(TAG, "Config didn't destroy " + starting
11008 + ", ensuring others are correct.");
11009 ensureActivitiesVisibleLocked(starting, changes);
11010 }
11011 }
11012
11013 return kept;
11014 }
11015
11016 private final boolean relaunchActivityLocked(HistoryRecord r,
11017 int changes, boolean andResume) {
11018 List<ResultInfo> results = null;
11019 List<Intent> newIntents = null;
11020 if (andResume) {
11021 results = r.results;
11022 newIntents = r.newIntents;
11023 }
11024 if (DEBUG_SWITCH) Log.v(TAG, "Relaunching: " + r
11025 + " with results=" + results + " newIntents=" + newIntents
11026 + " andResume=" + andResume);
11027 EventLog.writeEvent(andResume ? LOG_AM_RELAUNCH_RESUME_ACTIVITY
11028 : LOG_AM_RELAUNCH_ACTIVITY, System.identityHashCode(r),
11029 r.task.taskId, r.shortComponentName);
11030
11031 r.startFreezingScreenLocked(r.app, 0);
11032
11033 try {
11034 if (DEBUG_SWITCH) Log.i(TAG, "Switch is restarting resumed " + r);
11035 r.app.thread.scheduleRelaunchActivity(r, results, newIntents,
11036 changes, !andResume);
11037 // Note: don't need to call pauseIfSleepingLocked() here, because
11038 // the caller will only pass in 'andResume' if this activity is
11039 // currently resumed, which implies we aren't sleeping.
11040 } catch (RemoteException e) {
11041 return false;
11042 }
11043
11044 if (andResume) {
11045 r.results = null;
11046 r.newIntents = null;
11047 }
11048
11049 return true;
11050 }
11051
11052 /**
11053 * Make sure the given activity matches the current configuration. Returns
11054 * false if the activity had to be destroyed. Returns true if the
11055 * configuration is the same, or the activity will remain running as-is
11056 * for whatever reason. Ensures the HistoryRecord is updated with the
11057 * correct configuration and all other bookkeeping is handled.
11058 */
11059 private final boolean ensureActivityConfigurationLocked(HistoryRecord r,
11060 int globalChanges) {
11061 if (DEBUG_SWITCH) Log.i(TAG, "Ensuring correct configuration: " + r);
11062
11063 // Short circuit: if the two configurations are the exact same
11064 // object (the common case), then there is nothing to do.
11065 Configuration newConfig = mConfiguration;
11066 if (r.configuration == newConfig) {
11067 if (DEBUG_SWITCH) Log.i(TAG, "Configuration unchanged in " + r);
11068 return true;
11069 }
11070
11071 // We don't worry about activities that are finishing.
11072 if (r.finishing) {
11073 if (DEBUG_SWITCH) Log.i(TAG,
11074 "Configuration doesn't matter in finishing " + r);
11075 r.stopFreezingScreenLocked(false);
11076 return true;
11077 }
11078
11079 // Okay we now are going to make this activity have the new config.
11080 // But then we need to figure out how it needs to deal with that.
11081 Configuration oldConfig = r.configuration;
11082 r.configuration = newConfig;
11083
11084 // If the activity isn't currently running, just leave the new
11085 // configuration and it will pick that up next time it starts.
11086 if (r.app == null || r.app.thread == null) {
11087 if (DEBUG_SWITCH) Log.i(TAG,
11088 "Configuration doesn't matter not running " + r);
11089 r.stopFreezingScreenLocked(false);
11090 return true;
11091 }
11092
11093 // If the activity isn't persistent, there is a chance we will
11094 // need to restart it.
11095 if (!r.persistent) {
11096
11097 // Figure out what has changed between the two configurations.
11098 int changes = oldConfig.diff(newConfig);
11099 if (DEBUG_SWITCH) {
11100 Log.i(TAG, "Checking to restart " + r.info.name + ": changed=0x"
11101 + Integer.toHexString(changes) + ", handles=0x"
11102 + Integer.toHexString(r.info.configChanges));
11103 }
11104 if ((changes&(~r.info.configChanges)) != 0) {
11105 // Aha, the activity isn't handling the change, so DIE DIE DIE.
11106 r.configChangeFlags |= changes;
11107 r.startFreezingScreenLocked(r.app, globalChanges);
11108 if (r.app == null || r.app.thread == null) {
11109 if (DEBUG_SWITCH) Log.i(TAG, "Switch is destroying non-running " + r);
11110 destroyActivityLocked(r, true);
11111 } else if (r.state == ActivityState.PAUSING) {
11112 // A little annoying: we are waiting for this activity to
11113 // finish pausing. Let's not do anything now, but just
11114 // flag that it needs to be restarted when done pausing.
11115 r.configDestroy = true;
11116 return true;
11117 } else if (r.state == ActivityState.RESUMED) {
11118 // Try to optimize this case: the configuration is changing
11119 // and we need to restart the top, resumed activity.
11120 // Instead of doing the normal handshaking, just say
11121 // "restart!".
11122 if (DEBUG_SWITCH) Log.i(TAG, "Switch is restarting resumed " + r);
11123 relaunchActivityLocked(r, r.configChangeFlags, true);
11124 r.configChangeFlags = 0;
11125 } else {
11126 if (DEBUG_SWITCH) Log.i(TAG, "Switch is restarting non-resumed " + r);
11127 relaunchActivityLocked(r, r.configChangeFlags, false);
11128 r.configChangeFlags = 0;
11129 }
11130
11131 // All done... tell the caller we weren't able to keep this
11132 // activity around.
11133 return false;
11134 }
11135 }
11136
11137 // Default case: the activity can handle this new configuration, so
11138 // hand it over. Note that we don't need to give it the new
11139 // configuration, since we always send configuration changes to all
11140 // process when they happen so it can just use whatever configuration
11141 // it last got.
11142 if (r.app != null && r.app.thread != null) {
11143 try {
11144 r.app.thread.scheduleActivityConfigurationChanged(r);
11145 } catch (RemoteException e) {
11146 // If process died, whatever.
11147 }
11148 }
11149 r.stopFreezingScreenLocked(false);
11150
11151 return true;
11152 }
11153
11154 /**
11155 * Save the locale. You must be inside a synchronized (this) block.
11156 */
11157 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
11158 if(isDiff) {
11159 SystemProperties.set("user.language", l.getLanguage());
11160 SystemProperties.set("user.region", l.getCountry());
11161 }
11162
11163 if(isPersist) {
11164 SystemProperties.set("persist.sys.language", l.getLanguage());
11165 SystemProperties.set("persist.sys.country", l.getCountry());
11166 SystemProperties.set("persist.sys.localevar", l.getVariant());
11167 }
11168 }
11169
11170 // =========================================================
11171 // LIFETIME MANAGEMENT
11172 // =========================================================
11173
11174 private final int computeOomAdjLocked(
11175 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
11176 if (mAdjSeq == app.adjSeq) {
11177 // This adjustment has already been computed.
11178 return app.curAdj;
11179 }
11180
11181 if (app.thread == null) {
11182 app.adjSeq = mAdjSeq;
11183 return (app.curAdj=EMPTY_APP_ADJ);
11184 }
11185
11186 app.isForeground = false;
11187
11188 // Right now there are three interesting states: it is
11189 // either the foreground app, background with activities,
11190 // or background without activities.
11191 int adj;
11192 int N;
11193 if (app == TOP_APP || app.instrumentationClass != null
11194 || app.persistentActivities > 0) {
11195 // The last app on the list is the foreground app.
11196 adj = FOREGROUND_APP_ADJ;
11197 app.isForeground = true;
11198 } else if (app.curReceiver != null ||
11199 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
11200 // An app that is currently receiving a broadcast also
11201 // counts as being in the foreground.
11202 adj = FOREGROUND_APP_ADJ;
11203 } else if (app.executingServices.size() > 0) {
11204 // An app that is currently executing a service callback also
11205 // counts as being in the foreground.
11206 adj = FOREGROUND_APP_ADJ;
11207 } else if (app.foregroundServices || app.forcingToForeground != null) {
11208 // The user is aware of this app, so make it visible.
11209 adj = VISIBLE_APP_ADJ;
11210 } else if ((N=app.activities.size()) != 0) {
11211 // This app is in the background with paused activities.
11212 adj = hiddenAdj;
11213 for (int j=0; j<N; j++) {
11214 if (((HistoryRecord)app.activities.get(j)).visible) {
11215 // This app has a visible activity!
11216 adj = VISIBLE_APP_ADJ;
11217 break;
11218 }
11219 }
11220 } else {
11221 // A very not-needed process.
11222 adj = EMPTY_APP_ADJ;
11223 }
11224
11225 // By default, we use the computed adjusted. It may be changed if
11226 // there are applications dependent on our services or providers, but
11227 // this gives us a baseline and makes sure we don't get into an
11228 // infinite recursion.
11229 app.adjSeq = mAdjSeq;
11230 app.curRawAdj = adj;
11231 app.curAdj = adj <= app.maxAdj ? adj : app.maxAdj;
11232
11233 if (app.services.size() != 0 && adj > FOREGROUND_APP_ADJ) {
11234 // If this process has active services running in it, we would
11235 // like to avoid killing it unless it would prevent the current
11236 // application from running.
11237 if (adj > hiddenAdj) {
11238 adj = hiddenAdj;
11239 }
11240 final long now = SystemClock.uptimeMillis();
11241 // This process is more important if the top activity is
11242 // bound to the service.
11243 Iterator jt = app.services.iterator();
11244 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
11245 ServiceRecord s = (ServiceRecord)jt.next();
11246 if (s.startRequested) {
11247 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
11248 // This service has seen some activity within
11249 // recent memory, so we will keep its process ahead
11250 // of the background processes.
11251 if (adj > SECONDARY_SERVER_ADJ) {
11252 adj = SECONDARY_SERVER_ADJ;
11253 }
11254 } else {
11255 // This service has been inactive for too long, just
11256 // put it with the rest of the background processes.
11257 if (adj > hiddenAdj) {
11258 adj = hiddenAdj;
11259 }
11260 }
11261 }
11262 if (s.connections.size() > 0 && adj > FOREGROUND_APP_ADJ) {
11263 Iterator<ConnectionRecord> kt
11264 = s.connections.values().iterator();
11265 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
11266 // XXX should compute this based on the max of
11267 // all connected clients.
11268 ConnectionRecord cr = kt.next();
11269 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
11270 ProcessRecord client = cr.binding.client;
11271 int myHiddenAdj = hiddenAdj;
11272 if (myHiddenAdj > client.hiddenAdj) {
11273 if (client.hiddenAdj > VISIBLE_APP_ADJ) {
11274 myHiddenAdj = client.hiddenAdj;
11275 } else {
11276 myHiddenAdj = VISIBLE_APP_ADJ;
11277 }
11278 }
11279 int clientAdj = computeOomAdjLocked(
11280 client, myHiddenAdj, TOP_APP);
11281 if (adj > clientAdj) {
11282 adj = clientAdj > VISIBLE_APP_ADJ
11283 ? clientAdj : VISIBLE_APP_ADJ;
11284 }
11285 }
11286 HistoryRecord a = cr.activity;
11287 //if (a != null) {
11288 // Log.i(TAG, "Connection to " + a ": state=" + a.state);
11289 //}
11290 if (a != null && adj > FOREGROUND_APP_ADJ &&
11291 (a.state == ActivityState.RESUMED
11292 || a.state == ActivityState.PAUSING)) {
11293 adj = FOREGROUND_APP_ADJ;
11294 }
11295 }
11296 }
11297 }
11298 }
11299
11300 if (app.pubProviders.size() != 0 && adj > FOREGROUND_APP_ADJ) {
11301 // If this process has published any content providers, then
11302 // its adjustment makes it at least as important as any of the
11303 // processes using those providers, and no less important than
11304 // CONTENT_PROVIDER_ADJ, which is just shy of EMPTY.
11305 if (adj > CONTENT_PROVIDER_ADJ) {
11306 adj = CONTENT_PROVIDER_ADJ;
11307 }
11308 Iterator jt = app.pubProviders.values().iterator();
11309 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
11310 ContentProviderRecord cpr = (ContentProviderRecord)jt.next();
11311 if (cpr.clients.size() != 0) {
11312 Iterator<ProcessRecord> kt = cpr.clients.iterator();
11313 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
11314 ProcessRecord client = kt.next();
11315 int myHiddenAdj = hiddenAdj;
11316 if (myHiddenAdj > client.hiddenAdj) {
11317 if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
11318 myHiddenAdj = client.hiddenAdj;
11319 } else {
11320 myHiddenAdj = FOREGROUND_APP_ADJ;
11321 }
11322 }
11323 int clientAdj = computeOomAdjLocked(
11324 client, myHiddenAdj, TOP_APP);
11325 if (adj > clientAdj) {
11326 adj = clientAdj > FOREGROUND_APP_ADJ
11327 ? clientAdj : FOREGROUND_APP_ADJ;
11328 }
11329 }
11330 }
11331 // If the provider has external (non-framework) process
11332 // dependencies, ensure that its adjustment is at least
11333 // FOREGROUND_APP_ADJ.
11334 if (cpr.externals != 0) {
11335 if (adj > FOREGROUND_APP_ADJ) {
11336 adj = FOREGROUND_APP_ADJ;
11337 }
11338 }
11339 }
11340 }
11341
11342 app.curRawAdj = adj;
11343
11344 //Log.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
11345 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
11346 if (adj > app.maxAdj) {
11347 adj = app.maxAdj;
11348 }
11349
11350 app.curAdj = adj;
11351
11352 return adj;
11353 }
11354
11355 /**
11356 * Ask a given process to GC right now.
11357 */
11358 final void performAppGcLocked(ProcessRecord app) {
11359 try {
11360 app.lastRequestedGc = SystemClock.uptimeMillis();
11361 if (app.thread != null) {
11362 app.thread.processInBackground();
11363 }
11364 } catch (Exception e) {
11365 // whatever.
11366 }
11367 }
11368
11369 /**
11370 * Returns true if things are idle enough to perform GCs.
11371 */
11372 private final boolean canGcNow() {
11373 return mParallelBroadcasts.size() == 0
11374 && mOrderedBroadcasts.size() == 0
11375 && (mSleeping || (mResumedActivity != null &&
11376 mResumedActivity.idle));
11377 }
11378
11379 /**
11380 * Perform GCs on all processes that are waiting for it, but only
11381 * if things are idle.
11382 */
11383 final void performAppGcsLocked() {
11384 final int N = mProcessesToGc.size();
11385 if (N <= 0) {
11386 return;
11387 }
11388 if (canGcNow()) {
11389 while (mProcessesToGc.size() > 0) {
11390 ProcessRecord proc = mProcessesToGc.remove(0);
11391 if (proc.curRawAdj > VISIBLE_APP_ADJ) {
11392 // To avoid spamming the system, we will GC processes one
11393 // at a time, waiting a few seconds between each.
11394 performAppGcLocked(proc);
11395 scheduleAppGcsLocked();
11396 return;
11397 }
11398 }
11399 }
11400 }
11401
11402 /**
11403 * If all looks good, perform GCs on all processes waiting for them.
11404 */
11405 final void performAppGcsIfAppropriateLocked() {
11406 if (canGcNow()) {
11407 performAppGcsLocked();
11408 return;
11409 }
11410 // Still not idle, wait some more.
11411 scheduleAppGcsLocked();
11412 }
11413
11414 /**
11415 * Schedule the execution of all pending app GCs.
11416 */
11417 final void scheduleAppGcsLocked() {
11418 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
11419 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
11420 mHandler.sendMessageDelayed(msg, GC_TIMEOUT);
11421 }
11422
11423 /**
11424 * Set up to ask a process to GC itself. This will either do it
11425 * immediately, or put it on the list of processes to gc the next
11426 * time things are idle.
11427 */
11428 final void scheduleAppGcLocked(ProcessRecord app) {
11429 long now = SystemClock.uptimeMillis();
11430 if ((app.lastRequestedGc+5000) > now) {
11431 return;
11432 }
11433 if (!mProcessesToGc.contains(app)) {
11434 mProcessesToGc.add(app);
11435 scheduleAppGcsLocked();
11436 }
11437 }
11438
11439 private final boolean updateOomAdjLocked(
11440 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
11441 app.hiddenAdj = hiddenAdj;
11442
11443 if (app.thread == null) {
11444 return true;
11445 }
11446
11447 int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP);
11448
11449 //Log.i(TAG, "Computed adj " + adj + " for app " + app.processName);
11450 //Thread priority adjustment is disabled out to see
11451 //how the kernel scheduler performs.
11452 if (false) {
11453 if (app.pid != 0 && app.isForeground != app.setIsForeground) {
11454 app.setIsForeground = app.isForeground;
11455 if (app.pid != MY_PID) {
11456 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v(TAG, "Setting priority of " + app
11457 + " to " + (app.isForeground
11458 ? Process.THREAD_PRIORITY_FOREGROUND
11459 : Process.THREAD_PRIORITY_DEFAULT));
11460 try {
11461 Process.setThreadPriority(app.pid, app.isForeground
11462 ? Process.THREAD_PRIORITY_FOREGROUND
11463 : Process.THREAD_PRIORITY_DEFAULT);
11464 } catch (RuntimeException e) {
11465 Log.w(TAG, "Exception trying to set priority of application thread "
11466 + app.pid, e);
11467 }
11468 }
11469 }
11470 }
11471 if (app.pid != 0 && app.pid != MY_PID) {
11472 if (app.curRawAdj != app.setRawAdj) {
11473 if (app.curRawAdj > FOREGROUND_APP_ADJ
11474 && app.setRawAdj <= FOREGROUND_APP_ADJ) {
11475 // If this app is transitioning from foreground to
11476 // non-foreground, have it do a gc.
11477 scheduleAppGcLocked(app);
11478 } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
11479 && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
11480 // Likewise do a gc when an app is moving in to the
11481 // background (such as a service stopping).
11482 scheduleAppGcLocked(app);
11483 }
11484 app.setRawAdj = app.curRawAdj;
11485 }
11486 if (adj != app.setAdj) {
11487 if (Process.setOomAdj(app.pid, adj)) {
11488 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v(
11489 TAG, "Set app " + app.processName +
11490 " oom adj to " + adj);
11491 app.setAdj = adj;
11492 } else {
11493 return false;
11494 }
11495 }
11496 }
11497
11498 return true;
11499 }
11500
11501 private final HistoryRecord resumedAppLocked() {
11502 HistoryRecord resumedActivity = mResumedActivity;
11503 if (resumedActivity == null || resumedActivity.app == null) {
11504 resumedActivity = mPausingActivity;
11505 if (resumedActivity == null || resumedActivity.app == null) {
11506 resumedActivity = topRunningActivityLocked(null);
11507 }
11508 }
11509 return resumedActivity;
11510 }
11511
11512 private final boolean updateOomAdjLocked(ProcessRecord app) {
11513 final HistoryRecord TOP_ACT = resumedAppLocked();
11514 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
11515 int curAdj = app.curAdj;
11516 final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
11517 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
11518
11519 mAdjSeq++;
11520
11521 final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
11522 if (res) {
11523 final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
11524 && app.curAdj <= HIDDEN_APP_MAX_ADJ;
11525 if (nowHidden != wasHidden) {
11526 // Changed to/from hidden state, so apps after it in the LRU
11527 // list may also be changed.
11528 updateOomAdjLocked();
11529 }
11530 }
11531 return res;
11532 }
11533
11534 private final boolean updateOomAdjLocked() {
11535 boolean didOomAdj = true;
11536 final HistoryRecord TOP_ACT = resumedAppLocked();
11537 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
11538
11539 if (false) {
11540 RuntimeException e = new RuntimeException();
11541 e.fillInStackTrace();
11542 Log.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
11543 }
11544
11545 mAdjSeq++;
11546
11547 // First try updating the OOM adjustment for each of the
11548 // application processes based on their current state.
11549 int i = mLRUProcesses.size();
11550 int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
11551 while (i > 0) {
11552 i--;
11553 ProcessRecord app = mLRUProcesses.get(i);
11554 if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
11555 if (curHiddenAdj < HIDDEN_APP_MAX_ADJ
11556 && app.curAdj == curHiddenAdj) {
11557 curHiddenAdj++;
11558 }
11559 } else {
11560 didOomAdj = false;
11561 }
11562 }
11563
11564 // todo: for now pretend like OOM ADJ didn't work, because things
11565 // aren't behaving as expected on Linux -- it's not killing processes.
11566 return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj;
11567 }
11568
11569 private final void trimApplications() {
11570 synchronized (this) {
11571 int i;
11572
11573 // First remove any unused application processes whose package
11574 // has been removed.
11575 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
11576 final ProcessRecord app = mRemovedProcesses.get(i);
11577 if (app.activities.size() == 0
11578 && app.curReceiver == null && app.services.size() == 0) {
11579 Log.i(
11580 TAG, "Exiting empty application process "
11581 + app.processName + " ("
11582 + (app.thread != null ? app.thread.asBinder() : null)
11583 + ")\n");
11584 if (app.pid > 0 && app.pid != MY_PID) {
11585 Process.killProcess(app.pid);
11586 } else {
11587 try {
11588 app.thread.scheduleExit();
11589 } catch (Exception e) {
11590 // Ignore exceptions.
11591 }
11592 }
11593 cleanUpApplicationRecordLocked(app, false, -1);
11594 mRemovedProcesses.remove(i);
11595
11596 if (app.persistent) {
11597 if (app.persistent) {
11598 addAppLocked(app.info);
11599 }
11600 }
11601 }
11602 }
11603
11604 // Now try updating the OOM adjustment for each of the
11605 // application processes based on their current state.
11606 // If the setOomAdj() API is not supported, then go with our
11607 // back-up plan...
11608 if (!updateOomAdjLocked()) {
11609
11610 // Count how many processes are running services.
11611 int numServiceProcs = 0;
11612 for (i=mLRUProcesses.size()-1; i>=0; i--) {
11613 final ProcessRecord app = mLRUProcesses.get(i);
11614
11615 if (app.persistent || app.services.size() != 0
11616 || app.curReceiver != null
11617 || app.persistentActivities > 0) {
11618 // Don't count processes holding services against our
11619 // maximum process count.
11620 if (localLOGV) Log.v(
11621 TAG, "Not trimming app " + app + " with services: "
11622 + app.services);
11623 numServiceProcs++;
11624 }
11625 }
11626
11627 int curMaxProcs = mProcessLimit;
11628 if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES;
11629 if (mAlwaysFinishActivities) {
11630 curMaxProcs = 1;
11631 }
11632 curMaxProcs += numServiceProcs;
11633
11634 // Quit as many processes as we can to get down to the desired
11635 // process count. First remove any processes that no longer
11636 // have activites running in them.
11637 for ( i=0;
11638 i<mLRUProcesses.size()
11639 && mLRUProcesses.size() > curMaxProcs;
11640 i++) {
11641 final ProcessRecord app = mLRUProcesses.get(i);
11642 // Quit an application only if it is not currently
11643 // running any activities.
11644 if (!app.persistent && app.activities.size() == 0
11645 && app.curReceiver == null && app.services.size() == 0) {
11646 Log.i(
11647 TAG, "Exiting empty application process "
11648 + app.processName + " ("
11649 + (app.thread != null ? app.thread.asBinder() : null)
11650 + ")\n");
11651 if (app.pid > 0 && app.pid != MY_PID) {
11652 Process.killProcess(app.pid);
11653 } else {
11654 try {
11655 app.thread.scheduleExit();
11656 } catch (Exception e) {
11657 // Ignore exceptions.
11658 }
11659 }
11660 // todo: For now we assume the application is not buggy
11661 // or evil, and will quit as a result of our request.
11662 // Eventually we need to drive this off of the death
11663 // notification, and kill the process if it takes too long.
11664 cleanUpApplicationRecordLocked(app, false, i);
11665 i--;
11666 }
11667 }
11668
11669 // If we still have too many processes, now from the least
11670 // recently used process we start finishing activities.
11671 if (Config.LOGV) Log.v(
11672 TAG, "*** NOW HAVE " + mLRUProcesses.size() +
11673 " of " + curMaxProcs + " processes");
11674 for ( i=0;
11675 i<mLRUProcesses.size()
11676 && mLRUProcesses.size() > curMaxProcs;
11677 i++) {
11678 final ProcessRecord app = mLRUProcesses.get(i);
11679 // Quit the application only if we have a state saved for
11680 // all of its activities.
11681 boolean canQuit = !app.persistent && app.curReceiver == null
11682 && app.services.size() == 0
11683 && app.persistentActivities == 0;
11684 int NUMA = app.activities.size();
11685 int j;
11686 if (Config.LOGV) Log.v(
11687 TAG, "Looking to quit " + app.processName);
11688 for (j=0; j<NUMA && canQuit; j++) {
11689 HistoryRecord r = (HistoryRecord)app.activities.get(j);
11690 if (Config.LOGV) Log.v(
11691 TAG, " " + r.intent.getComponent().flattenToShortString()
11692 + ": frozen=" + r.haveState + ", visible=" + r.visible);
11693 canQuit = (r.haveState || !r.stateNotNeeded)
11694 && !r.visible && r.stopped;
11695 }
11696 if (canQuit) {
11697 // Finish all of the activities, and then the app itself.
11698 for (j=0; j<NUMA; j++) {
11699 HistoryRecord r = (HistoryRecord)app.activities.get(j);
11700 if (!r.finishing) {
11701 destroyActivityLocked(r, false);
11702 }
11703 r.resultTo = null;
11704 }
11705 Log.i(TAG, "Exiting application process "
11706 + app.processName + " ("
11707 + (app.thread != null ? app.thread.asBinder() : null)
11708 + ")\n");
11709 if (app.pid > 0 && app.pid != MY_PID) {
11710 Process.killProcess(app.pid);
11711 } else {
11712 try {
11713 app.thread.scheduleExit();
11714 } catch (Exception e) {
11715 // Ignore exceptions.
11716 }
11717 }
11718 // todo: For now we assume the application is not buggy
11719 // or evil, and will quit as a result of our request.
11720 // Eventually we need to drive this off of the death
11721 // notification, and kill the process if it takes too long.
11722 cleanUpApplicationRecordLocked(app, false, i);
11723 i--;
11724 //dump();
11725 }
11726 }
11727
11728 }
11729
11730 int curMaxActivities = MAX_ACTIVITIES;
11731 if (mAlwaysFinishActivities) {
11732 curMaxActivities = 1;
11733 }
11734
11735 // Finally, if there are too many activities now running, try to
11736 // finish as many as we can to get back down to the limit.
11737 for ( i=0;
11738 i<mLRUActivities.size()
11739 && mLRUActivities.size() > curMaxActivities;
11740 i++) {
11741 final HistoryRecord r
11742 = (HistoryRecord)mLRUActivities.get(i);
11743
11744 // We can finish this one if we have its icicle saved and
11745 // it is not persistent.
11746 if ((r.haveState || !r.stateNotNeeded) && !r.visible
11747 && r.stopped && !r.persistent && !r.finishing) {
11748 final int origSize = mLRUActivities.size();
11749 destroyActivityLocked(r, true);
11750
11751 // This will remove it from the LRU list, so keep
11752 // our index at the same value. Note that this check to
11753 // see if the size changes is just paranoia -- if
11754 // something unexpected happens, we don't want to end up
11755 // in an infinite loop.
11756 if (origSize > mLRUActivities.size()) {
11757 i--;
11758 }
11759 }
11760 }
11761 }
11762 }
11763
11764 /** This method sends the specified signal to each of the persistent apps */
11765 public void signalPersistentProcesses(int sig) throws RemoteException {
11766 if (sig != Process.SIGNAL_USR1) {
11767 throw new SecurityException("Only SIGNAL_USR1 is allowed");
11768 }
11769
11770 synchronized (this) {
11771 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
11772 != PackageManager.PERMISSION_GRANTED) {
11773 throw new SecurityException("Requires permission "
11774 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
11775 }
11776
11777 for (int i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) {
11778 ProcessRecord r = mLRUProcesses.get(i);
11779 if (r.thread != null && r.persistent) {
11780 Process.sendSignal(r.pid, sig);
11781 }
11782 }
11783 }
11784 }
11785
11786 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
11787 public void monitor() {
11788 synchronized (this) { }
11789 }
11790}