ActivityManagerService.java revision c7b31e3c3cd71129557d4bf9e3fbcebb9235aba5
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import 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.ApplicationErrorReport; 34import android.app.Dialog; 35import android.app.IActivityWatcher; 36import android.app.IApplicationThread; 37import android.app.IInstrumentationWatcher; 38import android.app.IIntentReceiver; 39import android.app.IIntentSender; 40import android.app.IServiceConnection; 41import android.app.IThumbnailReceiver; 42import android.app.Instrumentation; 43import android.app.PendingIntent; 44import android.app.ResultInfo; 45import android.backup.IBackupManager; 46import android.content.ActivityNotFoundException; 47import android.content.ComponentName; 48import android.content.ContentResolver; 49import android.content.Context; 50import android.content.Intent; 51import android.content.IntentFilter; 52import android.content.pm.ActivityInfo; 53import android.content.pm.ApplicationInfo; 54import android.content.pm.ConfigurationInfo; 55import android.content.pm.IPackageDataObserver; 56import android.content.pm.IPackageManager; 57import android.content.pm.InstrumentationInfo; 58import android.content.pm.PackageManager; 59import android.content.pm.ProviderInfo; 60import android.content.pm.ResolveInfo; 61import android.content.pm.ServiceInfo; 62import android.content.res.Configuration; 63import android.graphics.Bitmap; 64import android.net.Uri; 65import android.os.BatteryStats; 66import android.os.Binder; 67import android.os.Bundle; 68import android.os.Environment; 69import android.os.FileUtils; 70import android.os.Handler; 71import android.os.IBinder; 72import android.os.IPermissionController; 73import android.os.Looper; 74import android.os.Message; 75import android.os.Parcel; 76import android.os.ParcelFileDescriptor; 77import android.os.PowerManager; 78import android.os.Process; 79import android.os.RemoteException; 80import android.os.ServiceManager; 81import android.os.SystemClock; 82import android.os.SystemProperties; 83import android.provider.Checkin; 84import android.provider.Settings; 85import android.server.data.CrashData; 86import android.server.data.StackTraceElementData; 87import android.server.data.ThrowableData; 88import android.text.TextUtils; 89import android.util.Config; 90import android.util.EventLog; 91import android.util.Log; 92import android.util.LogPrinter; 93import android.util.PrintWriterPrinter; 94import android.util.SparseArray; 95import android.view.Gravity; 96import android.view.LayoutInflater; 97import android.view.View; 98import android.view.WindowManager; 99import android.view.WindowManagerPolicy; 100 101import dalvik.system.Zygote; 102 103import java.io.ByteArrayInputStream; 104import java.io.DataInputStream; 105import java.io.File; 106import java.io.FileDescriptor; 107import java.io.FileInputStream; 108import java.io.FileNotFoundException; 109import java.io.IOException; 110import java.io.PrintWriter; 111import java.lang.IllegalStateException; 112import java.lang.ref.WeakReference; 113import java.util.ArrayList; 114import java.util.HashMap; 115import java.util.HashSet; 116import java.util.Iterator; 117import java.util.List; 118import java.util.Locale; 119import java.util.Map; 120 121public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor { 122 static final String TAG = "ActivityManager"; 123 static final boolean DEBUG = false; 124 static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV; 125 static final boolean DEBUG_SWITCH = localLOGV || false; 126 static final boolean DEBUG_TASKS = localLOGV || false; 127 static final boolean DEBUG_PAUSE = localLOGV || false; 128 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 129 static final boolean DEBUG_TRANSITION = localLOGV || false; 130 static final boolean DEBUG_BROADCAST = localLOGV || false; 131 static final boolean DEBUG_SERVICE = localLOGV || false; 132 static final boolean DEBUG_VISBILITY = localLOGV || false; 133 static final boolean DEBUG_PROCESSES = localLOGV || false; 134 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 135 static final boolean DEBUG_RESULTS = localLOGV || false; 136 static final boolean DEBUG_BACKUP = localLOGV || true; 137 static final boolean VALIDATE_TOKENS = false; 138 static final boolean SHOW_ACTIVITY_START_TIME = true; 139 140 // Control over CPU and battery monitoring. 141 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 142 static final boolean MONITOR_CPU_USAGE = true; 143 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 144 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 145 static final boolean MONITOR_THREAD_CPU_USAGE = false; 146 147 // Event log tags 148 static final int LOG_CONFIGURATION_CHANGED = 2719; 149 static final int LOG_CPU = 2721; 150 static final int LOG_AM_FINISH_ACTIVITY = 30001; 151 static final int LOG_TASK_TO_FRONT = 30002; 152 static final int LOG_AM_NEW_INTENT = 30003; 153 static final int LOG_AM_CREATE_TASK = 30004; 154 static final int LOG_AM_CREATE_ACTIVITY = 30005; 155 static final int LOG_AM_RESTART_ACTIVITY = 30006; 156 static final int LOG_AM_RESUME_ACTIVITY = 30007; 157 static final int LOG_ANR = 30008; 158 static final int LOG_ACTIVITY_LAUNCH_TIME = 30009; 159 static final int LOG_AM_PROCESS_BOUND = 30010; 160 static final int LOG_AM_PROCESS_DIED = 30011; 161 static final int LOG_AM_FAILED_TO_PAUSE_ACTIVITY = 30012; 162 static final int LOG_AM_PAUSE_ACTIVITY = 30013; 163 static final int LOG_AM_PROCESS_START = 30014; 164 static final int LOG_AM_PROCESS_BAD = 30015; 165 static final int LOG_AM_PROCESS_GOOD = 30016; 166 static final int LOG_AM_LOW_MEMORY = 30017; 167 static final int LOG_AM_DESTROY_ACTIVITY = 30018; 168 static final int LOG_AM_RELAUNCH_RESUME_ACTIVITY = 30019; 169 static final int LOG_AM_RELAUNCH_ACTIVITY = 30020; 170 static final int LOG_AM_KILL_FOR_MEMORY = 30023; 171 static final int LOG_AM_BROADCAST_DISCARD_FILTER = 30024; 172 static final int LOG_AM_BROADCAST_DISCARD_APP = 30025; 173 static final int LOG_AM_CREATE_SERVICE = 30030; 174 static final int LOG_AM_DESTROY_SERVICE = 30031; 175 static final int LOG_AM_PROCESS_CRASHED_TOO_MUCH = 30032; 176 static final int LOG_AM_DROP_PROCESS = 30033; 177 static final int LOG_AM_SERVICE_CRASHED_TOO_MUCH = 30034; 178 static final int LOG_AM_SCHEDULE_SERVICE_RESTART = 30035; 179 static final int LOG_AM_PROVIDER_LOST_PROCESS = 30036; 180 181 static final int LOG_BOOT_PROGRESS_AMS_READY = 3040; 182 static final int LOG_BOOT_PROGRESS_ENABLE_SCREEN = 3050; 183 184 // The flags that are set for all calls we make to the package manager. 185 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES 186 | PackageManager.GET_SUPPORTS_DENSITIES | PackageManager.GET_EXPANDABLE; 187 188 private static final String SYSTEM_SECURE = "ro.secure"; 189 190 // This is the maximum number of application processes we would like 191 // to have running. Due to the asynchronous nature of things, we can 192 // temporarily go beyond this limit. 193 static final int MAX_PROCESSES = 2; 194 195 // Set to false to leave processes running indefinitely, relying on 196 // the kernel killing them as resources are required. 197 static final boolean ENFORCE_PROCESS_LIMIT = false; 198 199 // This is the maximum number of activities that we would like to have 200 // running at a given time. 201 static final int MAX_ACTIVITIES = 20; 202 203 // Maximum number of recent tasks that we can remember. 204 static final int MAX_RECENT_TASKS = 20; 205 206 // Amount of time after a call to stopAppSwitches() during which we will 207 // prevent further untrusted switches from happening. 208 static final long APP_SWITCH_DELAY_TIME = 5*1000; 209 210 // How long until we reset a task when the user returns to it. Currently 211 // 30 minutes. 212 static final long ACTIVITY_INACTIVE_RESET_TIME = 1000*60*30; 213 214 // Set to true to disable the icon that is shown while a new activity 215 // is being started. 216 static final boolean SHOW_APP_STARTING_ICON = true; 217 218 // How long we wait until giving up on the last activity to pause. This 219 // is short because it directly impacts the responsiveness of starting the 220 // next activity. 221 static final int PAUSE_TIMEOUT = 500; 222 223 /** 224 * How long we can hold the launch wake lock before giving up. 225 */ 226 static final int LAUNCH_TIMEOUT = 10*1000; 227 228 // How long we wait for a launched process to attach to the activity manager 229 // before we decide it's never going to come up for real. 230 static final int PROC_START_TIMEOUT = 10*1000; 231 232 // How long we wait until giving up on the last activity telling us it 233 // is idle. 234 static final int IDLE_TIMEOUT = 10*1000; 235 236 // How long to wait after going idle before forcing apps to GC. 237 static final int GC_TIMEOUT = 5*1000; 238 239 // How long we wait until giving up on an activity telling us it has 240 // finished destroying itself. 241 static final int DESTROY_TIMEOUT = 10*1000; 242 243 // How long we allow a receiver to run before giving up on it. 244 static final int BROADCAST_TIMEOUT = 10*1000; 245 246 // How long we wait for a service to finish executing. 247 static final int SERVICE_TIMEOUT = 20*1000; 248 249 // How long a service needs to be running until restarting its process 250 // is no longer considered to be a relaunch of the service. 251 static final int SERVICE_RESTART_DURATION = 5*1000; 252 253 // Maximum amount of time for there to be no activity on a service before 254 // we consider it non-essential and allow its process to go on the 255 // LRU background list. 256 static final int MAX_SERVICE_INACTIVITY = 10*60*1000; 257 258 // How long we wait until we timeout on key dispatching. 259 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 260 261 // The minimum time we allow between crashes, for us to consider this 262 // application to be bad and stop and its services and reject broadcasts. 263 static final int MIN_CRASH_INTERVAL = 60*1000; 264 265 // How long we wait until we timeout on key dispatching during instrumentation. 266 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 267 268 // OOM adjustments for processes in various states: 269 270 // This is a process without anything currently running in it. Definitely 271 // the first to go! Value set in system/rootdir/init.rc on startup. 272 // This value is initalized in the constructor, careful when refering to 273 // this static variable externally. 274 static int EMPTY_APP_ADJ; 275 276 // This is a process with a content provider that does not have any clients 277 // attached to it. If it did have any clients, its adjustment would be the 278 // one for the highest-priority of those processes. 279 static int CONTENT_PROVIDER_ADJ; 280 281 // This is a process only hosting activities that are not visible, 282 // so it can be killed without any disruption. Value set in 283 // system/rootdir/init.rc on startup. 284 final int HIDDEN_APP_MAX_ADJ; 285 static int HIDDEN_APP_MIN_ADJ; 286 287 // This is a process holding the home application -- we want to try 288 // avoiding killing it, even if it would normally be in the background, 289 // because the user interacts with it so much. 290 final int HOME_APP_ADJ; 291 292 // This is a process currently hosting a backup operation. Killing it 293 // is not entirely fatal but is generally a bad idea. 294 final int BACKUP_APP_ADJ; 295 296 // This is a process holding a secondary server -- killing it will not 297 // have much of an impact as far as the user is concerned. Value set in 298 // system/rootdir/init.rc on startup. 299 final int SECONDARY_SERVER_ADJ; 300 301 // This is a process only hosting activities that are visible to the 302 // user, so we'd prefer they don't disappear. Value set in 303 // system/rootdir/init.rc on startup. 304 final int VISIBLE_APP_ADJ; 305 306 // This is the process running the current foreground app. We'd really 307 // rather not kill it! Value set in system/rootdir/init.rc on startup. 308 final int FOREGROUND_APP_ADJ; 309 310 // This is a process running a core server, such as telephony. Definitely 311 // don't want to kill it, but doing so is not completely fatal. 312 static final int CORE_SERVER_ADJ = -12; 313 314 // The system process runs at the default adjustment. 315 static final int SYSTEM_ADJ = -16; 316 317 // Memory pages are 4K. 318 static final int PAGE_SIZE = 4*1024; 319 320 // Corresponding memory levels for above adjustments. 321 final int EMPTY_APP_MEM; 322 final int HIDDEN_APP_MEM; 323 final int HOME_APP_MEM; 324 final int BACKUP_APP_MEM; 325 final int SECONDARY_SERVER_MEM; 326 final int VISIBLE_APP_MEM; 327 final int FOREGROUND_APP_MEM; 328 329 final int MY_PID; 330 331 static final String[] EMPTY_STRING_ARRAY = new String[0]; 332 333 enum ActivityState { 334 INITIALIZING, 335 RESUMED, 336 PAUSING, 337 PAUSED, 338 STOPPING, 339 STOPPED, 340 FINISHING, 341 DESTROYING, 342 DESTROYED 343 } 344 345 /** 346 * The back history of all previous (and possibly still 347 * running) activities. It contains HistoryRecord objects. 348 */ 349 final ArrayList mHistory = new ArrayList(); 350 351 /** 352 * Description of a request to start a new activity, which has been held 353 * due to app switches being disabled. 354 */ 355 class PendingActivityLaunch { 356 HistoryRecord r; 357 HistoryRecord sourceRecord; 358 Uri[] grantedUriPermissions; 359 int grantedMode; 360 boolean onlyIfNeeded; 361 } 362 363 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 364 = new ArrayList<PendingActivityLaunch>(); 365 366 /** 367 * List of all active broadcasts that are to be executed immediately 368 * (without waiting for another broadcast to finish). Currently this only 369 * contains broadcasts to registered receivers, to avoid spinning up 370 * a bunch of processes to execute IntentReceiver components. 371 */ 372 final ArrayList<BroadcastRecord> mParallelBroadcasts 373 = new ArrayList<BroadcastRecord>(); 374 375 /** 376 * List of all active broadcasts that are to be executed one at a time. 377 * The object at the top of the list is the currently activity broadcasts; 378 * those after it are waiting for the top to finish.. 379 */ 380 final ArrayList<BroadcastRecord> mOrderedBroadcasts 381 = new ArrayList<BroadcastRecord>(); 382 383 /** 384 * Set when we current have a BROADCAST_INTENT_MSG in flight. 385 */ 386 boolean mBroadcastsScheduled = false; 387 388 /** 389 * Set to indicate whether to issue an onUserLeaving callback when a 390 * newly launched activity is being brought in front of us. 391 */ 392 boolean mUserLeaving = false; 393 394 /** 395 * When we are in the process of pausing an activity, before starting the 396 * next one, this variable holds the activity that is currently being paused. 397 */ 398 HistoryRecord mPausingActivity = null; 399 400 /** 401 * Current activity that is resumed, or null if there is none. 402 */ 403 HistoryRecord mResumedActivity = null; 404 405 /** 406 * Activity we have told the window manager to have key focus. 407 */ 408 HistoryRecord mFocusedActivity = null; 409 410 /** 411 * This is the last activity that we put into the paused state. This is 412 * used to determine if we need to do an activity transition while sleeping, 413 * when we normally hold the top activity paused. 414 */ 415 HistoryRecord mLastPausedActivity = null; 416 417 /** 418 * List of activities that are waiting for a new activity 419 * to become visible before completing whatever operation they are 420 * supposed to do. 421 */ 422 final ArrayList mWaitingVisibleActivities = new ArrayList(); 423 424 /** 425 * List of activities that are ready to be stopped, but waiting 426 * for the next activity to settle down before doing so. It contains 427 * HistoryRecord objects. 428 */ 429 final ArrayList<HistoryRecord> mStoppingActivities 430 = new ArrayList<HistoryRecord>(); 431 432 /** 433 * List of intents that were used to start the most recent tasks. 434 */ 435 final ArrayList<TaskRecord> mRecentTasks 436 = new ArrayList<TaskRecord>(); 437 438 /** 439 * List of activities that are ready to be finished, but waiting 440 * for the previous activity to settle down before doing so. It contains 441 * HistoryRecord objects. 442 */ 443 final ArrayList mFinishingActivities = new ArrayList(); 444 445 /** 446 * All of the applications we currently have running organized by name. 447 * The keys are strings of the application package name (as 448 * returned by the package manager), and the keys are ApplicationRecord 449 * objects. 450 */ 451 final ProcessMap<ProcessRecord> mProcessNames 452 = new ProcessMap<ProcessRecord>(); 453 454 /** 455 * The last time that various processes have crashed. 456 */ 457 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 458 459 /** 460 * Set of applications that we consider to be bad, and will reject 461 * incoming broadcasts from (which the user has no control over). 462 * Processes are added to this set when they have crashed twice within 463 * a minimum amount of time; they are removed from it when they are 464 * later restarted (hopefully due to some user action). The value is the 465 * time it was added to the list. 466 */ 467 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 468 469 /** 470 * All of the processes we currently have running organized by pid. 471 * The keys are the pid running the application. 472 * 473 * <p>NOTE: This object is protected by its own lock, NOT the global 474 * activity manager lock! 475 */ 476 final SparseArray<ProcessRecord> mPidsSelfLocked 477 = new SparseArray<ProcessRecord>(); 478 479 /** 480 * All of the processes that have been forced to be foreground. The key 481 * is the pid of the caller who requested it (we hold a death 482 * link on it). 483 */ 484 abstract class ForegroundToken implements IBinder.DeathRecipient { 485 int pid; 486 IBinder token; 487 } 488 final SparseArray<ForegroundToken> mForegroundProcesses 489 = new SparseArray<ForegroundToken>(); 490 491 /** 492 * List of records for processes that someone had tried to start before the 493 * system was ready. We don't start them at that point, but ensure they 494 * are started by the time booting is complete. 495 */ 496 final ArrayList<ProcessRecord> mProcessesOnHold 497 = new ArrayList<ProcessRecord>(); 498 499 /** 500 * List of records for processes that we have started and are waiting 501 * for them to call back. This is really only needed when running in 502 * single processes mode, in which case we do not have a unique pid for 503 * each process. 504 */ 505 final ArrayList<ProcessRecord> mStartingProcesses 506 = new ArrayList<ProcessRecord>(); 507 508 /** 509 * List of persistent applications that are in the process 510 * of being started. 511 */ 512 final ArrayList<ProcessRecord> mPersistentStartingProcesses 513 = new ArrayList<ProcessRecord>(); 514 515 /** 516 * Processes that are being forcibly torn down. 517 */ 518 final ArrayList<ProcessRecord> mRemovedProcesses 519 = new ArrayList<ProcessRecord>(); 520 521 /** 522 * List of running applications, sorted by recent usage. 523 * The first entry in the list is the least recently used. 524 * It contains ApplicationRecord objects. This list does NOT include 525 * any persistent application records (since we never want to exit them). 526 */ 527 final ArrayList<ProcessRecord> mLRUProcesses 528 = new ArrayList<ProcessRecord>(); 529 530 /** 531 * List of processes that should gc as soon as things are idle. 532 */ 533 final ArrayList<ProcessRecord> mProcessesToGc 534 = new ArrayList<ProcessRecord>(); 535 536 /** 537 * This is the process holding what we currently consider to be 538 * the "home" activity. 539 */ 540 private ProcessRecord mHomeProcess; 541 542 /** 543 * List of running activities, sorted by recent usage. 544 * The first entry in the list is the least recently used. 545 * It contains HistoryRecord objects. 546 */ 547 private final ArrayList mLRUActivities = new ArrayList(); 548 549 /** 550 * Set of PendingResultRecord objects that are currently active. 551 */ 552 final HashSet mPendingResultRecords = new HashSet(); 553 554 /** 555 * Set of IntentSenderRecord objects that are currently active. 556 */ 557 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 558 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 559 560 /** 561 * Intent broadcast that we have tried to start, but are 562 * waiting for its application's process to be created. We only 563 * need one (instead of a list) because we always process broadcasts 564 * one at a time, so no others can be started while waiting for this 565 * one. 566 */ 567 BroadcastRecord mPendingBroadcast = null; 568 569 /** 570 * Keeps track of all IIntentReceivers that have been registered for 571 * broadcasts. Hash keys are the receiver IBinder, hash value is 572 * a ReceiverList. 573 */ 574 final HashMap mRegisteredReceivers = new HashMap(); 575 576 /** 577 * Resolver for broadcast intents to registered receivers. 578 * Holds BroadcastFilter (subclass of IntentFilter). 579 */ 580 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 581 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 582 @Override 583 protected boolean allowFilterResult( 584 BroadcastFilter filter, List<BroadcastFilter> dest) { 585 IBinder target = filter.receiverList.receiver.asBinder(); 586 for (int i=dest.size()-1; i>=0; i--) { 587 if (dest.get(i).receiverList.receiver.asBinder() == target) { 588 return false; 589 } 590 } 591 return true; 592 } 593 }; 594 595 /** 596 * State of all active sticky broadcasts. Keys are the action of the 597 * sticky Intent, values are an ArrayList of all broadcasted intents with 598 * that action (which should usually be one). 599 */ 600 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts = 601 new HashMap<String, ArrayList<Intent>>(); 602 603 /** 604 * All currently running services. 605 */ 606 final HashMap<ComponentName, ServiceRecord> mServices = 607 new HashMap<ComponentName, ServiceRecord>(); 608 609 /** 610 * All currently running services indexed by the Intent used to start them. 611 */ 612 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent = 613 new HashMap<Intent.FilterComparison, ServiceRecord>(); 614 615 /** 616 * All currently bound service connections. Keys are the IBinder of 617 * the client's IServiceConnection. 618 */ 619 final HashMap<IBinder, ConnectionRecord> mServiceConnections 620 = new HashMap<IBinder, ConnectionRecord>(); 621 622 /** 623 * List of services that we have been asked to start, 624 * but haven't yet been able to. It is used to hold start requests 625 * while waiting for their corresponding application thread to get 626 * going. 627 */ 628 final ArrayList<ServiceRecord> mPendingServices 629 = new ArrayList<ServiceRecord>(); 630 631 /** 632 * List of services that are scheduled to restart following a crash. 633 */ 634 final ArrayList<ServiceRecord> mRestartingServices 635 = new ArrayList<ServiceRecord>(); 636 637 /** 638 * List of services that are in the process of being stopped. 639 */ 640 final ArrayList<ServiceRecord> mStoppingServices 641 = new ArrayList<ServiceRecord>(); 642 643 /** 644 * Backup/restore process management 645 */ 646 String mBackupAppName = null; 647 BackupRecord mBackupTarget = null; 648 649 /** 650 * List of PendingThumbnailsRecord objects of clients who are still 651 * waiting to receive all of the thumbnails for a task. 652 */ 653 final ArrayList mPendingThumbnails = new ArrayList(); 654 655 /** 656 * List of HistoryRecord objects that have been finished and must 657 * still report back to a pending thumbnail receiver. 658 */ 659 final ArrayList mCancelledThumbnails = new ArrayList(); 660 661 /** 662 * All of the currently running global content providers. Keys are a 663 * string containing the provider name and values are a 664 * ContentProviderRecord object containing the data about it. Note 665 * that a single provider may be published under multiple names, so 666 * there may be multiple entries here for a single one in mProvidersByClass. 667 */ 668 final HashMap mProvidersByName = new HashMap(); 669 670 /** 671 * All of the currently running global content providers. Keys are a 672 * string containing the provider's implementation class and values are a 673 * ContentProviderRecord object containing the data about it. 674 */ 675 final HashMap mProvidersByClass = new HashMap(); 676 677 /** 678 * List of content providers who have clients waiting for them. The 679 * application is currently being launched and the provider will be 680 * removed from this list once it is published. 681 */ 682 final ArrayList mLaunchingProviders = new ArrayList(); 683 684 /** 685 * Global set of specific Uri permissions that have been granted. 686 */ 687 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 688 = new SparseArray<HashMap<Uri, UriPermission>>(); 689 690 /** 691 * Thread-local storage used to carry caller permissions over through 692 * indirect content-provider access. 693 * @see #ActivityManagerService.openContentUri() 694 */ 695 private class Identity { 696 public int pid; 697 public int uid; 698 699 Identity(int _pid, int _uid) { 700 pid = _pid; 701 uid = _uid; 702 } 703 } 704 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 705 706 /** 707 * All information we have collected about the runtime performance of 708 * any user id that can impact battery performance. 709 */ 710 final BatteryStatsService mBatteryStatsService; 711 712 /** 713 * information about component usage 714 */ 715 final UsageStatsService mUsageStatsService; 716 717 /** 718 * Current configuration information. HistoryRecord objects are given 719 * a reference to this object to indicate which configuration they are 720 * currently running in, so this object must be kept immutable. 721 */ 722 Configuration mConfiguration = new Configuration(); 723 724 /** 725 * List of initialization arguments to pass to all processes when binding applications to them. 726 * For example, references to the commonly used services. 727 */ 728 HashMap<String, IBinder> mAppBindArgs; 729 730 /** 731 * Temporary to avoid allocations. Protected by main lock. 732 */ 733 final StringBuilder mStringBuilder = new StringBuilder(256); 734 735 /** 736 * Used to control how we initialize the service. 737 */ 738 boolean mStartRunning = false; 739 ComponentName mTopComponent; 740 String mTopAction; 741 String mTopData; 742 boolean mSystemReady = false; 743 boolean mBooting = false; 744 745 Context mContext; 746 747 int mFactoryTest; 748 749 /** 750 * The time at which we will allow normal application switches again, 751 * after a call to {@link #stopAppSwitches()}. 752 */ 753 long mAppSwitchesAllowedTime; 754 755 /** 756 * This is set to true after the first switch after mAppSwitchesAllowedTime 757 * is set; any switches after that will clear the time. 758 */ 759 boolean mDidAppSwitch; 760 761 /** 762 * Set while we are wanting to sleep, to prevent any 763 * activities from being started/resumed. 764 */ 765 boolean mSleeping = false; 766 767 /** 768 * Set if we are shutting down the system, similar to sleeping. 769 */ 770 boolean mShuttingDown = false; 771 772 /** 773 * Set when the system is going to sleep, until we have 774 * successfully paused the current activity and released our wake lock. 775 * At that point the system is allowed to actually sleep. 776 */ 777 PowerManager.WakeLock mGoingToSleep; 778 779 /** 780 * We don't want to allow the device to go to sleep while in the process 781 * of launching an activity. This is primarily to allow alarm intent 782 * receivers to launch an activity and get that to run before the device 783 * goes back to sleep. 784 */ 785 PowerManager.WakeLock mLaunchingActivity; 786 787 /** 788 * Task identifier that activities are currently being started 789 * in. Incremented each time a new task is created. 790 * todo: Replace this with a TokenSpace class that generates non-repeating 791 * integers that won't wrap. 792 */ 793 int mCurTask = 1; 794 795 /** 796 * Current sequence id for oom_adj computation traversal. 797 */ 798 int mAdjSeq = 0; 799 800 /** 801 * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar 802 * is set, indicating the user wants processes started in such a way 803 * that they can use ANDROID_PROCESS_WRAPPER and know what will be 804 * running in each process (thus no pre-initialized process, etc). 805 */ 806 boolean mSimpleProcessManagement = false; 807 808 /** 809 * System monitoring: number of processes that died since the last 810 * N procs were started. 811 */ 812 int[] mProcDeaths = new int[20]; 813 814 String mDebugApp = null; 815 boolean mWaitForDebugger = false; 816 boolean mDebugTransient = false; 817 String mOrigDebugApp = null; 818 boolean mOrigWaitForDebugger = false; 819 boolean mAlwaysFinishActivities = false; 820 IActivityWatcher mWatcher = null; 821 822 /** 823 * Callback of last caller to {@link #requestPss}. 824 */ 825 Runnable mRequestPssCallback; 826 827 /** 828 * Remaining processes for which we are waiting results from the last 829 * call to {@link #requestPss}. 830 */ 831 final ArrayList<ProcessRecord> mRequestPssList 832 = new ArrayList<ProcessRecord>(); 833 834 /** 835 * Runtime statistics collection thread. This object's lock is used to 836 * protect all related state. 837 */ 838 final Thread mProcessStatsThread; 839 840 /** 841 * Used to collect process stats when showing not responding dialog. 842 * Protected by mProcessStatsThread. 843 */ 844 final ProcessStats mProcessStats = new ProcessStats( 845 MONITOR_THREAD_CPU_USAGE); 846 long mLastCpuTime = 0; 847 long mLastWriteTime = 0; 848 849 long mInitialStartTime = 0; 850 851 /** 852 * Set to true after the system has finished booting. 853 */ 854 boolean mBooted = false; 855 856 int mProcessLimit = 0; 857 858 WindowManagerService mWindowManager; 859 860 static ActivityManagerService mSelf; 861 static ActivityThread mSystemThread; 862 863 private final class AppDeathRecipient implements IBinder.DeathRecipient { 864 final ProcessRecord mApp; 865 final int mPid; 866 final IApplicationThread mAppThread; 867 868 AppDeathRecipient(ProcessRecord app, int pid, 869 IApplicationThread thread) { 870 if (localLOGV) Log.v( 871 TAG, "New death recipient " + this 872 + " for thread " + thread.asBinder()); 873 mApp = app; 874 mPid = pid; 875 mAppThread = thread; 876 } 877 878 public void binderDied() { 879 if (localLOGV) Log.v( 880 TAG, "Death received in " + this 881 + " for thread " + mAppThread.asBinder()); 882 removeRequestedPss(mApp); 883 synchronized(ActivityManagerService.this) { 884 appDiedLocked(mApp, mPid, mAppThread); 885 } 886 } 887 } 888 889 static final int SHOW_ERROR_MSG = 1; 890 static final int SHOW_NOT_RESPONDING_MSG = 2; 891 static final int SHOW_FACTORY_ERROR_MSG = 3; 892 static final int UPDATE_CONFIGURATION_MSG = 4; 893 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 894 static final int WAIT_FOR_DEBUGGER_MSG = 6; 895 static final int BROADCAST_INTENT_MSG = 7; 896 static final int BROADCAST_TIMEOUT_MSG = 8; 897 static final int PAUSE_TIMEOUT_MSG = 9; 898 static final int IDLE_TIMEOUT_MSG = 10; 899 static final int IDLE_NOW_MSG = 11; 900 static final int SERVICE_TIMEOUT_MSG = 12; 901 static final int UPDATE_TIME_ZONE = 13; 902 static final int SHOW_UID_ERROR_MSG = 14; 903 static final int IM_FEELING_LUCKY_MSG = 15; 904 static final int LAUNCH_TIMEOUT_MSG = 16; 905 static final int DESTROY_TIMEOUT_MSG = 17; 906 static final int SERVICE_ERROR_MSG = 18; 907 static final int RESUME_TOP_ACTIVITY_MSG = 19; 908 static final int PROC_START_TIMEOUT_MSG = 20; 909 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 910 911 AlertDialog mUidAlert; 912 913 final Handler mHandler = new Handler() { 914 //public Handler() { 915 // if (localLOGV) Log.v(TAG, "Handler started!"); 916 //} 917 918 public void handleMessage(Message msg) { 919 switch (msg.what) { 920 case SHOW_ERROR_MSG: { 921 HashMap data = (HashMap) msg.obj; 922 byte[] crashData = (byte[])data.get("crashData"); 923 if (crashData != null) { 924 // This needs to be *un*synchronized to avoid deadlock. 925 ContentResolver resolver = mContext.getContentResolver(); 926 Checkin.reportCrash(resolver, crashData); 927 } 928 synchronized (ActivityManagerService.this) { 929 ProcessRecord proc = (ProcessRecord)data.get("app"); 930 if (proc != null && proc.crashDialog != null) { 931 Log.e(TAG, "App already has crash dialog: " + proc); 932 return; 933 } 934 AppErrorResult res = (AppErrorResult) data.get("result"); 935 if (!mSleeping && !mShuttingDown) { 936 Dialog d = new AppErrorDialog( 937 mContext, res, proc, 938 (Integer)data.get("flags"), 939 (String)data.get("shortMsg"), 940 (String)data.get("longMsg")); 941 d.show(); 942 proc.crashDialog = d; 943 } else { 944 // The device is asleep, so just pretend that the user 945 // saw a crash dialog and hit "force quit". 946 res.set(0); 947 } 948 } 949 } break; 950 case SHOW_NOT_RESPONDING_MSG: { 951 synchronized (ActivityManagerService.this) { 952 HashMap data = (HashMap) msg.obj; 953 ProcessRecord proc = (ProcessRecord)data.get("app"); 954 if (proc != null && proc.anrDialog != null) { 955 Log.e(TAG, "App already has anr dialog: " + proc); 956 return; 957 } 958 959 broadcastIntentLocked(null, null, new Intent("android.intent.action.ANR"), 960 null, null, 0, null, null, null, 961 false, false, MY_PID, Process.SYSTEM_UID); 962 963 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 964 mContext, proc, (HistoryRecord)data.get("activity")); 965 d.show(); 966 proc.anrDialog = d; 967 } 968 969 ensureScreenEnabled(); 970 } break; 971 case SHOW_FACTORY_ERROR_MSG: { 972 Dialog d = new FactoryErrorDialog( 973 mContext, msg.getData().getCharSequence("msg")); 974 d.show(); 975 enableScreenAfterBoot(); 976 } break; 977 case UPDATE_CONFIGURATION_MSG: { 978 final ContentResolver resolver = mContext.getContentResolver(); 979 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 980 } break; 981 case GC_BACKGROUND_PROCESSES_MSG: { 982 synchronized (ActivityManagerService.this) { 983 performAppGcsIfAppropriateLocked(); 984 } 985 } break; 986 case WAIT_FOR_DEBUGGER_MSG: { 987 synchronized (ActivityManagerService.this) { 988 ProcessRecord app = (ProcessRecord)msg.obj; 989 if (msg.arg1 != 0) { 990 if (!app.waitedForDebugger) { 991 Dialog d = new AppWaitingForDebuggerDialog( 992 ActivityManagerService.this, 993 mContext, app); 994 app.waitDialog = d; 995 app.waitedForDebugger = true; 996 d.show(); 997 } 998 } else { 999 if (app.waitDialog != null) { 1000 app.waitDialog.dismiss(); 1001 app.waitDialog = null; 1002 } 1003 } 1004 } 1005 } break; 1006 case BROADCAST_INTENT_MSG: { 1007 if (DEBUG_BROADCAST) Log.v( 1008 TAG, "Received BROADCAST_INTENT_MSG"); 1009 processNextBroadcast(true); 1010 } break; 1011 case BROADCAST_TIMEOUT_MSG: { 1012 broadcastTimeout(); 1013 } break; 1014 case PAUSE_TIMEOUT_MSG: { 1015 IBinder token = (IBinder)msg.obj; 1016 // We don't at this point know if the activity is fullscreen, 1017 // so we need to be conservative and assume it isn't. 1018 Log.w(TAG, "Activity pause timeout for " + token); 1019 activityPaused(token, null, true); 1020 } break; 1021 case IDLE_TIMEOUT_MSG: { 1022 IBinder token = (IBinder)msg.obj; 1023 // We don't at this point know if the activity is fullscreen, 1024 // so we need to be conservative and assume it isn't. 1025 Log.w(TAG, "Activity idle timeout for " + token); 1026 activityIdleInternal(token, true); 1027 } break; 1028 case DESTROY_TIMEOUT_MSG: { 1029 IBinder token = (IBinder)msg.obj; 1030 // We don't at this point know if the activity is fullscreen, 1031 // so we need to be conservative and assume it isn't. 1032 Log.w(TAG, "Activity destroy timeout for " + token); 1033 activityDestroyed(token); 1034 } break; 1035 case IDLE_NOW_MSG: { 1036 IBinder token = (IBinder)msg.obj; 1037 activityIdle(token); 1038 } break; 1039 case SERVICE_TIMEOUT_MSG: { 1040 serviceTimeout((ProcessRecord)msg.obj); 1041 } break; 1042 case UPDATE_TIME_ZONE: { 1043 synchronized (ActivityManagerService.this) { 1044 for (int i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) { 1045 ProcessRecord r = mLRUProcesses.get(i); 1046 if (r.thread != null) { 1047 try { 1048 r.thread.updateTimeZone(); 1049 } catch (RemoteException ex) { 1050 Log.w(TAG, "Failed to update time zone for: " + r.info.processName); 1051 } 1052 } 1053 } 1054 } 1055 break; 1056 } 1057 case SHOW_UID_ERROR_MSG: { 1058 // XXX This is a temporary dialog, no need to localize. 1059 AlertDialog d = new BaseErrorDialog(mContext); 1060 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1061 d.setCancelable(false); 1062 d.setTitle("System UIDs Inconsistent"); 1063 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable."); 1064 d.setButton("I'm Feeling Lucky", 1065 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1066 mUidAlert = d; 1067 d.show(); 1068 } break; 1069 case IM_FEELING_LUCKY_MSG: { 1070 if (mUidAlert != null) { 1071 mUidAlert.dismiss(); 1072 mUidAlert = null; 1073 } 1074 } break; 1075 case LAUNCH_TIMEOUT_MSG: { 1076 synchronized (ActivityManagerService.this) { 1077 if (mLaunchingActivity.isHeld()) { 1078 Log.w(TAG, "Launch timeout has expired, giving up wake lock!"); 1079 mLaunchingActivity.release(); 1080 } 1081 } 1082 } break; 1083 case SERVICE_ERROR_MSG: { 1084 ServiceRecord srv = (ServiceRecord)msg.obj; 1085 // This needs to be *un*synchronized to avoid deadlock. 1086 Checkin.logEvent(mContext.getContentResolver(), 1087 Checkin.Events.Tag.SYSTEM_SERVICE_LOOPING, 1088 srv.name.toShortString()); 1089 } break; 1090 case RESUME_TOP_ACTIVITY_MSG: { 1091 synchronized (ActivityManagerService.this) { 1092 resumeTopActivityLocked(null); 1093 } 1094 } 1095 case PROC_START_TIMEOUT_MSG: { 1096 ProcessRecord app = (ProcessRecord)msg.obj; 1097 synchronized (ActivityManagerService.this) { 1098 processStartTimedOutLocked(app); 1099 } 1100 } 1101 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1102 synchronized (ActivityManagerService.this) { 1103 doPendingActivityLaunchesLocked(true); 1104 } 1105 } 1106 } 1107 } 1108 }; 1109 1110 public static void setSystemProcess() { 1111 try { 1112 ActivityManagerService m = mSelf; 1113 1114 ServiceManager.addService("activity", m); 1115 ServiceManager.addService("meminfo", new MemBinder(m)); 1116 if (MONITOR_CPU_USAGE) { 1117 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1118 } 1119 ServiceManager.addService("activity.broadcasts", new BroadcastsBinder(m)); 1120 ServiceManager.addService("activity.services", new ServicesBinder(m)); 1121 ServiceManager.addService("activity.senders", new SendersBinder(m)); 1122 ServiceManager.addService("activity.providers", new ProvidersBinder(m)); 1123 ServiceManager.addService("permission", new PermissionController(m)); 1124 1125 ApplicationInfo info = 1126 mSelf.mContext.getPackageManager().getApplicationInfo( 1127 "android", STOCK_PM_FLAGS); 1128 synchronized (mSelf) { 1129 ProcessRecord app = mSelf.newProcessRecordLocked( 1130 mSystemThread.getApplicationThread(), info, 1131 info.processName); 1132 app.persistent = true; 1133 app.pid = Process.myPid(); 1134 app.maxAdj = SYSTEM_ADJ; 1135 mSelf.mProcessNames.put(app.processName, app.info.uid, app); 1136 synchronized (mSelf.mPidsSelfLocked) { 1137 mSelf.mPidsSelfLocked.put(app.pid, app); 1138 } 1139 mSelf.updateLRUListLocked(app, true); 1140 } 1141 } catch (PackageManager.NameNotFoundException e) { 1142 throw new RuntimeException( 1143 "Unable to find android system package", e); 1144 } 1145 } 1146 1147 public void setWindowManager(WindowManagerService wm) { 1148 mWindowManager = wm; 1149 } 1150 1151 public static final Context main(int factoryTest) { 1152 AThread thr = new AThread(); 1153 thr.start(); 1154 1155 synchronized (thr) { 1156 while (thr.mService == null) { 1157 try { 1158 thr.wait(); 1159 } catch (InterruptedException e) { 1160 } 1161 } 1162 } 1163 1164 ActivityManagerService m = thr.mService; 1165 mSelf = m; 1166 ActivityThread at = ActivityThread.systemMain(); 1167 mSystemThread = at; 1168 Context context = at.getSystemContext(); 1169 m.mContext = context; 1170 m.mFactoryTest = factoryTest; 1171 PowerManager pm = 1172 (PowerManager)context.getSystemService(Context.POWER_SERVICE); 1173 m.mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep"); 1174 m.mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch"); 1175 m.mLaunchingActivity.setReferenceCounted(false); 1176 1177 m.mBatteryStatsService.publish(context); 1178 m.mUsageStatsService.publish(context); 1179 1180 synchronized (thr) { 1181 thr.mReady = true; 1182 thr.notifyAll(); 1183 } 1184 1185 m.startRunning(null, null, null, null); 1186 1187 return context; 1188 } 1189 1190 public static ActivityManagerService self() { 1191 return mSelf; 1192 } 1193 1194 static class AThread extends Thread { 1195 ActivityManagerService mService; 1196 boolean mReady = false; 1197 1198 public AThread() { 1199 super("ActivityManager"); 1200 } 1201 1202 public void run() { 1203 Looper.prepare(); 1204 1205 android.os.Process.setThreadPriority( 1206 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1207 1208 ActivityManagerService m = new ActivityManagerService(); 1209 1210 synchronized (this) { 1211 mService = m; 1212 notifyAll(); 1213 } 1214 1215 synchronized (this) { 1216 while (!mReady) { 1217 try { 1218 wait(); 1219 } catch (InterruptedException e) { 1220 } 1221 } 1222 } 1223 1224 Looper.loop(); 1225 } 1226 } 1227 1228 static class BroadcastsBinder extends Binder { 1229 ActivityManagerService mActivityManagerService; 1230 BroadcastsBinder(ActivityManagerService activityManagerService) { 1231 mActivityManagerService = activityManagerService; 1232 } 1233 1234 @Override 1235 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1236 mActivityManagerService.dumpBroadcasts(pw); 1237 } 1238 } 1239 1240 static class ServicesBinder extends Binder { 1241 ActivityManagerService mActivityManagerService; 1242 ServicesBinder(ActivityManagerService activityManagerService) { 1243 mActivityManagerService = activityManagerService; 1244 } 1245 1246 @Override 1247 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1248 mActivityManagerService.dumpServices(pw); 1249 } 1250 } 1251 1252 static class SendersBinder extends Binder { 1253 ActivityManagerService mActivityManagerService; 1254 SendersBinder(ActivityManagerService activityManagerService) { 1255 mActivityManagerService = activityManagerService; 1256 } 1257 1258 @Override 1259 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1260 mActivityManagerService.dumpSenders(pw); 1261 } 1262 } 1263 1264 static class ProvidersBinder extends Binder { 1265 ActivityManagerService mActivityManagerService; 1266 ProvidersBinder(ActivityManagerService activityManagerService) { 1267 mActivityManagerService = activityManagerService; 1268 } 1269 1270 @Override 1271 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1272 mActivityManagerService.dumpProviders(pw); 1273 } 1274 } 1275 1276 static class MemBinder extends Binder { 1277 ActivityManagerService mActivityManagerService; 1278 MemBinder(ActivityManagerService activityManagerService) { 1279 mActivityManagerService = activityManagerService; 1280 } 1281 1282 @Override 1283 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1284 ActivityManagerService service = mActivityManagerService; 1285 ArrayList<ProcessRecord> procs; 1286 synchronized (mActivityManagerService) { 1287 if (args != null && args.length > 0 1288 && args[0].charAt(0) != '-') { 1289 procs = new ArrayList<ProcessRecord>(); 1290 int pid = -1; 1291 try { 1292 pid = Integer.parseInt(args[0]); 1293 } catch (NumberFormatException e) { 1294 1295 } 1296 for (int i=0; i<service.mLRUProcesses.size(); i++) { 1297 ProcessRecord proc = service.mLRUProcesses.get(i); 1298 if (proc.pid == pid) { 1299 procs.add(proc); 1300 } else if (proc.processName.equals(args[0])) { 1301 procs.add(proc); 1302 } 1303 } 1304 if (procs.size() <= 0) { 1305 pw.println("No process found for: " + args[0]); 1306 return; 1307 } 1308 } else { 1309 procs = service.mLRUProcesses; 1310 } 1311 } 1312 dumpApplicationMemoryUsage(fd, pw, procs, " ", args); 1313 } 1314 } 1315 1316 static class CpuBinder extends Binder { 1317 ActivityManagerService mActivityManagerService; 1318 CpuBinder(ActivityManagerService activityManagerService) { 1319 mActivityManagerService = activityManagerService; 1320 } 1321 1322 @Override 1323 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1324 synchronized (mActivityManagerService.mProcessStatsThread) { 1325 pw.print(mActivityManagerService.mProcessStats.printCurrentState()); 1326 } 1327 } 1328 } 1329 1330 private ActivityManagerService() { 1331 String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT"); 1332 if (v != null && Integer.getInteger(v) != 0) { 1333 mSimpleProcessManagement = true; 1334 } 1335 v = System.getenv("ANDROID_DEBUG_APP"); 1336 if (v != null) { 1337 mSimpleProcessManagement = true; 1338 } 1339 1340 MY_PID = Process.myPid(); 1341 1342 File dataDir = Environment.getDataDirectory(); 1343 File systemDir = new File(dataDir, "system"); 1344 systemDir.mkdirs(); 1345 mBatteryStatsService = new BatteryStatsService(new File( 1346 systemDir, "batterystats.bin").toString()); 1347 mBatteryStatsService.getActiveStatistics().readLocked(); 1348 mBatteryStatsService.getActiveStatistics().writeLocked(); 1349 1350 mUsageStatsService = new UsageStatsService( new File( 1351 systemDir, "usagestats").toString()); 1352 1353 mConfiguration.makeDefault(); 1354 mProcessStats.init(); 1355 1356 // Add ourself to the Watchdog monitors. 1357 Watchdog.getInstance().addMonitor(this); 1358 1359 // These values are set in system/rootdir/init.rc on startup. 1360 FOREGROUND_APP_ADJ = 1361 Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_ADJ")); 1362 VISIBLE_APP_ADJ = 1363 Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_ADJ")); 1364 SECONDARY_SERVER_ADJ = 1365 Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_ADJ")); 1366 BACKUP_APP_ADJ = 1367 Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_ADJ")); 1368 HOME_APP_ADJ = 1369 Integer.valueOf(SystemProperties.get("ro.HOME_APP_ADJ")); 1370 HIDDEN_APP_MIN_ADJ = 1371 Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MIN_ADJ")); 1372 CONTENT_PROVIDER_ADJ = 1373 Integer.valueOf(SystemProperties.get("ro.CONTENT_PROVIDER_ADJ")); 1374 HIDDEN_APP_MAX_ADJ = CONTENT_PROVIDER_ADJ-1; 1375 EMPTY_APP_ADJ = 1376 Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_ADJ")); 1377 FOREGROUND_APP_MEM = 1378 Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_MEM"))*PAGE_SIZE; 1379 VISIBLE_APP_MEM = 1380 Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_MEM"))*PAGE_SIZE; 1381 SECONDARY_SERVER_MEM = 1382 Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_MEM"))*PAGE_SIZE; 1383 BACKUP_APP_MEM = 1384 Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_MEM"))*PAGE_SIZE; 1385 HOME_APP_MEM = 1386 Integer.valueOf(SystemProperties.get("ro.HOME_APP_MEM"))*PAGE_SIZE; 1387 HIDDEN_APP_MEM = 1388 Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MEM"))*PAGE_SIZE; 1389 EMPTY_APP_MEM = 1390 Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_MEM"))*PAGE_SIZE; 1391 1392 mProcessStatsThread = new Thread("ProcessStats") { 1393 public void run() { 1394 while (true) { 1395 try { 1396 try { 1397 synchronized(this) { 1398 final long now = SystemClock.uptimeMillis(); 1399 long nextCpuDelay = (mLastCpuTime+MONITOR_CPU_MAX_TIME)-now; 1400 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1401 //Log.i(TAG, "Cpu delay=" + nextCpuDelay 1402 // + ", write delay=" + nextWriteDelay); 1403 if (nextWriteDelay < nextCpuDelay) { 1404 nextCpuDelay = nextWriteDelay; 1405 } 1406 if (nextCpuDelay > 0) { 1407 this.wait(nextCpuDelay); 1408 } 1409 } 1410 } catch (InterruptedException e) { 1411 } 1412 1413 updateCpuStatsNow(); 1414 } catch (Exception e) { 1415 Log.e(TAG, "Unexpected exception collecting process stats", e); 1416 } 1417 } 1418 } 1419 }; 1420 mProcessStatsThread.start(); 1421 } 1422 1423 @Override 1424 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1425 throws RemoteException { 1426 try { 1427 return super.onTransact(code, data, reply, flags); 1428 } catch (RuntimeException e) { 1429 // The activity manager only throws security exceptions, so let's 1430 // log all others. 1431 if (!(e instanceof SecurityException)) { 1432 Log.e(TAG, "Activity Manager Crash", e); 1433 } 1434 throw e; 1435 } 1436 } 1437 1438 void updateCpuStats() { 1439 synchronized (mProcessStatsThread) { 1440 final long now = SystemClock.uptimeMillis(); 1441 if (mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) { 1442 mProcessStatsThread.notify(); 1443 } 1444 } 1445 } 1446 1447 void updateCpuStatsNow() { 1448 synchronized (mProcessStatsThread) { 1449 final long now = SystemClock.uptimeMillis(); 1450 boolean haveNewCpuStats = false; 1451 1452 if (MONITOR_CPU_USAGE && 1453 mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) { 1454 mLastCpuTime = now; 1455 haveNewCpuStats = true; 1456 mProcessStats.update(); 1457 //Log.i(TAG, mProcessStats.printCurrentState()); 1458 //Log.i(TAG, "Total CPU usage: " 1459 // + mProcessStats.getTotalCpuPercent() + "%"); 1460 1461 // Log the cpu usage if the property is set. 1462 if ("true".equals(SystemProperties.get("events.cpu"))) { 1463 int user = mProcessStats.getLastUserTime(); 1464 int system = mProcessStats.getLastSystemTime(); 1465 int iowait = mProcessStats.getLastIoWaitTime(); 1466 int irq = mProcessStats.getLastIrqTime(); 1467 int softIrq = mProcessStats.getLastSoftIrqTime(); 1468 int idle = mProcessStats.getLastIdleTime(); 1469 1470 int total = user + system + iowait + irq + softIrq + idle; 1471 if (total == 0) total = 1; 1472 1473 EventLog.writeEvent(LOG_CPU, 1474 ((user+system+iowait+irq+softIrq) * 100) / total, 1475 (user * 100) / total, 1476 (system * 100) / total, 1477 (iowait * 100) / total, 1478 (irq * 100) / total, 1479 (softIrq * 100) / total); 1480 } 1481 } 1482 1483 synchronized(mBatteryStatsService.getActiveStatistics()) { 1484 synchronized(mPidsSelfLocked) { 1485 if (haveNewCpuStats) { 1486 if (mBatteryStatsService.isOnBattery()) { 1487 final int N = mProcessStats.countWorkingStats(); 1488 for (int i=0; i<N; i++) { 1489 ProcessStats.Stats st 1490 = mProcessStats.getWorkingStats(i); 1491 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1492 if (pr != null) { 1493 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1494 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); 1495 } 1496 } 1497 } 1498 } 1499 } 1500 1501 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1502 mLastWriteTime = now; 1503 mBatteryStatsService.getActiveStatistics().writeLocked(); 1504 } 1505 } 1506 } 1507 } 1508 1509 /** 1510 * Initialize the application bind args. These are passed to each 1511 * process when the bindApplication() IPC is sent to the process. They're 1512 * lazily setup to make sure the services are running when they're asked for. 1513 */ 1514 private HashMap<String, IBinder> getCommonServicesLocked() { 1515 if (mAppBindArgs == null) { 1516 mAppBindArgs = new HashMap<String, IBinder>(); 1517 1518 // Setup the application init args 1519 mAppBindArgs.put("package", ServiceManager.getService("package")); 1520 mAppBindArgs.put("window", ServiceManager.getService("window")); 1521 mAppBindArgs.put(Context.ALARM_SERVICE, 1522 ServiceManager.getService(Context.ALARM_SERVICE)); 1523 } 1524 return mAppBindArgs; 1525 } 1526 1527 private final void setFocusedActivityLocked(HistoryRecord r) { 1528 if (mFocusedActivity != r) { 1529 mFocusedActivity = r; 1530 mWindowManager.setFocusedApp(r, true); 1531 } 1532 } 1533 1534 private final void updateLRUListLocked(ProcessRecord app, 1535 boolean oomAdj) { 1536 // put it on the LRU to keep track of when it should be exited. 1537 int lrui = mLRUProcesses.indexOf(app); 1538 if (lrui >= 0) mLRUProcesses.remove(lrui); 1539 mLRUProcesses.add(app); 1540 //Log.i(TAG, "Putting proc to front: " + app.processName); 1541 if (oomAdj) { 1542 updateOomAdjLocked(); 1543 } 1544 } 1545 1546 private final boolean updateLRUListLocked(HistoryRecord r) { 1547 final boolean hadit = mLRUActivities.remove(r); 1548 mLRUActivities.add(r); 1549 return hadit; 1550 } 1551 1552 private final HistoryRecord topRunningActivityLocked(HistoryRecord notTop) { 1553 int i = mHistory.size()-1; 1554 while (i >= 0) { 1555 HistoryRecord r = (HistoryRecord)mHistory.get(i); 1556 if (!r.finishing && r != notTop) { 1557 return r; 1558 } 1559 i--; 1560 } 1561 return null; 1562 } 1563 1564 private final HistoryRecord topRunningNonDelayedActivityLocked(HistoryRecord notTop) { 1565 int i = mHistory.size()-1; 1566 while (i >= 0) { 1567 HistoryRecord r = (HistoryRecord)mHistory.get(i); 1568 if (!r.finishing && !r.delayedResume && r != notTop) { 1569 return r; 1570 } 1571 i--; 1572 } 1573 return null; 1574 } 1575 1576 /** 1577 * This is a simplified version of topRunningActivityLocked that provides a number of 1578 * optional skip-over modes. It is intended for use with the ActivityWatcher hook only. 1579 * 1580 * @param token If non-null, any history records matching this token will be skipped. 1581 * @param taskId If non-zero, we'll attempt to skip over records with the same task ID. 1582 * 1583 * @return Returns the HistoryRecord of the next activity on the stack. 1584 */ 1585 private final HistoryRecord topRunningActivityLocked(IBinder token, int taskId) { 1586 int i = mHistory.size()-1; 1587 while (i >= 0) { 1588 HistoryRecord r = (HistoryRecord)mHistory.get(i); 1589 // Note: the taskId check depends on real taskId fields being non-zero 1590 if (!r.finishing && (token != r) && (taskId != r.task.taskId)) { 1591 return r; 1592 } 1593 i--; 1594 } 1595 return null; 1596 } 1597 1598 private final ProcessRecord getProcessRecordLocked( 1599 String processName, int uid) { 1600 if (uid == Process.SYSTEM_UID) { 1601 // The system gets to run in any process. If there are multiple 1602 // processes with the same uid, just pick the first (this 1603 // should never happen). 1604 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1605 processName); 1606 return procs != null ? procs.valueAt(0) : null; 1607 } 1608 ProcessRecord proc = mProcessNames.get(processName, uid); 1609 return proc; 1610 } 1611 1612 private boolean isNextTransitionForward() { 1613 int transit = mWindowManager.getPendingAppTransition(); 1614 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1615 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1616 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1617 } 1618 1619 private final boolean realStartActivityLocked(HistoryRecord r, 1620 ProcessRecord app, boolean andResume, boolean checkConfig) 1621 throws RemoteException { 1622 1623 r.startFreezingScreenLocked(app, 0); 1624 mWindowManager.setAppVisibility(r, true); 1625 1626 // Have the window manager re-evaluate the orientation of 1627 // the screen based on the new activity order. Note that 1628 // as a result of this, it can call back into the activity 1629 // manager with a new orientation. We don't care about that, 1630 // because the activity is not currently running so we are 1631 // just restarting it anyway. 1632 if (checkConfig) { 1633 Configuration config = mWindowManager.updateOrientationFromAppTokens( 1634 mConfiguration, 1635 r.mayFreezeScreenLocked(app) ? r : null); 1636 updateConfigurationLocked(config, r); 1637 } 1638 1639 r.app = app; 1640 1641 if (localLOGV) Log.v(TAG, "Launching: " + r); 1642 1643 int idx = app.activities.indexOf(r); 1644 if (idx < 0) { 1645 app.activities.add(r); 1646 } 1647 updateLRUListLocked(app, true); 1648 1649 try { 1650 if (app.thread == null) { 1651 throw new RemoteException(); 1652 } 1653 List<ResultInfo> results = null; 1654 List<Intent> newIntents = null; 1655 if (andResume) { 1656 results = r.results; 1657 newIntents = r.newIntents; 1658 } 1659 if (DEBUG_SWITCH) Log.v(TAG, "Launching: " + r 1660 + " icicle=" + r.icicle 1661 + " with results=" + results + " newIntents=" + newIntents 1662 + " andResume=" + andResume); 1663 if (andResume) { 1664 EventLog.writeEvent(LOG_AM_RESTART_ACTIVITY, 1665 System.identityHashCode(r), 1666 r.task.taskId, r.shortComponentName); 1667 } 1668 if (r.isHomeActivity) { 1669 mHomeProcess = app; 1670 } 1671 app.thread.scheduleLaunchActivity(new Intent(r.intent), r, 1672 r.info, r.icicle, results, newIntents, !andResume, 1673 isNextTransitionForward()); 1674 // Update usage stats for launched activity 1675 updateUsageStats(r, true); 1676 } catch (RemoteException e) { 1677 if (r.launchFailed) { 1678 // This is the second time we failed -- finish activity 1679 // and give up. 1680 Log.e(TAG, "Second failure launching " 1681 + r.intent.getComponent().flattenToShortString() 1682 + ", giving up", e); 1683 appDiedLocked(app, app.pid, app.thread); 1684 requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null, 1685 "2nd-crash"); 1686 return false; 1687 } 1688 1689 // This is the first time we failed -- restart process and 1690 // retry. 1691 app.activities.remove(r); 1692 throw e; 1693 } 1694 1695 r.launchFailed = false; 1696 if (updateLRUListLocked(r)) { 1697 Log.w(TAG, "Activity " + r 1698 + " being launched, but already in LRU list"); 1699 } 1700 1701 if (andResume) { 1702 // As part of the process of launching, ActivityThread also performs 1703 // a resume. 1704 r.state = ActivityState.RESUMED; 1705 r.icicle = null; 1706 r.haveState = false; 1707 r.stopped = false; 1708 mResumedActivity = r; 1709 r.task.touchActiveTime(); 1710 completeResumeLocked(r); 1711 pauseIfSleepingLocked(); 1712 } else { 1713 // This activity is not starting in the resumed state... which 1714 // should look like we asked it to pause+stop (but remain visible), 1715 // and it has done so and reported back the current icicle and 1716 // other state. 1717 r.state = ActivityState.STOPPED; 1718 r.stopped = true; 1719 } 1720 1721 return true; 1722 } 1723 1724 private final void startSpecificActivityLocked(HistoryRecord r, 1725 boolean andResume, boolean checkConfig) { 1726 // Is this activity's application already running? 1727 ProcessRecord app = getProcessRecordLocked(r.processName, 1728 r.info.applicationInfo.uid); 1729 1730 if (r.startTime == 0) { 1731 r.startTime = SystemClock.uptimeMillis(); 1732 if (mInitialStartTime == 0) { 1733 mInitialStartTime = r.startTime; 1734 } 1735 } else if (mInitialStartTime == 0) { 1736 mInitialStartTime = SystemClock.uptimeMillis(); 1737 } 1738 1739 if (app != null && app.thread != null) { 1740 try { 1741 realStartActivityLocked(r, app, andResume, checkConfig); 1742 return; 1743 } catch (RemoteException e) { 1744 Log.w(TAG, "Exception when starting activity " 1745 + r.intent.getComponent().flattenToShortString(), e); 1746 } 1747 1748 // If a dead object exception was thrown -- fall through to 1749 // restart the application. 1750 } 1751 1752 startProcessLocked(r.processName, r.info.applicationInfo, true, 0, 1753 "activity", r.intent.getComponent()); 1754 } 1755 1756 private final ProcessRecord startProcessLocked(String processName, 1757 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1758 String hostingType, ComponentName hostingName) { 1759 ProcessRecord app = getProcessRecordLocked(processName, info.uid); 1760 // We don't have to do anything more if: 1761 // (1) There is an existing application record; and 1762 // (2) The caller doesn't think it is dead, OR there is no thread 1763 // object attached to it so we know it couldn't have crashed; and 1764 // (3) There is a pid assigned to it, so it is either starting or 1765 // already running. 1766 if (DEBUG_PROCESSES) Log.v(TAG, "startProcess: name=" + processName 1767 + " app=" + app + " knownToBeDead=" + knownToBeDead 1768 + " thread=" + (app != null ? app.thread : null) 1769 + " pid=" + (app != null ? app.pid : -1)); 1770 if (app != null && 1771 (!knownToBeDead || app.thread == null) && app.pid > 0) { 1772 return app; 1773 } 1774 1775 String hostingNameStr = hostingName != null 1776 ? hostingName.flattenToShortString() : null; 1777 1778 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1779 // If we are in the background, then check to see if this process 1780 // is bad. If so, we will just silently fail. 1781 if (mBadProcesses.get(info.processName, info.uid) != null) { 1782 return null; 1783 } 1784 } else { 1785 // When the user is explicitly starting a process, then clear its 1786 // crash count so that we won't make it bad until they see at 1787 // least one crash dialog again, and make the process good again 1788 // if it had been bad. 1789 mProcessCrashTimes.remove(info.processName, info.uid); 1790 if (mBadProcesses.get(info.processName, info.uid) != null) { 1791 EventLog.writeEvent(LOG_AM_PROCESS_GOOD, info.uid, 1792 info.processName); 1793 mBadProcesses.remove(info.processName, info.uid); 1794 if (app != null) { 1795 app.bad = false; 1796 } 1797 } 1798 } 1799 1800 if (app == null) { 1801 app = newProcessRecordLocked(null, info, processName); 1802 mProcessNames.put(processName, info.uid, app); 1803 } else { 1804 // If this is a new package in the process, add the package to the list 1805 app.addPackage(info.packageName); 1806 } 1807 1808 // If the system is not ready yet, then hold off on starting this 1809 // process until it is. 1810 if (!mSystemReady 1811 && (info.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) { 1812 if (!mProcessesOnHold.contains(app)) { 1813 mProcessesOnHold.add(app); 1814 } 1815 return app; 1816 } 1817 1818 startProcessLocked(app, hostingType, hostingNameStr); 1819 return (app.pid != 0) ? app : null; 1820 } 1821 1822 private final void startProcessLocked(ProcessRecord app, 1823 String hostingType, String hostingNameStr) { 1824 if (app.pid > 0 && app.pid != MY_PID) { 1825 synchronized (mPidsSelfLocked) { 1826 mPidsSelfLocked.remove(app.pid); 1827 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1828 } 1829 app.pid = 0; 1830 } 1831 1832 mProcessesOnHold.remove(app); 1833 1834 updateCpuStats(); 1835 1836 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 1837 mProcDeaths[0] = 0; 1838 1839 try { 1840 int uid = app.info.uid; 1841 int[] gids = null; 1842 try { 1843 gids = mContext.getPackageManager().getPackageGids( 1844 app.info.packageName); 1845 } catch (PackageManager.NameNotFoundException e) { 1846 Log.w(TAG, "Unable to retrieve gids", e); 1847 } 1848 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 1849 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 1850 && mTopComponent != null 1851 && app.processName.equals(mTopComponent.getPackageName())) { 1852 uid = 0; 1853 } 1854 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 1855 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 1856 uid = 0; 1857 } 1858 } 1859 int debugFlags = 0; 1860 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 1861 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 1862 } 1863 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 1864 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 1865 } 1866 if ("1".equals(SystemProperties.get("debug.assert"))) { 1867 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 1868 } 1869 int pid = Process.start("android.app.ActivityThread", 1870 mSimpleProcessManagement ? app.processName : null, uid, uid, 1871 gids, debugFlags, null); 1872 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 1873 synchronized (bs) { 1874 if (bs.isOnBattery()) { 1875 app.batteryStats.incStartsLocked(); 1876 } 1877 } 1878 1879 EventLog.writeEvent(LOG_AM_PROCESS_START, pid, uid, 1880 app.processName, hostingType, 1881 hostingNameStr != null ? hostingNameStr : ""); 1882 1883 if (app.persistent) { 1884 Watchdog.getInstance().processStarted(app, app.processName, pid); 1885 } 1886 1887 StringBuilder buf = mStringBuilder; 1888 buf.setLength(0); 1889 buf.append("Start proc "); 1890 buf.append(app.processName); 1891 buf.append(" for "); 1892 buf.append(hostingType); 1893 if (hostingNameStr != null) { 1894 buf.append(" "); 1895 buf.append(hostingNameStr); 1896 } 1897 buf.append(": pid="); 1898 buf.append(pid); 1899 buf.append(" uid="); 1900 buf.append(uid); 1901 buf.append(" gids={"); 1902 if (gids != null) { 1903 for (int gi=0; gi<gids.length; gi++) { 1904 if (gi != 0) buf.append(", "); 1905 buf.append(gids[gi]); 1906 1907 } 1908 } 1909 buf.append("}"); 1910 Log.i(TAG, buf.toString()); 1911 if (pid == 0 || pid == MY_PID) { 1912 // Processes are being emulated with threads. 1913 app.pid = MY_PID; 1914 app.removed = false; 1915 mStartingProcesses.add(app); 1916 } else if (pid > 0) { 1917 app.pid = pid; 1918 app.removed = false; 1919 synchronized (mPidsSelfLocked) { 1920 this.mPidsSelfLocked.put(pid, app); 1921 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1922 msg.obj = app; 1923 mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT); 1924 } 1925 } else { 1926 app.pid = 0; 1927 RuntimeException e = new RuntimeException( 1928 "Failure starting process " + app.processName 1929 + ": returned pid=" + pid); 1930 Log.e(TAG, e.getMessage(), e); 1931 } 1932 } catch (RuntimeException e) { 1933 // XXX do better error recovery. 1934 app.pid = 0; 1935 Log.e(TAG, "Failure starting process " + app.processName, e); 1936 } 1937 } 1938 1939 private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) { 1940 if (mPausingActivity != null) { 1941 RuntimeException e = new RuntimeException(); 1942 Log.e(TAG, "Trying to pause when pause is already pending for " 1943 + mPausingActivity, e); 1944 } 1945 HistoryRecord prev = mResumedActivity; 1946 if (prev == null) { 1947 RuntimeException e = new RuntimeException(); 1948 Log.e(TAG, "Trying to pause when nothing is resumed", e); 1949 resumeTopActivityLocked(null); 1950 return; 1951 } 1952 if (DEBUG_PAUSE) Log.v(TAG, "Start pausing: " + prev); 1953 mResumedActivity = null; 1954 mPausingActivity = prev; 1955 mLastPausedActivity = prev; 1956 prev.state = ActivityState.PAUSING; 1957 prev.task.touchActiveTime(); 1958 1959 updateCpuStats(); 1960 1961 if (prev.app != null && prev.app.thread != null) { 1962 if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending pause: " + prev); 1963 try { 1964 EventLog.writeEvent(LOG_AM_PAUSE_ACTIVITY, 1965 System.identityHashCode(prev), 1966 prev.shortComponentName); 1967 prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving, 1968 prev.configChangeFlags); 1969 updateUsageStats(prev, false); 1970 } catch (Exception e) { 1971 // Ignore exception, if process died other code will cleanup. 1972 Log.w(TAG, "Exception thrown during pause", e); 1973 mPausingActivity = null; 1974 mLastPausedActivity = null; 1975 } 1976 } else { 1977 mPausingActivity = null; 1978 mLastPausedActivity = null; 1979 } 1980 1981 // If we are not going to sleep, we want to ensure the device is 1982 // awake until the next activity is started. 1983 if (!mSleeping && !mShuttingDown) { 1984 mLaunchingActivity.acquire(); 1985 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) { 1986 // To be safe, don't allow the wake lock to be held for too long. 1987 Message msg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG); 1988 mHandler.sendMessageDelayed(msg, LAUNCH_TIMEOUT); 1989 } 1990 } 1991 1992 1993 if (mPausingActivity != null) { 1994 // Have the window manager pause its key dispatching until the new 1995 // activity has started. If we're pausing the activity just because 1996 // the screen is being turned off and the UI is sleeping, don't interrupt 1997 // key dispatch; the same activity will pick it up again on wakeup. 1998 if (!uiSleeping) { 1999 prev.pauseKeyDispatchingLocked(); 2000 } else { 2001 if (DEBUG_PAUSE) Log.v(TAG, "Key dispatch not paused for screen off"); 2002 } 2003 2004 // Schedule a pause timeout in case the app doesn't respond. 2005 // We don't give it much time because this directly impacts the 2006 // responsiveness seen by the user. 2007 Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG); 2008 msg.obj = prev; 2009 mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT); 2010 if (DEBUG_PAUSE) Log.v(TAG, "Waiting for pause to complete..."); 2011 } else { 2012 // This activity failed to schedule the 2013 // pause, so just treat it as being paused now. 2014 if (DEBUG_PAUSE) Log.v(TAG, "Activity not running, resuming next."); 2015 resumeTopActivityLocked(null); 2016 } 2017 } 2018 2019 private final void completePauseLocked() { 2020 HistoryRecord prev = mPausingActivity; 2021 if (DEBUG_PAUSE) Log.v(TAG, "Complete pause: " + prev); 2022 2023 if (prev != null) { 2024 if (prev.finishing) { 2025 if (DEBUG_PAUSE) Log.v(TAG, "Executing finish of activity: " + prev); 2026 prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE); 2027 } else if (prev.app != null) { 2028 if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending stop: " + prev); 2029 if (prev.waitingVisible) { 2030 prev.waitingVisible = false; 2031 mWaitingVisibleActivities.remove(prev); 2032 if (DEBUG_SWITCH || DEBUG_PAUSE) Log.v( 2033 TAG, "Complete pause, no longer waiting: " + prev); 2034 } 2035 if (prev.configDestroy) { 2036 // The previous is being paused because the configuration 2037 // is changing, which means it is actually stopping... 2038 // To juggle the fact that we are also starting a new 2039 // instance right now, we need to first completely stop 2040 // the current instance before starting the new one. 2041 if (DEBUG_PAUSE) Log.v(TAG, "Destroying after pause: " + prev); 2042 destroyActivityLocked(prev, true); 2043 } else { 2044 mStoppingActivities.add(prev); 2045 if (mStoppingActivities.size() > 3) { 2046 // If we already have a few activities waiting to stop, 2047 // then give up on things going idle and start clearing 2048 // them out. 2049 if (DEBUG_PAUSE) Log.v(TAG, "To many pending stops, forcing idle"); 2050 Message msg = Message.obtain(); 2051 msg.what = ActivityManagerService.IDLE_NOW_MSG; 2052 mHandler.sendMessage(msg); 2053 } 2054 } 2055 } else { 2056 if (DEBUG_PAUSE) Log.v(TAG, "App died during pause, not stopping: " + prev); 2057 prev = null; 2058 } 2059 mPausingActivity = null; 2060 } 2061 2062 if (!mSleeping && !mShuttingDown) { 2063 resumeTopActivityLocked(prev); 2064 } else { 2065 if (mGoingToSleep.isHeld()) { 2066 mGoingToSleep.release(); 2067 } 2068 if (mShuttingDown) { 2069 notifyAll(); 2070 } 2071 } 2072 2073 if (prev != null) { 2074 prev.resumeKeyDispatchingLocked(); 2075 } 2076 2077 if (prev.app != null && prev.cpuTimeAtResume > 0 && mBatteryStatsService.isOnBattery()) { 2078 long diff = 0; 2079 synchronized (mProcessStatsThread) { 2080 diff = mProcessStats.getCpuTimeForPid(prev.app.pid) - prev.cpuTimeAtResume; 2081 } 2082 if (diff > 0) { 2083 BatteryStatsImpl bsi = mBatteryStatsService.getActiveStatistics(); 2084 synchronized (bsi) { 2085 BatteryStatsImpl.Uid.Proc ps = 2086 bsi.getProcessStatsLocked(prev.info.applicationInfo.uid, 2087 prev.info.packageName); 2088 if (ps != null) { 2089 ps.addForegroundTimeLocked(diff); 2090 } 2091 } 2092 } 2093 } 2094 prev.cpuTimeAtResume = 0; // reset it 2095 } 2096 2097 /** 2098 * Once we know that we have asked an application to put an activity in 2099 * the resumed state (either by launching it or explicitly telling it), 2100 * this function updates the rest of our state to match that fact. 2101 */ 2102 private final void completeResumeLocked(HistoryRecord next) { 2103 next.idle = false; 2104 next.results = null; 2105 next.newIntents = null; 2106 2107 // schedule an idle timeout in case the app doesn't do it for us. 2108 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 2109 msg.obj = next; 2110 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 2111 2112 if (false) { 2113 // The activity was never told to pause, so just keep 2114 // things going as-is. To maintain our own state, 2115 // we need to emulate it coming back and saying it is 2116 // idle. 2117 msg = mHandler.obtainMessage(IDLE_NOW_MSG); 2118 msg.obj = next; 2119 mHandler.sendMessage(msg); 2120 } 2121 2122 next.thumbnail = null; 2123 setFocusedActivityLocked(next); 2124 next.resumeKeyDispatchingLocked(); 2125 ensureActivitiesVisibleLocked(null, 0); 2126 mWindowManager.executeAppTransition(); 2127 2128 // Mark the point when the activity is resuming 2129 // TODO: To be more accurate, the mark should be before the onCreate, 2130 // not after the onResume. But for subsequent starts, onResume is fine. 2131 if (next.app != null) { 2132 synchronized (mProcessStatsThread) { 2133 next.cpuTimeAtResume = mProcessStats.getCpuTimeForPid(next.app.pid); 2134 } 2135 } else { 2136 next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process 2137 } 2138 } 2139 2140 /** 2141 * Make sure that all activities that need to be visible (that is, they 2142 * currently can be seen by the user) actually are. 2143 */ 2144 private final void ensureActivitiesVisibleLocked(HistoryRecord top, 2145 HistoryRecord starting, String onlyThisProcess, int configChanges) { 2146 if (DEBUG_VISBILITY) Log.v( 2147 TAG, "ensureActivitiesVisible behind " + top 2148 + " configChanges=0x" + Integer.toHexString(configChanges)); 2149 2150 // If the top activity is not fullscreen, then we need to 2151 // make sure any activities under it are now visible. 2152 final int count = mHistory.size(); 2153 int i = count-1; 2154 while (mHistory.get(i) != top) { 2155 i--; 2156 } 2157 HistoryRecord r; 2158 boolean behindFullscreen = false; 2159 for (; i>=0; i--) { 2160 r = (HistoryRecord)mHistory.get(i); 2161 if (DEBUG_VISBILITY) Log.v( 2162 TAG, "Make visible? " + r + " finishing=" + r.finishing 2163 + " state=" + r.state); 2164 if (r.finishing) { 2165 continue; 2166 } 2167 2168 final boolean doThisProcess = onlyThisProcess == null 2169 || onlyThisProcess.equals(r.processName); 2170 2171 // First: if this is not the current activity being started, make 2172 // sure it matches the current configuration. 2173 if (r != starting && doThisProcess) { 2174 ensureActivityConfigurationLocked(r, 0); 2175 } 2176 2177 if (r.app == null || r.app.thread == null) { 2178 if (onlyThisProcess == null 2179 || onlyThisProcess.equals(r.processName)) { 2180 // This activity needs to be visible, but isn't even 2181 // running... get it started, but don't resume it 2182 // at this point. 2183 if (DEBUG_VISBILITY) Log.v( 2184 TAG, "Start and freeze screen for " + r); 2185 if (r != starting) { 2186 r.startFreezingScreenLocked(r.app, configChanges); 2187 } 2188 if (!r.visible) { 2189 if (DEBUG_VISBILITY) Log.v( 2190 TAG, "Starting and making visible: " + r); 2191 mWindowManager.setAppVisibility(r, true); 2192 } 2193 if (r != starting) { 2194 startSpecificActivityLocked(r, false, false); 2195 } 2196 } 2197 2198 } else if (r.visible) { 2199 // If this activity is already visible, then there is nothing 2200 // else to do here. 2201 if (DEBUG_VISBILITY) Log.v( 2202 TAG, "Skipping: already visible at " + r); 2203 r.stopFreezingScreenLocked(false); 2204 2205 } else if (onlyThisProcess == null) { 2206 // This activity is not currently visible, but is running. 2207 // Tell it to become visible. 2208 r.visible = true; 2209 if (r.state != ActivityState.RESUMED && r != starting) { 2210 // If this activity is paused, tell it 2211 // to now show its window. 2212 if (DEBUG_VISBILITY) Log.v( 2213 TAG, "Making visible and scheduling visibility: " + r); 2214 try { 2215 mWindowManager.setAppVisibility(r, true); 2216 r.app.thread.scheduleWindowVisibility(r, true); 2217 r.stopFreezingScreenLocked(false); 2218 } catch (Exception e) { 2219 // Just skip on any failure; we'll make it 2220 // visible when it next restarts. 2221 Log.w(TAG, "Exception thrown making visibile: " 2222 + r.intent.getComponent(), e); 2223 } 2224 } 2225 } 2226 2227 // Aggregate current change flags. 2228 configChanges |= r.configChangeFlags; 2229 2230 if (r.fullscreen) { 2231 // At this point, nothing else needs to be shown 2232 if (DEBUG_VISBILITY) Log.v( 2233 TAG, "Stopping: fullscreen at " + r); 2234 behindFullscreen = true; 2235 i--; 2236 break; 2237 } 2238 } 2239 2240 // Now for any activities that aren't visible to the user, make 2241 // sure they no longer are keeping the screen frozen. 2242 while (i >= 0) { 2243 r = (HistoryRecord)mHistory.get(i); 2244 if (DEBUG_VISBILITY) Log.v( 2245 TAG, "Make invisible? " + r + " finishing=" + r.finishing 2246 + " state=" + r.state 2247 + " behindFullscreen=" + behindFullscreen); 2248 if (!r.finishing) { 2249 if (behindFullscreen) { 2250 if (r.visible) { 2251 if (DEBUG_VISBILITY) Log.v( 2252 TAG, "Making invisible: " + r); 2253 r.visible = false; 2254 try { 2255 mWindowManager.setAppVisibility(r, false); 2256 if ((r.state == ActivityState.STOPPING 2257 || r.state == ActivityState.STOPPED) 2258 && r.app != null && r.app.thread != null) { 2259 if (DEBUG_VISBILITY) Log.v( 2260 TAG, "Scheduling invisibility: " + r); 2261 r.app.thread.scheduleWindowVisibility(r, false); 2262 } 2263 } catch (Exception e) { 2264 // Just skip on any failure; we'll make it 2265 // visible when it next restarts. 2266 Log.w(TAG, "Exception thrown making hidden: " 2267 + r.intent.getComponent(), e); 2268 } 2269 } else { 2270 if (DEBUG_VISBILITY) Log.v( 2271 TAG, "Already invisible: " + r); 2272 } 2273 } else if (r.fullscreen) { 2274 if (DEBUG_VISBILITY) Log.v( 2275 TAG, "Now behindFullscreen: " + r); 2276 behindFullscreen = true; 2277 } 2278 } 2279 i--; 2280 } 2281 } 2282 2283 /** 2284 * Version of ensureActivitiesVisible that can easily be called anywhere. 2285 */ 2286 private final void ensureActivitiesVisibleLocked(HistoryRecord starting, 2287 int configChanges) { 2288 HistoryRecord r = topRunningActivityLocked(null); 2289 if (r != null) { 2290 ensureActivitiesVisibleLocked(r, starting, null, configChanges); 2291 } 2292 } 2293 2294 private void updateUsageStats(HistoryRecord resumedComponent, boolean resumed) { 2295 if (resumed) { 2296 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2297 } else { 2298 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2299 } 2300 } 2301 2302 /** 2303 * Ensure that the top activity in the stack is resumed. 2304 * 2305 * @param prev The previously resumed activity, for when in the process 2306 * of pausing; can be null to call from elsewhere. 2307 * 2308 * @return Returns true if something is being resumed, or false if 2309 * nothing happened. 2310 */ 2311 private final boolean resumeTopActivityLocked(HistoryRecord prev) { 2312 // Find the first activity that is not finishing. 2313 HistoryRecord next = topRunningActivityLocked(null); 2314 2315 // Remember how we'll process this pause/resume situation, and ensure 2316 // that the state is reset however we wind up proceeding. 2317 final boolean userLeaving = mUserLeaving; 2318 mUserLeaving = false; 2319 2320 if (next == null) { 2321 // There are no more activities! Let's just start up the 2322 // Launcher... 2323 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2324 && mTopAction == null) { 2325 // We are running in factory test mode, but unable to find 2326 // the factory test app, so just sit around displaying the 2327 // error message and don't try to start anything. 2328 return false; 2329 } 2330 Intent intent = new Intent( 2331 mTopAction, 2332 mTopData != null ? Uri.parse(mTopData) : null); 2333 intent.setComponent(mTopComponent); 2334 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2335 intent.addCategory(Intent.CATEGORY_HOME); 2336 } 2337 ActivityInfo aInfo = 2338 intent.resolveActivityInfo(mContext.getPackageManager(), 2339 STOCK_PM_FLAGS); 2340 if (aInfo != null) { 2341 intent.setComponent(new ComponentName( 2342 aInfo.applicationInfo.packageName, aInfo.name)); 2343 // Don't do this if the home app is currently being 2344 // instrumented. 2345 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2346 aInfo.applicationInfo.uid); 2347 if (app == null || app.instrumentationClass == null) { 2348 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2349 startActivityLocked(null, intent, null, null, 0, aInfo, 2350 null, null, 0, 0, 0, false, false); 2351 } 2352 } 2353 return true; 2354 } 2355 2356 next.delayedResume = false; 2357 2358 // If the top activity is the resumed one, nothing to do. 2359 if (mResumedActivity == next && next.state == ActivityState.RESUMED) { 2360 // Make sure we have executed any pending transitions, since there 2361 // should be nothing left to do at this point. 2362 mWindowManager.executeAppTransition(); 2363 return false; 2364 } 2365 2366 // If we are sleeping, and there is no resumed activity, and the top 2367 // activity is paused, well that is the state we want. 2368 if ((mSleeping || mShuttingDown) 2369 && mLastPausedActivity == next && next.state == ActivityState.PAUSED) { 2370 // Make sure we have executed any pending transitions, since there 2371 // should be nothing left to do at this point. 2372 mWindowManager.executeAppTransition(); 2373 return false; 2374 } 2375 2376 // The activity may be waiting for stop, but that is no longer 2377 // appropriate for it. 2378 mStoppingActivities.remove(next); 2379 mWaitingVisibleActivities.remove(next); 2380 2381 if (DEBUG_SWITCH) Log.v(TAG, "Resuming " + next); 2382 2383 // If we are currently pausing an activity, then don't do anything 2384 // until that is done. 2385 if (mPausingActivity != null) { 2386 if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: pausing=" + mPausingActivity); 2387 return false; 2388 } 2389 2390 // We need to start pausing the current activity so the top one 2391 // can be resumed... 2392 if (mResumedActivity != null) { 2393 if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: need to start pausing"); 2394 startPausingLocked(userLeaving, false); 2395 return true; 2396 } 2397 2398 if (prev != null && prev != next) { 2399 if (!prev.waitingVisible && next != null && !next.nowVisible) { 2400 prev.waitingVisible = true; 2401 mWaitingVisibleActivities.add(prev); 2402 if (DEBUG_SWITCH) Log.v( 2403 TAG, "Resuming top, waiting visible to hide: " + prev); 2404 } else { 2405 // The next activity is already visible, so hide the previous 2406 // activity's windows right now so we can show the new one ASAP. 2407 // We only do this if the previous is finishing, which should mean 2408 // it is on top of the one being resumed so hiding it quickly 2409 // is good. Otherwise, we want to do the normal route of allowing 2410 // the resumed activity to be shown so we can decide if the 2411 // previous should actually be hidden depending on whether the 2412 // new one is found to be full-screen or not. 2413 if (prev.finishing) { 2414 mWindowManager.setAppVisibility(prev, false); 2415 if (DEBUG_SWITCH) Log.v(TAG, "Not waiting for visible to hide: " 2416 + prev + ", waitingVisible=" 2417 + (prev != null ? prev.waitingVisible : null) 2418 + ", nowVisible=" + next.nowVisible); 2419 } else { 2420 if (DEBUG_SWITCH) Log.v(TAG, "Previous already visible but still waiting to hide: " 2421 + prev + ", waitingVisible=" 2422 + (prev != null ? prev.waitingVisible : null) 2423 + ", nowVisible=" + next.nowVisible); 2424 } 2425 } 2426 } 2427 2428 // We are starting up the next activity, so tell the window manager 2429 // that the previous one will be hidden soon. This way it can know 2430 // to ignore it when computing the desired screen orientation. 2431 if (prev != null) { 2432 if (prev.finishing) { 2433 if (DEBUG_TRANSITION) Log.v(TAG, 2434 "Prepare close transition: prev=" + prev); 2435 mWindowManager.prepareAppTransition(prev.task == next.task 2436 ? WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE 2437 : WindowManagerPolicy.TRANSIT_TASK_CLOSE); 2438 mWindowManager.setAppWillBeHidden(prev); 2439 mWindowManager.setAppVisibility(prev, false); 2440 } else { 2441 if (DEBUG_TRANSITION) Log.v(TAG, 2442 "Prepare open transition: prev=" + prev); 2443 mWindowManager.prepareAppTransition(prev.task == next.task 2444 ? WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 2445 : WindowManagerPolicy.TRANSIT_TASK_OPEN); 2446 } 2447 if (false) { 2448 mWindowManager.setAppWillBeHidden(prev); 2449 mWindowManager.setAppVisibility(prev, false); 2450 } 2451 } else if (mHistory.size() > 1) { 2452 if (DEBUG_TRANSITION) Log.v(TAG, 2453 "Prepare open transition: no previous"); 2454 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN); 2455 } 2456 2457 if (next.app != null && next.app.thread != null) { 2458 if (DEBUG_SWITCH) Log.v(TAG, "Resume running: " + next); 2459 2460 // This activity is now becoming visible. 2461 mWindowManager.setAppVisibility(next, true); 2462 2463 HistoryRecord lastResumedActivity = mResumedActivity; 2464 ActivityState lastState = next.state; 2465 2466 updateCpuStats(); 2467 2468 next.state = ActivityState.RESUMED; 2469 mResumedActivity = next; 2470 next.task.touchActiveTime(); 2471 updateLRUListLocked(next.app, true); 2472 updateLRUListLocked(next); 2473 2474 // Have the window manager re-evaluate the orientation of 2475 // the screen based on the new activity order. 2476 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2477 mConfiguration, 2478 next.mayFreezeScreenLocked(next.app) ? next : null); 2479 if (config != null) { 2480 next.frozenBeforeDestroy = true; 2481 } 2482 if (!updateConfigurationLocked(config, next)) { 2483 // The configuration update wasn't able to keep the existing 2484 // instance of the activity, and instead started a new one. 2485 // We should be all done, but let's just make sure our activity 2486 // is still at the top and schedule another run if something 2487 // weird happened. 2488 HistoryRecord nextNext = topRunningActivityLocked(null); 2489 if (DEBUG_SWITCH) Log.i(TAG, 2490 "Activity config changed during resume: " + next 2491 + ", new next: " + nextNext); 2492 if (nextNext != next) { 2493 // Do over! 2494 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 2495 } 2496 mWindowManager.executeAppTransition(); 2497 return true; 2498 } 2499 2500 try { 2501 // Deliver all pending results. 2502 ArrayList a = next.results; 2503 if (a != null) { 2504 final int N = a.size(); 2505 if (!next.finishing && N > 0) { 2506 if (DEBUG_RESULTS) Log.v( 2507 TAG, "Delivering results to " + next 2508 + ": " + a); 2509 next.app.thread.scheduleSendResult(next, a); 2510 } 2511 } 2512 2513 if (next.newIntents != null) { 2514 next.app.thread.scheduleNewIntent(next.newIntents, next); 2515 } 2516 2517 EventLog.writeEvent(LOG_AM_RESUME_ACTIVITY, 2518 System.identityHashCode(next), 2519 next.task.taskId, next.shortComponentName); 2520 updateUsageStats(next, true); 2521 2522 next.app.thread.scheduleResumeActivity(next, 2523 isNextTransitionForward()); 2524 pauseIfSleepingLocked(); 2525 2526 } catch (Exception e) { 2527 // Whoops, need to restart this activity! 2528 next.state = lastState; 2529 mResumedActivity = lastResumedActivity; 2530 if (Config.LOGD) Log.d(TAG, 2531 "Restarting because process died: " + next); 2532 if (!next.hasBeenLaunched) { 2533 next.hasBeenLaunched = true; 2534 } else { 2535 if (SHOW_APP_STARTING_ICON) { 2536 mWindowManager.setAppStartingWindow( 2537 next, next.packageName, next.theme, 2538 next.nonLocalizedLabel, 2539 next.labelRes, next.icon, null, true); 2540 } 2541 } 2542 startSpecificActivityLocked(next, true, false); 2543 return true; 2544 } 2545 2546 // From this point on, if something goes wrong there is no way 2547 // to recover the activity. 2548 try { 2549 next.visible = true; 2550 completeResumeLocked(next); 2551 } catch (Exception e) { 2552 // If any exception gets thrown, toss away this 2553 // activity and try the next one. 2554 Log.w(TAG, "Exception thrown during resume of " + next, e); 2555 requestFinishActivityLocked(next, Activity.RESULT_CANCELED, null, 2556 "resume-exception"); 2557 return true; 2558 } 2559 2560 // Didn't need to use the icicle, and it is now out of date. 2561 next.icicle = null; 2562 next.haveState = false; 2563 next.stopped = false; 2564 2565 } else { 2566 // Whoops, need to restart this activity! 2567 if (!next.hasBeenLaunched) { 2568 next.hasBeenLaunched = true; 2569 } else { 2570 if (SHOW_APP_STARTING_ICON) { 2571 mWindowManager.setAppStartingWindow( 2572 next, next.packageName, next.theme, 2573 next.nonLocalizedLabel, 2574 next.labelRes, next.icon, null, true); 2575 } 2576 if (DEBUG_SWITCH) Log.v(TAG, "Restarting: " + next); 2577 } 2578 startSpecificActivityLocked(next, true, true); 2579 } 2580 2581 return true; 2582 } 2583 2584 private final void startActivityLocked(HistoryRecord r, boolean newTask, 2585 boolean doResume) { 2586 final int NH = mHistory.size(); 2587 2588 int addPos = -1; 2589 2590 if (!newTask) { 2591 // If starting in an existing task, find where that is... 2592 HistoryRecord next = null; 2593 boolean startIt = true; 2594 for (int i = NH-1; i >= 0; i--) { 2595 HistoryRecord p = (HistoryRecord)mHistory.get(i); 2596 if (p.finishing) { 2597 continue; 2598 } 2599 if (p.task == r.task) { 2600 // Here it is! Now, if this is not yet visible to the 2601 // user, then just add it without starting; it will 2602 // get started when the user navigates back to it. 2603 addPos = i+1; 2604 if (!startIt) { 2605 mHistory.add(addPos, r); 2606 r.inHistory = true; 2607 r.task.numActivities++; 2608 mWindowManager.addAppToken(addPos, r, r.task.taskId, 2609 r.info.screenOrientation, r.fullscreen); 2610 if (VALIDATE_TOKENS) { 2611 mWindowManager.validateAppTokens(mHistory); 2612 } 2613 return; 2614 } 2615 break; 2616 } 2617 if (p.fullscreen) { 2618 startIt = false; 2619 } 2620 next = p; 2621 } 2622 } 2623 2624 // Place a new activity at top of stack, so it is next to interact 2625 // with the user. 2626 if (addPos < 0) { 2627 addPos = mHistory.size(); 2628 } 2629 2630 // If we are not placing the new activity frontmost, we do not want 2631 // to deliver the onUserLeaving callback to the actual frontmost 2632 // activity 2633 if (addPos < NH) { 2634 mUserLeaving = false; 2635 if (DEBUG_USER_LEAVING) Log.v(TAG, "startActivity() behind front, mUserLeaving=false"); 2636 } 2637 2638 // Slot the activity into the history stack and proceed 2639 mHistory.add(addPos, r); 2640 r.inHistory = true; 2641 r.frontOfTask = newTask; 2642 r.task.numActivities++; 2643 if (NH > 0) { 2644 // We want to show the starting preview window if we are 2645 // switching to a new task, or the next activity's process is 2646 // not currently running. 2647 boolean showStartingIcon = newTask; 2648 ProcessRecord proc = r.app; 2649 if (proc == null) { 2650 proc = mProcessNames.get(r.processName, r.info.applicationInfo.uid); 2651 } 2652 if (proc == null || proc.thread == null) { 2653 showStartingIcon = true; 2654 } 2655 if (DEBUG_TRANSITION) Log.v(TAG, 2656 "Prepare open transition: starting " + r); 2657 mWindowManager.prepareAppTransition(newTask 2658 ? WindowManagerPolicy.TRANSIT_TASK_OPEN 2659 : WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN); 2660 mWindowManager.addAppToken( 2661 addPos, r, r.task.taskId, r.info.screenOrientation, r.fullscreen); 2662 boolean doShow = true; 2663 if (newTask) { 2664 // Even though this activity is starting fresh, we still need 2665 // to reset it to make sure we apply affinities to move any 2666 // existing activities from other tasks in to it. 2667 // If the caller has requested that the target task be 2668 // reset, then do so. 2669 if ((r.intent.getFlags() 2670 &Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 2671 resetTaskIfNeededLocked(r, r); 2672 doShow = topRunningNonDelayedActivityLocked(null) == r; 2673 } 2674 } 2675 if (SHOW_APP_STARTING_ICON && doShow) { 2676 // Figure out if we are transitioning from another activity that is 2677 // "has the same starting icon" as the next one. This allows the 2678 // window manager to keep the previous window it had previously 2679 // created, if it still had one. 2680 HistoryRecord prev = mResumedActivity; 2681 if (prev != null) { 2682 // We don't want to reuse the previous starting preview if: 2683 // (1) The current activity is in a different task. 2684 if (prev.task != r.task) prev = null; 2685 // (2) The current activity is already displayed. 2686 else if (prev.nowVisible) prev = null; 2687 } 2688 mWindowManager.setAppStartingWindow( 2689 r, r.packageName, r.theme, r.nonLocalizedLabel, 2690 r.labelRes, r.icon, prev, showStartingIcon); 2691 } 2692 } else { 2693 // If this is the first activity, don't do any fancy animations, 2694 // because there is nothing for it to animate on top of. 2695 mWindowManager.addAppToken(addPos, r, r.task.taskId, 2696 r.info.screenOrientation, r.fullscreen); 2697 } 2698 if (VALIDATE_TOKENS) { 2699 mWindowManager.validateAppTokens(mHistory); 2700 } 2701 2702 if (doResume) { 2703 resumeTopActivityLocked(null); 2704 } 2705 } 2706 2707 /** 2708 * Perform clear operation as requested by 2709 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the 2710 * stack to the given task, then look for 2711 * an instance of that activity in the stack and, if found, finish all 2712 * activities on top of it and return the instance. 2713 * 2714 * @param newR Description of the new activity being started. 2715 * @return Returns the old activity that should be continue to be used, 2716 * or null if none was found. 2717 */ 2718 private final HistoryRecord performClearTaskLocked(int taskId, 2719 HistoryRecord newR, boolean doClear) { 2720 int i = mHistory.size(); 2721 2722 // First find the requested task. 2723 while (i > 0) { 2724 i--; 2725 HistoryRecord r = (HistoryRecord)mHistory.get(i); 2726 if (r.task.taskId == taskId) { 2727 i++; 2728 break; 2729 } 2730 } 2731 2732 // Now clear it. 2733 while (i > 0) { 2734 i--; 2735 HistoryRecord r = (HistoryRecord)mHistory.get(i); 2736 if (r.finishing) { 2737 continue; 2738 } 2739 if (r.task.taskId != taskId) { 2740 return null; 2741 } 2742 if (r.realActivity.equals(newR.realActivity)) { 2743 // Here it is! Now finish everything in front... 2744 HistoryRecord ret = r; 2745 if (doClear) { 2746 while (i < (mHistory.size()-1)) { 2747 i++; 2748 r = (HistoryRecord)mHistory.get(i); 2749 if (r.finishing) { 2750 continue; 2751 } 2752 if (finishActivityLocked(r, i, Activity.RESULT_CANCELED, 2753 null, "clear")) { 2754 i--; 2755 } 2756 } 2757 } 2758 2759 // Finally, if this is a normal launch mode (that is, not 2760 // expecting onNewIntent()), then we will finish the current 2761 // instance of the activity so a new fresh one can be started. 2762 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE) { 2763 if (!ret.finishing) { 2764 int index = indexOfTokenLocked(ret, false); 2765 if (index >= 0) { 2766 finishActivityLocked(ret, 0, Activity.RESULT_CANCELED, 2767 null, "clear"); 2768 } 2769 return null; 2770 } 2771 } 2772 2773 return ret; 2774 } 2775 } 2776 2777 return null; 2778 } 2779 2780 /** 2781 * Find the activity in the history stack within the given task. Returns 2782 * the index within the history at which it's found, or < 0 if not found. 2783 */ 2784 private final int findActivityInHistoryLocked(HistoryRecord r, int task) { 2785 int i = mHistory.size(); 2786 while (i > 0) { 2787 i--; 2788 HistoryRecord candidate = (HistoryRecord)mHistory.get(i); 2789 if (candidate.task.taskId != task) { 2790 break; 2791 } 2792 if (candidate.realActivity.equals(r.realActivity)) { 2793 return i; 2794 } 2795 } 2796 2797 return -1; 2798 } 2799 2800 /** 2801 * Reorder the history stack so that the activity at the given index is 2802 * brought to the front. 2803 */ 2804 private final HistoryRecord moveActivityToFrontLocked(int where) { 2805 HistoryRecord newTop = (HistoryRecord)mHistory.remove(where); 2806 int top = mHistory.size(); 2807 HistoryRecord oldTop = (HistoryRecord)mHistory.get(top-1); 2808 mHistory.add(top, newTop); 2809 oldTop.frontOfTask = false; 2810 newTop.frontOfTask = true; 2811 return newTop; 2812 } 2813 2814 /** 2815 * Deliver a new Intent to an existing activity, so that its onNewIntent() 2816 * method will be called at the proper time. 2817 */ 2818 private final void deliverNewIntentLocked(HistoryRecord r, Intent intent) { 2819 boolean sent = false; 2820 if (r.state == ActivityState.RESUMED 2821 && r.app != null && r.app.thread != null) { 2822 try { 2823 ArrayList<Intent> ar = new ArrayList<Intent>(); 2824 ar.add(new Intent(intent)); 2825 r.app.thread.scheduleNewIntent(ar, r); 2826 sent = true; 2827 } catch (Exception e) { 2828 Log.w(TAG, "Exception thrown sending new intent to " + r, e); 2829 } 2830 } 2831 if (!sent) { 2832 r.addNewIntentLocked(new Intent(intent)); 2833 } 2834 } 2835 2836 private final void logStartActivity(int tag, HistoryRecord r, 2837 TaskRecord task) { 2838 EventLog.writeEvent(tag, 2839 System.identityHashCode(r), task.taskId, 2840 r.shortComponentName, r.intent.getAction(), 2841 r.intent.getType(), r.intent.getDataString(), 2842 r.intent.getFlags()); 2843 } 2844 2845 private final int startActivityLocked(IApplicationThread caller, 2846 Intent intent, String resolvedType, 2847 Uri[] grantedUriPermissions, 2848 int grantedMode, ActivityInfo aInfo, IBinder resultTo, 2849 String resultWho, int requestCode, 2850 int callingPid, int callingUid, boolean onlyIfNeeded, 2851 boolean componentSpecified) { 2852 Log.i(TAG, "Starting activity: " + intent); 2853 2854 HistoryRecord sourceRecord = null; 2855 HistoryRecord resultRecord = null; 2856 if (resultTo != null) { 2857 int index = indexOfTokenLocked(resultTo, false); 2858 if (DEBUG_RESULTS) Log.v( 2859 TAG, "Sending result to " + resultTo + " (index " + index + ")"); 2860 if (index >= 0) { 2861 sourceRecord = (HistoryRecord)mHistory.get(index); 2862 if (requestCode >= 0 && !sourceRecord.finishing) { 2863 resultRecord = sourceRecord; 2864 } 2865 } 2866 } 2867 2868 int launchFlags = intent.getFlags(); 2869 2870 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 2871 && sourceRecord != null) { 2872 // Transfer the result target from the source activity to the new 2873 // one being started, including any failures. 2874 if (requestCode >= 0) { 2875 return START_FORWARD_AND_REQUEST_CONFLICT; 2876 } 2877 resultRecord = sourceRecord.resultTo; 2878 resultWho = sourceRecord.resultWho; 2879 requestCode = sourceRecord.requestCode; 2880 sourceRecord.resultTo = null; 2881 if (resultRecord != null) { 2882 resultRecord.removeResultsLocked( 2883 sourceRecord, resultWho, requestCode); 2884 } 2885 } 2886 2887 int err = START_SUCCESS; 2888 2889 if (intent.getComponent() == null) { 2890 // We couldn't find a class that can handle the given Intent. 2891 // That's the end of that! 2892 err = START_INTENT_NOT_RESOLVED; 2893 } 2894 2895 if (err == START_SUCCESS && aInfo == null) { 2896 // We couldn't find the specific class specified in the Intent. 2897 // Also the end of the line. 2898 err = START_CLASS_NOT_FOUND; 2899 } 2900 2901 ProcessRecord callerApp = null; 2902 if (err == START_SUCCESS && caller != null) { 2903 callerApp = getRecordForAppLocked(caller); 2904 if (callerApp != null) { 2905 callingPid = callerApp.pid; 2906 callingUid = callerApp.info.uid; 2907 } else { 2908 Log.w(TAG, "Unable to find app for caller " + caller 2909 + " (pid=" + callingPid + ") when starting: " 2910 + intent.toString()); 2911 err = START_PERMISSION_DENIED; 2912 } 2913 } 2914 2915 if (err != START_SUCCESS) { 2916 if (resultRecord != null) { 2917 sendActivityResultLocked(-1, 2918 resultRecord, resultWho, requestCode, 2919 Activity.RESULT_CANCELED, null); 2920 } 2921 return err; 2922 } 2923 2924 final int perm = checkComponentPermission(aInfo.permission, callingPid, 2925 callingUid, aInfo.exported ? -1 : aInfo.applicationInfo.uid); 2926 if (perm != PackageManager.PERMISSION_GRANTED) { 2927 if (resultRecord != null) { 2928 sendActivityResultLocked(-1, 2929 resultRecord, resultWho, requestCode, 2930 Activity.RESULT_CANCELED, null); 2931 } 2932 String msg = "Permission Denial: starting " + intent.toString() 2933 + " from " + callerApp + " (pid=" + callingPid 2934 + ", uid=" + callingUid + ")" 2935 + " requires " + aInfo.permission; 2936 Log.w(TAG, msg); 2937 throw new SecurityException(msg); 2938 } 2939 2940 if (mWatcher != null) { 2941 boolean abort = false; 2942 try { 2943 // The Intent we give to the watcher has the extra data 2944 // stripped off, since it can contain private information. 2945 Intent watchIntent = intent.cloneFilter(); 2946 abort = !mWatcher.activityStarting(watchIntent, 2947 aInfo.applicationInfo.packageName); 2948 } catch (RemoteException e) { 2949 mWatcher = null; 2950 } 2951 2952 if (abort) { 2953 if (resultRecord != null) { 2954 sendActivityResultLocked(-1, 2955 resultRecord, resultWho, requestCode, 2956 Activity.RESULT_CANCELED, null); 2957 } 2958 // We pretend to the caller that it was really started, but 2959 // they will just get a cancel result. 2960 return START_SUCCESS; 2961 } 2962 } 2963 2964 HistoryRecord r = new HistoryRecord(this, callerApp, callingUid, 2965 intent, resolvedType, aInfo, mConfiguration, 2966 resultRecord, resultWho, requestCode, componentSpecified); 2967 2968 if (mResumedActivity == null 2969 || mResumedActivity.info.applicationInfo.uid != callingUid) { 2970 if (!checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) { 2971 PendingActivityLaunch pal = new PendingActivityLaunch(); 2972 pal.r = r; 2973 pal.sourceRecord = sourceRecord; 2974 pal.grantedUriPermissions = grantedUriPermissions; 2975 pal.grantedMode = grantedMode; 2976 pal.onlyIfNeeded = onlyIfNeeded; 2977 mPendingActivityLaunches.add(pal); 2978 return START_SWITCHES_CANCELED; 2979 } 2980 } 2981 2982 if (mDidAppSwitch) { 2983 // This is the second allowed switch since we stopped switches, 2984 // so now just generally allow switches. Use case: user presses 2985 // home (switches disabled, switch to home, mDidAppSwitch now true); 2986 // user taps a home icon (coming from home so allowed, we hit here 2987 // and now allow anyone to switch again). 2988 mAppSwitchesAllowedTime = 0; 2989 } else { 2990 mDidAppSwitch = true; 2991 } 2992 2993 doPendingActivityLaunchesLocked(false); 2994 2995 return startActivityUncheckedLocked(r, sourceRecord, 2996 grantedUriPermissions, grantedMode, onlyIfNeeded, true); 2997 } 2998 2999 private final void doPendingActivityLaunchesLocked(boolean doResume) { 3000 final int N = mPendingActivityLaunches.size(); 3001 if (N <= 0) { 3002 return; 3003 } 3004 for (int i=0; i<N; i++) { 3005 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3006 startActivityUncheckedLocked(pal.r, pal.sourceRecord, 3007 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded, 3008 doResume && i == (N-1)); 3009 } 3010 mPendingActivityLaunches.clear(); 3011 } 3012 3013 private final int startActivityUncheckedLocked(HistoryRecord r, 3014 HistoryRecord sourceRecord, Uri[] grantedUriPermissions, 3015 int grantedMode, boolean onlyIfNeeded, boolean doResume) { 3016 final Intent intent = r.intent; 3017 final int callingUid = r.launchedFromUid; 3018 3019 int launchFlags = intent.getFlags(); 3020 3021 // We'll invoke onUserLeaving before onPause only if the launching 3022 // activity did not explicitly state that this is an automated launch. 3023 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0; 3024 if (DEBUG_USER_LEAVING) Log.v(TAG, 3025 "startActivity() => mUserLeaving=" + mUserLeaving); 3026 3027 // If the caller has asked not to resume at this point, we make note 3028 // of this in the record so that we can skip it when trying to find 3029 // the top running activity. 3030 if (!doResume) { 3031 r.delayedResume = true; 3032 } 3033 3034 HistoryRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) 3035 != 0 ? r : null; 3036 3037 // If the onlyIfNeeded flag is set, then we can do this if the activity 3038 // being launched is the same as the one making the call... or, as 3039 // a special case, if we do not know the caller then we count the 3040 // current top activity as the caller. 3041 if (onlyIfNeeded) { 3042 HistoryRecord checkedCaller = sourceRecord; 3043 if (checkedCaller == null) { 3044 checkedCaller = topRunningNonDelayedActivityLocked(notTop); 3045 } 3046 if (!checkedCaller.realActivity.equals(r.realActivity)) { 3047 // Caller is not the same as launcher, so always needed. 3048 onlyIfNeeded = false; 3049 } 3050 } 3051 3052 if (grantedUriPermissions != null && callingUid > 0) { 3053 for (int i=0; i<grantedUriPermissions.length; i++) { 3054 grantUriPermissionLocked(callingUid, r.packageName, 3055 grantedUriPermissions[i], grantedMode, r); 3056 } 3057 } 3058 3059 grantUriPermissionFromIntentLocked(callingUid, r.packageName, 3060 intent, r); 3061 3062 if (sourceRecord == null) { 3063 // This activity is not being started from another... in this 3064 // case we -always- start a new task. 3065 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 3066 Log.w(TAG, "startActivity called from non-Activity context; forcing Intent.FLAG_ACTIVITY_NEW_TASK for: " 3067 + intent); 3068 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 3069 } 3070 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 3071 // The original activity who is starting us is running as a single 3072 // instance... this new activity it is starting must go on its 3073 // own task. 3074 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 3075 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE 3076 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 3077 // The activity being started is a single instance... it always 3078 // gets launched into its own task. 3079 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 3080 } 3081 3082 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 3083 // For whatever reason this activity is being launched into a new 3084 // task... yet the caller has requested a result back. Well, that 3085 // is pretty messed up, so instead immediately send back a cancel 3086 // and let the new task continue launched as normal without a 3087 // dependency on its originator. 3088 Log.w(TAG, "Activity is launching as a new task, so cancelling activity result."); 3089 sendActivityResultLocked(-1, 3090 r.resultTo, r.resultWho, r.requestCode, 3091 Activity.RESULT_CANCELED, null); 3092 r.resultTo = null; 3093 } 3094 3095 boolean addingToTask = false; 3096 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && 3097 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) 3098 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 3099 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 3100 // If bring to front is requested, and no result is requested, and 3101 // we can find a task that was started with this same 3102 // component, then instead of launching bring that one to the front. 3103 if (r.resultTo == null) { 3104 // See if there is a task to bring to the front. If this is 3105 // a SINGLE_INSTANCE activity, there can be one and only one 3106 // instance of it in the history, and it is always in its own 3107 // unique task, so we do a special search. 3108 HistoryRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE 3109 ? findTaskLocked(intent, r.info) 3110 : findActivityLocked(intent, r.info); 3111 if (taskTop != null) { 3112 if (taskTop.task.intent == null) { 3113 // This task was started because of movement of 3114 // the activity based on affinity... now that we 3115 // are actually launching it, we can assign the 3116 // base intent. 3117 taskTop.task.setIntent(intent, r.info); 3118 } 3119 // If the target task is not in the front, then we need 3120 // to bring it to the front... except... well, with 3121 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like 3122 // to have the same behavior as if a new instance was 3123 // being started, which means not bringing it to the front 3124 // if the caller is not itself in the front. 3125 HistoryRecord curTop = topRunningNonDelayedActivityLocked(notTop); 3126 if (curTop.task != taskTop.task) { 3127 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); 3128 boolean callerAtFront = sourceRecord == null 3129 || curTop.task == sourceRecord.task; 3130 if (callerAtFront) { 3131 // We really do want to push this one into the 3132 // user's face, right now. 3133 moveTaskToFrontLocked(taskTop.task); 3134 } 3135 } 3136 // If the caller has requested that the target task be 3137 // reset, then do so. 3138 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 3139 taskTop = resetTaskIfNeededLocked(taskTop, r); 3140 } 3141 if (onlyIfNeeded) { 3142 // We don't need to start a new activity, and 3143 // the client said not to do anything if that 3144 // is the case, so this is it! And for paranoia, make 3145 // sure we have correctly resumed the top activity. 3146 if (doResume) { 3147 resumeTopActivityLocked(null); 3148 } 3149 return START_RETURN_INTENT_TO_CALLER; 3150 } 3151 if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0 3152 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 3153 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 3154 // In this situation we want to remove all activities 3155 // from the task up to the one being started. In most 3156 // cases this means we are resetting the task to its 3157 // initial state. 3158 HistoryRecord top = performClearTaskLocked( 3159 taskTop.task.taskId, r, true); 3160 if (top != null) { 3161 if (top.frontOfTask) { 3162 // Activity aliases may mean we use different 3163 // intents for the top activity, so make sure 3164 // the task now has the identity of the new 3165 // intent. 3166 top.task.setIntent(r.intent, r.info); 3167 } 3168 logStartActivity(LOG_AM_NEW_INTENT, r, top.task); 3169 deliverNewIntentLocked(top, r.intent); 3170 } else { 3171 // A special case: we need to 3172 // start the activity because it is not currently 3173 // running, and the caller has asked to clear the 3174 // current task to have this activity at the top. 3175 addingToTask = true; 3176 // Now pretend like this activity is being started 3177 // by the top of its task, so it is put in the 3178 // right place. 3179 sourceRecord = taskTop; 3180 } 3181 } else if (r.realActivity.equals(taskTop.task.realActivity)) { 3182 // In this case the top activity on the task is the 3183 // same as the one being launched, so we take that 3184 // as a request to bring the task to the foreground. 3185 // If the top activity in the task is the root 3186 // activity, deliver this new intent to it if it 3187 // desires. 3188 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 3189 && taskTop.realActivity.equals(r.realActivity)) { 3190 logStartActivity(LOG_AM_NEW_INTENT, r, taskTop.task); 3191 if (taskTop.frontOfTask) { 3192 taskTop.task.setIntent(r.intent, r.info); 3193 } 3194 deliverNewIntentLocked(taskTop, r.intent); 3195 } else if (!r.intent.filterEquals(taskTop.task.intent)) { 3196 // In this case we are launching the root activity 3197 // of the task, but with a different intent. We 3198 // should start a new instance on top. 3199 addingToTask = true; 3200 sourceRecord = taskTop; 3201 } 3202 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) { 3203 // In this case an activity is being launched in to an 3204 // existing task, without resetting that task. This 3205 // is typically the situation of launching an activity 3206 // from a notification or shortcut. We want to place 3207 // the new activity on top of the current task. 3208 addingToTask = true; 3209 sourceRecord = taskTop; 3210 } else if (!taskTop.task.rootWasReset) { 3211 // In this case we are launching in to an existing task 3212 // that has not yet been started from its front door. 3213 // The current task has been brought to the front. 3214 // Ideally, we'd probably like to place this new task 3215 // at the bottom of its stack, but that's a little hard 3216 // to do with the current organization of the code so 3217 // for now we'll just drop it. 3218 taskTop.task.setIntent(r.intent, r.info); 3219 } 3220 if (!addingToTask) { 3221 // We didn't do anything... but it was needed (a.k.a., client 3222 // don't use that intent!) And for paranoia, make 3223 // sure we have correctly resumed the top activity. 3224 if (doResume) { 3225 resumeTopActivityLocked(null); 3226 } 3227 return START_TASK_TO_FRONT; 3228 } 3229 } 3230 } 3231 } 3232 3233 //String uri = r.intent.toURI(); 3234 //Intent intent2 = new Intent(uri); 3235 //Log.i(TAG, "Given intent: " + r.intent); 3236 //Log.i(TAG, "URI is: " + uri); 3237 //Log.i(TAG, "To intent: " + intent2); 3238 3239 if (r.packageName != null) { 3240 // If the activity being launched is the same as the one currently 3241 // at the top, then we need to check if it should only be launched 3242 // once. 3243 HistoryRecord top = topRunningNonDelayedActivityLocked(notTop); 3244 if (top != null && r.resultTo == null) { 3245 if (top.realActivity.equals(r.realActivity)) { 3246 if (top.app != null && top.app.thread != null) { 3247 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 3248 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP 3249 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 3250 logStartActivity(LOG_AM_NEW_INTENT, top, top.task); 3251 // For paranoia, make sure we have correctly 3252 // resumed the top activity. 3253 if (doResume) { 3254 resumeTopActivityLocked(null); 3255 } 3256 if (onlyIfNeeded) { 3257 // We don't need to start a new activity, and 3258 // the client said not to do anything if that 3259 // is the case, so this is it! 3260 return START_RETURN_INTENT_TO_CALLER; 3261 } 3262 deliverNewIntentLocked(top, r.intent); 3263 return START_DELIVERED_TO_TOP; 3264 } 3265 } 3266 } 3267 } 3268 3269 } else { 3270 if (r.resultTo != null) { 3271 sendActivityResultLocked(-1, 3272 r.resultTo, r.resultWho, r.requestCode, 3273 Activity.RESULT_CANCELED, null); 3274 } 3275 return START_CLASS_NOT_FOUND; 3276 } 3277 3278 boolean newTask = false; 3279 3280 // Should this be considered a new task? 3281 if (r.resultTo == null && !addingToTask 3282 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 3283 // todo: should do better management of integers. 3284 mCurTask++; 3285 if (mCurTask <= 0) { 3286 mCurTask = 1; 3287 } 3288 r.task = new TaskRecord(mCurTask, r.info, intent, 3289 (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0); 3290 if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r 3291 + " in new task " + r.task); 3292 newTask = true; 3293 addRecentTask(r.task); 3294 3295 } else if (sourceRecord != null) { 3296 if (!addingToTask && 3297 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 3298 // In this case, we are adding the activity to an existing 3299 // task, but the caller has asked to clear that task if the 3300 // activity is already running. 3301 HistoryRecord top = performClearTaskLocked( 3302 sourceRecord.task.taskId, r, true); 3303 if (top != null) { 3304 logStartActivity(LOG_AM_NEW_INTENT, r, top.task); 3305 deliverNewIntentLocked(top, r.intent); 3306 // For paranoia, make sure we have correctly 3307 // resumed the top activity. 3308 if (doResume) { 3309 resumeTopActivityLocked(null); 3310 } 3311 return START_DELIVERED_TO_TOP; 3312 } 3313 } else if (!addingToTask && 3314 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { 3315 // In this case, we are launching an activity in our own task 3316 // that may already be running somewhere in the history, and 3317 // we want to shuffle it to the front of the stack if so. 3318 int where = findActivityInHistoryLocked(r, sourceRecord.task.taskId); 3319 if (where >= 0) { 3320 HistoryRecord top = moveActivityToFrontLocked(where); 3321 logStartActivity(LOG_AM_NEW_INTENT, r, top.task); 3322 deliverNewIntentLocked(top, r.intent); 3323 if (doResume) { 3324 resumeTopActivityLocked(null); 3325 } 3326 return START_DELIVERED_TO_TOP; 3327 } 3328 } 3329 // An existing activity is starting this new activity, so we want 3330 // to keep the new one in the same task as the one that is starting 3331 // it. 3332 r.task = sourceRecord.task; 3333 if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r 3334 + " in existing task " + r.task); 3335 3336 } else { 3337 // This not being started from an existing activity, and not part 3338 // of a new task... just put it in the top task, though these days 3339 // this case should never happen. 3340 final int N = mHistory.size(); 3341 HistoryRecord prev = 3342 N > 0 ? (HistoryRecord)mHistory.get(N-1) : null; 3343 r.task = prev != null 3344 ? prev.task 3345 : new TaskRecord(mCurTask, r.info, intent, 3346 (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0); 3347 if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r 3348 + " in new guessed " + r.task); 3349 } 3350 if (newTask) { 3351 EventLog.writeEvent(LOG_AM_CREATE_TASK, r.task.taskId); 3352 } 3353 logStartActivity(LOG_AM_CREATE_ACTIVITY, r, r.task); 3354 startActivityLocked(r, newTask, doResume); 3355 return START_SUCCESS; 3356 } 3357 3358 public final int startActivity(IApplicationThread caller, 3359 Intent intent, String resolvedType, Uri[] grantedUriPermissions, 3360 int grantedMode, IBinder resultTo, 3361 String resultWho, int requestCode, boolean onlyIfNeeded, 3362 boolean debug) { 3363 // Refuse possible leaked file descriptors 3364 if (intent != null && intent.hasFileDescriptors()) { 3365 throw new IllegalArgumentException("File descriptors passed in Intent"); 3366 } 3367 3368 final boolean componentSpecified = intent.getComponent() != null; 3369 3370 // Don't modify the client's object! 3371 intent = new Intent(intent); 3372 3373 // Collect information about the target of the Intent. 3374 // Must do this before locking, because resolving the intent 3375 // may require launching a process to run its content provider. 3376 ActivityInfo aInfo; 3377 try { 3378 ResolveInfo rInfo = 3379 ActivityThread.getPackageManager().resolveIntent( 3380 intent, resolvedType, 3381 PackageManager.MATCH_DEFAULT_ONLY 3382 | STOCK_PM_FLAGS); 3383 aInfo = rInfo != null ? rInfo.activityInfo : null; 3384 } catch (RemoteException e) { 3385 aInfo = null; 3386 } 3387 3388 if (aInfo != null) { 3389 // Store the found target back into the intent, because now that 3390 // we have it we never want to do this again. For example, if the 3391 // user navigates back to this point in the history, we should 3392 // always restart the exact same activity. 3393 intent.setComponent(new ComponentName( 3394 aInfo.applicationInfo.packageName, aInfo.name)); 3395 3396 // Don't debug things in the system process 3397 if (debug) { 3398 if (!aInfo.processName.equals("system")) { 3399 setDebugApp(aInfo.processName, true, false); 3400 } 3401 } 3402 } 3403 3404 synchronized(this) { 3405 final long origId = Binder.clearCallingIdentity(); 3406 int res = startActivityLocked(caller, intent, resolvedType, 3407 grantedUriPermissions, grantedMode, aInfo, 3408 resultTo, resultWho, requestCode, -1, -1, 3409 onlyIfNeeded, componentSpecified); 3410 Binder.restoreCallingIdentity(origId); 3411 return res; 3412 } 3413 } 3414 3415 public boolean startNextMatchingActivity(IBinder callingActivity, 3416 Intent intent) { 3417 // Refuse possible leaked file descriptors 3418 if (intent != null && intent.hasFileDescriptors() == true) { 3419 throw new IllegalArgumentException("File descriptors passed in Intent"); 3420 } 3421 3422 synchronized (this) { 3423 int index = indexOfTokenLocked(callingActivity, false); 3424 if (index < 0) { 3425 return false; 3426 } 3427 HistoryRecord r = (HistoryRecord)mHistory.get(index); 3428 if (r.app == null || r.app.thread == null) { 3429 // The caller is not running... d'oh! 3430 return false; 3431 } 3432 intent = new Intent(intent); 3433 // The caller is not allowed to change the data. 3434 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3435 // And we are resetting to find the next component... 3436 intent.setComponent(null); 3437 3438 ActivityInfo aInfo = null; 3439 try { 3440 List<ResolveInfo> resolves = 3441 ActivityThread.getPackageManager().queryIntentActivities( 3442 intent, r.resolvedType, 3443 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS); 3444 3445 // Look for the original activity in the list... 3446 final int N = resolves != null ? resolves.size() : 0; 3447 for (int i=0; i<N; i++) { 3448 ResolveInfo rInfo = resolves.get(i); 3449 if (rInfo.activityInfo.packageName.equals(r.packageName) 3450 && rInfo.activityInfo.name.equals(r.info.name)) { 3451 // We found the current one... the next matching is 3452 // after it. 3453 i++; 3454 if (i<N) { 3455 aInfo = resolves.get(i).activityInfo; 3456 } 3457 break; 3458 } 3459 } 3460 } catch (RemoteException e) { 3461 } 3462 3463 if (aInfo == null) { 3464 // Nobody who is next! 3465 return false; 3466 } 3467 3468 intent.setComponent(new ComponentName( 3469 aInfo.applicationInfo.packageName, aInfo.name)); 3470 intent.setFlags(intent.getFlags()&~( 3471 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3472 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3473 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3474 Intent.FLAG_ACTIVITY_NEW_TASK)); 3475 3476 // Okay now we need to start the new activity, replacing the 3477 // currently running activity. This is a little tricky because 3478 // we want to start the new one as if the current one is finished, 3479 // but not finish the current one first so that there is no flicker. 3480 // And thus... 3481 final boolean wasFinishing = r.finishing; 3482 r.finishing = true; 3483 3484 // Propagate reply information over to the new activity. 3485 final HistoryRecord resultTo = r.resultTo; 3486 final String resultWho = r.resultWho; 3487 final int requestCode = r.requestCode; 3488 r.resultTo = null; 3489 if (resultTo != null) { 3490 resultTo.removeResultsLocked(r, resultWho, requestCode); 3491 } 3492 3493 final long origId = Binder.clearCallingIdentity(); 3494 // XXX we are not dealing with propagating grantedUriPermissions... 3495 // those are not yet exposed to user code, so there is no need. 3496 int res = startActivityLocked(r.app.thread, intent, 3497 r.resolvedType, null, 0, aInfo, resultTo, resultWho, 3498 requestCode, -1, r.launchedFromUid, false, false); 3499 Binder.restoreCallingIdentity(origId); 3500 3501 r.finishing = wasFinishing; 3502 if (res != START_SUCCESS) { 3503 return false; 3504 } 3505 return true; 3506 } 3507 } 3508 3509 final int startActivityInPackage(int uid, 3510 Intent intent, String resolvedType, IBinder resultTo, 3511 String resultWho, int requestCode, boolean onlyIfNeeded) { 3512 final boolean componentSpecified = intent.getComponent() != null; 3513 3514 // Don't modify the client's object! 3515 intent = new Intent(intent); 3516 3517 // Collect information about the target of the Intent. 3518 // Must do this before locking, because resolving the intent 3519 // may require launching a process to run its content provider. 3520 ActivityInfo aInfo; 3521 try { 3522 ResolveInfo rInfo = 3523 ActivityThread.getPackageManager().resolveIntent( 3524 intent, resolvedType, 3525 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS); 3526 aInfo = rInfo != null ? rInfo.activityInfo : null; 3527 } catch (RemoteException e) { 3528 aInfo = null; 3529 } 3530 3531 if (aInfo != null) { 3532 // Store the found target back into the intent, because now that 3533 // we have it we never want to do this again. For example, if the 3534 // user navigates back to this point in the history, we should 3535 // always restart the exact same activity. 3536 intent.setComponent(new ComponentName( 3537 aInfo.applicationInfo.packageName, aInfo.name)); 3538 } 3539 3540 synchronized(this) { 3541 return startActivityLocked(null, intent, resolvedType, 3542 null, 0, aInfo, resultTo, resultWho, requestCode, -1, uid, 3543 onlyIfNeeded, componentSpecified); 3544 } 3545 } 3546 3547 private final void addRecentTask(TaskRecord task) { 3548 // Remove any existing entries that are the same kind of task. 3549 int N = mRecentTasks.size(); 3550 for (int i=0; i<N; i++) { 3551 TaskRecord tr = mRecentTasks.get(i); 3552 if ((task.affinity != null && task.affinity.equals(tr.affinity)) 3553 || (task.intent != null && task.intent.filterEquals(tr.intent))) { 3554 mRecentTasks.remove(i); 3555 i--; 3556 N--; 3557 if (task.intent == null) { 3558 // If the new recent task we are adding is not fully 3559 // specified, then replace it with the existing recent task. 3560 task = tr; 3561 } 3562 } 3563 } 3564 if (N >= MAX_RECENT_TASKS) { 3565 mRecentTasks.remove(N-1); 3566 } 3567 mRecentTasks.add(0, task); 3568 } 3569 3570 public void setRequestedOrientation(IBinder token, 3571 int requestedOrientation) { 3572 synchronized (this) { 3573 int index = indexOfTokenLocked(token, false); 3574 if (index < 0) { 3575 return; 3576 } 3577 HistoryRecord r = (HistoryRecord)mHistory.get(index); 3578 final long origId = Binder.clearCallingIdentity(); 3579 mWindowManager.setAppOrientation(r, requestedOrientation); 3580 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3581 mConfiguration, 3582 r.mayFreezeScreenLocked(r.app) ? r : null); 3583 if (config != null) { 3584 r.frozenBeforeDestroy = true; 3585 if (!updateConfigurationLocked(config, r)) { 3586 resumeTopActivityLocked(null); 3587 } 3588 } 3589 Binder.restoreCallingIdentity(origId); 3590 } 3591 } 3592 3593 public int getRequestedOrientation(IBinder token) { 3594 synchronized (this) { 3595 int index = indexOfTokenLocked(token, false); 3596 if (index < 0) { 3597 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3598 } 3599 HistoryRecord r = (HistoryRecord)mHistory.get(index); 3600 return mWindowManager.getAppOrientation(r); 3601 } 3602 } 3603 3604 private final void stopActivityLocked(HistoryRecord r) { 3605 if (DEBUG_SWITCH) Log.d(TAG, "Stopping: " + r); 3606 if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0 3607 || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) { 3608 if (!r.finishing) { 3609 requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null, 3610 "no-history"); 3611 } 3612 } else if (r.app != null && r.app.thread != null) { 3613 if (mFocusedActivity == r) { 3614 setFocusedActivityLocked(topRunningActivityLocked(null)); 3615 } 3616 r.resumeKeyDispatchingLocked(); 3617 try { 3618 r.stopped = false; 3619 r.state = ActivityState.STOPPING; 3620 if (DEBUG_VISBILITY) Log.v( 3621 TAG, "Stopping visible=" + r.visible + " for " + r); 3622 if (!r.visible) { 3623 mWindowManager.setAppVisibility(r, false); 3624 } 3625 r.app.thread.scheduleStopActivity(r, r.visible, r.configChangeFlags); 3626 } catch (Exception e) { 3627 // Maybe just ignore exceptions here... if the process 3628 // has crashed, our death notification will clean things 3629 // up. 3630 Log.w(TAG, "Exception thrown during pause", e); 3631 // Just in case, assume it to be stopped. 3632 r.stopped = true; 3633 r.state = ActivityState.STOPPED; 3634 if (r.configDestroy) { 3635 destroyActivityLocked(r, true); 3636 } 3637 } 3638 } 3639 } 3640 3641 /** 3642 * @return Returns true if the activity is being finished, false if for 3643 * some reason it is being left as-is. 3644 */ 3645 private final boolean requestFinishActivityLocked(IBinder token, int resultCode, 3646 Intent resultData, String reason) { 3647 if (DEBUG_RESULTS) Log.v( 3648 TAG, "Finishing activity: token=" + token 3649 + ", result=" + resultCode + ", data=" + resultData); 3650 3651 int index = indexOfTokenLocked(token, false); 3652 if (index < 0) { 3653 return false; 3654 } 3655 HistoryRecord r = (HistoryRecord)mHistory.get(index); 3656 3657 // Is this the last activity left? 3658 boolean lastActivity = true; 3659 for (int i=mHistory.size()-1; i>=0; i--) { 3660 HistoryRecord p = (HistoryRecord)mHistory.get(i); 3661 if (!p.finishing && p != r) { 3662 lastActivity = false; 3663 break; 3664 } 3665 } 3666 3667 // If this is the last activity, but it is the home activity, then 3668 // just don't finish it. 3669 if (lastActivity) { 3670 if (r.intent.hasCategory(Intent.CATEGORY_HOME)) { 3671 return false; 3672 } 3673 } 3674 3675 finishActivityLocked(r, index, resultCode, resultData, reason); 3676 return true; 3677 } 3678 3679 /** 3680 * @return Returns true if this activity has been removed from the history 3681 * list, or false if it is still in the list and will be removed later. 3682 */ 3683 private final boolean finishActivityLocked(HistoryRecord r, int index, 3684 int resultCode, Intent resultData, String reason) { 3685 if (r.finishing) { 3686 Log.w(TAG, "Duplicate finish request for " + r); 3687 return false; 3688 } 3689 3690 r.finishing = true; 3691 EventLog.writeEvent(LOG_AM_FINISH_ACTIVITY, 3692 System.identityHashCode(r), 3693 r.task.taskId, r.shortComponentName, reason); 3694 r.task.numActivities--; 3695 if (r.frontOfTask && index < (mHistory.size()-1)) { 3696 HistoryRecord next = (HistoryRecord)mHistory.get(index+1); 3697 if (next.task == r.task) { 3698 next.frontOfTask = true; 3699 } 3700 } 3701 3702 r.pauseKeyDispatchingLocked(); 3703 if (mFocusedActivity == r) { 3704 setFocusedActivityLocked(topRunningActivityLocked(null)); 3705 } 3706 3707 // send the result 3708 HistoryRecord resultTo = r.resultTo; 3709 if (resultTo != null) { 3710 if (DEBUG_RESULTS) Log.v(TAG, "Adding result to " + resultTo 3711 + " who=" + r.resultWho + " req=" + r.requestCode 3712 + " res=" + resultCode + " data=" + resultData); 3713 if (r.info.applicationInfo.uid > 0) { 3714 grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid, 3715 r.packageName, resultData, r); 3716 } 3717 resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode, 3718 resultData); 3719 r.resultTo = null; 3720 } 3721 else if (DEBUG_RESULTS) Log.v(TAG, "No result destination from " + r); 3722 3723 // Make sure this HistoryRecord is not holding on to other resources, 3724 // because clients have remote IPC references to this object so we 3725 // can't assume that will go away and want to avoid circular IPC refs. 3726 r.results = null; 3727 r.pendingResults = null; 3728 r.newIntents = null; 3729 r.icicle = null; 3730 3731 if (mPendingThumbnails.size() > 0) { 3732 // There are clients waiting to receive thumbnails so, in case 3733 // this is an activity that someone is waiting for, add it 3734 // to the pending list so we can correctly update the clients. 3735 mCancelledThumbnails.add(r); 3736 } 3737 3738 if (mResumedActivity == r) { 3739 boolean endTask = index <= 0 3740 || ((HistoryRecord)mHistory.get(index-1)).task != r.task; 3741 if (DEBUG_TRANSITION) Log.v(TAG, 3742 "Prepare close transition: finishing " + r); 3743 mWindowManager.prepareAppTransition(endTask 3744 ? WindowManagerPolicy.TRANSIT_TASK_CLOSE 3745 : WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE); 3746 3747 // Tell window manager to prepare for this one to be removed. 3748 mWindowManager.setAppVisibility(r, false); 3749 3750 if (mPausingActivity == null) { 3751 if (DEBUG_PAUSE) Log.v(TAG, "Finish needs to pause: " + r); 3752 if (DEBUG_USER_LEAVING) Log.v(TAG, "finish() => pause with userLeaving=false"); 3753 startPausingLocked(false, false); 3754 } 3755 3756 } else if (r.state != ActivityState.PAUSING) { 3757 // If the activity is PAUSING, we will complete the finish once 3758 // it is done pausing; else we can just directly finish it here. 3759 if (DEBUG_PAUSE) Log.v(TAG, "Finish not pausing: " + r); 3760 return finishCurrentActivityLocked(r, index, 3761 FINISH_AFTER_PAUSE) == null; 3762 } else { 3763 if (DEBUG_PAUSE) Log.v(TAG, "Finish waiting for pause of: " + r); 3764 } 3765 3766 return false; 3767 } 3768 3769 private static final int FINISH_IMMEDIATELY = 0; 3770 private static final int FINISH_AFTER_PAUSE = 1; 3771 private static final int FINISH_AFTER_VISIBLE = 2; 3772 3773 private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r, 3774 int mode) { 3775 final int index = indexOfTokenLocked(r, false); 3776 if (index < 0) { 3777 return null; 3778 } 3779 3780 return finishCurrentActivityLocked(r, index, mode); 3781 } 3782 3783 private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r, 3784 int index, int mode) { 3785 // First things first: if this activity is currently visible, 3786 // and the resumed activity is not yet visible, then hold off on 3787 // finishing until the resumed one becomes visible. 3788 if (mode == FINISH_AFTER_VISIBLE && r.nowVisible) { 3789 if (!mStoppingActivities.contains(r)) { 3790 mStoppingActivities.add(r); 3791 if (mStoppingActivities.size() > 3) { 3792 // If we already have a few activities waiting to stop, 3793 // then give up on things going idle and start clearing 3794 // them out. 3795 Message msg = Message.obtain(); 3796 msg.what = ActivityManagerService.IDLE_NOW_MSG; 3797 mHandler.sendMessage(msg); 3798 } 3799 } 3800 r.state = ActivityState.STOPPING; 3801 updateOomAdjLocked(); 3802 return r; 3803 } 3804 3805 // make sure the record is cleaned out of other places. 3806 mStoppingActivities.remove(r); 3807 mWaitingVisibleActivities.remove(r); 3808 if (mResumedActivity == r) { 3809 mResumedActivity = null; 3810 } 3811 final ActivityState prevState = r.state; 3812 r.state = ActivityState.FINISHING; 3813 3814 if (mode == FINISH_IMMEDIATELY 3815 || prevState == ActivityState.STOPPED 3816 || prevState == ActivityState.INITIALIZING) { 3817 // If this activity is already stopped, we can just finish 3818 // it right now. 3819 return destroyActivityLocked(r, true) ? null : r; 3820 } else { 3821 // Need to go through the full pause cycle to get this 3822 // activity into the stopped state and then finish it. 3823 if (localLOGV) Log.v(TAG, "Enqueueing pending finish: " + r); 3824 mFinishingActivities.add(r); 3825 resumeTopActivityLocked(null); 3826 } 3827 return r; 3828 } 3829 3830 /** 3831 * This is the internal entry point for handling Activity.finish(). 3832 * 3833 * @param token The Binder token referencing the Activity we want to finish. 3834 * @param resultCode Result code, if any, from this Activity. 3835 * @param resultData Result data (Intent), if any, from this Activity. 3836 * 3837 * @result Returns true if the activity successfully finished, or false if it is still running. 3838 */ 3839 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3840 // Refuse possible leaked file descriptors 3841 if (resultData != null && resultData.hasFileDescriptors() == true) { 3842 throw new IllegalArgumentException("File descriptors passed in Intent"); 3843 } 3844 3845 synchronized(this) { 3846 if (mWatcher != null) { 3847 // Find the first activity that is not finishing. 3848 HistoryRecord next = topRunningActivityLocked(token, 0); 3849 if (next != null) { 3850 // ask watcher if this is allowed 3851 boolean resumeOK = true; 3852 try { 3853 resumeOK = mWatcher.activityResuming(next.packageName); 3854 } catch (RemoteException e) { 3855 mWatcher = null; 3856 } 3857 3858 if (!resumeOK) { 3859 return false; 3860 } 3861 } 3862 } 3863 final long origId = Binder.clearCallingIdentity(); 3864 boolean res = requestFinishActivityLocked(token, resultCode, 3865 resultData, "app-request"); 3866 Binder.restoreCallingIdentity(origId); 3867 return res; 3868 } 3869 } 3870 3871 void sendActivityResultLocked(int callingUid, HistoryRecord r, 3872 String resultWho, int requestCode, int resultCode, Intent data) { 3873 3874 if (callingUid > 0) { 3875 grantUriPermissionFromIntentLocked(callingUid, r.packageName, 3876 data, r); 3877 } 3878 3879 if (DEBUG_RESULTS) Log.v(TAG, "Send activity result to " + r 3880 + " : who=" + resultWho + " req=" + requestCode 3881 + " res=" + resultCode + " data=" + data); 3882 if (mResumedActivity == r && r.app != null && r.app.thread != null) { 3883 try { 3884 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>(); 3885 list.add(new ResultInfo(resultWho, requestCode, 3886 resultCode, data)); 3887 r.app.thread.scheduleSendResult(r, list); 3888 return; 3889 } catch (Exception e) { 3890 Log.w(TAG, "Exception thrown sending result to " + r, e); 3891 } 3892 } 3893 3894 r.addResultLocked(null, resultWho, requestCode, resultCode, data); 3895 } 3896 3897 public final void finishSubActivity(IBinder token, String resultWho, 3898 int requestCode) { 3899 synchronized(this) { 3900 int index = indexOfTokenLocked(token, false); 3901 if (index < 0) { 3902 return; 3903 } 3904 HistoryRecord self = (HistoryRecord)mHistory.get(index); 3905 3906 final long origId = Binder.clearCallingIdentity(); 3907 3908 int i; 3909 for (i=mHistory.size()-1; i>=0; i--) { 3910 HistoryRecord r = (HistoryRecord)mHistory.get(i); 3911 if (r.resultTo == self && r.requestCode == requestCode) { 3912 if ((r.resultWho == null && resultWho == null) || 3913 (r.resultWho != null && r.resultWho.equals(resultWho))) { 3914 finishActivityLocked(r, i, 3915 Activity.RESULT_CANCELED, null, "request-sub"); 3916 } 3917 } 3918 } 3919 3920 Binder.restoreCallingIdentity(origId); 3921 } 3922 } 3923 3924 /** 3925 * Perform clean-up of service connections in an activity record. 3926 */ 3927 private final void cleanUpActivityServicesLocked(HistoryRecord r) { 3928 // Throw away any services that have been bound by this activity. 3929 if (r.connections != null) { 3930 Iterator<ConnectionRecord> it = r.connections.iterator(); 3931 while (it.hasNext()) { 3932 ConnectionRecord c = it.next(); 3933 removeConnectionLocked(c, null, r); 3934 } 3935 r.connections = null; 3936 } 3937 } 3938 3939 /** 3940 * Perform the common clean-up of an activity record. This is called both 3941 * as part of destroyActivityLocked() (when destroying the client-side 3942 * representation) and cleaning things up as a result of its hosting 3943 * processing going away, in which case there is no remaining client-side 3944 * state to destroy so only the cleanup here is needed. 3945 */ 3946 private final void cleanUpActivityLocked(HistoryRecord r, boolean cleanServices) { 3947 if (mResumedActivity == r) { 3948 mResumedActivity = null; 3949 } 3950 if (mFocusedActivity == r) { 3951 mFocusedActivity = null; 3952 } 3953 3954 r.configDestroy = false; 3955 r.frozenBeforeDestroy = false; 3956 3957 // Make sure this record is no longer in the pending finishes list. 3958 // This could happen, for example, if we are trimming activities 3959 // down to the max limit while they are still waiting to finish. 3960 mFinishingActivities.remove(r); 3961 mWaitingVisibleActivities.remove(r); 3962 3963 // Remove any pending results. 3964 if (r.finishing && r.pendingResults != null) { 3965 for (WeakReference<PendingIntentRecord> apr : r.pendingResults) { 3966 PendingIntentRecord rec = apr.get(); 3967 if (rec != null) { 3968 cancelIntentSenderLocked(rec, false); 3969 } 3970 } 3971 r.pendingResults = null; 3972 } 3973 3974 if (cleanServices) { 3975 cleanUpActivityServicesLocked(r); 3976 } 3977 3978 if (mPendingThumbnails.size() > 0) { 3979 // There are clients waiting to receive thumbnails so, in case 3980 // this is an activity that someone is waiting for, add it 3981 // to the pending list so we can correctly update the clients. 3982 mCancelledThumbnails.add(r); 3983 } 3984 3985 // Get rid of any pending idle timeouts. 3986 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); 3987 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 3988 } 3989 3990 private final void removeActivityFromHistoryLocked(HistoryRecord r) { 3991 if (r.state != ActivityState.DESTROYED) { 3992 mHistory.remove(r); 3993 r.inHistory = false; 3994 r.state = ActivityState.DESTROYED; 3995 mWindowManager.removeAppToken(r); 3996 if (VALIDATE_TOKENS) { 3997 mWindowManager.validateAppTokens(mHistory); 3998 } 3999 cleanUpActivityServicesLocked(r); 4000 removeActivityUriPermissionsLocked(r); 4001 } 4002 } 4003 4004 /** 4005 * Destroy the current CLIENT SIDE instance of an activity. This may be 4006 * called both when actually finishing an activity, or when performing 4007 * a configuration switch where we destroy the current client-side object 4008 * but then create a new client-side object for this same HistoryRecord. 4009 */ 4010 private final boolean destroyActivityLocked(HistoryRecord r, 4011 boolean removeFromApp) { 4012 if (DEBUG_SWITCH) Log.v( 4013 TAG, "Removing activity: token=" + r 4014 + ", app=" + (r.app != null ? r.app.processName : "(null)")); 4015 EventLog.writeEvent(LOG_AM_DESTROY_ACTIVITY, 4016 System.identityHashCode(r), 4017 r.task.taskId, r.shortComponentName); 4018 4019 boolean removedFromHistory = false; 4020 4021 cleanUpActivityLocked(r, false); 4022 4023 if (r.app != null) { 4024 if (removeFromApp) { 4025 int idx = r.app.activities.indexOf(r); 4026 if (idx >= 0) { 4027 r.app.activities.remove(idx); 4028 } 4029 if (r.persistent) { 4030 decPersistentCountLocked(r.app); 4031 } 4032 } 4033 4034 boolean skipDestroy = false; 4035 4036 try { 4037 if (DEBUG_SWITCH) Log.i(TAG, "Destroying: " + r); 4038 r.app.thread.scheduleDestroyActivity(r, r.finishing, 4039 r.configChangeFlags); 4040 } catch (Exception e) { 4041 // We can just ignore exceptions here... if the process 4042 // has crashed, our death notification will clean things 4043 // up. 4044 //Log.w(TAG, "Exception thrown during finish", e); 4045 if (r.finishing) { 4046 removeActivityFromHistoryLocked(r); 4047 removedFromHistory = true; 4048 skipDestroy = true; 4049 } 4050 } 4051 4052 r.app = null; 4053 r.nowVisible = false; 4054 4055 if (r.finishing && !skipDestroy) { 4056 r.state = ActivityState.DESTROYING; 4057 Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG); 4058 msg.obj = r; 4059 mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT); 4060 } else { 4061 r.state = ActivityState.DESTROYED; 4062 } 4063 } else { 4064 // remove this record from the history. 4065 if (r.finishing) { 4066 removeActivityFromHistoryLocked(r); 4067 removedFromHistory = true; 4068 } else { 4069 r.state = ActivityState.DESTROYED; 4070 } 4071 } 4072 4073 r.configChangeFlags = 0; 4074 4075 if (!mLRUActivities.remove(r)) { 4076 Log.w(TAG, "Activity " + r + " being finished, but not in LRU list"); 4077 } 4078 4079 return removedFromHistory; 4080 } 4081 4082 private static void removeHistoryRecordsForAppLocked(ArrayList list, 4083 ProcessRecord app) 4084 { 4085 int i = list.size(); 4086 if (localLOGV) Log.v( 4087 TAG, "Removing app " + app + " from list " + list 4088 + " with " + i + " entries"); 4089 while (i > 0) { 4090 i--; 4091 HistoryRecord r = (HistoryRecord)list.get(i); 4092 if (localLOGV) Log.v( 4093 TAG, "Record #" + i + " " + r + ": app=" + r.app); 4094 if (r.app == app) { 4095 if (localLOGV) Log.v(TAG, "Removing this entry!"); 4096 list.remove(i); 4097 } 4098 } 4099 } 4100 4101 /** 4102 * Main function for removing an existing process from the activity manager 4103 * as a result of that process going away. Clears out all connections 4104 * to the process. 4105 */ 4106 private final void handleAppDiedLocked(ProcessRecord app, 4107 boolean restarting) { 4108 cleanUpApplicationRecordLocked(app, restarting, -1); 4109 if (!restarting) { 4110 mLRUProcesses.remove(app); 4111 } 4112 4113 // Just in case... 4114 if (mPausingActivity != null && mPausingActivity.app == app) { 4115 if (DEBUG_PAUSE) Log.v(TAG, "App died while pausing: " + mPausingActivity); 4116 mPausingActivity = null; 4117 } 4118 if (mLastPausedActivity != null && mLastPausedActivity.app == app) { 4119 mLastPausedActivity = null; 4120 } 4121 4122 // Remove this application's activities from active lists. 4123 removeHistoryRecordsForAppLocked(mLRUActivities, app); 4124 removeHistoryRecordsForAppLocked(mStoppingActivities, app); 4125 removeHistoryRecordsForAppLocked(mWaitingVisibleActivities, app); 4126 removeHistoryRecordsForAppLocked(mFinishingActivities, app); 4127 4128 boolean atTop = true; 4129 boolean hasVisibleActivities = false; 4130 4131 // Clean out the history list. 4132 int i = mHistory.size(); 4133 if (localLOGV) Log.v( 4134 TAG, "Removing app " + app + " from history with " + i + " entries"); 4135 while (i > 0) { 4136 i--; 4137 HistoryRecord r = (HistoryRecord)mHistory.get(i); 4138 if (localLOGV) Log.v( 4139 TAG, "Record #" + i + " " + r + ": app=" + r.app); 4140 if (r.app == app) { 4141 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 4142 if (localLOGV) Log.v( 4143 TAG, "Removing this entry! frozen=" + r.haveState 4144 + " finishing=" + r.finishing); 4145 mHistory.remove(i); 4146 4147 r.inHistory = false; 4148 mWindowManager.removeAppToken(r); 4149 if (VALIDATE_TOKENS) { 4150 mWindowManager.validateAppTokens(mHistory); 4151 } 4152 removeActivityUriPermissionsLocked(r); 4153 4154 } else { 4155 // We have the current state for this activity, so 4156 // it can be restarted later when needed. 4157 if (localLOGV) Log.v( 4158 TAG, "Keeping entry, setting app to null"); 4159 if (r.visible) { 4160 hasVisibleActivities = true; 4161 } 4162 r.app = null; 4163 r.nowVisible = false; 4164 if (!r.haveState) { 4165 r.icicle = null; 4166 } 4167 } 4168 4169 cleanUpActivityLocked(r, true); 4170 r.state = ActivityState.STOPPED; 4171 } 4172 atTop = false; 4173 } 4174 4175 app.activities.clear(); 4176 4177 if (app.instrumentationClass != null) { 4178 Log.w(TAG, "Crash of app " + app.processName 4179 + " running instrumentation " + app.instrumentationClass); 4180 Bundle info = new Bundle(); 4181 info.putString("shortMsg", "Process crashed."); 4182 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4183 } 4184 4185 if (!restarting) { 4186 if (!resumeTopActivityLocked(null)) { 4187 // If there was nothing to resume, and we are not already 4188 // restarting this process, but there is a visible activity that 4189 // is hosted by the process... then make sure all visible 4190 // activities are running, taking care of restarting this 4191 // process. 4192 if (hasVisibleActivities) { 4193 ensureActivitiesVisibleLocked(null, 0); 4194 } 4195 } 4196 } 4197 } 4198 4199 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4200 IBinder threadBinder = thread.asBinder(); 4201 4202 // Find the application record. 4203 int count = mLRUProcesses.size(); 4204 int i; 4205 for (i=0; i<count; i++) { 4206 ProcessRecord rec = mLRUProcesses.get(i); 4207 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4208 return i; 4209 } 4210 } 4211 return -1; 4212 } 4213 4214 private final ProcessRecord getRecordForAppLocked( 4215 IApplicationThread thread) { 4216 if (thread == null) { 4217 return null; 4218 } 4219 4220 int appIndex = getLRURecordIndexForAppLocked(thread); 4221 return appIndex >= 0 ? mLRUProcesses.get(appIndex) : null; 4222 } 4223 4224 private final void appDiedLocked(ProcessRecord app, int pid, 4225 IApplicationThread thread) { 4226 4227 mProcDeaths[0]++; 4228 4229 if (app.thread != null && app.thread.asBinder() == thread.asBinder()) { 4230 Log.i(TAG, "Process " + app.processName + " (pid " + pid 4231 + ") has died."); 4232 EventLog.writeEvent(LOG_AM_PROCESS_DIED, app.pid, app.processName); 4233 if (localLOGV) Log.v( 4234 TAG, "Dying app: " + app + ", pid: " + pid 4235 + ", thread: " + thread.asBinder()); 4236 boolean doLowMem = app.instrumentationClass == null; 4237 handleAppDiedLocked(app, false); 4238 4239 if (doLowMem) { 4240 // If there are no longer any background processes running, 4241 // and the app that died was not running instrumentation, 4242 // then tell everyone we are now low on memory. 4243 boolean haveBg = false; 4244 int count = mLRUProcesses.size(); 4245 int i; 4246 for (i=0; i<count; i++) { 4247 ProcessRecord rec = mLRUProcesses.get(i); 4248 if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) { 4249 haveBg = true; 4250 break; 4251 } 4252 } 4253 4254 if (!haveBg) { 4255 Log.i(TAG, "Low Memory: No more background processes."); 4256 EventLog.writeEvent(LOG_AM_LOW_MEMORY, mLRUProcesses.size()); 4257 for (i=0; i<count; i++) { 4258 ProcessRecord rec = mLRUProcesses.get(i); 4259 if (rec.thread != null) { 4260 rec.lastRequestedGc = SystemClock.uptimeMillis(); 4261 try { 4262 rec.thread.scheduleLowMemory(); 4263 } catch (RemoteException e) { 4264 // Don't care if the process is gone. 4265 } 4266 } 4267 } 4268 } 4269 } 4270 } else if (Config.LOGD) { 4271 Log.d(TAG, "Received spurious death notification for thread " 4272 + thread.asBinder()); 4273 } 4274 } 4275 4276 final String readFile(String filename) { 4277 try { 4278 FileInputStream fs = new FileInputStream(filename); 4279 byte[] inp = new byte[8192]; 4280 int size = fs.read(inp); 4281 fs.close(); 4282 return new String(inp, 0, 0, size); 4283 } catch (java.io.IOException e) { 4284 } 4285 return ""; 4286 } 4287 4288 final void appNotRespondingLocked(ProcessRecord app, HistoryRecord activity, 4289 final String annotation) { 4290 if (app.notResponding || app.crashing) { 4291 return; 4292 } 4293 4294 // Log the ANR to the event log. 4295 EventLog.writeEvent(LOG_ANR, app.pid, app.processName, annotation); 4296 4297 // If we are on a secure build and the application is not interesting to the user (it is 4298 // not visible or in the background), just kill it instead of displaying a dialog. 4299 boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0")); 4300 if (isSecure && !app.isInterestingToUserLocked() && Process.myPid() != app.pid) { 4301 Process.killProcess(app.pid); 4302 return; 4303 } 4304 4305 // DeviceMonitor.start(); 4306 4307 String processInfo = null; 4308 if (MONITOR_CPU_USAGE) { 4309 updateCpuStatsNow(); 4310 synchronized (mProcessStatsThread) { 4311 processInfo = mProcessStats.printCurrentState(); 4312 } 4313 } 4314 4315 StringBuilder info = mStringBuilder; 4316 info.setLength(0); 4317 info.append("ANR (application not responding) in process: "); 4318 info.append(app.processName); 4319 if (annotation != null) { 4320 info.append("\nAnnotation: "); 4321 info.append(annotation); 4322 } 4323 if (MONITOR_CPU_USAGE) { 4324 info.append("\nCPU usage:\n"); 4325 info.append(processInfo); 4326 } 4327 Log.i(TAG, info.toString()); 4328 4329 // The application is not responding. Dump as many thread traces as we can. 4330 boolean fileDump = prepareTraceFile(true); 4331 if (!fileDump) { 4332 // Dumping traces to the log, just dump the process that isn't responding so 4333 // we don't overflow the log 4334 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4335 } else { 4336 // Dumping traces to a file so dump all active processes we know about 4337 synchronized (this) { 4338 for (int i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) { 4339 ProcessRecord r = mLRUProcesses.get(i); 4340 if (r.thread != null) { 4341 Process.sendSignal(r.pid, Process.SIGNAL_QUIT); 4342 } 4343 } 4344 } 4345 } 4346 4347 if (mWatcher != null) { 4348 try { 4349 int res = mWatcher.appNotResponding(app.processName, 4350 app.pid, info.toString()); 4351 if (res != 0) { 4352 if (res < 0) { 4353 // wait until the SIGQUIT has had a chance to process before killing the 4354 // process. 4355 try { 4356 wait(2000); 4357 } catch (InterruptedException e) { 4358 } 4359 4360 Process.killProcess(app.pid); 4361 return; 4362 } 4363 } 4364 } catch (RemoteException e) { 4365 mWatcher = null; 4366 } 4367 } 4368 4369 makeAppNotRespondingLocked(app, 4370 activity != null ? activity.shortComponentName : null, 4371 annotation != null ? "ANR " + annotation : "ANR", 4372 info.toString(), null); 4373 Message msg = Message.obtain(); 4374 HashMap map = new HashMap(); 4375 msg.what = SHOW_NOT_RESPONDING_MSG; 4376 msg.obj = map; 4377 map.put("app", app); 4378 if (activity != null) { 4379 map.put("activity", activity); 4380 } 4381 4382 mHandler.sendMessage(msg); 4383 return; 4384 } 4385 4386 /** 4387 * If a stack trace file has been configured, prepare the filesystem 4388 * by creating the directory if it doesn't exist and optionally 4389 * removing the old trace file. 4390 * 4391 * @param removeExisting If set, the existing trace file will be removed. 4392 * @return Returns true if the trace file preparations succeeded 4393 */ 4394 public static boolean prepareTraceFile(boolean removeExisting) { 4395 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4396 boolean fileReady = false; 4397 if (!TextUtils.isEmpty(tracesPath)) { 4398 File f = new File(tracesPath); 4399 if (!f.exists()) { 4400 // Ensure the enclosing directory exists 4401 File dir = f.getParentFile(); 4402 if (!dir.exists()) { 4403 fileReady = dir.mkdirs(); 4404 FileUtils.setPermissions(dir.getAbsolutePath(), 4405 FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IRWXO, -1, -1); 4406 } else if (dir.isDirectory()) { 4407 fileReady = true; 4408 } 4409 } else if (removeExisting) { 4410 // Remove the previous traces file, so we don't fill the disk. 4411 // The VM will recreate it 4412 Log.i(TAG, "Removing old ANR trace file from " + tracesPath); 4413 fileReady = f.delete(); 4414 } 4415 } 4416 4417 return fileReady; 4418 } 4419 4420 4421 private final void decPersistentCountLocked(ProcessRecord app) 4422 { 4423 app.persistentActivities--; 4424 if (app.persistentActivities > 0) { 4425 // Still more of 'em... 4426 return; 4427 } 4428 if (app.persistent) { 4429 // Ah, but the application itself is persistent. Whatever! 4430 return; 4431 } 4432 4433 // App is no longer persistent... make sure it and the ones 4434 // following it in the LRU list have the correc oom_adj. 4435 updateOomAdjLocked(); 4436 } 4437 4438 public void setPersistent(IBinder token, boolean isPersistent) { 4439 if (checkCallingPermission(android.Manifest.permission.PERSISTENT_ACTIVITY) 4440 != PackageManager.PERMISSION_GRANTED) { 4441 String msg = "Permission Denial: setPersistent() from pid=" 4442 + Binder.getCallingPid() 4443 + ", uid=" + Binder.getCallingUid() 4444 + " requires " + android.Manifest.permission.PERSISTENT_ACTIVITY; 4445 Log.w(TAG, msg); 4446 throw new SecurityException(msg); 4447 } 4448 4449 synchronized(this) { 4450 int index = indexOfTokenLocked(token, true); 4451 if (index < 0) { 4452 return; 4453 } 4454 HistoryRecord r = (HistoryRecord)mHistory.get(index); 4455 ProcessRecord app = r.app; 4456 4457 if (localLOGV) Log.v( 4458 TAG, "Setting persistence " + isPersistent + ": " + r); 4459 4460 if (isPersistent) { 4461 if (r.persistent) { 4462 // Okay okay, I heard you already! 4463 if (localLOGV) Log.v(TAG, "Already persistent!"); 4464 return; 4465 } 4466 r.persistent = true; 4467 app.persistentActivities++; 4468 if (localLOGV) Log.v(TAG, "Num persistent now: " + app.persistentActivities); 4469 if (app.persistentActivities > 1) { 4470 // We aren't the first... 4471 if (localLOGV) Log.v(TAG, "Not the first!"); 4472 return; 4473 } 4474 if (app.persistent) { 4475 // This would be redundant. 4476 if (localLOGV) Log.v(TAG, "App is persistent!"); 4477 return; 4478 } 4479 4480 // App is now persistent... make sure it and the ones 4481 // following it now have the correct oom_adj. 4482 final long origId = Binder.clearCallingIdentity(); 4483 updateOomAdjLocked(); 4484 Binder.restoreCallingIdentity(origId); 4485 4486 } else { 4487 if (!r.persistent) { 4488 // Okay okay, I heard you already! 4489 return; 4490 } 4491 r.persistent = false; 4492 final long origId = Binder.clearCallingIdentity(); 4493 decPersistentCountLocked(app); 4494 Binder.restoreCallingIdentity(origId); 4495 4496 } 4497 } 4498 } 4499 4500 public boolean clearApplicationUserData(final String packageName, 4501 final IPackageDataObserver observer) { 4502 int uid = Binder.getCallingUid(); 4503 int pid = Binder.getCallingPid(); 4504 long callingId = Binder.clearCallingIdentity(); 4505 try { 4506 IPackageManager pm = ActivityThread.getPackageManager(); 4507 int pkgUid = -1; 4508 synchronized(this) { 4509 try { 4510 pkgUid = pm.getPackageUid(packageName); 4511 } catch (RemoteException e) { 4512 } 4513 if (pkgUid == -1) { 4514 Log.w(TAG, "Invalid packageName:" + packageName); 4515 return false; 4516 } 4517 if (uid == pkgUid || checkComponentPermission( 4518 android.Manifest.permission.CLEAR_APP_USER_DATA, 4519 pid, uid, -1) 4520 == PackageManager.PERMISSION_GRANTED) { 4521 restartPackageLocked(packageName, pkgUid); 4522 } else { 4523 throw new SecurityException(pid+" does not have permission:"+ 4524 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 4525 "for process:"+packageName); 4526 } 4527 } 4528 4529 try { 4530 //clear application user data 4531 pm.clearApplicationUserData(packageName, observer); 4532 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4533 Uri.fromParts("package", packageName, null)); 4534 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4535 broadcastIntentLocked(null, null, intent, 4536 null, null, 0, null, null, null, 4537 false, false, MY_PID, Process.SYSTEM_UID); 4538 } catch (RemoteException e) { 4539 } 4540 } finally { 4541 Binder.restoreCallingIdentity(callingId); 4542 } 4543 return true; 4544 } 4545 4546 public void restartPackage(final String packageName) { 4547 if (checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4548 != PackageManager.PERMISSION_GRANTED) { 4549 String msg = "Permission Denial: restartPackage() from pid=" 4550 + Binder.getCallingPid() 4551 + ", uid=" + Binder.getCallingUid() 4552 + " requires " + android.Manifest.permission.RESTART_PACKAGES; 4553 Log.w(TAG, msg); 4554 throw new SecurityException(msg); 4555 } 4556 4557 long callingId = Binder.clearCallingIdentity(); 4558 try { 4559 IPackageManager pm = ActivityThread.getPackageManager(); 4560 int pkgUid = -1; 4561 synchronized(this) { 4562 try { 4563 pkgUid = pm.getPackageUid(packageName); 4564 } catch (RemoteException e) { 4565 } 4566 if (pkgUid == -1) { 4567 Log.w(TAG, "Invalid packageName: " + packageName); 4568 return; 4569 } 4570 restartPackageLocked(packageName, pkgUid); 4571 } 4572 } finally { 4573 Binder.restoreCallingIdentity(callingId); 4574 } 4575 } 4576 4577 private void restartPackageLocked(final String packageName, int uid) { 4578 uninstallPackageLocked(packageName, uid, false); 4579 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4580 Uri.fromParts("package", packageName, null)); 4581 intent.putExtra(Intent.EXTRA_UID, uid); 4582 broadcastIntentLocked(null, null, intent, 4583 null, null, 0, null, null, null, 4584 false, false, MY_PID, Process.SYSTEM_UID); 4585 } 4586 4587 private final void uninstallPackageLocked(String name, int uid, 4588 boolean callerWillRestart) { 4589 if (Config.LOGD) Log.d(TAG, "Uninstalling process " + name); 4590 4591 int i, N; 4592 4593 final String procNamePrefix = name + ":"; 4594 if (uid < 0) { 4595 try { 4596 uid = ActivityThread.getPackageManager().getPackageUid(name); 4597 } catch (RemoteException e) { 4598 } 4599 } 4600 4601 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 4602 while (badApps.hasNext()) { 4603 SparseArray<Long> ba = badApps.next(); 4604 if (ba.get(uid) != null) { 4605 badApps.remove(); 4606 } 4607 } 4608 4609 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4610 4611 // Remove all processes this package may have touched: all with the 4612 // same UID (except for the system or root user), and all whose name 4613 // matches the package name. 4614 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 4615 final int NA = apps.size(); 4616 for (int ia=0; ia<NA; ia++) { 4617 ProcessRecord app = apps.valueAt(ia); 4618 if (app.removed) { 4619 procs.add(app); 4620 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 4621 || app.processName.equals(name) 4622 || app.processName.startsWith(procNamePrefix)) { 4623 app.removed = true; 4624 procs.add(app); 4625 } 4626 } 4627 } 4628 4629 N = procs.size(); 4630 for (i=0; i<N; i++) { 4631 removeProcessLocked(procs.get(i), callerWillRestart); 4632 } 4633 4634 for (i=mHistory.size()-1; i>=0; i--) { 4635 HistoryRecord r = (HistoryRecord)mHistory.get(i); 4636 if (r.packageName.equals(name)) { 4637 if (Config.LOGD) Log.d( 4638 TAG, " Force finishing activity " 4639 + r.intent.getComponent().flattenToShortString()); 4640 if (r.app != null) { 4641 r.app.removed = true; 4642 } 4643 r.app = null; 4644 finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall"); 4645 } 4646 } 4647 4648 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 4649 for (ServiceRecord service : mServices.values()) { 4650 if (service.packageName.equals(name)) { 4651 if (service.app != null) { 4652 service.app.removed = true; 4653 } 4654 service.app = null; 4655 services.add(service); 4656 } 4657 } 4658 4659 N = services.size(); 4660 for (i=0; i<N; i++) { 4661 bringDownServiceLocked(services.get(i), true); 4662 } 4663 4664 resumeTopActivityLocked(null); 4665 } 4666 4667 private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) { 4668 final String name = app.processName; 4669 final int uid = app.info.uid; 4670 if (Config.LOGD) Log.d( 4671 TAG, "Force removing process " + app + " (" + name 4672 + "/" + uid + ")"); 4673 4674 mProcessNames.remove(name, uid); 4675 boolean needRestart = false; 4676 if (app.pid > 0 && app.pid != MY_PID) { 4677 int pid = app.pid; 4678 synchronized (mPidsSelfLocked) { 4679 mPidsSelfLocked.remove(pid); 4680 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4681 } 4682 handleAppDiedLocked(app, true); 4683 mLRUProcesses.remove(app); 4684 Process.killProcess(pid); 4685 4686 if (app.persistent) { 4687 if (!callerWillRestart) { 4688 addAppLocked(app.info); 4689 } else { 4690 needRestart = true; 4691 } 4692 } 4693 } else { 4694 mRemovedProcesses.add(app); 4695 } 4696 4697 return needRestart; 4698 } 4699 4700 private final void processStartTimedOutLocked(ProcessRecord app) { 4701 final int pid = app.pid; 4702 boolean gone = false; 4703 synchronized (mPidsSelfLocked) { 4704 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4705 if (knownApp != null && knownApp.thread == null) { 4706 mPidsSelfLocked.remove(pid); 4707 gone = true; 4708 } 4709 } 4710 4711 if (gone) { 4712 Log.w(TAG, "Process " + app + " failed to attach"); 4713 mProcessNames.remove(app.processName, app.info.uid); 4714 Process.killProcess(pid); 4715 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) { 4716 Log.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4717 mPendingBroadcast = null; 4718 scheduleBroadcastsLocked(); 4719 } 4720 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4721 Log.w(TAG, "Unattached app died before backup, skipping"); 4722 try { 4723 IBackupManager bm = IBackupManager.Stub.asInterface( 4724 ServiceManager.getService(Context.BACKUP_SERVICE)); 4725 bm.agentDisconnected(app.info.packageName); 4726 } catch (RemoteException e) { 4727 // Can't happen; the backup manager is local 4728 } 4729 } 4730 } else { 4731 Log.w(TAG, "Spurious process start timeout - pid not known for " + app); 4732 } 4733 } 4734 4735 private final boolean attachApplicationLocked(IApplicationThread thread, 4736 int pid) { 4737 4738 // Find the application record that is being attached... either via 4739 // the pid if we are running in multiple processes, or just pull the 4740 // next app record if we are emulating process with anonymous threads. 4741 ProcessRecord app; 4742 if (pid != MY_PID && pid >= 0) { 4743 synchronized (mPidsSelfLocked) { 4744 app = mPidsSelfLocked.get(pid); 4745 } 4746 } else if (mStartingProcesses.size() > 0) { 4747 app = mStartingProcesses.remove(0); 4748 app.setPid(pid); 4749 } else { 4750 app = null; 4751 } 4752 4753 if (app == null) { 4754 Log.w(TAG, "No pending application record for pid " + pid 4755 + " (IApplicationThread " + thread + "); dropping process"); 4756 EventLog.writeEvent(LOG_AM_DROP_PROCESS, pid); 4757 if (pid > 0 && pid != MY_PID) { 4758 Process.killProcess(pid); 4759 } else { 4760 try { 4761 thread.scheduleExit(); 4762 } catch (Exception e) { 4763 // Ignore exceptions. 4764 } 4765 } 4766 return false; 4767 } 4768 4769 // If this application record is still attached to a previous 4770 // process, clean it up now. 4771 if (app.thread != null) { 4772 handleAppDiedLocked(app, true); 4773 } 4774 4775 // Tell the process all about itself. 4776 4777 if (localLOGV) Log.v( 4778 TAG, "Binding process pid " + pid + " to record " + app); 4779 4780 String processName = app.processName; 4781 try { 4782 thread.asBinder().linkToDeath(new AppDeathRecipient( 4783 app, pid, thread), 0); 4784 } catch (RemoteException e) { 4785 app.resetPackageList(); 4786 startProcessLocked(app, "link fail", processName); 4787 return false; 4788 } 4789 4790 EventLog.writeEvent(LOG_AM_PROCESS_BOUND, app.pid, app.processName); 4791 4792 app.thread = thread; 4793 app.curAdj = app.setAdj = -100; 4794 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4795 app.forcingToForeground = null; 4796 app.foregroundServices = false; 4797 app.debugging = false; 4798 4799 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4800 4801 List providers = generateApplicationProvidersLocked(app); 4802 4803 if (localLOGV) Log.v( 4804 TAG, "New app record " + app 4805 + " thread=" + thread.asBinder() + " pid=" + pid); 4806 try { 4807 int testMode = IApplicationThread.DEBUG_OFF; 4808 if (mDebugApp != null && mDebugApp.equals(processName)) { 4809 testMode = mWaitForDebugger 4810 ? IApplicationThread.DEBUG_WAIT 4811 : IApplicationThread.DEBUG_ON; 4812 app.debugging = true; 4813 if (mDebugTransient) { 4814 mDebugApp = mOrigDebugApp; 4815 mWaitForDebugger = mOrigWaitForDebugger; 4816 } 4817 } 4818 // If the app is being launched for restore or full backup, set it up specially 4819 boolean isRestrictedBackupMode = false; 4820 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4821 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4822 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4823 } 4824 thread.bindApplication(processName, app.instrumentationInfo != null 4825 ? app.instrumentationInfo : app.info, providers, 4826 app.instrumentationClass, app.instrumentationProfileFile, 4827 app.instrumentationArguments, app.instrumentationWatcher, testMode, 4828 isRestrictedBackupMode, mConfiguration, getCommonServicesLocked()); 4829 updateLRUListLocked(app, false); 4830 app.lastRequestedGc = SystemClock.uptimeMillis(); 4831 } catch (Exception e) { 4832 // todo: Yikes! What should we do? For now we will try to 4833 // start another process, but that could easily get us in 4834 // an infinite loop of restarting processes... 4835 Log.w(TAG, "Exception thrown during bind!", e); 4836 4837 app.resetPackageList(); 4838 startProcessLocked(app, "bind fail", processName); 4839 return false; 4840 } 4841 4842 // Remove this record from the list of starting applications. 4843 mPersistentStartingProcesses.remove(app); 4844 mProcessesOnHold.remove(app); 4845 4846 boolean badApp = false; 4847 boolean didSomething = false; 4848 4849 // See if the top visible activity is waiting to run in this process... 4850 HistoryRecord hr = topRunningActivityLocked(null); 4851 if (hr != null) { 4852 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid 4853 && processName.equals(hr.processName)) { 4854 try { 4855 if (realStartActivityLocked(hr, app, true, true)) { 4856 didSomething = true; 4857 } 4858 } catch (Exception e) { 4859 Log.w(TAG, "Exception in new application when starting activity " 4860 + hr.intent.getComponent().flattenToShortString(), e); 4861 badApp = true; 4862 } 4863 } else { 4864 ensureActivitiesVisibleLocked(hr, null, processName, 0); 4865 } 4866 } 4867 4868 // Find any services that should be running in this process... 4869 if (!badApp && mPendingServices.size() > 0) { 4870 ServiceRecord sr = null; 4871 try { 4872 for (int i=0; i<mPendingServices.size(); i++) { 4873 sr = mPendingServices.get(i); 4874 if (app.info.uid != sr.appInfo.uid 4875 || !processName.equals(sr.processName)) { 4876 continue; 4877 } 4878 4879 mPendingServices.remove(i); 4880 i--; 4881 realStartServiceLocked(sr, app); 4882 didSomething = true; 4883 } 4884 } catch (Exception e) { 4885 Log.w(TAG, "Exception in new application when starting service " 4886 + sr.shortName, e); 4887 badApp = true; 4888 } 4889 } 4890 4891 // Check if the next broadcast receiver is in this process... 4892 BroadcastRecord br = mPendingBroadcast; 4893 if (!badApp && br != null && br.curApp == app) { 4894 try { 4895 mPendingBroadcast = null; 4896 processCurBroadcastLocked(br, app); 4897 didSomething = true; 4898 } catch (Exception e) { 4899 Log.w(TAG, "Exception in new application when starting receiver " 4900 + br.curComponent.flattenToShortString(), e); 4901 badApp = true; 4902 logBroadcastReceiverDiscard(br); 4903 finishReceiverLocked(br.receiver, br.resultCode, br.resultData, 4904 br.resultExtras, br.resultAbort, true); 4905 scheduleBroadcastsLocked(); 4906 } 4907 } 4908 4909 // Check whether the next backup agent is in this process... 4910 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) { 4911 if (DEBUG_BACKUP) Log.v(TAG, "New app is backup target, launching agent for " + app); 4912 try { 4913 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, mBackupTarget.backupMode); 4914 } catch (Exception e) { 4915 Log.w(TAG, "Exception scheduling backup agent creation: "); 4916 e.printStackTrace(); 4917 } 4918 } 4919 4920 if (badApp) { 4921 // todo: Also need to kill application to deal with all 4922 // kinds of exceptions. 4923 handleAppDiedLocked(app, false); 4924 return false; 4925 } 4926 4927 if (!didSomething) { 4928 updateOomAdjLocked(); 4929 } 4930 4931 return true; 4932 } 4933 4934 public final void attachApplication(IApplicationThread thread) { 4935 synchronized (this) { 4936 int callingPid = Binder.getCallingPid(); 4937 final long origId = Binder.clearCallingIdentity(); 4938 attachApplicationLocked(thread, callingPid); 4939 Binder.restoreCallingIdentity(origId); 4940 } 4941 } 4942 4943 public final void activityIdle(IBinder token) { 4944 final long origId = Binder.clearCallingIdentity(); 4945 activityIdleInternal(token, false); 4946 Binder.restoreCallingIdentity(origId); 4947 } 4948 4949 final ArrayList<HistoryRecord> processStoppingActivitiesLocked( 4950 boolean remove) { 4951 int N = mStoppingActivities.size(); 4952 if (N <= 0) return null; 4953 4954 ArrayList<HistoryRecord> stops = null; 4955 4956 final boolean nowVisible = mResumedActivity != null 4957 && mResumedActivity.nowVisible 4958 && !mResumedActivity.waitingVisible; 4959 for (int i=0; i<N; i++) { 4960 HistoryRecord s = mStoppingActivities.get(i); 4961 if (localLOGV) Log.v(TAG, "Stopping " + s + ": nowVisible=" 4962 + nowVisible + " waitingVisible=" + s.waitingVisible 4963 + " finishing=" + s.finishing); 4964 if (s.waitingVisible && nowVisible) { 4965 mWaitingVisibleActivities.remove(s); 4966 s.waitingVisible = false; 4967 if (s.finishing) { 4968 // If this activity is finishing, it is sitting on top of 4969 // everyone else but we now know it is no longer needed... 4970 // so get rid of it. Otherwise, we need to go through the 4971 // normal flow and hide it once we determine that it is 4972 // hidden by the activities in front of it. 4973 if (localLOGV) Log.v(TAG, "Before stopping, can hide: " + s); 4974 mWindowManager.setAppVisibility(s, false); 4975 } 4976 } 4977 if (!s.waitingVisible && remove) { 4978 if (localLOGV) Log.v(TAG, "Ready to stop: " + s); 4979 if (stops == null) { 4980 stops = new ArrayList<HistoryRecord>(); 4981 } 4982 stops.add(s); 4983 mStoppingActivities.remove(i); 4984 N--; 4985 i--; 4986 } 4987 } 4988 4989 return stops; 4990 } 4991 4992 void enableScreenAfterBoot() { 4993 mWindowManager.enableScreenAfterBoot(); 4994 } 4995 4996 final void activityIdleInternal(IBinder token, boolean fromTimeout) { 4997 if (localLOGV) Log.v(TAG, "Activity idle: " + token); 4998 4999 ArrayList<HistoryRecord> stops = null; 5000 ArrayList<HistoryRecord> finishes = null; 5001 ArrayList<HistoryRecord> thumbnails = null; 5002 int NS = 0; 5003 int NF = 0; 5004 int NT = 0; 5005 IApplicationThread sendThumbnail = null; 5006 boolean booting = false; 5007 boolean enableScreen = false; 5008 5009 synchronized (this) { 5010 if (token != null) { 5011 mHandler.removeMessages(IDLE_TIMEOUT_MSG, token); 5012 } 5013 5014 // Get the activity record. 5015 int index = indexOfTokenLocked(token, false); 5016 if (index >= 0) { 5017 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5018 5019 // No longer need to keep the device awake. 5020 if (mResumedActivity == r && mLaunchingActivity.isHeld()) { 5021 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 5022 mLaunchingActivity.release(); 5023 } 5024 5025 // We are now idle. If someone is waiting for a thumbnail from 5026 // us, we can now deliver. 5027 r.idle = true; 5028 scheduleAppGcsLocked(); 5029 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) { 5030 sendThumbnail = r.app.thread; 5031 r.thumbnailNeeded = false; 5032 } 5033 5034 // If this activity is fullscreen, set up to hide those under it. 5035 5036 if (DEBUG_VISBILITY) Log.v(TAG, "Idle activity for " + r); 5037 ensureActivitiesVisibleLocked(null, 0); 5038 5039 //Log.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); 5040 if (!mBooted && !fromTimeout) { 5041 mBooted = true; 5042 enableScreen = true; 5043 } 5044 } 5045 5046 // Atomically retrieve all of the other things to do. 5047 stops = processStoppingActivitiesLocked(true); 5048 NS = stops != null ? stops.size() : 0; 5049 if ((NF=mFinishingActivities.size()) > 0) { 5050 finishes = new ArrayList<HistoryRecord>(mFinishingActivities); 5051 mFinishingActivities.clear(); 5052 } 5053 if ((NT=mCancelledThumbnails.size()) > 0) { 5054 thumbnails = new ArrayList<HistoryRecord>(mCancelledThumbnails); 5055 mCancelledThumbnails.clear(); 5056 } 5057 5058 booting = mBooting; 5059 mBooting = false; 5060 } 5061 5062 int i; 5063 5064 // Send thumbnail if requested. 5065 if (sendThumbnail != null) { 5066 try { 5067 sendThumbnail.requestThumbnail(token); 5068 } catch (Exception e) { 5069 Log.w(TAG, "Exception thrown when requesting thumbnail", e); 5070 sendPendingThumbnail(null, token, null, null, true); 5071 } 5072 } 5073 5074 // Stop any activities that are scheduled to do so but have been 5075 // waiting for the next one to start. 5076 for (i=0; i<NS; i++) { 5077 HistoryRecord r = (HistoryRecord)stops.get(i); 5078 synchronized (this) { 5079 if (r.finishing) { 5080 finishCurrentActivityLocked(r, FINISH_IMMEDIATELY); 5081 } else { 5082 stopActivityLocked(r); 5083 } 5084 } 5085 } 5086 5087 // Finish any activities that are scheduled to do so but have been 5088 // waiting for the next one to start. 5089 for (i=0; i<NF; i++) { 5090 HistoryRecord r = (HistoryRecord)finishes.get(i); 5091 synchronized (this) { 5092 destroyActivityLocked(r, true); 5093 } 5094 } 5095 5096 // Report back to any thumbnail receivers. 5097 for (i=0; i<NT; i++) { 5098 HistoryRecord r = (HistoryRecord)thumbnails.get(i); 5099 sendPendingThumbnail(r, null, null, null, true); 5100 } 5101 5102 if (booting) { 5103 // Ensure that any processes we had put on hold are now started 5104 // up. 5105 final int NP = mProcessesOnHold.size(); 5106 if (NP > 0) { 5107 ArrayList<ProcessRecord> procs = 5108 new ArrayList<ProcessRecord>(mProcessesOnHold); 5109 for (int ip=0; ip<NP; ip++) { 5110 this.startProcessLocked(procs.get(ip), "on-hold", null); 5111 } 5112 } 5113 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 5114 // Tell anyone interested that we are done booting! 5115 synchronized (this) { 5116 broadcastIntentLocked(null, null, 5117 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 5118 null, null, 0, null, null, 5119 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5120 false, false, MY_PID, Process.SYSTEM_UID); 5121 } 5122 } 5123 } 5124 5125 trimApplications(); 5126 //dump(); 5127 //mWindowManager.dump(); 5128 5129 if (enableScreen) { 5130 EventLog.writeEvent(LOG_BOOT_PROGRESS_ENABLE_SCREEN, 5131 SystemClock.uptimeMillis()); 5132 enableScreenAfterBoot(); 5133 } 5134 } 5135 5136 final void ensureScreenEnabled() { 5137 boolean enableScreen; 5138 synchronized (this) { 5139 enableScreen = !mBooted; 5140 mBooted = true; 5141 } 5142 5143 if (enableScreen) { 5144 EventLog.writeEvent(LOG_BOOT_PROGRESS_ENABLE_SCREEN, 5145 SystemClock.uptimeMillis()); 5146 enableScreenAfterBoot(); 5147 } 5148 } 5149 5150 public final void activityPaused(IBinder token, Bundle icicle) { 5151 // Refuse possible leaked file descriptors 5152 if (icicle != null && icicle.hasFileDescriptors()) { 5153 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5154 } 5155 5156 final long origId = Binder.clearCallingIdentity(); 5157 activityPaused(token, icicle, false); 5158 Binder.restoreCallingIdentity(origId); 5159 } 5160 5161 final void activityPaused(IBinder token, Bundle icicle, boolean timeout) { 5162 if (DEBUG_PAUSE) Log.v( 5163 TAG, "Activity paused: token=" + token + ", icicle=" + icicle 5164 + ", timeout=" + timeout); 5165 5166 HistoryRecord r = null; 5167 5168 synchronized (this) { 5169 int index = indexOfTokenLocked(token, false); 5170 if (index >= 0) { 5171 r = (HistoryRecord)mHistory.get(index); 5172 if (!timeout) { 5173 r.icicle = icicle; 5174 r.haveState = true; 5175 } 5176 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); 5177 if (mPausingActivity == r) { 5178 r.state = ActivityState.PAUSED; 5179 completePauseLocked(); 5180 } else { 5181 EventLog.writeEvent(LOG_AM_FAILED_TO_PAUSE_ACTIVITY, 5182 System.identityHashCode(r), r.shortComponentName, 5183 mPausingActivity != null 5184 ? mPausingActivity.shortComponentName : "(none)"); 5185 } 5186 } 5187 } 5188 } 5189 5190 public final void activityStopped(IBinder token, Bitmap thumbnail, 5191 CharSequence description) { 5192 if (localLOGV) Log.v( 5193 TAG, "Activity stopped: token=" + token); 5194 5195 HistoryRecord r = null; 5196 5197 final long origId = Binder.clearCallingIdentity(); 5198 5199 synchronized (this) { 5200 int index = indexOfTokenLocked(token, false); 5201 if (index >= 0) { 5202 r = (HistoryRecord)mHistory.get(index); 5203 r.thumbnail = thumbnail; 5204 r.description = description; 5205 r.stopped = true; 5206 r.state = ActivityState.STOPPED; 5207 if (!r.finishing) { 5208 if (r.configDestroy) { 5209 destroyActivityLocked(r, true); 5210 resumeTopActivityLocked(null); 5211 } 5212 } 5213 } 5214 } 5215 5216 if (r != null) { 5217 sendPendingThumbnail(r, null, null, null, false); 5218 } 5219 5220 trimApplications(); 5221 5222 Binder.restoreCallingIdentity(origId); 5223 } 5224 5225 public final void activityDestroyed(IBinder token) { 5226 if (DEBUG_SWITCH) Log.v(TAG, "ACTIVITY DESTROYED: " + token); 5227 synchronized (this) { 5228 mHandler.removeMessages(DESTROY_TIMEOUT_MSG, token); 5229 5230 int index = indexOfTokenLocked(token, false); 5231 if (index >= 0) { 5232 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5233 if (r.state == ActivityState.DESTROYING) { 5234 final long origId = Binder.clearCallingIdentity(); 5235 removeActivityFromHistoryLocked(r); 5236 Binder.restoreCallingIdentity(origId); 5237 } 5238 } 5239 } 5240 } 5241 5242 public String getCallingPackage(IBinder token) { 5243 synchronized (this) { 5244 HistoryRecord r = getCallingRecordLocked(token); 5245 return r != null && r.app != null ? r.app.processName : null; 5246 } 5247 } 5248 5249 public ComponentName getCallingActivity(IBinder token) { 5250 synchronized (this) { 5251 HistoryRecord r = getCallingRecordLocked(token); 5252 return r != null ? r.intent.getComponent() : null; 5253 } 5254 } 5255 5256 private HistoryRecord getCallingRecordLocked(IBinder token) { 5257 int index = indexOfTokenLocked(token, true); 5258 if (index >= 0) { 5259 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5260 if (r != null) { 5261 return r.resultTo; 5262 } 5263 } 5264 return null; 5265 } 5266 5267 public ComponentName getActivityClassForToken(IBinder token) { 5268 synchronized(this) { 5269 int index = indexOfTokenLocked(token, false); 5270 if (index >= 0) { 5271 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5272 return r.intent.getComponent(); 5273 } 5274 return null; 5275 } 5276 } 5277 5278 public String getPackageForToken(IBinder token) { 5279 synchronized(this) { 5280 int index = indexOfTokenLocked(token, false); 5281 if (index >= 0) { 5282 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5283 return r.packageName; 5284 } 5285 return null; 5286 } 5287 } 5288 5289 public IIntentSender getIntentSender(int type, 5290 String packageName, IBinder token, String resultWho, 5291 int requestCode, Intent intent, String resolvedType, int flags) { 5292 // Refuse possible leaked file descriptors 5293 if (intent != null && intent.hasFileDescriptors() == true) { 5294 throw new IllegalArgumentException("File descriptors passed in Intent"); 5295 } 5296 5297 synchronized(this) { 5298 int callingUid = Binder.getCallingUid(); 5299 try { 5300 if (callingUid != 0 && callingUid != Process.SYSTEM_UID && 5301 Process.supportsProcesses()) { 5302 int uid = ActivityThread.getPackageManager() 5303 .getPackageUid(packageName); 5304 if (uid != Binder.getCallingUid()) { 5305 String msg = "Permission Denial: getIntentSender() from pid=" 5306 + Binder.getCallingPid() 5307 + ", uid=" + Binder.getCallingUid() 5308 + ", (need uid=" + uid + ")" 5309 + " is not allowed to send as package " + packageName; 5310 Log.w(TAG, msg); 5311 throw new SecurityException(msg); 5312 } 5313 } 5314 } catch (RemoteException e) { 5315 throw new SecurityException(e); 5316 } 5317 HistoryRecord activity = null; 5318 if (type == INTENT_SENDER_ACTIVITY_RESULT) { 5319 int index = indexOfTokenLocked(token, false); 5320 if (index < 0) { 5321 return null; 5322 } 5323 activity = (HistoryRecord)mHistory.get(index); 5324 if (activity.finishing) { 5325 return null; 5326 } 5327 } 5328 5329 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5330 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5331 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5332 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5333 |PendingIntent.FLAG_UPDATE_CURRENT); 5334 5335 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5336 type, packageName, activity, resultWho, 5337 requestCode, intent, resolvedType, flags); 5338 WeakReference<PendingIntentRecord> ref; 5339 ref = mIntentSenderRecords.get(key); 5340 PendingIntentRecord rec = ref != null ? ref.get() : null; 5341 if (rec != null) { 5342 if (!cancelCurrent) { 5343 if (updateCurrent) { 5344 rec.key.requestIntent.replaceExtras(intent); 5345 } 5346 return rec; 5347 } 5348 rec.canceled = true; 5349 mIntentSenderRecords.remove(key); 5350 } 5351 if (noCreate) { 5352 return rec; 5353 } 5354 rec = new PendingIntentRecord(this, key, callingUid); 5355 mIntentSenderRecords.put(key, rec.ref); 5356 if (type == INTENT_SENDER_ACTIVITY_RESULT) { 5357 if (activity.pendingResults == null) { 5358 activity.pendingResults 5359 = new HashSet<WeakReference<PendingIntentRecord>>(); 5360 } 5361 activity.pendingResults.add(rec.ref); 5362 } 5363 return rec; 5364 } 5365 } 5366 5367 public void cancelIntentSender(IIntentSender sender) { 5368 if (!(sender instanceof PendingIntentRecord)) { 5369 return; 5370 } 5371 synchronized(this) { 5372 PendingIntentRecord rec = (PendingIntentRecord)sender; 5373 try { 5374 int uid = ActivityThread.getPackageManager() 5375 .getPackageUid(rec.key.packageName); 5376 if (uid != Binder.getCallingUid()) { 5377 String msg = "Permission Denial: cancelIntentSender() from pid=" 5378 + Binder.getCallingPid() 5379 + ", uid=" + Binder.getCallingUid() 5380 + " is not allowed to cancel packges " 5381 + rec.key.packageName; 5382 Log.w(TAG, msg); 5383 throw new SecurityException(msg); 5384 } 5385 } catch (RemoteException e) { 5386 throw new SecurityException(e); 5387 } 5388 cancelIntentSenderLocked(rec, true); 5389 } 5390 } 5391 5392 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5393 rec.canceled = true; 5394 mIntentSenderRecords.remove(rec.key); 5395 if (cleanActivity && rec.key.activity != null) { 5396 rec.key.activity.pendingResults.remove(rec.ref); 5397 } 5398 } 5399 5400 public String getPackageForIntentSender(IIntentSender pendingResult) { 5401 if (!(pendingResult instanceof PendingIntentRecord)) { 5402 return null; 5403 } 5404 synchronized(this) { 5405 try { 5406 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5407 return res.key.packageName; 5408 } catch (ClassCastException e) { 5409 } 5410 } 5411 return null; 5412 } 5413 5414 public void setProcessLimit(int max) { 5415 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5416 "setProcessLimit()"); 5417 mProcessLimit = max; 5418 } 5419 5420 public int getProcessLimit() { 5421 return mProcessLimit; 5422 } 5423 5424 void foregroundTokenDied(ForegroundToken token) { 5425 synchronized (ActivityManagerService.this) { 5426 synchronized (mPidsSelfLocked) { 5427 ForegroundToken cur 5428 = mForegroundProcesses.get(token.pid); 5429 if (cur != token) { 5430 return; 5431 } 5432 mForegroundProcesses.remove(token.pid); 5433 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5434 if (pr == null) { 5435 return; 5436 } 5437 pr.forcingToForeground = null; 5438 pr.foregroundServices = false; 5439 } 5440 updateOomAdjLocked(); 5441 } 5442 } 5443 5444 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5445 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5446 "setProcessForeground()"); 5447 synchronized(this) { 5448 boolean changed = false; 5449 5450 synchronized (mPidsSelfLocked) { 5451 ProcessRecord pr = mPidsSelfLocked.get(pid); 5452 if (pr == null) { 5453 Log.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5454 return; 5455 } 5456 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5457 if (oldToken != null) { 5458 oldToken.token.unlinkToDeath(oldToken, 0); 5459 mForegroundProcesses.remove(pid); 5460 pr.forcingToForeground = null; 5461 changed = true; 5462 } 5463 if (isForeground && token != null) { 5464 ForegroundToken newToken = new ForegroundToken() { 5465 public void binderDied() { 5466 foregroundTokenDied(this); 5467 } 5468 }; 5469 newToken.pid = pid; 5470 newToken.token = token; 5471 try { 5472 token.linkToDeath(newToken, 0); 5473 mForegroundProcesses.put(pid, newToken); 5474 pr.forcingToForeground = token; 5475 changed = true; 5476 } catch (RemoteException e) { 5477 // If the process died while doing this, we will later 5478 // do the cleanup with the process death link. 5479 } 5480 } 5481 } 5482 5483 if (changed) { 5484 updateOomAdjLocked(); 5485 } 5486 } 5487 } 5488 5489 // ========================================================= 5490 // PERMISSIONS 5491 // ========================================================= 5492 5493 static class PermissionController extends IPermissionController.Stub { 5494 ActivityManagerService mActivityManagerService; 5495 PermissionController(ActivityManagerService activityManagerService) { 5496 mActivityManagerService = activityManagerService; 5497 } 5498 5499 public boolean checkPermission(String permission, int pid, int uid) { 5500 return mActivityManagerService.checkPermission(permission, pid, 5501 uid) == PackageManager.PERMISSION_GRANTED; 5502 } 5503 } 5504 5505 /** 5506 * This can be called with or without the global lock held. 5507 */ 5508 int checkComponentPermission(String permission, int pid, int uid, 5509 int reqUid) { 5510 // We might be performing an operation on behalf of an indirect binder 5511 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5512 // client identity accordingly before proceeding. 5513 Identity tlsIdentity = sCallerIdentity.get(); 5514 if (tlsIdentity != null) { 5515 Log.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5516 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5517 uid = tlsIdentity.uid; 5518 pid = tlsIdentity.pid; 5519 } 5520 5521 // Root, system server and our own process get to do everything. 5522 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID || 5523 !Process.supportsProcesses()) { 5524 return PackageManager.PERMISSION_GRANTED; 5525 } 5526 // If the target requires a specific UID, always fail for others. 5527 if (reqUid >= 0 && uid != reqUid) { 5528 return PackageManager.PERMISSION_DENIED; 5529 } 5530 if (permission == null) { 5531 return PackageManager.PERMISSION_GRANTED; 5532 } 5533 try { 5534 return ActivityThread.getPackageManager() 5535 .checkUidPermission(permission, uid); 5536 } catch (RemoteException e) { 5537 // Should never happen, but if it does... deny! 5538 Log.e(TAG, "PackageManager is dead?!?", e); 5539 } 5540 return PackageManager.PERMISSION_DENIED; 5541 } 5542 5543 /** 5544 * As the only public entry point for permissions checking, this method 5545 * can enforce the semantic that requesting a check on a null global 5546 * permission is automatically denied. (Internally a null permission 5547 * string is used when calling {@link #checkComponentPermission} in cases 5548 * when only uid-based security is needed.) 5549 * 5550 * This can be called with or without the global lock held. 5551 */ 5552 public int checkPermission(String permission, int pid, int uid) { 5553 if (permission == null) { 5554 return PackageManager.PERMISSION_DENIED; 5555 } 5556 return checkComponentPermission(permission, pid, uid, -1); 5557 } 5558 5559 /** 5560 * Binder IPC calls go through the public entry point. 5561 * This can be called with or without the global lock held. 5562 */ 5563 int checkCallingPermission(String permission) { 5564 return checkPermission(permission, 5565 Binder.getCallingPid(), 5566 Binder.getCallingUid()); 5567 } 5568 5569 /** 5570 * This can be called with or without the global lock held. 5571 */ 5572 void enforceCallingPermission(String permission, String func) { 5573 if (checkCallingPermission(permission) 5574 == PackageManager.PERMISSION_GRANTED) { 5575 return; 5576 } 5577 5578 String msg = "Permission Denial: " + func + " from pid=" 5579 + Binder.getCallingPid() 5580 + ", uid=" + Binder.getCallingUid() 5581 + " requires " + permission; 5582 Log.w(TAG, msg); 5583 throw new SecurityException(msg); 5584 } 5585 5586 private final boolean checkHoldingPermissionsLocked(IPackageManager pm, 5587 ProviderInfo pi, int uid, int modeFlags) { 5588 try { 5589 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5590 if ((pi.readPermission != null) && 5591 (pm.checkUidPermission(pi.readPermission, uid) 5592 != PackageManager.PERMISSION_GRANTED)) { 5593 return false; 5594 } 5595 } 5596 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5597 if ((pi.writePermission != null) && 5598 (pm.checkUidPermission(pi.writePermission, uid) 5599 != PackageManager.PERMISSION_GRANTED)) { 5600 return false; 5601 } 5602 } 5603 return true; 5604 } catch (RemoteException e) { 5605 return false; 5606 } 5607 } 5608 5609 private final boolean checkUriPermissionLocked(Uri uri, int uid, 5610 int modeFlags) { 5611 // Root gets to do everything. 5612 if (uid == 0 || !Process.supportsProcesses()) { 5613 return true; 5614 } 5615 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5616 if (perms == null) return false; 5617 UriPermission perm = perms.get(uri); 5618 if (perm == null) return false; 5619 return (modeFlags&perm.modeFlags) == modeFlags; 5620 } 5621 5622 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5623 // Another redirected-binder-call permissions check as in 5624 // {@link checkComponentPermission}. 5625 Identity tlsIdentity = sCallerIdentity.get(); 5626 if (tlsIdentity != null) { 5627 uid = tlsIdentity.uid; 5628 pid = tlsIdentity.pid; 5629 } 5630 5631 // Our own process gets to do everything. 5632 if (pid == MY_PID) { 5633 return PackageManager.PERMISSION_GRANTED; 5634 } 5635 synchronized(this) { 5636 return checkUriPermissionLocked(uri, uid, modeFlags) 5637 ? PackageManager.PERMISSION_GRANTED 5638 : PackageManager.PERMISSION_DENIED; 5639 } 5640 } 5641 5642 private void grantUriPermissionLocked(int callingUid, 5643 String targetPkg, Uri uri, int modeFlags, HistoryRecord activity) { 5644 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5645 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5646 if (modeFlags == 0) { 5647 return; 5648 } 5649 5650 final IPackageManager pm = ActivityThread.getPackageManager(); 5651 5652 // If this is not a content: uri, we can't do anything with it. 5653 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5654 return; 5655 } 5656 5657 String name = uri.getAuthority(); 5658 ProviderInfo pi = null; 5659 ContentProviderRecord cpr 5660 = (ContentProviderRecord)mProvidersByName.get(name); 5661 if (cpr != null) { 5662 pi = cpr.info; 5663 } else { 5664 try { 5665 pi = pm.resolveContentProvider(name, 5666 PackageManager.GET_URI_PERMISSION_PATTERNS); 5667 } catch (RemoteException ex) { 5668 } 5669 } 5670 if (pi == null) { 5671 Log.w(TAG, "No content provider found for: " + name); 5672 return; 5673 } 5674 5675 int targetUid; 5676 try { 5677 targetUid = pm.getPackageUid(targetPkg); 5678 if (targetUid < 0) { 5679 return; 5680 } 5681 } catch (RemoteException ex) { 5682 return; 5683 } 5684 5685 // First... does the target actually need this permission? 5686 if (checkHoldingPermissionsLocked(pm, pi, targetUid, modeFlags)) { 5687 // No need to grant the target this permission. 5688 return; 5689 } 5690 5691 // Second... maybe someone else has already granted the 5692 // permission? 5693 if (checkUriPermissionLocked(uri, targetUid, modeFlags)) { 5694 // No need to grant the target this permission. 5695 return; 5696 } 5697 5698 // Third... is the provider allowing granting of URI permissions? 5699 if (!pi.grantUriPermissions) { 5700 throw new SecurityException("Provider " + pi.packageName 5701 + "/" + pi.name 5702 + " does not allow granting of Uri permissions (uri " 5703 + uri + ")"); 5704 } 5705 if (pi.uriPermissionPatterns != null) { 5706 final int N = pi.uriPermissionPatterns.length; 5707 boolean allowed = false; 5708 for (int i=0; i<N; i++) { 5709 if (pi.uriPermissionPatterns[i] != null 5710 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 5711 allowed = true; 5712 break; 5713 } 5714 } 5715 if (!allowed) { 5716 throw new SecurityException("Provider " + pi.packageName 5717 + "/" + pi.name 5718 + " does not allow granting of permission to path of Uri " 5719 + uri); 5720 } 5721 } 5722 5723 // Fourth... does the caller itself have permission to access 5724 // this uri? 5725 if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) { 5726 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5727 throw new SecurityException("Uid " + callingUid 5728 + " does not have permission to uri " + uri); 5729 } 5730 } 5731 5732 // Okay! So here we are: the caller has the assumed permission 5733 // to the uri, and the target doesn't. Let's now give this to 5734 // the target. 5735 5736 HashMap<Uri, UriPermission> targetUris 5737 = mGrantedUriPermissions.get(targetUid); 5738 if (targetUris == null) { 5739 targetUris = new HashMap<Uri, UriPermission>(); 5740 mGrantedUriPermissions.put(targetUid, targetUris); 5741 } 5742 5743 UriPermission perm = targetUris.get(uri); 5744 if (perm == null) { 5745 perm = new UriPermission(targetUid, uri); 5746 targetUris.put(uri, perm); 5747 5748 } 5749 perm.modeFlags |= modeFlags; 5750 if (activity == null) { 5751 perm.globalModeFlags |= modeFlags; 5752 } else if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 5753 perm.readActivities.add(activity); 5754 if (activity.readUriPermissions == null) { 5755 activity.readUriPermissions = new HashSet<UriPermission>(); 5756 } 5757 activity.readUriPermissions.add(perm); 5758 } else if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 5759 perm.writeActivities.add(activity); 5760 if (activity.writeUriPermissions == null) { 5761 activity.writeUriPermissions = new HashSet<UriPermission>(); 5762 } 5763 activity.writeUriPermissions.add(perm); 5764 } 5765 } 5766 5767 private void grantUriPermissionFromIntentLocked(int callingUid, 5768 String targetPkg, Intent intent, HistoryRecord activity) { 5769 if (intent == null) { 5770 return; 5771 } 5772 Uri data = intent.getData(); 5773 if (data == null) { 5774 return; 5775 } 5776 grantUriPermissionLocked(callingUid, targetPkg, data, 5777 intent.getFlags(), activity); 5778 } 5779 5780 public void grantUriPermission(IApplicationThread caller, String targetPkg, 5781 Uri uri, int modeFlags) { 5782 synchronized(this) { 5783 final ProcessRecord r = getRecordForAppLocked(caller); 5784 if (r == null) { 5785 throw new SecurityException("Unable to find app for caller " 5786 + caller 5787 + " when granting permission to uri " + uri); 5788 } 5789 if (targetPkg == null) { 5790 Log.w(TAG, "grantUriPermission: null target"); 5791 return; 5792 } 5793 if (uri == null) { 5794 Log.w(TAG, "grantUriPermission: null uri"); 5795 return; 5796 } 5797 5798 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags, 5799 null); 5800 } 5801 } 5802 5803 private void removeUriPermissionIfNeededLocked(UriPermission perm) { 5804 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 5805 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 5806 HashMap<Uri, UriPermission> perms 5807 = mGrantedUriPermissions.get(perm.uid); 5808 if (perms != null) { 5809 perms.remove(perm.uri); 5810 if (perms.size() == 0) { 5811 mGrantedUriPermissions.remove(perm.uid); 5812 } 5813 } 5814 } 5815 } 5816 5817 private void removeActivityUriPermissionsLocked(HistoryRecord activity) { 5818 if (activity.readUriPermissions != null) { 5819 for (UriPermission perm : activity.readUriPermissions) { 5820 perm.readActivities.remove(activity); 5821 if (perm.readActivities.size() == 0 && (perm.globalModeFlags 5822 &Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0) { 5823 perm.modeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION; 5824 removeUriPermissionIfNeededLocked(perm); 5825 } 5826 } 5827 } 5828 if (activity.writeUriPermissions != null) { 5829 for (UriPermission perm : activity.writeUriPermissions) { 5830 perm.writeActivities.remove(activity); 5831 if (perm.writeActivities.size() == 0 && (perm.globalModeFlags 5832 &Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0) { 5833 perm.modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION; 5834 removeUriPermissionIfNeededLocked(perm); 5835 } 5836 } 5837 } 5838 } 5839 5840 private void revokeUriPermissionLocked(int callingUid, Uri uri, 5841 int modeFlags) { 5842 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5843 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5844 if (modeFlags == 0) { 5845 return; 5846 } 5847 5848 final IPackageManager pm = ActivityThread.getPackageManager(); 5849 5850 final String authority = uri.getAuthority(); 5851 ProviderInfo pi = null; 5852 ContentProviderRecord cpr 5853 = (ContentProviderRecord)mProvidersByName.get(authority); 5854 if (cpr != null) { 5855 pi = cpr.info; 5856 } else { 5857 try { 5858 pi = pm.resolveContentProvider(authority, 5859 PackageManager.GET_URI_PERMISSION_PATTERNS); 5860 } catch (RemoteException ex) { 5861 } 5862 } 5863 if (pi == null) { 5864 Log.w(TAG, "No content provider found for: " + authority); 5865 return; 5866 } 5867 5868 // Does the caller have this permission on the URI? 5869 if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) { 5870 // Right now, if you are not the original owner of the permission, 5871 // you are not allowed to revoke it. 5872 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 5873 throw new SecurityException("Uid " + callingUid 5874 + " does not have permission to uri " + uri); 5875 //} 5876 } 5877 5878 // Go through all of the permissions and remove any that match. 5879 final List<String> SEGMENTS = uri.getPathSegments(); 5880 if (SEGMENTS != null) { 5881 final int NS = SEGMENTS.size(); 5882 int N = mGrantedUriPermissions.size(); 5883 for (int i=0; i<N; i++) { 5884 HashMap<Uri, UriPermission> perms 5885 = mGrantedUriPermissions.valueAt(i); 5886 Iterator<UriPermission> it = perms.values().iterator(); 5887 toploop: 5888 while (it.hasNext()) { 5889 UriPermission perm = it.next(); 5890 Uri targetUri = perm.uri; 5891 if (!authority.equals(targetUri.getAuthority())) { 5892 continue; 5893 } 5894 List<String> targetSegments = targetUri.getPathSegments(); 5895 if (targetSegments == null) { 5896 continue; 5897 } 5898 if (targetSegments.size() < NS) { 5899 continue; 5900 } 5901 for (int j=0; j<NS; j++) { 5902 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 5903 continue toploop; 5904 } 5905 } 5906 perm.clearModes(modeFlags); 5907 if (perm.modeFlags == 0) { 5908 it.remove(); 5909 } 5910 } 5911 if (perms.size() == 0) { 5912 mGrantedUriPermissions.remove( 5913 mGrantedUriPermissions.keyAt(i)); 5914 N--; 5915 i--; 5916 } 5917 } 5918 } 5919 } 5920 5921 public void revokeUriPermission(IApplicationThread caller, Uri uri, 5922 int modeFlags) { 5923 synchronized(this) { 5924 final ProcessRecord r = getRecordForAppLocked(caller); 5925 if (r == null) { 5926 throw new SecurityException("Unable to find app for caller " 5927 + caller 5928 + " when revoking permission to uri " + uri); 5929 } 5930 if (uri == null) { 5931 Log.w(TAG, "revokeUriPermission: null uri"); 5932 return; 5933 } 5934 5935 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5936 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5937 if (modeFlags == 0) { 5938 return; 5939 } 5940 5941 final IPackageManager pm = ActivityThread.getPackageManager(); 5942 5943 final String authority = uri.getAuthority(); 5944 ProviderInfo pi = null; 5945 ContentProviderRecord cpr 5946 = (ContentProviderRecord)mProvidersByName.get(authority); 5947 if (cpr != null) { 5948 pi = cpr.info; 5949 } else { 5950 try { 5951 pi = pm.resolveContentProvider(authority, 5952 PackageManager.GET_URI_PERMISSION_PATTERNS); 5953 } catch (RemoteException ex) { 5954 } 5955 } 5956 if (pi == null) { 5957 Log.w(TAG, "No content provider found for: " + authority); 5958 return; 5959 } 5960 5961 revokeUriPermissionLocked(r.info.uid, uri, modeFlags); 5962 } 5963 } 5964 5965 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 5966 synchronized (this) { 5967 ProcessRecord app = 5968 who != null ? getRecordForAppLocked(who) : null; 5969 if (app == null) return; 5970 5971 Message msg = Message.obtain(); 5972 msg.what = WAIT_FOR_DEBUGGER_MSG; 5973 msg.obj = app; 5974 msg.arg1 = waiting ? 1 : 0; 5975 mHandler.sendMessage(msg); 5976 } 5977 } 5978 5979 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 5980 outInfo.availMem = Process.getFreeMemory(); 5981 outInfo.threshold = HOME_APP_MEM; 5982 outInfo.lowMemory = outInfo.availMem < 5983 (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2)); 5984 } 5985 5986 // ========================================================= 5987 // TASK MANAGEMENT 5988 // ========================================================= 5989 5990 public List getTasks(int maxNum, int flags, 5991 IThumbnailReceiver receiver) { 5992 ArrayList list = new ArrayList(); 5993 5994 PendingThumbnailsRecord pending = null; 5995 IApplicationThread topThumbnail = null; 5996 HistoryRecord topRecord = null; 5997 5998 synchronized(this) { 5999 if (localLOGV) Log.v( 6000 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6001 + ", receiver=" + receiver); 6002 6003 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6004 != PackageManager.PERMISSION_GRANTED) { 6005 if (receiver != null) { 6006 // If the caller wants to wait for pending thumbnails, 6007 // it ain't gonna get them. 6008 try { 6009 receiver.finished(); 6010 } catch (RemoteException ex) { 6011 } 6012 } 6013 String msg = "Permission Denial: getTasks() from pid=" 6014 + Binder.getCallingPid() 6015 + ", uid=" + Binder.getCallingUid() 6016 + " requires " + android.Manifest.permission.GET_TASKS; 6017 Log.w(TAG, msg); 6018 throw new SecurityException(msg); 6019 } 6020 6021 int pos = mHistory.size()-1; 6022 HistoryRecord next = 6023 pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null; 6024 HistoryRecord top = null; 6025 CharSequence topDescription = null; 6026 TaskRecord curTask = null; 6027 int numActivities = 0; 6028 int numRunning = 0; 6029 while (pos >= 0 && maxNum > 0) { 6030 final HistoryRecord r = next; 6031 pos--; 6032 next = pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null; 6033 6034 // Initialize state for next task if needed. 6035 if (top == null || 6036 (top.state == ActivityState.INITIALIZING 6037 && top.task == r.task)) { 6038 top = r; 6039 topDescription = r.description; 6040 curTask = r.task; 6041 numActivities = numRunning = 0; 6042 } 6043 6044 // Add 'r' into the current task. 6045 numActivities++; 6046 if (r.app != null && r.app.thread != null) { 6047 numRunning++; 6048 } 6049 if (topDescription == null) { 6050 topDescription = r.description; 6051 } 6052 6053 if (localLOGV) Log.v( 6054 TAG, r.intent.getComponent().flattenToShortString() 6055 + ": task=" + r.task); 6056 6057 // If the next one is a different task, generate a new 6058 // TaskInfo entry for what we have. 6059 if (next == null || next.task != curTask) { 6060 ActivityManager.RunningTaskInfo ci 6061 = new ActivityManager.RunningTaskInfo(); 6062 ci.id = curTask.taskId; 6063 ci.baseActivity = r.intent.getComponent(); 6064 ci.topActivity = top.intent.getComponent(); 6065 ci.thumbnail = top.thumbnail; 6066 ci.description = topDescription; 6067 ci.numActivities = numActivities; 6068 ci.numRunning = numRunning; 6069 //System.out.println( 6070 // "#" + maxNum + ": " + " descr=" + ci.description); 6071 if (ci.thumbnail == null && receiver != null) { 6072 if (localLOGV) Log.v( 6073 TAG, "State=" + top.state + "Idle=" + top.idle 6074 + " app=" + top.app 6075 + " thr=" + (top.app != null ? top.app.thread : null)); 6076 if (top.state == ActivityState.RESUMED 6077 || top.state == ActivityState.PAUSING) { 6078 if (top.idle && top.app != null 6079 && top.app.thread != null) { 6080 topRecord = top; 6081 topThumbnail = top.app.thread; 6082 } else { 6083 top.thumbnailNeeded = true; 6084 } 6085 } 6086 if (pending == null) { 6087 pending = new PendingThumbnailsRecord(receiver); 6088 } 6089 pending.pendingRecords.add(top); 6090 } 6091 list.add(ci); 6092 maxNum--; 6093 top = null; 6094 } 6095 } 6096 6097 if (pending != null) { 6098 mPendingThumbnails.add(pending); 6099 } 6100 } 6101 6102 if (localLOGV) Log.v(TAG, "We have pending thumbnails: " + pending); 6103 6104 if (topThumbnail != null) { 6105 if (localLOGV) Log.v(TAG, "Requesting top thumbnail"); 6106 try { 6107 topThumbnail.requestThumbnail(topRecord); 6108 } catch (Exception e) { 6109 Log.w(TAG, "Exception thrown when requesting thumbnail", e); 6110 sendPendingThumbnail(null, topRecord, null, null, true); 6111 } 6112 } 6113 6114 if (pending == null && receiver != null) { 6115 // In this case all thumbnails were available and the client 6116 // is being asked to be told when the remaining ones come in... 6117 // which is unusually, since the top-most currently running 6118 // activity should never have a canned thumbnail! Oh well. 6119 try { 6120 receiver.finished(); 6121 } catch (RemoteException ex) { 6122 } 6123 } 6124 6125 return list; 6126 } 6127 6128 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6129 int flags) { 6130 synchronized (this) { 6131 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6132 "getRecentTasks()"); 6133 6134 final int N = mRecentTasks.size(); 6135 ArrayList<ActivityManager.RecentTaskInfo> res 6136 = new ArrayList<ActivityManager.RecentTaskInfo>( 6137 maxNum < N ? maxNum : N); 6138 for (int i=0; i<N && maxNum > 0; i++) { 6139 TaskRecord tr = mRecentTasks.get(i); 6140 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6141 || (tr.intent == null) 6142 || ((tr.intent.getFlags() 6143 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6144 ActivityManager.RecentTaskInfo rti 6145 = new ActivityManager.RecentTaskInfo(); 6146 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6147 rti.baseIntent = new Intent( 6148 tr.intent != null ? tr.intent : tr.affinityIntent); 6149 rti.origActivity = tr.origActivity; 6150 res.add(rti); 6151 maxNum--; 6152 } 6153 } 6154 return res; 6155 } 6156 } 6157 6158 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 6159 int j; 6160 TaskRecord startTask = ((HistoryRecord)mHistory.get(startIndex)).task; 6161 TaskRecord jt = startTask; 6162 6163 // First look backwards 6164 for (j=startIndex-1; j>=0; j--) { 6165 HistoryRecord r = (HistoryRecord)mHistory.get(j); 6166 if (r.task != jt) { 6167 jt = r.task; 6168 if (affinity.equals(jt.affinity)) { 6169 return j; 6170 } 6171 } 6172 } 6173 6174 // Now look forwards 6175 final int N = mHistory.size(); 6176 jt = startTask; 6177 for (j=startIndex+1; j<N; j++) { 6178 HistoryRecord r = (HistoryRecord)mHistory.get(j); 6179 if (r.task != jt) { 6180 if (affinity.equals(jt.affinity)) { 6181 return j; 6182 } 6183 jt = r.task; 6184 } 6185 } 6186 6187 // Might it be at the top? 6188 if (affinity.equals(((HistoryRecord)mHistory.get(N-1)).task.affinity)) { 6189 return N-1; 6190 } 6191 6192 return -1; 6193 } 6194 6195 /** 6196 * Perform a reset of the given task, if needed as part of launching it. 6197 * Returns the new HistoryRecord at the top of the task. 6198 */ 6199 private final HistoryRecord resetTaskIfNeededLocked(HistoryRecord taskTop, 6200 HistoryRecord newActivity) { 6201 boolean forceReset = (newActivity.info.flags 6202 &ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0; 6203 if (taskTop.task.getInactiveDuration() > ACTIVITY_INACTIVE_RESET_TIME) { 6204 if ((newActivity.info.flags 6205 &ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE) == 0) { 6206 forceReset = true; 6207 } 6208 } 6209 6210 final TaskRecord task = taskTop.task; 6211 6212 // We are going to move through the history list so that we can look 6213 // at each activity 'target' with 'below' either the interesting 6214 // activity immediately below it in the stack or null. 6215 HistoryRecord target = null; 6216 int targetI = 0; 6217 int taskTopI = -1; 6218 int replyChainEnd = -1; 6219 int lastReparentPos = -1; 6220 for (int i=mHistory.size()-1; i>=-1; i--) { 6221 HistoryRecord below = i >= 0 ? (HistoryRecord)mHistory.get(i) : null; 6222 6223 if (below != null && below.finishing) { 6224 continue; 6225 } 6226 if (target == null) { 6227 target = below; 6228 targetI = i; 6229 // If we were in the middle of a reply chain before this 6230 // task, it doesn't appear like the root of the chain wants 6231 // anything interesting, so drop it. 6232 replyChainEnd = -1; 6233 continue; 6234 } 6235 6236 final int flags = target.info.flags; 6237 6238 final boolean finishOnTaskLaunch = 6239 (flags&ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0; 6240 final boolean allowTaskReparenting = 6241 (flags&ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0; 6242 6243 if (target.task == task) { 6244 // We are inside of the task being reset... we'll either 6245 // finish this activity, push it out for another task, 6246 // or leave it as-is. We only do this 6247 // for activities that are not the root of the task (since 6248 // if we finish the root, we may no longer have the task!). 6249 if (taskTopI < 0) { 6250 taskTopI = targetI; 6251 } 6252 if (below != null && below.task == task) { 6253 final boolean clearWhenTaskReset = 6254 (target.intent.getFlags() 6255 &Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0; 6256 if (!finishOnTaskLaunch && !clearWhenTaskReset && target.resultTo != null) { 6257 // If this activity is sending a reply to a previous 6258 // activity, we can't do anything with it now until 6259 // we reach the start of the reply chain. 6260 // XXX note that we are assuming the result is always 6261 // to the previous activity, which is almost always 6262 // the case but we really shouldn't count on. 6263 if (replyChainEnd < 0) { 6264 replyChainEnd = targetI; 6265 } 6266 } else if (!finishOnTaskLaunch && !clearWhenTaskReset && allowTaskReparenting 6267 && target.taskAffinity != null 6268 && !target.taskAffinity.equals(task.affinity)) { 6269 // If this activity has an affinity for another 6270 // task, then we need to move it out of here. We will 6271 // move it as far out of the way as possible, to the 6272 // bottom of the activity stack. This also keeps it 6273 // correctly ordered with any activities we previously 6274 // moved. 6275 HistoryRecord p = (HistoryRecord)mHistory.get(0); 6276 if (target.taskAffinity != null 6277 && target.taskAffinity.equals(p.task.affinity)) { 6278 // If the activity currently at the bottom has the 6279 // same task affinity as the one we are moving, 6280 // then merge it into the same task. 6281 target.task = p.task; 6282 if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target 6283 + " out to bottom task " + p.task); 6284 } else { 6285 mCurTask++; 6286 if (mCurTask <= 0) { 6287 mCurTask = 1; 6288 } 6289 target.task = new TaskRecord(mCurTask, target.info, null, 6290 (target.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0); 6291 target.task.affinityIntent = target.intent; 6292 if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target 6293 + " out to new task " + target.task); 6294 } 6295 mWindowManager.setAppGroupId(target, task.taskId); 6296 if (replyChainEnd < 0) { 6297 replyChainEnd = targetI; 6298 } 6299 int dstPos = 0; 6300 for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) { 6301 p = (HistoryRecord)mHistory.get(srcPos); 6302 if (p.finishing) { 6303 continue; 6304 } 6305 if (DEBUG_TASKS) Log.v(TAG, "Pushing next activity " + p 6306 + " out to target's task " + target.task); 6307 task.numActivities--; 6308 p.task = target.task; 6309 target.task.numActivities++; 6310 mHistory.remove(srcPos); 6311 mHistory.add(dstPos, p); 6312 mWindowManager.moveAppToken(dstPos, p); 6313 mWindowManager.setAppGroupId(p, p.task.taskId); 6314 dstPos++; 6315 if (VALIDATE_TOKENS) { 6316 mWindowManager.validateAppTokens(mHistory); 6317 } 6318 i++; 6319 } 6320 if (taskTop == p) { 6321 taskTop = below; 6322 } 6323 if (taskTopI == replyChainEnd) { 6324 taskTopI = -1; 6325 } 6326 replyChainEnd = -1; 6327 addRecentTask(target.task); 6328 } else if (forceReset || finishOnTaskLaunch 6329 || clearWhenTaskReset) { 6330 // If the activity should just be removed -- either 6331 // because it asks for it, or the task should be 6332 // cleared -- then finish it and anything that is 6333 // part of its reply chain. 6334 if (clearWhenTaskReset) { 6335 // In this case, we want to finish this activity 6336 // and everything above it, so be sneaky and pretend 6337 // like these are all in the reply chain. 6338 replyChainEnd = targetI+1; 6339 while (replyChainEnd < mHistory.size() && 6340 ((HistoryRecord)mHistory.get( 6341 replyChainEnd)).task == task) { 6342 replyChainEnd++; 6343 } 6344 replyChainEnd--; 6345 } else if (replyChainEnd < 0) { 6346 replyChainEnd = targetI; 6347 } 6348 HistoryRecord p = null; 6349 for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) { 6350 p = (HistoryRecord)mHistory.get(srcPos); 6351 if (p.finishing) { 6352 continue; 6353 } 6354 if (finishActivityLocked(p, srcPos, 6355 Activity.RESULT_CANCELED, null, "reset")) { 6356 replyChainEnd--; 6357 srcPos--; 6358 } 6359 } 6360 if (taskTop == p) { 6361 taskTop = below; 6362 } 6363 if (taskTopI == replyChainEnd) { 6364 taskTopI = -1; 6365 } 6366 replyChainEnd = -1; 6367 } else { 6368 // If we were in the middle of a chain, well the 6369 // activity that started it all doesn't want anything 6370 // special, so leave it all as-is. 6371 replyChainEnd = -1; 6372 } 6373 } else { 6374 // Reached the bottom of the task -- any reply chain 6375 // should be left as-is. 6376 replyChainEnd = -1; 6377 } 6378 6379 } else if (target.resultTo != null) { 6380 // If this activity is sending a reply to a previous 6381 // activity, we can't do anything with it now until 6382 // we reach the start of the reply chain. 6383 // XXX note that we are assuming the result is always 6384 // to the previous activity, which is almost always 6385 // the case but we really shouldn't count on. 6386 if (replyChainEnd < 0) { 6387 replyChainEnd = targetI; 6388 } 6389 6390 } else if (taskTopI >= 0 && allowTaskReparenting 6391 && task.affinity != null 6392 && task.affinity.equals(target.taskAffinity)) { 6393 // We are inside of another task... if this activity has 6394 // an affinity for our task, then either remove it if we are 6395 // clearing or move it over to our task. Note that 6396 // we currently punt on the case where we are resetting a 6397 // task that is not at the top but who has activities above 6398 // with an affinity to it... this is really not a normal 6399 // case, and we will need to later pull that task to the front 6400 // and usually at that point we will do the reset and pick 6401 // up those remaining activities. (This only happens if 6402 // someone starts an activity in a new task from an activity 6403 // in a task that is not currently on top.) 6404 if (forceReset || finishOnTaskLaunch) { 6405 if (replyChainEnd < 0) { 6406 replyChainEnd = targetI; 6407 } 6408 HistoryRecord p = null; 6409 for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) { 6410 p = (HistoryRecord)mHistory.get(srcPos); 6411 if (p.finishing) { 6412 continue; 6413 } 6414 if (finishActivityLocked(p, srcPos, 6415 Activity.RESULT_CANCELED, null, "reset")) { 6416 taskTopI--; 6417 lastReparentPos--; 6418 replyChainEnd--; 6419 srcPos--; 6420 } 6421 } 6422 replyChainEnd = -1; 6423 } else { 6424 if (replyChainEnd < 0) { 6425 replyChainEnd = targetI; 6426 } 6427 for (int srcPos=replyChainEnd; srcPos>=targetI; srcPos--) { 6428 HistoryRecord p = (HistoryRecord)mHistory.get(srcPos); 6429 if (p.finishing) { 6430 continue; 6431 } 6432 if (lastReparentPos < 0) { 6433 lastReparentPos = taskTopI; 6434 taskTop = p; 6435 } else { 6436 lastReparentPos--; 6437 } 6438 mHistory.remove(srcPos); 6439 p.task.numActivities--; 6440 p.task = task; 6441 mHistory.add(lastReparentPos, p); 6442 if (DEBUG_TASKS) Log.v(TAG, "Pulling activity " + p 6443 + " in to resetting task " + task); 6444 task.numActivities++; 6445 mWindowManager.moveAppToken(lastReparentPos, p); 6446 mWindowManager.setAppGroupId(p, p.task.taskId); 6447 if (VALIDATE_TOKENS) { 6448 mWindowManager.validateAppTokens(mHistory); 6449 } 6450 } 6451 replyChainEnd = -1; 6452 6453 // Now we've moved it in to place... but what if this is 6454 // a singleTop activity and we have put it on top of another 6455 // instance of the same activity? Then we drop the instance 6456 // below so it remains singleTop. 6457 if (target.info.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) { 6458 for (int j=lastReparentPos-1; j>=0; j--) { 6459 HistoryRecord p = (HistoryRecord)mHistory.get(j); 6460 if (p.finishing) { 6461 continue; 6462 } 6463 if (p.intent.getComponent().equals(target.intent.getComponent())) { 6464 if (finishActivityLocked(p, j, 6465 Activity.RESULT_CANCELED, null, "replace")) { 6466 taskTopI--; 6467 lastReparentPos--; 6468 } 6469 } 6470 } 6471 } 6472 } 6473 } 6474 6475 target = below; 6476 targetI = i; 6477 } 6478 6479 return taskTop; 6480 } 6481 6482 /** 6483 * TODO: Add mWatcher hook 6484 */ 6485 public void moveTaskToFront(int task) { 6486 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6487 "moveTaskToFront()"); 6488 6489 synchronized(this) { 6490 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6491 Binder.getCallingUid(), "Task to front")) { 6492 return; 6493 } 6494 final long origId = Binder.clearCallingIdentity(); 6495 try { 6496 int N = mRecentTasks.size(); 6497 for (int i=0; i<N; i++) { 6498 TaskRecord tr = mRecentTasks.get(i); 6499 if (tr.taskId == task) { 6500 moveTaskToFrontLocked(tr); 6501 return; 6502 } 6503 } 6504 for (int i=mHistory.size()-1; i>=0; i--) { 6505 HistoryRecord hr = (HistoryRecord)mHistory.get(i); 6506 if (hr.task.taskId == task) { 6507 moveTaskToFrontLocked(hr.task); 6508 return; 6509 } 6510 } 6511 } finally { 6512 Binder.restoreCallingIdentity(origId); 6513 } 6514 } 6515 } 6516 6517 private final void moveTaskToFrontLocked(TaskRecord tr) { 6518 if (DEBUG_SWITCH) Log.v(TAG, "moveTaskToFront: " + tr); 6519 6520 final int task = tr.taskId; 6521 int top = mHistory.size()-1; 6522 6523 if (top < 0 || ((HistoryRecord)mHistory.get(top)).task.taskId == task) { 6524 // nothing to do! 6525 return; 6526 } 6527 6528 if (DEBUG_TRANSITION) Log.v(TAG, 6529 "Prepare to front transition: task=" + tr); 6530 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT); 6531 6532 ArrayList moved = new ArrayList(); 6533 6534 // Applying the affinities may have removed entries from the history, 6535 // so get the size again. 6536 top = mHistory.size()-1; 6537 int pos = top; 6538 6539 // Shift all activities with this task up to the top 6540 // of the stack, keeping them in the same internal order. 6541 while (pos >= 0) { 6542 HistoryRecord r = (HistoryRecord)mHistory.get(pos); 6543 if (localLOGV) Log.v( 6544 TAG, "At " + pos + " ckp " + r.task + ": " + r); 6545 boolean first = true; 6546 if (r.task.taskId == task) { 6547 if (localLOGV) Log.v(TAG, "Removing and adding at " + top); 6548 mHistory.remove(pos); 6549 mHistory.add(top, r); 6550 moved.add(0, r); 6551 top--; 6552 if (first) { 6553 addRecentTask(r.task); 6554 first = false; 6555 } 6556 } 6557 pos--; 6558 } 6559 6560 mWindowManager.moveAppTokensToTop(moved); 6561 if (VALIDATE_TOKENS) { 6562 mWindowManager.validateAppTokens(mHistory); 6563 } 6564 6565 finishTaskMove(task); 6566 EventLog.writeEvent(LOG_TASK_TO_FRONT, task); 6567 } 6568 6569 private final void finishTaskMove(int task) { 6570 resumeTopActivityLocked(null); 6571 } 6572 6573 public void moveTaskToBack(int task) { 6574 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6575 "moveTaskToBack()"); 6576 6577 synchronized(this) { 6578 if (mResumedActivity != null && mResumedActivity.task.taskId == task) { 6579 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6580 Binder.getCallingUid(), "Task to back")) { 6581 return; 6582 } 6583 } 6584 final long origId = Binder.clearCallingIdentity(); 6585 moveTaskToBackLocked(task); 6586 Binder.restoreCallingIdentity(origId); 6587 } 6588 } 6589 6590 /** 6591 * Moves an activity, and all of the other activities within the same task, to the bottom 6592 * of the history stack. The activity's order within the task is unchanged. 6593 * 6594 * @param token A reference to the activity we wish to move 6595 * @param nonRoot If false then this only works if the activity is the root 6596 * of a task; if true it will work for any activity in a task. 6597 * @return Returns true if the move completed, false if not. 6598 */ 6599 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 6600 synchronized(this) { 6601 final long origId = Binder.clearCallingIdentity(); 6602 int taskId = getTaskForActivityLocked(token, !nonRoot); 6603 if (taskId >= 0) { 6604 return moveTaskToBackLocked(taskId); 6605 } 6606 Binder.restoreCallingIdentity(origId); 6607 } 6608 return false; 6609 } 6610 6611 /** 6612 * Worker method for rearranging history stack. Implements the function of moving all 6613 * activities for a specific task (gathering them if disjoint) into a single group at the 6614 * bottom of the stack. 6615 * 6616 * If a watcher is installed, the action is preflighted and the watcher has an opportunity 6617 * to premeptively cancel the move. 6618 * 6619 * @param task The taskId to collect and move to the bottom. 6620 * @return Returns true if the move completed, false if not. 6621 */ 6622 private final boolean moveTaskToBackLocked(int task) { 6623 Log.i(TAG, "moveTaskToBack: " + task); 6624 6625 // If we have a watcher, preflight the move before committing to it. First check 6626 // for *other* available tasks, but if none are available, then try again allowing the 6627 // current task to be selected. 6628 if (mWatcher != null) { 6629 HistoryRecord next = topRunningActivityLocked(null, task); 6630 if (next == null) { 6631 next = topRunningActivityLocked(null, 0); 6632 } 6633 if (next != null) { 6634 // ask watcher if this is allowed 6635 boolean moveOK = true; 6636 try { 6637 moveOK = mWatcher.activityResuming(next.packageName); 6638 } catch (RemoteException e) { 6639 mWatcher = null; 6640 } 6641 if (!moveOK) { 6642 return false; 6643 } 6644 } 6645 } 6646 6647 ArrayList moved = new ArrayList(); 6648 6649 if (DEBUG_TRANSITION) Log.v(TAG, 6650 "Prepare to back transition: task=" + task); 6651 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_BACK); 6652 6653 final int N = mHistory.size(); 6654 int bottom = 0; 6655 int pos = 0; 6656 6657 // Shift all activities with this task down to the bottom 6658 // of the stack, keeping them in the same internal order. 6659 while (pos < N) { 6660 HistoryRecord r = (HistoryRecord)mHistory.get(pos); 6661 if (localLOGV) Log.v( 6662 TAG, "At " + pos + " ckp " + r.task + ": " + r); 6663 if (r.task.taskId == task) { 6664 if (localLOGV) Log.v(TAG, "Removing and adding at " + (N-1)); 6665 mHistory.remove(pos); 6666 mHistory.add(bottom, r); 6667 moved.add(r); 6668 bottom++; 6669 } 6670 pos++; 6671 } 6672 6673 mWindowManager.moveAppTokensToBottom(moved); 6674 if (VALIDATE_TOKENS) { 6675 mWindowManager.validateAppTokens(mHistory); 6676 } 6677 6678 finishTaskMove(task); 6679 return true; 6680 } 6681 6682 public void moveTaskBackwards(int task) { 6683 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6684 "moveTaskBackwards()"); 6685 6686 synchronized(this) { 6687 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6688 Binder.getCallingUid(), "Task backwards")) { 6689 return; 6690 } 6691 final long origId = Binder.clearCallingIdentity(); 6692 moveTaskBackwardsLocked(task); 6693 Binder.restoreCallingIdentity(origId); 6694 } 6695 } 6696 6697 private final void moveTaskBackwardsLocked(int task) { 6698 Log.e(TAG, "moveTaskBackwards not yet implemented!"); 6699 } 6700 6701 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 6702 synchronized(this) { 6703 return getTaskForActivityLocked(token, onlyRoot); 6704 } 6705 } 6706 6707 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 6708 final int N = mHistory.size(); 6709 TaskRecord lastTask = null; 6710 for (int i=0; i<N; i++) { 6711 HistoryRecord r = (HistoryRecord)mHistory.get(i); 6712 if (r == token) { 6713 if (!onlyRoot || lastTask != r.task) { 6714 return r.task.taskId; 6715 } 6716 return -1; 6717 } 6718 lastTask = r.task; 6719 } 6720 6721 return -1; 6722 } 6723 6724 /** 6725 * Returns the top activity in any existing task matching the given 6726 * Intent. Returns null if no such task is found. 6727 */ 6728 private HistoryRecord findTaskLocked(Intent intent, ActivityInfo info) { 6729 ComponentName cls = intent.getComponent(); 6730 if (info.targetActivity != null) { 6731 cls = new ComponentName(info.packageName, info.targetActivity); 6732 } 6733 6734 TaskRecord cp = null; 6735 6736 final int N = mHistory.size(); 6737 for (int i=(N-1); i>=0; i--) { 6738 HistoryRecord r = (HistoryRecord)mHistory.get(i); 6739 if (!r.finishing && r.task != cp 6740 && r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 6741 cp = r.task; 6742 //Log.i(TAG, "Comparing existing cls=" + r.task.intent.getComponent().flattenToShortString() 6743 // + "/aff=" + r.task.affinity + " to new cls=" 6744 // + intent.getComponent().flattenToShortString() + "/aff=" + taskAffinity); 6745 if (r.task.affinity != null) { 6746 if (r.task.affinity.equals(info.taskAffinity)) { 6747 //Log.i(TAG, "Found matching affinity!"); 6748 return r; 6749 } 6750 } else if (r.task.intent != null 6751 && r.task.intent.getComponent().equals(cls)) { 6752 //Log.i(TAG, "Found matching class!"); 6753 //dump(); 6754 //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent); 6755 return r; 6756 } else if (r.task.affinityIntent != null 6757 && r.task.affinityIntent.getComponent().equals(cls)) { 6758 //Log.i(TAG, "Found matching class!"); 6759 //dump(); 6760 //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent); 6761 return r; 6762 } 6763 } 6764 } 6765 6766 return null; 6767 } 6768 6769 /** 6770 * Returns the first activity (starting from the top of the stack) that 6771 * is the same as the given activity. Returns null if no such activity 6772 * is found. 6773 */ 6774 private HistoryRecord findActivityLocked(Intent intent, ActivityInfo info) { 6775 ComponentName cls = intent.getComponent(); 6776 if (info.targetActivity != null) { 6777 cls = new ComponentName(info.packageName, info.targetActivity); 6778 } 6779 6780 final int N = mHistory.size(); 6781 for (int i=(N-1); i>=0; i--) { 6782 HistoryRecord r = (HistoryRecord)mHistory.get(i); 6783 if (!r.finishing) { 6784 if (r.intent.getComponent().equals(cls)) { 6785 //Log.i(TAG, "Found matching class!"); 6786 //dump(); 6787 //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent); 6788 return r; 6789 } 6790 } 6791 } 6792 6793 return null; 6794 } 6795 6796 public void finishOtherInstances(IBinder token, ComponentName className) { 6797 synchronized(this) { 6798 final long origId = Binder.clearCallingIdentity(); 6799 6800 int N = mHistory.size(); 6801 TaskRecord lastTask = null; 6802 for (int i=0; i<N; i++) { 6803 HistoryRecord r = (HistoryRecord)mHistory.get(i); 6804 if (r.realActivity.equals(className) 6805 && r != token && lastTask != r.task) { 6806 if (finishActivityLocked(r, i, Activity.RESULT_CANCELED, 6807 null, "others")) { 6808 i--; 6809 N--; 6810 } 6811 } 6812 lastTask = r.task; 6813 } 6814 6815 Binder.restoreCallingIdentity(origId); 6816 } 6817 } 6818 6819 // ========================================================= 6820 // THUMBNAILS 6821 // ========================================================= 6822 6823 public void reportThumbnail(IBinder token, 6824 Bitmap thumbnail, CharSequence description) { 6825 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 6826 final long origId = Binder.clearCallingIdentity(); 6827 sendPendingThumbnail(null, token, thumbnail, description, true); 6828 Binder.restoreCallingIdentity(origId); 6829 } 6830 6831 final void sendPendingThumbnail(HistoryRecord r, IBinder token, 6832 Bitmap thumbnail, CharSequence description, boolean always) { 6833 TaskRecord task = null; 6834 ArrayList receivers = null; 6835 6836 //System.out.println("Send pending thumbnail: " + r); 6837 6838 synchronized(this) { 6839 if (r == null) { 6840 int index = indexOfTokenLocked(token, false); 6841 if (index < 0) { 6842 return; 6843 } 6844 r = (HistoryRecord)mHistory.get(index); 6845 } 6846 if (thumbnail == null) { 6847 thumbnail = r.thumbnail; 6848 description = r.description; 6849 } 6850 if (thumbnail == null && !always) { 6851 // If there is no thumbnail, and this entry is not actually 6852 // going away, then abort for now and pick up the next 6853 // thumbnail we get. 6854 return; 6855 } 6856 task = r.task; 6857 6858 int N = mPendingThumbnails.size(); 6859 int i=0; 6860 while (i<N) { 6861 PendingThumbnailsRecord pr = 6862 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 6863 //System.out.println("Looking in " + pr.pendingRecords); 6864 if (pr.pendingRecords.remove(r)) { 6865 if (receivers == null) { 6866 receivers = new ArrayList(); 6867 } 6868 receivers.add(pr); 6869 if (pr.pendingRecords.size() == 0) { 6870 pr.finished = true; 6871 mPendingThumbnails.remove(i); 6872 N--; 6873 continue; 6874 } 6875 } 6876 i++; 6877 } 6878 } 6879 6880 if (receivers != null) { 6881 final int N = receivers.size(); 6882 for (int i=0; i<N; i++) { 6883 try { 6884 PendingThumbnailsRecord pr = 6885 (PendingThumbnailsRecord)receivers.get(i); 6886 pr.receiver.newThumbnail( 6887 task != null ? task.taskId : -1, thumbnail, description); 6888 if (pr.finished) { 6889 pr.receiver.finished(); 6890 } 6891 } catch (Exception e) { 6892 Log.w(TAG, "Exception thrown when sending thumbnail", e); 6893 } 6894 } 6895 } 6896 } 6897 6898 // ========================================================= 6899 // CONTENT PROVIDERS 6900 // ========================================================= 6901 6902 private final List generateApplicationProvidersLocked(ProcessRecord app) { 6903 List providers = null; 6904 try { 6905 providers = ActivityThread.getPackageManager(). 6906 queryContentProviders(app.processName, app.info.uid, 6907 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 6908 } catch (RemoteException ex) { 6909 } 6910 if (providers != null) { 6911 final int N = providers.size(); 6912 for (int i=0; i<N; i++) { 6913 ProviderInfo cpi = 6914 (ProviderInfo)providers.get(i); 6915 ContentProviderRecord cpr = 6916 (ContentProviderRecord)mProvidersByClass.get(cpi.name); 6917 if (cpr == null) { 6918 cpr = new ContentProviderRecord(cpi, app.info); 6919 mProvidersByClass.put(cpi.name, cpr); 6920 } 6921 app.pubProviders.put(cpi.name, cpr); 6922 app.addPackage(cpi.applicationInfo.packageName); 6923 } 6924 } 6925 return providers; 6926 } 6927 6928 private final String checkContentProviderPermissionLocked( 6929 ProviderInfo cpi, ProcessRecord r, int mode) { 6930 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 6931 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid(); 6932 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 6933 cpi.exported ? -1 : cpi.applicationInfo.uid) 6934 == PackageManager.PERMISSION_GRANTED 6935 && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) { 6936 return null; 6937 } 6938 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 6939 cpi.exported ? -1 : cpi.applicationInfo.uid) 6940 == PackageManager.PERMISSION_GRANTED) { 6941 return null; 6942 } 6943 String msg = "Permission Denial: opening provider " + cpi.name 6944 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 6945 + ", uid=" + callingUid + ") requires " 6946 + cpi.readPermission + " or " + cpi.writePermission; 6947 Log.w(TAG, msg); 6948 return msg; 6949 } 6950 6951 private final ContentProviderHolder getContentProviderImpl( 6952 IApplicationThread caller, String name) { 6953 ContentProviderRecord cpr; 6954 ProviderInfo cpi = null; 6955 6956 synchronized(this) { 6957 ProcessRecord r = null; 6958 if (caller != null) { 6959 r = getRecordForAppLocked(caller); 6960 if (r == null) { 6961 throw new SecurityException( 6962 "Unable to find app for caller " + caller 6963 + " (pid=" + Binder.getCallingPid() 6964 + ") when getting content provider " + name); 6965 } 6966 } 6967 6968 // First check if this content provider has been published... 6969 cpr = (ContentProviderRecord)mProvidersByName.get(name); 6970 if (cpr != null) { 6971 cpi = cpr.info; 6972 if (checkContentProviderPermissionLocked(cpi, r, -1) != null) { 6973 return new ContentProviderHolder(cpi, 6974 cpi.readPermission != null 6975 ? cpi.readPermission : cpi.writePermission); 6976 } 6977 6978 if (r != null && cpr.canRunHere(r)) { 6979 // This provider has been published or is in the process 6980 // of being published... but it is also allowed to run 6981 // in the caller's process, so don't make a connection 6982 // and just let the caller instantiate its own instance. 6983 if (cpr.provider != null) { 6984 // don't give caller the provider object, it needs 6985 // to make its own. 6986 cpr = new ContentProviderRecord(cpr); 6987 } 6988 return cpr; 6989 } 6990 6991 final long origId = Binder.clearCallingIdentity(); 6992 6993 // In this case the provider is a single instance, so we can 6994 // return it right away. 6995 if (r != null) { 6996 r.conProviders.add(cpr); 6997 cpr.clients.add(r); 6998 } else { 6999 cpr.externals++; 7000 } 7001 7002 if (cpr.app != null) { 7003 updateOomAdjLocked(cpr.app); 7004 } 7005 7006 Binder.restoreCallingIdentity(origId); 7007 7008 } else { 7009 try { 7010 cpi = ActivityThread.getPackageManager(). 7011 resolveContentProvider(name, 7012 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7013 } catch (RemoteException ex) { 7014 } 7015 if (cpi == null) { 7016 return null; 7017 } 7018 7019 if (checkContentProviderPermissionLocked(cpi, r, -1) != null) { 7020 return new ContentProviderHolder(cpi, 7021 cpi.readPermission != null 7022 ? cpi.readPermission : cpi.writePermission); 7023 } 7024 7025 cpr = (ContentProviderRecord)mProvidersByClass.get(cpi.name); 7026 final boolean firstClass = cpr == null; 7027 if (firstClass) { 7028 try { 7029 ApplicationInfo ai = 7030 ActivityThread.getPackageManager(). 7031 getApplicationInfo( 7032 cpi.applicationInfo.packageName, 7033 STOCK_PM_FLAGS); 7034 if (ai == null) { 7035 Log.w(TAG, "No package info for content provider " 7036 + cpi.name); 7037 return null; 7038 } 7039 cpr = new ContentProviderRecord(cpi, ai); 7040 } catch (RemoteException ex) { 7041 // pm is in same process, this will never happen. 7042 } 7043 } 7044 7045 if (r != null && cpr.canRunHere(r)) { 7046 // If this is a multiprocess provider, then just return its 7047 // info and allow the caller to instantiate it. Only do 7048 // this if the provider is the same user as the caller's 7049 // process, or can run as root (so can be in any process). 7050 return cpr; 7051 } 7052 7053 if (false) { 7054 RuntimeException e = new RuntimeException("foo"); 7055 //Log.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid 7056 // + " pruid " + ai.uid + "): " + cpi.className, e); 7057 } 7058 7059 // This is single process, and our app is now connecting to it. 7060 // See if we are already in the process of launching this 7061 // provider. 7062 final int N = mLaunchingProviders.size(); 7063 int i; 7064 for (i=0; i<N; i++) { 7065 if (mLaunchingProviders.get(i) == cpr) { 7066 break; 7067 } 7068 if (false) { 7069 final ContentProviderRecord rec = 7070 (ContentProviderRecord)mLaunchingProviders.get(i); 7071 if (rec.info.name.equals(cpr.info.name)) { 7072 cpr = rec; 7073 break; 7074 } 7075 } 7076 } 7077 7078 // If the provider is not already being launched, then get it 7079 // started. 7080 if (i >= N) { 7081 final long origId = Binder.clearCallingIdentity(); 7082 ProcessRecord proc = startProcessLocked(cpi.processName, 7083 cpr.appInfo, false, 0, "content provider", 7084 new ComponentName(cpi.applicationInfo.packageName, 7085 cpi.name)); 7086 if (proc == null) { 7087 Log.w(TAG, "Unable to launch app " 7088 + cpi.applicationInfo.packageName + "/" 7089 + cpi.applicationInfo.uid + " for provider " 7090 + name + ": process is bad"); 7091 return null; 7092 } 7093 cpr.launchingApp = proc; 7094 mLaunchingProviders.add(cpr); 7095 Binder.restoreCallingIdentity(origId); 7096 } 7097 7098 // Make sure the provider is published (the same provider class 7099 // may be published under multiple names). 7100 if (firstClass) { 7101 mProvidersByClass.put(cpi.name, cpr); 7102 } 7103 mProvidersByName.put(name, cpr); 7104 7105 if (r != null) { 7106 r.conProviders.add(cpr); 7107 cpr.clients.add(r); 7108 } else { 7109 cpr.externals++; 7110 } 7111 } 7112 } 7113 7114 // Wait for the provider to be published... 7115 synchronized (cpr) { 7116 while (cpr.provider == null) { 7117 if (cpr.launchingApp == null) { 7118 Log.w(TAG, "Unable to launch app " 7119 + cpi.applicationInfo.packageName + "/" 7120 + cpi.applicationInfo.uid + " for provider " 7121 + name + ": launching app became null"); 7122 EventLog.writeEvent(LOG_AM_PROVIDER_LOST_PROCESS, 7123 cpi.applicationInfo.packageName, 7124 cpi.applicationInfo.uid, name); 7125 return null; 7126 } 7127 try { 7128 cpr.wait(); 7129 } catch (InterruptedException ex) { 7130 } 7131 } 7132 } 7133 return cpr; 7134 } 7135 7136 public final ContentProviderHolder getContentProvider( 7137 IApplicationThread caller, String name) { 7138 if (caller == null) { 7139 String msg = "null IApplicationThread when getting content provider " 7140 + name; 7141 Log.w(TAG, msg); 7142 throw new SecurityException(msg); 7143 } 7144 7145 return getContentProviderImpl(caller, name); 7146 } 7147 7148 private ContentProviderHolder getContentProviderExternal(String name) { 7149 return getContentProviderImpl(null, name); 7150 } 7151 7152 /** 7153 * Drop a content provider from a ProcessRecord's bookkeeping 7154 * @param cpr 7155 */ 7156 public void removeContentProvider(IApplicationThread caller, String name) { 7157 synchronized (this) { 7158 ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name); 7159 if(cpr == null) { 7160 //remove from mProvidersByClass 7161 if(localLOGV) Log.v(TAG, name+" content provider not found in providers list"); 7162 return; 7163 } 7164 final ProcessRecord r = getRecordForAppLocked(caller); 7165 if (r == null) { 7166 throw new SecurityException( 7167 "Unable to find app for caller " + caller + 7168 " when removing content provider " + name); 7169 } 7170 //update content provider record entry info 7171 ContentProviderRecord localCpr = (ContentProviderRecord) mProvidersByClass.get(cpr.info.name); 7172 if(localLOGV) Log.v(TAG, "Removing content provider requested by "+ 7173 r.info.processName+" from process "+localCpr.appInfo.processName); 7174 if(localCpr.appInfo.processName == r.info.processName) { 7175 //should not happen. taken care of as a local provider 7176 if(localLOGV) Log.v(TAG, "local provider doing nothing Ignoring other names"); 7177 return; 7178 } else { 7179 localCpr.clients.remove(r); 7180 r.conProviders.remove(localCpr); 7181 } 7182 updateOomAdjLocked(); 7183 } 7184 } 7185 7186 private void removeContentProviderExternal(String name) { 7187 synchronized (this) { 7188 ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name); 7189 if(cpr == null) { 7190 //remove from mProvidersByClass 7191 if(localLOGV) Log.v(TAG, name+" content provider not found in providers list"); 7192 return; 7193 } 7194 7195 //update content provider record entry info 7196 ContentProviderRecord localCpr = (ContentProviderRecord) mProvidersByClass.get(cpr.info.name); 7197 localCpr.externals--; 7198 if (localCpr.externals < 0) { 7199 Log.e(TAG, "Externals < 0 for content provider " + localCpr); 7200 } 7201 updateOomAdjLocked(); 7202 } 7203 } 7204 7205 public final void publishContentProviders(IApplicationThread caller, 7206 List<ContentProviderHolder> providers) { 7207 if (providers == null) { 7208 return; 7209 } 7210 7211 synchronized(this) { 7212 final ProcessRecord r = getRecordForAppLocked(caller); 7213 if (r == null) { 7214 throw new SecurityException( 7215 "Unable to find app for caller " + caller 7216 + " (pid=" + Binder.getCallingPid() 7217 + ") when publishing content providers"); 7218 } 7219 7220 final long origId = Binder.clearCallingIdentity(); 7221 7222 final int N = providers.size(); 7223 for (int i=0; i<N; i++) { 7224 ContentProviderHolder src = providers.get(i); 7225 if (src == null || src.info == null || src.provider == null) { 7226 continue; 7227 } 7228 ContentProviderRecord dst = 7229 (ContentProviderRecord)r.pubProviders.get(src.info.name); 7230 if (dst != null) { 7231 mProvidersByClass.put(dst.info.name, dst); 7232 String names[] = dst.info.authority.split(";"); 7233 for (int j = 0; j < names.length; j++) { 7234 mProvidersByName.put(names[j], dst); 7235 } 7236 7237 int NL = mLaunchingProviders.size(); 7238 int j; 7239 for (j=0; j<NL; j++) { 7240 if (mLaunchingProviders.get(j) == dst) { 7241 mLaunchingProviders.remove(j); 7242 j--; 7243 NL--; 7244 } 7245 } 7246 synchronized (dst) { 7247 dst.provider = src.provider; 7248 dst.app = r; 7249 dst.notifyAll(); 7250 } 7251 updateOomAdjLocked(r); 7252 } 7253 } 7254 7255 Binder.restoreCallingIdentity(origId); 7256 } 7257 } 7258 7259 public static final void installSystemProviders() { 7260 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 7261 List providers = mSelf.generateApplicationProvidersLocked(app); 7262 mSystemThread.installSystemProviders(providers); 7263 } 7264 7265 // ========================================================= 7266 // GLOBAL MANAGEMENT 7267 // ========================================================= 7268 7269 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 7270 ApplicationInfo info, String customProcess) { 7271 String proc = customProcess != null ? customProcess : info.processName; 7272 BatteryStatsImpl.Uid.Proc ps = null; 7273 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7274 synchronized (stats) { 7275 ps = stats.getProcessStatsLocked(info.uid, proc); 7276 } 7277 return new ProcessRecord(ps, thread, info, proc); 7278 } 7279 7280 final ProcessRecord addAppLocked(ApplicationInfo info) { 7281 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid); 7282 7283 if (app == null) { 7284 app = newProcessRecordLocked(null, info, null); 7285 mProcessNames.put(info.processName, info.uid, app); 7286 updateLRUListLocked(app, true); 7287 } 7288 7289 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 7290 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 7291 app.persistent = true; 7292 app.maxAdj = CORE_SERVER_ADJ; 7293 } 7294 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 7295 mPersistentStartingProcesses.add(app); 7296 startProcessLocked(app, "added application", app.processName); 7297 } 7298 7299 return app; 7300 } 7301 7302 public void unhandledBack() { 7303 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 7304 "unhandledBack()"); 7305 7306 synchronized(this) { 7307 int count = mHistory.size(); 7308 if (Config.LOGD) Log.d( 7309 TAG, "Performing unhandledBack(): stack size = " + count); 7310 if (count > 1) { 7311 final long origId = Binder.clearCallingIdentity(); 7312 finishActivityLocked((HistoryRecord)mHistory.get(count-1), 7313 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 7314 Binder.restoreCallingIdentity(origId); 7315 } 7316 } 7317 } 7318 7319 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 7320 String name = uri.getAuthority(); 7321 ContentProviderHolder cph = getContentProviderExternal(name); 7322 ParcelFileDescriptor pfd = null; 7323 if (cph != null) { 7324 // We record the binder invoker's uid in thread-local storage before 7325 // going to the content provider to open the file. Later, in the code 7326 // that handles all permissions checks, we look for this uid and use 7327 // that rather than the Activity Manager's own uid. The effect is that 7328 // we do the check against the caller's permissions even though it looks 7329 // to the content provider like the Activity Manager itself is making 7330 // the request. 7331 sCallerIdentity.set(new Identity( 7332 Binder.getCallingPid(), Binder.getCallingUid())); 7333 try { 7334 pfd = cph.provider.openFile(uri, "r"); 7335 } catch (FileNotFoundException e) { 7336 // do nothing; pfd will be returned null 7337 } finally { 7338 // Ensure that whatever happens, we clean up the identity state 7339 sCallerIdentity.remove(); 7340 } 7341 7342 // We've got the fd now, so we're done with the provider. 7343 removeContentProviderExternal(name); 7344 } else { 7345 Log.d(TAG, "Failed to get provider for authority '" + name + "'"); 7346 } 7347 return pfd; 7348 } 7349 7350 public void goingToSleep() { 7351 synchronized(this) { 7352 mSleeping = true; 7353 mWindowManager.setEventDispatching(false); 7354 7355 if (mResumedActivity != null) { 7356 pauseIfSleepingLocked(); 7357 } else { 7358 Log.w(TAG, "goingToSleep with no resumed activity!"); 7359 } 7360 } 7361 } 7362 7363 public boolean shutdown(int timeout) { 7364 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 7365 != PackageManager.PERMISSION_GRANTED) { 7366 throw new SecurityException("Requires permission " 7367 + android.Manifest.permission.SHUTDOWN); 7368 } 7369 7370 boolean timedout = false; 7371 7372 synchronized(this) { 7373 mShuttingDown = true; 7374 mWindowManager.setEventDispatching(false); 7375 7376 if (mResumedActivity != null) { 7377 pauseIfSleepingLocked(); 7378 final long endTime = System.currentTimeMillis() + timeout; 7379 while (mResumedActivity != null || mPausingActivity != null) { 7380 long delay = endTime - System.currentTimeMillis(); 7381 if (delay <= 0) { 7382 Log.w(TAG, "Activity manager shutdown timed out"); 7383 timedout = true; 7384 break; 7385 } 7386 try { 7387 this.wait(); 7388 } catch (InterruptedException e) { 7389 } 7390 } 7391 } 7392 } 7393 7394 mUsageStatsService.shutdown(); 7395 mBatteryStatsService.shutdown(); 7396 7397 return timedout; 7398 } 7399 7400 void pauseIfSleepingLocked() { 7401 if (mSleeping || mShuttingDown) { 7402 if (!mGoingToSleep.isHeld()) { 7403 mGoingToSleep.acquire(); 7404 if (mLaunchingActivity.isHeld()) { 7405 mLaunchingActivity.release(); 7406 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 7407 } 7408 } 7409 7410 // If we are not currently pausing an activity, get the current 7411 // one to pause. If we are pausing one, we will just let that stuff 7412 // run and release the wake lock when all done. 7413 if (mPausingActivity == null) { 7414 if (DEBUG_PAUSE) Log.v(TAG, "Sleep needs to pause..."); 7415 if (DEBUG_USER_LEAVING) Log.v(TAG, "Sleep => pause with userLeaving=false"); 7416 startPausingLocked(false, true); 7417 } 7418 } 7419 } 7420 7421 public void wakingUp() { 7422 synchronized(this) { 7423 if (mGoingToSleep.isHeld()) { 7424 mGoingToSleep.release(); 7425 } 7426 mWindowManager.setEventDispatching(true); 7427 mSleeping = false; 7428 resumeTopActivityLocked(null); 7429 } 7430 } 7431 7432 public void stopAppSwitches() { 7433 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7434 != PackageManager.PERMISSION_GRANTED) { 7435 throw new SecurityException("Requires permission " 7436 + android.Manifest.permission.STOP_APP_SWITCHES); 7437 } 7438 7439 synchronized(this) { 7440 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 7441 + APP_SWITCH_DELAY_TIME; 7442 mDidAppSwitch = false; 7443 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7444 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7445 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 7446 } 7447 } 7448 7449 public void resumeAppSwitches() { 7450 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7451 != PackageManager.PERMISSION_GRANTED) { 7452 throw new SecurityException("Requires permission " 7453 + android.Manifest.permission.STOP_APP_SWITCHES); 7454 } 7455 7456 synchronized(this) { 7457 // Note that we don't execute any pending app switches... we will 7458 // let those wait until either the timeout, or the next start 7459 // activity request. 7460 mAppSwitchesAllowedTime = 0; 7461 } 7462 } 7463 7464 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 7465 String name) { 7466 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 7467 return true; 7468 } 7469 7470 final int perm = checkComponentPermission( 7471 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 7472 callingUid, -1); 7473 if (perm == PackageManager.PERMISSION_GRANTED) { 7474 return true; 7475 } 7476 7477 Log.w(TAG, name + " request from " + callingUid + " stopped"); 7478 return false; 7479 } 7480 7481 public void setDebugApp(String packageName, boolean waitForDebugger, 7482 boolean persistent) { 7483 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 7484 "setDebugApp()"); 7485 7486 // Note that this is not really thread safe if there are multiple 7487 // callers into it at the same time, but that's not a situation we 7488 // care about. 7489 if (persistent) { 7490 final ContentResolver resolver = mContext.getContentResolver(); 7491 Settings.System.putString( 7492 resolver, Settings.System.DEBUG_APP, 7493 packageName); 7494 Settings.System.putInt( 7495 resolver, Settings.System.WAIT_FOR_DEBUGGER, 7496 waitForDebugger ? 1 : 0); 7497 } 7498 7499 synchronized (this) { 7500 if (!persistent) { 7501 mOrigDebugApp = mDebugApp; 7502 mOrigWaitForDebugger = mWaitForDebugger; 7503 } 7504 mDebugApp = packageName; 7505 mWaitForDebugger = waitForDebugger; 7506 mDebugTransient = !persistent; 7507 if (packageName != null) { 7508 final long origId = Binder.clearCallingIdentity(); 7509 uninstallPackageLocked(packageName, -1, false); 7510 Binder.restoreCallingIdentity(origId); 7511 } 7512 } 7513 } 7514 7515 public void setAlwaysFinish(boolean enabled) { 7516 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 7517 "setAlwaysFinish()"); 7518 7519 Settings.System.putInt( 7520 mContext.getContentResolver(), 7521 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 7522 7523 synchronized (this) { 7524 mAlwaysFinishActivities = enabled; 7525 } 7526 } 7527 7528 public void setActivityWatcher(IActivityWatcher watcher) { 7529 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 7530 "setActivityWatcher()"); 7531 synchronized (this) { 7532 mWatcher = watcher; 7533 } 7534 } 7535 7536 public final void enterSafeMode() { 7537 synchronized(this) { 7538 // It only makes sense to do this before the system is ready 7539 // and started launching other packages. 7540 if (!mSystemReady) { 7541 try { 7542 ActivityThread.getPackageManager().enterSafeMode(); 7543 } catch (RemoteException e) { 7544 } 7545 7546 View v = LayoutInflater.from(mContext).inflate( 7547 com.android.internal.R.layout.safe_mode, null); 7548 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 7549 lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; 7550 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 7551 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 7552 lp.gravity = Gravity.BOTTOM | Gravity.LEFT; 7553 lp.format = v.getBackground().getOpacity(); 7554 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 7555 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 7556 ((WindowManager)mContext.getSystemService( 7557 Context.WINDOW_SERVICE)).addView(v, lp); 7558 } 7559 } 7560 } 7561 7562 public void noteWakeupAlarm(IIntentSender sender) { 7563 if (!(sender instanceof PendingIntentRecord)) { 7564 return; 7565 } 7566 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7567 synchronized (stats) { 7568 if (mBatteryStatsService.isOnBattery()) { 7569 mBatteryStatsService.enforceCallingPermission(); 7570 PendingIntentRecord rec = (PendingIntentRecord)sender; 7571 int MY_UID = Binder.getCallingUid(); 7572 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 7573 BatteryStatsImpl.Uid.Pkg pkg = 7574 stats.getPackageStatsLocked(uid, rec.key.packageName); 7575 pkg.incWakeupsLocked(); 7576 } 7577 } 7578 } 7579 7580 public boolean killPidsForMemory(int[] pids) { 7581 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 7582 throw new SecurityException("killPidsForMemory only available to the system"); 7583 } 7584 7585 // XXX Note: don't acquire main activity lock here, because the window 7586 // manager calls in with its locks held. 7587 7588 boolean killed = false; 7589 synchronized (mPidsSelfLocked) { 7590 int[] types = new int[pids.length]; 7591 int worstType = 0; 7592 for (int i=0; i<pids.length; i++) { 7593 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7594 if (proc != null) { 7595 int type = proc.setAdj; 7596 types[i] = type; 7597 if (type > worstType) { 7598 worstType = type; 7599 } 7600 } 7601 } 7602 7603 // If the worse oom_adj is somewhere in the hidden proc LRU range, 7604 // then constrain it so we will kill all hidden procs. 7605 if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) { 7606 worstType = HIDDEN_APP_MIN_ADJ; 7607 } 7608 Log.w(TAG, "Killing processes for memory at adjustment " + worstType); 7609 for (int i=0; i<pids.length; i++) { 7610 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 7611 if (proc == null) { 7612 continue; 7613 } 7614 int adj = proc.setAdj; 7615 if (adj >= worstType) { 7616 Log.w(TAG, "Killing for memory: " + proc + " (adj " 7617 + adj + ")"); 7618 EventLog.writeEvent(LOG_AM_KILL_FOR_MEMORY, proc.pid, 7619 proc.processName, adj); 7620 killed = true; 7621 Process.killProcess(pids[i]); 7622 } 7623 } 7624 } 7625 return killed; 7626 } 7627 7628 public void reportPss(IApplicationThread caller, int pss) { 7629 Watchdog.PssRequestor req; 7630 String name; 7631 ProcessRecord callerApp; 7632 synchronized (this) { 7633 if (caller == null) { 7634 return; 7635 } 7636 callerApp = getRecordForAppLocked(caller); 7637 if (callerApp == null) { 7638 return; 7639 } 7640 callerApp.lastPss = pss; 7641 req = callerApp; 7642 name = callerApp.processName; 7643 } 7644 Watchdog.getInstance().reportPss(req, name, pss); 7645 if (!callerApp.persistent) { 7646 removeRequestedPss(callerApp); 7647 } 7648 } 7649 7650 public void requestPss(Runnable completeCallback) { 7651 ArrayList<ProcessRecord> procs; 7652 synchronized (this) { 7653 mRequestPssCallback = completeCallback; 7654 mRequestPssList.clear(); 7655 for (int i=mLRUProcesses.size()-1; i>=0; i--) { 7656 ProcessRecord proc = mLRUProcesses.get(i); 7657 if (!proc.persistent) { 7658 mRequestPssList.add(proc); 7659 } 7660 } 7661 procs = new ArrayList<ProcessRecord>(mRequestPssList); 7662 } 7663 7664 int oldPri = Process.getThreadPriority(Process.myTid()); 7665 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 7666 for (int i=procs.size()-1; i>=0; i--) { 7667 ProcessRecord proc = procs.get(i); 7668 proc.lastPss = 0; 7669 proc.requestPss(); 7670 } 7671 Process.setThreadPriority(oldPri); 7672 } 7673 7674 void removeRequestedPss(ProcessRecord proc) { 7675 Runnable callback = null; 7676 synchronized (this) { 7677 if (mRequestPssList.remove(proc)) { 7678 if (mRequestPssList.size() == 0) { 7679 callback = mRequestPssCallback; 7680 mRequestPssCallback = null; 7681 } 7682 } 7683 } 7684 7685 if (callback != null) { 7686 callback.run(); 7687 } 7688 } 7689 7690 public void collectPss(Watchdog.PssStats stats) { 7691 stats.mEmptyPss = 0; 7692 stats.mEmptyCount = 0; 7693 stats.mBackgroundPss = 0; 7694 stats.mBackgroundCount = 0; 7695 stats.mServicePss = 0; 7696 stats.mServiceCount = 0; 7697 stats.mVisiblePss = 0; 7698 stats.mVisibleCount = 0; 7699 stats.mForegroundPss = 0; 7700 stats.mForegroundCount = 0; 7701 stats.mNoPssCount = 0; 7702 synchronized (this) { 7703 int i; 7704 int NPD = mProcDeaths.length < stats.mProcDeaths.length 7705 ? mProcDeaths.length : stats.mProcDeaths.length; 7706 int aggr = 0; 7707 for (i=0; i<NPD; i++) { 7708 aggr += mProcDeaths[i]; 7709 stats.mProcDeaths[i] = aggr; 7710 } 7711 while (i<stats.mProcDeaths.length) { 7712 stats.mProcDeaths[i] = 0; 7713 i++; 7714 } 7715 7716 for (i=mLRUProcesses.size()-1; i>=0; i--) { 7717 ProcessRecord proc = mLRUProcesses.get(i); 7718 if (proc.persistent) { 7719 continue; 7720 } 7721 //Log.i(TAG, "Proc " + proc + ": pss=" + proc.lastPss); 7722 if (proc.lastPss == 0) { 7723 stats.mNoPssCount++; 7724 continue; 7725 } 7726 if (proc.setAdj == EMPTY_APP_ADJ) { 7727 stats.mEmptyPss += proc.lastPss; 7728 stats.mEmptyCount++; 7729 } else if (proc.setAdj == CONTENT_PROVIDER_ADJ) { 7730 stats.mEmptyPss += proc.lastPss; 7731 stats.mEmptyCount++; 7732 } else if (proc.setAdj >= HIDDEN_APP_MIN_ADJ) { 7733 stats.mBackgroundPss += proc.lastPss; 7734 stats.mBackgroundCount++; 7735 } else if (proc.setAdj >= VISIBLE_APP_ADJ) { 7736 stats.mVisiblePss += proc.lastPss; 7737 stats.mVisibleCount++; 7738 } else { 7739 stats.mForegroundPss += proc.lastPss; 7740 stats.mForegroundCount++; 7741 } 7742 } 7743 } 7744 } 7745 7746 public final void startRunning(String pkg, String cls, String action, 7747 String data) { 7748 synchronized(this) { 7749 if (mStartRunning) { 7750 return; 7751 } 7752 mStartRunning = true; 7753 mTopComponent = pkg != null && cls != null 7754 ? new ComponentName(pkg, cls) : null; 7755 mTopAction = action != null ? action : Intent.ACTION_MAIN; 7756 mTopData = data; 7757 if (!mSystemReady) { 7758 return; 7759 } 7760 } 7761 7762 systemReady(); 7763 } 7764 7765 private void retrieveSettings() { 7766 final ContentResolver resolver = mContext.getContentResolver(); 7767 String debugApp = Settings.System.getString( 7768 resolver, Settings.System.DEBUG_APP); 7769 boolean waitForDebugger = Settings.System.getInt( 7770 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 7771 boolean alwaysFinishActivities = Settings.System.getInt( 7772 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 7773 7774 Configuration configuration = new Configuration(); 7775 Settings.System.getConfiguration(resolver, configuration); 7776 7777 synchronized (this) { 7778 mDebugApp = mOrigDebugApp = debugApp; 7779 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 7780 mAlwaysFinishActivities = alwaysFinishActivities; 7781 // This happens before any activities are started, so we can 7782 // change mConfiguration in-place. 7783 mConfiguration.updateFrom(configuration); 7784 } 7785 } 7786 7787 public boolean testIsSystemReady() { 7788 // no need to synchronize(this) just to read & return the value 7789 return mSystemReady; 7790 } 7791 7792 public void systemReady() { 7793 // In the simulator, startRunning will never have been called, which 7794 // normally sets a few crucial variables. Do it here instead. 7795 if (!Process.supportsProcesses()) { 7796 mStartRunning = true; 7797 mTopAction = Intent.ACTION_MAIN; 7798 } 7799 7800 synchronized(this) { 7801 if (mSystemReady) { 7802 return; 7803 } 7804 mSystemReady = true; 7805 if (!mStartRunning) { 7806 return; 7807 } 7808 } 7809 7810 if (Config.LOGD) Log.d(TAG, "Start running!"); 7811 EventLog.writeEvent(LOG_BOOT_PROGRESS_AMS_READY, 7812 SystemClock.uptimeMillis()); 7813 7814 synchronized(this) { 7815 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 7816 ResolveInfo ri = mContext.getPackageManager() 7817 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 7818 STOCK_PM_FLAGS); 7819 CharSequence errorMsg = null; 7820 if (ri != null) { 7821 ActivityInfo ai = ri.activityInfo; 7822 ApplicationInfo app = ai.applicationInfo; 7823 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7824 mTopAction = Intent.ACTION_FACTORY_TEST; 7825 mTopData = null; 7826 mTopComponent = new ComponentName(app.packageName, 7827 ai.name); 7828 } else { 7829 errorMsg = mContext.getResources().getText( 7830 com.android.internal.R.string.factorytest_not_system); 7831 } 7832 } else { 7833 errorMsg = mContext.getResources().getText( 7834 com.android.internal.R.string.factorytest_no_action); 7835 } 7836 if (errorMsg != null) { 7837 mTopAction = null; 7838 mTopData = null; 7839 mTopComponent = null; 7840 Message msg = Message.obtain(); 7841 msg.what = SHOW_FACTORY_ERROR_MSG; 7842 msg.getData().putCharSequence("msg", errorMsg); 7843 mHandler.sendMessage(msg); 7844 } 7845 } 7846 } 7847 7848 retrieveSettings(); 7849 7850 synchronized (this) { 7851 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 7852 try { 7853 List apps = ActivityThread.getPackageManager(). 7854 getPersistentApplications(STOCK_PM_FLAGS); 7855 if (apps != null) { 7856 int N = apps.size(); 7857 int i; 7858 for (i=0; i<N; i++) { 7859 ApplicationInfo info 7860 = (ApplicationInfo)apps.get(i); 7861 if (info != null && 7862 !info.packageName.equals("android")) { 7863 addAppLocked(info); 7864 } 7865 } 7866 } 7867 } catch (RemoteException ex) { 7868 // pm is in same process, this will never happen. 7869 } 7870 } 7871 7872 try { 7873 if (ActivityThread.getPackageManager().hasSystemUidErrors()) { 7874 Message msg = Message.obtain(); 7875 msg.what = SHOW_UID_ERROR_MSG; 7876 mHandler.sendMessage(msg); 7877 } 7878 } catch (RemoteException e) { 7879 } 7880 7881 // Start up initial activity. 7882 mBooting = true; 7883 resumeTopActivityLocked(null); 7884 } 7885 } 7886 7887 boolean makeAppCrashingLocked(ProcessRecord app, 7888 String tag, String shortMsg, String longMsg, byte[] crashData) { 7889 app.crashing = true; 7890 app.crashingReport = generateProcessError(app, 7891 ActivityManager.ProcessErrorStateInfo.CRASHED, tag, shortMsg, longMsg, crashData); 7892 startAppProblemLocked(app); 7893 app.stopFreezingAllLocked(); 7894 return handleAppCrashLocked(app); 7895 } 7896 7897 private ComponentName getErrorReportReceiver(ProcessRecord app) { 7898 IPackageManager pm = ActivityThread.getPackageManager(); 7899 try { 7900 // was an installer package name specified when this app was 7901 // installed? 7902 String installerPackageName = pm.getInstallerPackageName(app.info.packageName); 7903 if (installerPackageName == null) { 7904 return null; 7905 } 7906 7907 // is there an Activity in this package that handles ACTION_APP_ERROR? 7908 Intent intent = new Intent(Intent.ACTION_APP_ERROR); 7909 ResolveInfo info = pm.resolveIntentForPackage(intent, null, 0, installerPackageName); 7910 if (info == null || info.activityInfo == null) { 7911 return null; 7912 } 7913 7914 return new ComponentName(installerPackageName, info.activityInfo.name); 7915 } catch (RemoteException e) { 7916 // will return null and no error report will be delivered 7917 } 7918 return null; 7919 } 7920 7921 void makeAppNotRespondingLocked(ProcessRecord app, 7922 String tag, String shortMsg, String longMsg, byte[] crashData) { 7923 app.notResponding = true; 7924 app.notRespondingReport = generateProcessError(app, 7925 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, tag, shortMsg, longMsg, 7926 crashData); 7927 startAppProblemLocked(app); 7928 app.stopFreezingAllLocked(); 7929 } 7930 7931 /** 7932 * Generate a process error record, suitable for attachment to a ProcessRecord. 7933 * 7934 * @param app The ProcessRecord in which the error occurred. 7935 * @param condition Crashing, Application Not Responding, etc. Values are defined in 7936 * ActivityManager.AppErrorStateInfo 7937 * @param tag The tag that was passed into handleApplicationError(). Typically the classname. 7938 * @param shortMsg Short message describing the crash. 7939 * @param longMsg Long message describing the crash. 7940 * @param crashData Raw data passed into handleApplicationError(). Typically a stack trace. 7941 * 7942 * @return Returns a fully-formed AppErrorStateInfo record. 7943 */ 7944 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 7945 int condition, String tag, String shortMsg, String longMsg, byte[] crashData) { 7946 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 7947 7948 report.condition = condition; 7949 report.processName = app.processName; 7950 report.pid = app.pid; 7951 report.uid = app.info.uid; 7952 report.tag = tag; 7953 report.shortMsg = shortMsg; 7954 report.longMsg = longMsg; 7955 report.crashData = crashData; 7956 7957 return report; 7958 } 7959 7960 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog, 7961 boolean crashed) { 7962 synchronized (this) { 7963 app.crashing = false; 7964 app.crashingReport = null; 7965 app.notResponding = false; 7966 app.notRespondingReport = null; 7967 if (app.anrDialog == fromDialog) { 7968 app.anrDialog = null; 7969 } 7970 if (app.waitDialog == fromDialog) { 7971 app.waitDialog = null; 7972 } 7973 if (app.pid > 0 && app.pid != MY_PID) { 7974 if (crashed) { 7975 handleAppCrashLocked(app); 7976 } 7977 Log.i(ActivityManagerService.TAG, "Killing process " 7978 + app.processName 7979 + " (pid=" + app.pid + ") at user's request"); 7980 Process.killProcess(app.pid); 7981 } 7982 7983 } 7984 } 7985 7986 boolean handleAppCrashLocked(ProcessRecord app) { 7987 long now = SystemClock.uptimeMillis(); 7988 7989 Long crashTime = mProcessCrashTimes.get(app.info.processName, 7990 app.info.uid); 7991 if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) { 7992 // This process loses! 7993 Log.w(TAG, "Process " + app.info.processName 7994 + " has crashed too many times: killing!"); 7995 EventLog.writeEvent(LOG_AM_PROCESS_CRASHED_TOO_MUCH, 7996 app.info.processName, app.info.uid); 7997 killServicesLocked(app, false); 7998 for (int i=mHistory.size()-1; i>=0; i--) { 7999 HistoryRecord r = (HistoryRecord)mHistory.get(i); 8000 if (r.app == app) { 8001 if (Config.LOGD) Log.d( 8002 TAG, " Force finishing activity " 8003 + r.intent.getComponent().flattenToShortString()); 8004 finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 8005 } 8006 } 8007 if (!app.persistent) { 8008 // We don't want to start this process again until the user 8009 // explicitly does so... but for persistent process, we really 8010 // need to keep it running. If a persistent process is actually 8011 // repeatedly crashing, then badness for everyone. 8012 EventLog.writeEvent(LOG_AM_PROCESS_BAD, app.info.uid, 8013 app.info.processName); 8014 mBadProcesses.put(app.info.processName, app.info.uid, now); 8015 app.bad = true; 8016 mProcessCrashTimes.remove(app.info.processName, app.info.uid); 8017 app.removed = true; 8018 removeProcessLocked(app, false); 8019 return false; 8020 } 8021 } 8022 8023 // Bump up the crash count of any services currently running in the proc. 8024 if (app.services.size() != 0) { 8025 // Any services running in the application need to be placed 8026 // back in the pending list. 8027 Iterator it = app.services.iterator(); 8028 while (it.hasNext()) { 8029 ServiceRecord sr = (ServiceRecord)it.next(); 8030 sr.crashCount++; 8031 } 8032 } 8033 8034 mProcessCrashTimes.put(app.info.processName, app.info.uid, now); 8035 return true; 8036 } 8037 8038 void startAppProblemLocked(ProcessRecord app) { 8039 app.errorReportReceiver = getErrorReportReceiver(app); 8040 skipCurrentReceiverLocked(app); 8041 } 8042 8043 void skipCurrentReceiverLocked(ProcessRecord app) { 8044 boolean reschedule = false; 8045 BroadcastRecord r = app.curReceiver; 8046 if (r != null) { 8047 // The current broadcast is waiting for this app's receiver 8048 // to be finished. Looks like that's not going to happen, so 8049 // let the broadcast continue. 8050 logBroadcastReceiverDiscard(r); 8051 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 8052 r.resultExtras, r.resultAbort, true); 8053 reschedule = true; 8054 } 8055 r = mPendingBroadcast; 8056 if (r != null && r.curApp == app) { 8057 if (DEBUG_BROADCAST) Log.v(TAG, 8058 "skip & discard pending app " + r); 8059 logBroadcastReceiverDiscard(r); 8060 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 8061 r.resultExtras, r.resultAbort, true); 8062 reschedule = true; 8063 } 8064 if (reschedule) { 8065 scheduleBroadcastsLocked(); 8066 } 8067 } 8068 8069 public int handleApplicationError(IBinder app, int flags, 8070 String tag, String shortMsg, String longMsg, byte[] crashData) { 8071 AppErrorResult result = new AppErrorResult(); 8072 ProcessRecord r = null; 8073 synchronized (this) { 8074 if (app != null) { 8075 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8076 final int NA = apps.size(); 8077 for (int ia=0; ia<NA; ia++) { 8078 ProcessRecord p = apps.valueAt(ia); 8079 if (p.thread != null && p.thread.asBinder() == app) { 8080 r = p; 8081 break; 8082 } 8083 } 8084 } 8085 } 8086 8087 if (r != null) { 8088 // The application has crashed. Send the SIGQUIT to the process so 8089 // that it can dump its state. 8090 Process.sendSignal(r.pid, Process.SIGNAL_QUIT); 8091 //Log.i(TAG, "Current system threads:"); 8092 //Process.sendSignal(MY_PID, Process.SIGNAL_QUIT); 8093 } 8094 8095 if (mWatcher != null) { 8096 try { 8097 String name = r != null ? r.processName : null; 8098 int pid = r != null ? r.pid : Binder.getCallingPid(); 8099 if (!mWatcher.appCrashed(name, pid, 8100 shortMsg, longMsg, crashData)) { 8101 Log.w(TAG, "Force-killing crashed app " + name 8102 + " at watcher's request"); 8103 Process.killProcess(pid); 8104 return 0; 8105 } 8106 } catch (RemoteException e) { 8107 mWatcher = null; 8108 } 8109 } 8110 8111 final long origId = Binder.clearCallingIdentity(); 8112 8113 // If this process is running instrumentation, finish it. 8114 if (r != null && r.instrumentationClass != null) { 8115 Log.w(TAG, "Error in app " + r.processName 8116 + " running instrumentation " + r.instrumentationClass + ":"); 8117 if (shortMsg != null) Log.w(TAG, " " + shortMsg); 8118 if (longMsg != null) Log.w(TAG, " " + longMsg); 8119 Bundle info = new Bundle(); 8120 info.putString("shortMsg", shortMsg); 8121 info.putString("longMsg", longMsg); 8122 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8123 Binder.restoreCallingIdentity(origId); 8124 return 0; 8125 } 8126 8127 if (r != null) { 8128 if (!makeAppCrashingLocked(r, tag, shortMsg, longMsg, crashData)) { 8129 return 0; 8130 } 8131 } else { 8132 Log.w(TAG, "Some application object " + app + " tag " + tag 8133 + " has crashed, but I don't know who it is."); 8134 Log.w(TAG, "ShortMsg:" + shortMsg); 8135 Log.w(TAG, "LongMsg:" + longMsg); 8136 Binder.restoreCallingIdentity(origId); 8137 return 0; 8138 } 8139 8140 Message msg = Message.obtain(); 8141 msg.what = SHOW_ERROR_MSG; 8142 HashMap data = new HashMap(); 8143 data.put("result", result); 8144 data.put("app", r); 8145 data.put("flags", flags); 8146 data.put("shortMsg", shortMsg); 8147 data.put("longMsg", longMsg); 8148 if (r != null && (r.info.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 8149 // For system processes, submit crash data to the server. 8150 data.put("crashData", crashData); 8151 } 8152 msg.obj = data; 8153 mHandler.sendMessage(msg); 8154 8155 Binder.restoreCallingIdentity(origId); 8156 } 8157 8158 int res = result.get(); 8159 8160 Intent appErrorIntent = null; 8161 synchronized (this) { 8162 if (r != null) { 8163 mProcessCrashTimes.put(r.info.processName, r.info.uid, 8164 SystemClock.uptimeMillis()); 8165 } 8166 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8167 appErrorIntent = createAppErrorIntentLocked(r); 8168 res = AppErrorDialog.FORCE_QUIT; 8169 } 8170 } 8171 8172 if (appErrorIntent != null) { 8173 try { 8174 mContext.startActivity(appErrorIntent); 8175 } catch (ActivityNotFoundException e) { 8176 Log.w(TAG, "bug report receiver dissappeared", e); 8177 } 8178 } 8179 8180 return res; 8181 } 8182 8183 Intent createAppErrorIntentLocked(ProcessRecord r) { 8184 ApplicationErrorReport report = createAppErrorReportLocked(r); 8185 if (report == null) { 8186 return null; 8187 } 8188 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8189 result.setComponent(r.errorReportReceiver); 8190 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8191 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8192 return result; 8193 } 8194 8195 ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r) { 8196 if (r.errorReportReceiver == null) { 8197 return null; 8198 } 8199 8200 if (!r.crashing && !r.notResponding) { 8201 return null; 8202 } 8203 8204 try { 8205 ApplicationErrorReport report = new ApplicationErrorReport(); 8206 report.packageName = r.info.packageName; 8207 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8208 report.processName = r.processName; 8209 8210 if (r.crashing) { 8211 report.type = ApplicationErrorReport.TYPE_CRASH; 8212 report.crashInfo = new ApplicationErrorReport.CrashInfo(); 8213 8214 ByteArrayInputStream byteStream = new ByteArrayInputStream( 8215 r.crashingReport.crashData); 8216 DataInputStream dataStream = new DataInputStream(byteStream); 8217 CrashData crashData = new CrashData(dataStream); 8218 ThrowableData throwData = crashData.getThrowableData(); 8219 8220 report.time = crashData.getTime(); 8221 report.crashInfo.stackTrace = throwData.toString(); 8222 8223 // extract the source of the exception, useful for report 8224 // clustering 8225 while (throwData.getCause() != null) { 8226 throwData = throwData.getCause(); 8227 } 8228 StackTraceElementData trace = throwData.getStackTrace()[0]; 8229 report.crashInfo.exceptionClassName = throwData.getType(); 8230 report.crashInfo.throwFileName = trace.getFileName(); 8231 report.crashInfo.throwClassName = trace.getClassName(); 8232 report.crashInfo.throwMethodName = trace.getMethodName(); 8233 } else if (r.notResponding) { 8234 report.type = ApplicationErrorReport.TYPE_ANR; 8235 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8236 8237 report.anrInfo.activity = r.notRespondingReport.tag; 8238 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8239 report.anrInfo.info = r.notRespondingReport.longMsg; 8240 } 8241 8242 return report; 8243 } catch (IOException e) { 8244 // we don't send it 8245 } 8246 8247 return null; 8248 } 8249 8250 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8251 // assume our apps are happy - lazy create the list 8252 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8253 8254 synchronized (this) { 8255 8256 // iterate across all processes 8257 final int N = mLRUProcesses.size(); 8258 for (int i = 0; i < N; i++) { 8259 ProcessRecord app = mLRUProcesses.get(i); 8260 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8261 // This one's in trouble, so we'll generate a report for it 8262 // crashes are higher priority (in case there's a crash *and* an anr) 8263 ActivityManager.ProcessErrorStateInfo report = null; 8264 if (app.crashing) { 8265 report = app.crashingReport; 8266 } else if (app.notResponding) { 8267 report = app.notRespondingReport; 8268 } 8269 8270 if (report != null) { 8271 if (errList == null) { 8272 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8273 } 8274 errList.add(report); 8275 } else { 8276 Log.w(TAG, "Missing app error report, app = " + app.processName + 8277 " crashing = " + app.crashing + 8278 " notResponding = " + app.notResponding); 8279 } 8280 } 8281 } 8282 } 8283 8284 return errList; 8285 } 8286 8287 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8288 // Lazy instantiation of list 8289 List<ActivityManager.RunningAppProcessInfo> runList = null; 8290 synchronized (this) { 8291 // Iterate across all processes 8292 final int N = mLRUProcesses.size(); 8293 for (int i = 0; i < N; i++) { 8294 ProcessRecord app = mLRUProcesses.get(i); 8295 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8296 // Generate process state info for running application 8297 ActivityManager.RunningAppProcessInfo currApp = 8298 new ActivityManager.RunningAppProcessInfo(app.processName, 8299 app.pid, app.getPackageList()); 8300 int adj = app.curAdj; 8301 if (adj >= CONTENT_PROVIDER_ADJ) { 8302 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY; 8303 } else if (adj >= HIDDEN_APP_MIN_ADJ) { 8304 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8305 currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1; 8306 } else if (adj >= HOME_APP_ADJ) { 8307 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8308 currApp.lru = 0; 8309 } else if (adj >= SECONDARY_SERVER_ADJ) { 8310 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8311 } else if (adj >= VISIBLE_APP_ADJ) { 8312 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8313 } else { 8314 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8315 } 8316 //Log.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 8317 // + " lru=" + currApp.lru); 8318 if (runList == null) { 8319 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 8320 } 8321 runList.add(currApp); 8322 } 8323 } 8324 } 8325 return runList; 8326 } 8327 8328 @Override 8329 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 8330 synchronized (this) { 8331 if (checkCallingPermission(android.Manifest.permission.DUMP) 8332 != PackageManager.PERMISSION_GRANTED) { 8333 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8334 + Binder.getCallingPid() 8335 + ", uid=" + Binder.getCallingUid() 8336 + " without permission " 8337 + android.Manifest.permission.DUMP); 8338 return; 8339 } 8340 if (args.length != 0 && "service".equals(args[0])) { 8341 dumpService(fd, pw, args); 8342 return; 8343 } 8344 pw.println("Activities in Current Activity Manager State:"); 8345 dumpHistoryList(pw, mHistory, " ", "Hist", true); 8346 pw.println(" "); 8347 pw.println(" Running activities (most recent first):"); 8348 dumpHistoryList(pw, mLRUActivities, " ", "Run", false); 8349 if (mWaitingVisibleActivities.size() > 0) { 8350 pw.println(" "); 8351 pw.println(" Activities waiting for another to become visible:"); 8352 dumpHistoryList(pw, mWaitingVisibleActivities, " ", "Wait", false); 8353 } 8354 if (mStoppingActivities.size() > 0) { 8355 pw.println(" "); 8356 pw.println(" Activities waiting to stop:"); 8357 dumpHistoryList(pw, mStoppingActivities, " ", "Stop", false); 8358 } 8359 if (mFinishingActivities.size() > 0) { 8360 pw.println(" "); 8361 pw.println(" Activities waiting to finish:"); 8362 dumpHistoryList(pw, mFinishingActivities, " ", "Fin", false); 8363 } 8364 8365 pw.println(" "); 8366 pw.println(" mPausingActivity: " + mPausingActivity); 8367 pw.println(" mResumedActivity: " + mResumedActivity); 8368 pw.println(" mFocusedActivity: " + mFocusedActivity); 8369 pw.println(" mLastPausedActivity: " + mLastPausedActivity); 8370 8371 if (mRecentTasks.size() > 0) { 8372 pw.println(" "); 8373 pw.println("Recent tasks in Current Activity Manager State:"); 8374 8375 final int N = mRecentTasks.size(); 8376 for (int i=0; i<N; i++) { 8377 TaskRecord tr = mRecentTasks.get(i); 8378 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 8379 pw.println(tr); 8380 mRecentTasks.get(i).dump(pw, " "); 8381 } 8382 } 8383 8384 pw.println(" "); 8385 pw.println(" mCurTask: " + mCurTask); 8386 8387 pw.println(" "); 8388 pw.println("Processes in Current Activity Manager State:"); 8389 8390 boolean needSep = false; 8391 int numPers = 0; 8392 8393 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 8394 final int NA = procs.size(); 8395 for (int ia=0; ia<NA; ia++) { 8396 if (!needSep) { 8397 pw.println(" All known processes:"); 8398 needSep = true; 8399 } 8400 ProcessRecord r = procs.valueAt(ia); 8401 pw.print(r.persistent ? " *PERS*" : " *APP*"); 8402 pw.print(" UID "); pw.print(procs.keyAt(ia)); 8403 pw.print(" "); pw.println(r); 8404 r.dump(pw, " "); 8405 if (r.persistent) { 8406 numPers++; 8407 } 8408 } 8409 } 8410 8411 if (mLRUProcesses.size() > 0) { 8412 if (needSep) pw.println(" "); 8413 needSep = true; 8414 pw.println(" Running processes (most recent first):"); 8415 dumpProcessList(pw, mLRUProcesses, " ", 8416 "App ", "PERS", true); 8417 needSep = true; 8418 } 8419 8420 synchronized (mPidsSelfLocked) { 8421 if (mPidsSelfLocked.size() > 0) { 8422 if (needSep) pw.println(" "); 8423 needSep = true; 8424 pw.println(" PID mappings:"); 8425 for (int i=0; i<mPidsSelfLocked.size(); i++) { 8426 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 8427 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 8428 } 8429 } 8430 } 8431 8432 if (mForegroundProcesses.size() > 0) { 8433 if (needSep) pw.println(" "); 8434 needSep = true; 8435 pw.println(" Foreground Processes:"); 8436 for (int i=0; i<mForegroundProcesses.size(); i++) { 8437 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 8438 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 8439 } 8440 } 8441 8442 if (mPersistentStartingProcesses.size() > 0) { 8443 if (needSep) pw.println(" "); 8444 needSep = true; 8445 pw.println(" Persisent processes that are starting:"); 8446 dumpProcessList(pw, mPersistentStartingProcesses, " ", 8447 "Starting Norm", "Restarting PERS", false); 8448 } 8449 8450 if (mStartingProcesses.size() > 0) { 8451 if (needSep) pw.println(" "); 8452 needSep = true; 8453 pw.println(" Processes that are starting:"); 8454 dumpProcessList(pw, mStartingProcesses, " ", 8455 "Starting Norm", "Starting PERS", false); 8456 } 8457 8458 if (mRemovedProcesses.size() > 0) { 8459 if (needSep) pw.println(" "); 8460 needSep = true; 8461 pw.println(" Processes that are being removed:"); 8462 dumpProcessList(pw, mRemovedProcesses, " ", 8463 "Removed Norm", "Removed PERS", false); 8464 } 8465 8466 if (mProcessesOnHold.size() > 0) { 8467 if (needSep) pw.println(" "); 8468 needSep = true; 8469 pw.println(" Processes that are on old until the system is ready:"); 8470 dumpProcessList(pw, mProcessesOnHold, " ", 8471 "OnHold Norm", "OnHold PERS", false); 8472 } 8473 8474 if (mProcessCrashTimes.getMap().size() > 0) { 8475 if (needSep) pw.println(" "); 8476 needSep = true; 8477 pw.println(" Time since processes crashed:"); 8478 long now = SystemClock.uptimeMillis(); 8479 for (Map.Entry<String, SparseArray<Long>> procs 8480 : mProcessCrashTimes.getMap().entrySet()) { 8481 SparseArray<Long> uids = procs.getValue(); 8482 final int N = uids.size(); 8483 for (int i=0; i<N; i++) { 8484 pw.print(" Process "); pw.print(procs.getKey()); 8485 pw.print(" uid "); pw.print(uids.keyAt(i)); 8486 pw.print(": last crashed "); 8487 pw.print((now-uids.valueAt(i))); 8488 pw.println(" ms ago"); 8489 } 8490 } 8491 } 8492 8493 if (mBadProcesses.getMap().size() > 0) { 8494 if (needSep) pw.println(" "); 8495 needSep = true; 8496 pw.println(" Bad processes:"); 8497 for (Map.Entry<String, SparseArray<Long>> procs 8498 : mBadProcesses.getMap().entrySet()) { 8499 SparseArray<Long> uids = procs.getValue(); 8500 final int N = uids.size(); 8501 for (int i=0; i<N; i++) { 8502 pw.print(" Bad process "); pw.print(procs.getKey()); 8503 pw.print(" uid "); pw.print(uids.keyAt(i)); 8504 pw.print(": crashed at time "); 8505 pw.println(uids.valueAt(i)); 8506 } 8507 } 8508 } 8509 8510 pw.println(" "); 8511 pw.println(" Total persistent processes: " + numPers); 8512 pw.println(" mHomeProcess: " + mHomeProcess); 8513 pw.println(" mConfiguration: " + mConfiguration); 8514 pw.println(" mStartRunning=" + mStartRunning 8515 + " mSystemReady=" + mSystemReady 8516 + " mBooting=" + mBooting 8517 + " mBooted=" + mBooted 8518 + " mFactoryTest=" + mFactoryTest); 8519 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown); 8520 pw.println(" mGoingToSleep=" + mGoingToSleep); 8521 pw.println(" mLaunchingActivity=" + mLaunchingActivity); 8522 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 8523 + " mDebugTransient=" + mDebugTransient 8524 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 8525 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 8526 + " mWatcher=" + mWatcher); 8527 } 8528 } 8529 8530 /** 8531 * There are three ways to call this: 8532 * - no service specified: dump all the services 8533 * - a flattened component name that matched an existing service was specified as the 8534 * first arg: dump that one service 8535 * - the first arg isn't the flattened component name of an existing service: 8536 * dump all services whose component contains the first arg as a substring 8537 */ 8538 protected void dumpService(FileDescriptor fd, PrintWriter pw, String[] args) { 8539 String[] newArgs; 8540 String componentNameString; 8541 ServiceRecord r; 8542 if (args.length == 1) { 8543 componentNameString = null; 8544 newArgs = EMPTY_STRING_ARRAY; 8545 r = null; 8546 } else { 8547 componentNameString = args[1]; 8548 ComponentName componentName = ComponentName.unflattenFromString(componentNameString); 8549 r = componentName != null ? mServices.get(componentName) : null; 8550 newArgs = new String[args.length - 2]; 8551 if (args.length > 2) System.arraycopy(args, 2, newArgs, 0, args.length - 2); 8552 } 8553 8554 if (r != null) { 8555 dumpService(fd, pw, r, newArgs); 8556 } else { 8557 for (ServiceRecord r1 : mServices.values()) { 8558 if (componentNameString == null 8559 || r1.name.flattenToString().contains(componentNameString)) { 8560 dumpService(fd, pw, r1, newArgs); 8561 } 8562 } 8563 } 8564 } 8565 8566 /** 8567 * Invokes IApplicationThread.dumpService() on the thread of the specified service if 8568 * there is a thread associated with the service. 8569 */ 8570 private void dumpService(FileDescriptor fd, PrintWriter pw, ServiceRecord r, String[] args) { 8571 pw.println(" Service " + r.name.flattenToString()); 8572 if (r.app != null && r.app.thread != null) { 8573 try { 8574 // flush anything that is already in the PrintWriter since the thread is going 8575 // to write to the file descriptor directly 8576 pw.flush(); 8577 r.app.thread.dumpService(fd, r, args); 8578 pw.print("\n"); 8579 } catch (RemoteException e) { 8580 pw.println("got a RemoteException while dumping the service"); 8581 } 8582 } 8583 } 8584 8585 void dumpBroadcasts(PrintWriter pw) { 8586 synchronized (this) { 8587 if (checkCallingPermission(android.Manifest.permission.DUMP) 8588 != PackageManager.PERMISSION_GRANTED) { 8589 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8590 + Binder.getCallingPid() 8591 + ", uid=" + Binder.getCallingUid() 8592 + " without permission " 8593 + android.Manifest.permission.DUMP); 8594 return; 8595 } 8596 pw.println("Broadcasts in Current Activity Manager State:"); 8597 8598 if (mRegisteredReceivers.size() > 0) { 8599 pw.println(" "); 8600 pw.println(" Registered Receivers:"); 8601 Iterator it = mRegisteredReceivers.values().iterator(); 8602 while (it.hasNext()) { 8603 ReceiverList r = (ReceiverList)it.next(); 8604 pw.print(" * "); pw.println(r); 8605 r.dump(pw, " "); 8606 } 8607 } 8608 8609 pw.println(" "); 8610 pw.println("Receiver Resolver Table:"); 8611 mReceiverResolver.dump(pw, " "); 8612 8613 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0 8614 || mPendingBroadcast != null) { 8615 if (mParallelBroadcasts.size() > 0) { 8616 pw.println(" "); 8617 pw.println(" Active broadcasts:"); 8618 } 8619 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) { 8620 pw.println(" Broadcast #" + i + ":"); 8621 mParallelBroadcasts.get(i).dump(pw, " "); 8622 } 8623 if (mOrderedBroadcasts.size() > 0) { 8624 pw.println(" "); 8625 pw.println(" Active serialized broadcasts:"); 8626 } 8627 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) { 8628 pw.println(" Serialized Broadcast #" + i + ":"); 8629 mOrderedBroadcasts.get(i).dump(pw, " "); 8630 } 8631 pw.println(" "); 8632 pw.println(" Pending broadcast:"); 8633 if (mPendingBroadcast != null) { 8634 mPendingBroadcast.dump(pw, " "); 8635 } else { 8636 pw.println(" (null)"); 8637 } 8638 } 8639 8640 pw.println(" "); 8641 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled); 8642 if (mStickyBroadcasts != null) { 8643 pw.println(" "); 8644 pw.println(" Sticky broadcasts:"); 8645 StringBuilder sb = new StringBuilder(128); 8646 for (Map.Entry<String, ArrayList<Intent>> ent 8647 : mStickyBroadcasts.entrySet()) { 8648 pw.print(" * Sticky action "); pw.print(ent.getKey()); 8649 pw.println(":"); 8650 ArrayList<Intent> intents = ent.getValue(); 8651 final int N = intents.size(); 8652 for (int i=0; i<N; i++) { 8653 sb.setLength(0); 8654 sb.append(" Intent: "); 8655 intents.get(i).toShortString(sb, true, false); 8656 pw.println(sb.toString()); 8657 Bundle bundle = intents.get(i).getExtras(); 8658 if (bundle != null) { 8659 pw.print(" "); 8660 pw.println(bundle.toString()); 8661 } 8662 } 8663 } 8664 } 8665 8666 pw.println(" "); 8667 pw.println(" mHandler:"); 8668 mHandler.dump(new PrintWriterPrinter(pw), " "); 8669 } 8670 } 8671 8672 void dumpServices(PrintWriter pw) { 8673 synchronized (this) { 8674 if (checkCallingPermission(android.Manifest.permission.DUMP) 8675 != PackageManager.PERMISSION_GRANTED) { 8676 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8677 + Binder.getCallingPid() 8678 + ", uid=" + Binder.getCallingUid() 8679 + " without permission " 8680 + android.Manifest.permission.DUMP); 8681 return; 8682 } 8683 pw.println("Services in Current Activity Manager State:"); 8684 8685 boolean needSep = false; 8686 8687 if (mServices.size() > 0) { 8688 pw.println(" Active services:"); 8689 Iterator<ServiceRecord> it = mServices.values().iterator(); 8690 while (it.hasNext()) { 8691 ServiceRecord r = it.next(); 8692 pw.print(" * "); pw.println(r); 8693 r.dump(pw, " "); 8694 } 8695 needSep = true; 8696 } 8697 8698 if (mPendingServices.size() > 0) { 8699 if (needSep) pw.println(" "); 8700 pw.println(" Pending services:"); 8701 for (int i=0; i<mPendingServices.size(); i++) { 8702 ServiceRecord r = mPendingServices.get(i); 8703 pw.print(" * Pending "); pw.println(r); 8704 r.dump(pw, " "); 8705 } 8706 needSep = true; 8707 } 8708 8709 if (mRestartingServices.size() > 0) { 8710 if (needSep) pw.println(" "); 8711 pw.println(" Restarting services:"); 8712 for (int i=0; i<mRestartingServices.size(); i++) { 8713 ServiceRecord r = mRestartingServices.get(i); 8714 pw.print(" * Restarting "); pw.println(r); 8715 r.dump(pw, " "); 8716 } 8717 needSep = true; 8718 } 8719 8720 if (mStoppingServices.size() > 0) { 8721 if (needSep) pw.println(" "); 8722 pw.println(" Stopping services:"); 8723 for (int i=0; i<mStoppingServices.size(); i++) { 8724 ServiceRecord r = mStoppingServices.get(i); 8725 pw.print(" * Stopping "); pw.println(r); 8726 r.dump(pw, " "); 8727 } 8728 needSep = true; 8729 } 8730 8731 if (mServiceConnections.size() > 0) { 8732 if (needSep) pw.println(" "); 8733 pw.println(" Connection bindings to services:"); 8734 Iterator<ConnectionRecord> it 8735 = mServiceConnections.values().iterator(); 8736 while (it.hasNext()) { 8737 ConnectionRecord r = it.next(); 8738 pw.print(" * "); pw.println(r); 8739 r.dump(pw, " "); 8740 } 8741 } 8742 } 8743 } 8744 8745 void dumpProviders(PrintWriter pw) { 8746 synchronized (this) { 8747 if (checkCallingPermission(android.Manifest.permission.DUMP) 8748 != PackageManager.PERMISSION_GRANTED) { 8749 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8750 + Binder.getCallingPid() 8751 + ", uid=" + Binder.getCallingUid() 8752 + " without permission " 8753 + android.Manifest.permission.DUMP); 8754 return; 8755 } 8756 8757 pw.println("Content Providers in Current Activity Manager State:"); 8758 8759 boolean needSep = false; 8760 8761 if (mProvidersByClass.size() > 0) { 8762 if (needSep) pw.println(" "); 8763 pw.println(" Published content providers (by class):"); 8764 Iterator it = mProvidersByClass.entrySet().iterator(); 8765 while (it.hasNext()) { 8766 Map.Entry e = (Map.Entry)it.next(); 8767 ContentProviderRecord r = (ContentProviderRecord)e.getValue(); 8768 pw.print(" * "); pw.println(r); 8769 r.dump(pw, " "); 8770 } 8771 needSep = true; 8772 } 8773 8774 if (mProvidersByName.size() > 0) { 8775 pw.println(" "); 8776 pw.println(" Authority to provider mappings:"); 8777 Iterator it = mProvidersByName.entrySet().iterator(); 8778 while (it.hasNext()) { 8779 Map.Entry e = (Map.Entry)it.next(); 8780 ContentProviderRecord r = (ContentProviderRecord)e.getValue(); 8781 pw.print(" "); pw.print(e.getKey()); pw.print(": "); 8782 pw.println(r); 8783 } 8784 needSep = true; 8785 } 8786 8787 if (mLaunchingProviders.size() > 0) { 8788 if (needSep) pw.println(" "); 8789 pw.println(" Launching content providers:"); 8790 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 8791 pw.print(" Launching #"); pw.print(i); pw.print(": "); 8792 pw.println(mLaunchingProviders.get(i)); 8793 } 8794 needSep = true; 8795 } 8796 8797 if (mGrantedUriPermissions.size() > 0) { 8798 pw.println(); 8799 pw.println("Granted Uri Permissions:"); 8800 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 8801 int uid = mGrantedUriPermissions.keyAt(i); 8802 HashMap<Uri, UriPermission> perms 8803 = mGrantedUriPermissions.valueAt(i); 8804 pw.print(" * UID "); pw.print(uid); 8805 pw.println(" holds:"); 8806 for (UriPermission perm : perms.values()) { 8807 pw.print(" "); pw.println(perm); 8808 perm.dump(pw, " "); 8809 } 8810 } 8811 } 8812 } 8813 } 8814 8815 void dumpSenders(PrintWriter pw) { 8816 synchronized (this) { 8817 if (checkCallingPermission(android.Manifest.permission.DUMP) 8818 != PackageManager.PERMISSION_GRANTED) { 8819 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 8820 + Binder.getCallingPid() 8821 + ", uid=" + Binder.getCallingUid() 8822 + " without permission " 8823 + android.Manifest.permission.DUMP); 8824 return; 8825 } 8826 8827 pw.println("Pending Intents in Current Activity Manager State:"); 8828 8829 if (this.mIntentSenderRecords.size() > 0) { 8830 Iterator<WeakReference<PendingIntentRecord>> it 8831 = mIntentSenderRecords.values().iterator(); 8832 while (it.hasNext()) { 8833 WeakReference<PendingIntentRecord> ref = it.next(); 8834 PendingIntentRecord rec = ref != null ? ref.get(): null; 8835 if (rec != null) { 8836 pw.print(" * "); pw.println(rec); 8837 rec.dump(pw, " "); 8838 } else { 8839 pw.print(" * "); pw.print(ref); 8840 } 8841 } 8842 } 8843 } 8844 } 8845 8846 private static final void dumpHistoryList(PrintWriter pw, List list, 8847 String prefix, String label, boolean complete) { 8848 TaskRecord lastTask = null; 8849 for (int i=list.size()-1; i>=0; i--) { 8850 HistoryRecord r = (HistoryRecord)list.get(i); 8851 final boolean full = complete || !r.inHistory; 8852 if (lastTask != r.task) { 8853 lastTask = r.task; 8854 pw.print(prefix); 8855 pw.print(full ? "* " : " "); 8856 pw.println(lastTask); 8857 if (full) { 8858 lastTask.dump(pw, prefix + " "); 8859 } 8860 } 8861 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 8862 pw.print(" #"); pw.print(i); pw.print(": "); 8863 pw.println(r); 8864 if (full) { 8865 r.dump(pw, prefix + " "); 8866 } 8867 } 8868 } 8869 8870 private static final int dumpProcessList(PrintWriter pw, List list, 8871 String prefix, String normalLabel, String persistentLabel, 8872 boolean inclOomAdj) { 8873 int numPers = 0; 8874 for (int i=list.size()-1; i>=0; i--) { 8875 ProcessRecord r = (ProcessRecord)list.get(i); 8876 if (false) { 8877 pw.println(prefix + (r.persistent ? persistentLabel : normalLabel) 8878 + " #" + i + ":"); 8879 r.dump(pw, prefix + " "); 8880 } else if (inclOomAdj) { 8881 pw.println(String.format("%s%s #%2d: adj=%3d/%d %s", 8882 prefix, (r.persistent ? persistentLabel : normalLabel), 8883 i, r.setAdj, r.setSchedGroup, r.toString())); 8884 } else { 8885 pw.println(String.format("%s%s #%2d: %s", 8886 prefix, (r.persistent ? persistentLabel : normalLabel), 8887 i, r.toString())); 8888 } 8889 if (r.persistent) { 8890 numPers++; 8891 } 8892 } 8893 return numPers; 8894 } 8895 8896 private static final void dumpApplicationMemoryUsage(FileDescriptor fd, 8897 PrintWriter pw, List list, String prefix, String[] args) { 8898 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 8899 long uptime = SystemClock.uptimeMillis(); 8900 long realtime = SystemClock.elapsedRealtime(); 8901 8902 if (isCheckinRequest) { 8903 // short checkin version 8904 pw.println(uptime + "," + realtime); 8905 pw.flush(); 8906 } else { 8907 pw.println("Applications Memory Usage (kB):"); 8908 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 8909 } 8910 for (int i = list.size() - 1 ; i >= 0 ; i--) { 8911 ProcessRecord r = (ProcessRecord)list.get(i); 8912 if (r.thread != null) { 8913 if (!isCheckinRequest) { 8914 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 8915 pw.flush(); 8916 } 8917 try { 8918 r.thread.asBinder().dump(fd, args); 8919 } catch (RemoteException e) { 8920 if (!isCheckinRequest) { 8921 pw.println("Got RemoteException!"); 8922 pw.flush(); 8923 } 8924 } 8925 } 8926 } 8927 } 8928 8929 /** 8930 * Searches array of arguments for the specified string 8931 * @param args array of argument strings 8932 * @param value value to search for 8933 * @return true if the value is contained in the array 8934 */ 8935 private static boolean scanArgs(String[] args, String value) { 8936 if (args != null) { 8937 for (String arg : args) { 8938 if (value.equals(arg)) { 8939 return true; 8940 } 8941 } 8942 } 8943 return false; 8944 } 8945 8946 private final int indexOfTokenLocked(IBinder token, boolean required) { 8947 int count = mHistory.size(); 8948 8949 // convert the token to an entry in the history. 8950 HistoryRecord r = null; 8951 int index = -1; 8952 for (int i=count-1; i>=0; i--) { 8953 Object o = mHistory.get(i); 8954 if (o == token) { 8955 r = (HistoryRecord)o; 8956 index = i; 8957 break; 8958 } 8959 } 8960 if (index < 0 && required) { 8961 RuntimeInit.crash(TAG, new InvalidTokenException(token)); 8962 } 8963 8964 return index; 8965 } 8966 8967 static class InvalidTokenException extends Exception { 8968 InvalidTokenException(IBinder token) { 8969 super("Bad activity token: " + token); 8970 } 8971 } 8972 8973 private final void killServicesLocked(ProcessRecord app, 8974 boolean allowRestart) { 8975 // Report disconnected services. 8976 if (false) { 8977 // XXX we are letting the client link to the service for 8978 // death notifications. 8979 if (app.services.size() > 0) { 8980 Iterator it = app.services.iterator(); 8981 while (it.hasNext()) { 8982 ServiceRecord r = (ServiceRecord)it.next(); 8983 if (r.connections.size() > 0) { 8984 Iterator<ConnectionRecord> jt 8985 = r.connections.values().iterator(); 8986 while (jt.hasNext()) { 8987 ConnectionRecord c = jt.next(); 8988 if (c.binding.client != app) { 8989 try { 8990 //c.conn.connected(r.className, null); 8991 } catch (Exception e) { 8992 // todo: this should be asynchronous! 8993 Log.w(TAG, "Exception thrown disconnected servce " 8994 + r.shortName 8995 + " from app " + app.processName, e); 8996 } 8997 } 8998 } 8999 } 9000 } 9001 } 9002 } 9003 9004 // Clean up any connections this application has to other services. 9005 if (app.connections.size() > 0) { 9006 Iterator<ConnectionRecord> it = app.connections.iterator(); 9007 while (it.hasNext()) { 9008 ConnectionRecord r = it.next(); 9009 removeConnectionLocked(r, app, null); 9010 } 9011 } 9012 app.connections.clear(); 9013 9014 if (app.services.size() != 0) { 9015 // Any services running in the application need to be placed 9016 // back in the pending list. 9017 Iterator it = app.services.iterator(); 9018 while (it.hasNext()) { 9019 ServiceRecord sr = (ServiceRecord)it.next(); 9020 synchronized (sr.stats.getBatteryStats()) { 9021 sr.stats.stopLaunchedLocked(); 9022 } 9023 sr.app = null; 9024 sr.executeNesting = 0; 9025 mStoppingServices.remove(sr); 9026 if (sr.bindings.size() > 0) { 9027 Iterator<IntentBindRecord> bindings 9028 = sr.bindings.values().iterator(); 9029 while (bindings.hasNext()) { 9030 IntentBindRecord b = bindings.next(); 9031 if (DEBUG_SERVICE) Log.v(TAG, "Killing binding " + b 9032 + ": shouldUnbind=" + b.hasBound); 9033 b.binder = null; 9034 b.requested = b.received = b.hasBound = false; 9035 } 9036 } 9037 9038 if (sr.crashCount >= 2) { 9039 Log.w(TAG, "Service crashed " + sr.crashCount 9040 + " times, stopping: " + sr); 9041 EventLog.writeEvent(LOG_AM_SERVICE_CRASHED_TOO_MUCH, 9042 sr.crashCount, sr.shortName, app.pid); 9043 bringDownServiceLocked(sr, true); 9044 } else if (!allowRestart) { 9045 bringDownServiceLocked(sr, true); 9046 } else { 9047 scheduleServiceRestartLocked(sr); 9048 } 9049 } 9050 9051 if (!allowRestart) { 9052 app.services.clear(); 9053 } 9054 } 9055 9056 app.executingServices.clear(); 9057 } 9058 9059 private final void removeDyingProviderLocked(ProcessRecord proc, 9060 ContentProviderRecord cpr) { 9061 synchronized (cpr) { 9062 cpr.launchingApp = null; 9063 cpr.notifyAll(); 9064 } 9065 9066 mProvidersByClass.remove(cpr.info.name); 9067 String names[] = cpr.info.authority.split(";"); 9068 for (int j = 0; j < names.length; j++) { 9069 mProvidersByName.remove(names[j]); 9070 } 9071 9072 Iterator<ProcessRecord> cit = cpr.clients.iterator(); 9073 while (cit.hasNext()) { 9074 ProcessRecord capp = cit.next(); 9075 if (!capp.persistent && capp.thread != null 9076 && capp.pid != 0 9077 && capp.pid != MY_PID) { 9078 Log.i(TAG, "Killing app " + capp.processName 9079 + " (pid " + capp.pid 9080 + ") because provider " + cpr.info.name 9081 + " is in dying process " + proc.processName); 9082 Process.killProcess(capp.pid); 9083 } 9084 } 9085 9086 mLaunchingProviders.remove(cpr); 9087 } 9088 9089 /** 9090 * Main code for cleaning up a process when it has gone away. This is 9091 * called both as a result of the process dying, or directly when stopping 9092 * a process when running in single process mode. 9093 */ 9094 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 9095 boolean restarting, int index) { 9096 if (index >= 0) { 9097 mLRUProcesses.remove(index); 9098 } 9099 9100 // Dismiss any open dialogs. 9101 if (app.crashDialog != null) { 9102 app.crashDialog.dismiss(); 9103 app.crashDialog = null; 9104 } 9105 if (app.anrDialog != null) { 9106 app.anrDialog.dismiss(); 9107 app.anrDialog = null; 9108 } 9109 if (app.waitDialog != null) { 9110 app.waitDialog.dismiss(); 9111 app.waitDialog = null; 9112 } 9113 9114 app.crashing = false; 9115 app.notResponding = false; 9116 9117 app.resetPackageList(); 9118 app.thread = null; 9119 app.forcingToForeground = null; 9120 app.foregroundServices = false; 9121 9122 killServicesLocked(app, true); 9123 9124 boolean restart = false; 9125 9126 int NL = mLaunchingProviders.size(); 9127 9128 // Remove published content providers. 9129 if (!app.pubProviders.isEmpty()) { 9130 Iterator it = app.pubProviders.values().iterator(); 9131 while (it.hasNext()) { 9132 ContentProviderRecord cpr = (ContentProviderRecord)it.next(); 9133 cpr.provider = null; 9134 cpr.app = null; 9135 9136 // See if someone is waiting for this provider... in which 9137 // case we don't remove it, but just let it restart. 9138 int i = 0; 9139 if (!app.bad) { 9140 for (; i<NL; i++) { 9141 if (mLaunchingProviders.get(i) == cpr) { 9142 restart = true; 9143 break; 9144 } 9145 } 9146 } else { 9147 i = NL; 9148 } 9149 9150 if (i >= NL) { 9151 removeDyingProviderLocked(app, cpr); 9152 NL = mLaunchingProviders.size(); 9153 } 9154 } 9155 app.pubProviders.clear(); 9156 } 9157 9158 // Look through the content providers we are waiting to have launched, 9159 // and if any run in this process then either schedule a restart of 9160 // the process or kill the client waiting for it if this process has 9161 // gone bad. 9162 for (int i=0; i<NL; i++) { 9163 ContentProviderRecord cpr = (ContentProviderRecord) 9164 mLaunchingProviders.get(i); 9165 if (cpr.launchingApp == app) { 9166 if (!app.bad) { 9167 restart = true; 9168 } else { 9169 removeDyingProviderLocked(app, cpr); 9170 NL = mLaunchingProviders.size(); 9171 } 9172 } 9173 } 9174 9175 // Unregister from connected content providers. 9176 if (!app.conProviders.isEmpty()) { 9177 Iterator it = app.conProviders.iterator(); 9178 while (it.hasNext()) { 9179 ContentProviderRecord cpr = (ContentProviderRecord)it.next(); 9180 cpr.clients.remove(app); 9181 } 9182 app.conProviders.clear(); 9183 } 9184 9185 skipCurrentReceiverLocked(app); 9186 9187 // Unregister any receivers. 9188 if (app.receivers.size() > 0) { 9189 Iterator<ReceiverList> it = app.receivers.iterator(); 9190 while (it.hasNext()) { 9191 removeReceiverLocked(it.next()); 9192 } 9193 app.receivers.clear(); 9194 } 9195 9196 // If the app is undergoing backup, tell the backup manager about it 9197 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 9198 if (DEBUG_BACKUP) Log.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 9199 try { 9200 IBackupManager bm = IBackupManager.Stub.asInterface( 9201 ServiceManager.getService(Context.BACKUP_SERVICE)); 9202 bm.agentDisconnected(app.info.packageName); 9203 } catch (RemoteException e) { 9204 // can't happen; backup manager is local 9205 } 9206 } 9207 9208 // If the caller is restarting this app, then leave it in its 9209 // current lists and let the caller take care of it. 9210 if (restarting) { 9211 return; 9212 } 9213 9214 if (!app.persistent) { 9215 if (DEBUG_PROCESSES) Log.v(TAG, 9216 "Removing non-persistent process during cleanup: " + app); 9217 mProcessNames.remove(app.processName, app.info.uid); 9218 } else if (!app.removed) { 9219 // This app is persistent, so we need to keep its record around. 9220 // If it is not already on the pending app list, add it there 9221 // and start a new process for it. 9222 app.thread = null; 9223 app.forcingToForeground = null; 9224 app.foregroundServices = false; 9225 if (mPersistentStartingProcesses.indexOf(app) < 0) { 9226 mPersistentStartingProcesses.add(app); 9227 restart = true; 9228 } 9229 } 9230 mProcessesOnHold.remove(app); 9231 9232 if (app == mHomeProcess) { 9233 mHomeProcess = null; 9234 } 9235 9236 if (restart) { 9237 // We have components that still need to be running in the 9238 // process, so re-launch it. 9239 mProcessNames.put(app.processName, app.info.uid, app); 9240 startProcessLocked(app, "restart", app.processName); 9241 } else if (app.pid > 0 && app.pid != MY_PID) { 9242 // Goodbye! 9243 synchronized (mPidsSelfLocked) { 9244 mPidsSelfLocked.remove(app.pid); 9245 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 9246 } 9247 app.setPid(0); 9248 } 9249 } 9250 9251 // ========================================================= 9252 // SERVICES 9253 // ========================================================= 9254 9255 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) { 9256 ActivityManager.RunningServiceInfo info = 9257 new ActivityManager.RunningServiceInfo(); 9258 info.service = r.name; 9259 if (r.app != null) { 9260 info.pid = r.app.pid; 9261 } 9262 info.process = r.processName; 9263 info.foreground = r.isForeground; 9264 info.activeSince = r.createTime; 9265 info.started = r.startRequested; 9266 info.clientCount = r.connections.size(); 9267 info.crashCount = r.crashCount; 9268 info.lastActivityTime = r.lastActivity; 9269 return info; 9270 } 9271 9272 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 9273 int flags) { 9274 synchronized (this) { 9275 ArrayList<ActivityManager.RunningServiceInfo> res 9276 = new ArrayList<ActivityManager.RunningServiceInfo>(); 9277 9278 if (mServices.size() > 0) { 9279 Iterator<ServiceRecord> it = mServices.values().iterator(); 9280 while (it.hasNext() && res.size() < maxNum) { 9281 res.add(makeRunningServiceInfoLocked(it.next())); 9282 } 9283 } 9284 9285 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) { 9286 ServiceRecord r = mRestartingServices.get(i); 9287 ActivityManager.RunningServiceInfo info = 9288 makeRunningServiceInfoLocked(r); 9289 info.restarting = r.nextRestartTime; 9290 res.add(info); 9291 } 9292 9293 return res; 9294 } 9295 } 9296 9297 private final ServiceRecord findServiceLocked(ComponentName name, 9298 IBinder token) { 9299 ServiceRecord r = mServices.get(name); 9300 return r == token ? r : null; 9301 } 9302 9303 private final class ServiceLookupResult { 9304 final ServiceRecord record; 9305 final String permission; 9306 9307 ServiceLookupResult(ServiceRecord _record, String _permission) { 9308 record = _record; 9309 permission = _permission; 9310 } 9311 }; 9312 9313 private ServiceLookupResult findServiceLocked(Intent service, 9314 String resolvedType) { 9315 ServiceRecord r = null; 9316 if (service.getComponent() != null) { 9317 r = mServices.get(service.getComponent()); 9318 } 9319 if (r == null) { 9320 Intent.FilterComparison filter = new Intent.FilterComparison(service); 9321 r = mServicesByIntent.get(filter); 9322 } 9323 9324 if (r == null) { 9325 try { 9326 ResolveInfo rInfo = 9327 ActivityThread.getPackageManager().resolveService( 9328 service, resolvedType, 0); 9329 ServiceInfo sInfo = 9330 rInfo != null ? rInfo.serviceInfo : null; 9331 if (sInfo == null) { 9332 return null; 9333 } 9334 9335 ComponentName name = new ComponentName( 9336 sInfo.applicationInfo.packageName, sInfo.name); 9337 r = mServices.get(name); 9338 } catch (RemoteException ex) { 9339 // pm is in same process, this will never happen. 9340 } 9341 } 9342 if (r != null) { 9343 int callingPid = Binder.getCallingPid(); 9344 int callingUid = Binder.getCallingUid(); 9345 if (checkComponentPermission(r.permission, 9346 callingPid, callingUid, r.exported ? -1 : r.appInfo.uid) 9347 != PackageManager.PERMISSION_GRANTED) { 9348 Log.w(TAG, "Permission Denial: Accessing service " + r.name 9349 + " from pid=" + callingPid 9350 + ", uid=" + callingUid 9351 + " requires " + r.permission); 9352 return new ServiceLookupResult(null, r.permission); 9353 } 9354 return new ServiceLookupResult(r, null); 9355 } 9356 return null; 9357 } 9358 9359 private class ServiceRestarter implements Runnable { 9360 private ServiceRecord mService; 9361 9362 void setService(ServiceRecord service) { 9363 mService = service; 9364 } 9365 9366 public void run() { 9367 synchronized(ActivityManagerService.this) { 9368 performServiceRestartLocked(mService); 9369 } 9370 } 9371 } 9372 9373 private ServiceLookupResult retrieveServiceLocked(Intent service, 9374 String resolvedType, int callingPid, int callingUid) { 9375 ServiceRecord r = null; 9376 if (service.getComponent() != null) { 9377 r = mServices.get(service.getComponent()); 9378 } 9379 Intent.FilterComparison filter = new Intent.FilterComparison(service); 9380 r = mServicesByIntent.get(filter); 9381 if (r == null) { 9382 try { 9383 ResolveInfo rInfo = 9384 ActivityThread.getPackageManager().resolveService( 9385 service, resolvedType, STOCK_PM_FLAGS); 9386 ServiceInfo sInfo = 9387 rInfo != null ? rInfo.serviceInfo : null; 9388 if (sInfo == null) { 9389 Log.w(TAG, "Unable to start service " + service + 9390 ": not found"); 9391 return null; 9392 } 9393 9394 ComponentName name = new ComponentName( 9395 sInfo.applicationInfo.packageName, sInfo.name); 9396 r = mServices.get(name); 9397 if (r == null) { 9398 filter = new Intent.FilterComparison(service.cloneFilter()); 9399 ServiceRestarter res = new ServiceRestarter(); 9400 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 9401 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9402 synchronized (stats) { 9403 ss = stats.getServiceStatsLocked( 9404 sInfo.applicationInfo.uid, sInfo.packageName, 9405 sInfo.name); 9406 } 9407 r = new ServiceRecord(ss, name, filter, sInfo, res); 9408 res.setService(r); 9409 mServices.put(name, r); 9410 mServicesByIntent.put(filter, r); 9411 9412 // Make sure this component isn't in the pending list. 9413 int N = mPendingServices.size(); 9414 for (int i=0; i<N; i++) { 9415 ServiceRecord pr = mPendingServices.get(i); 9416 if (pr.name.equals(name)) { 9417 mPendingServices.remove(i); 9418 i--; 9419 N--; 9420 } 9421 } 9422 } 9423 } catch (RemoteException ex) { 9424 // pm is in same process, this will never happen. 9425 } 9426 } 9427 if (r != null) { 9428 if (checkComponentPermission(r.permission, 9429 callingPid, callingUid, r.exported ? -1 : r.appInfo.uid) 9430 != PackageManager.PERMISSION_GRANTED) { 9431 Log.w(TAG, "Permission Denial: Accessing service " + r.name 9432 + " from pid=" + Binder.getCallingPid() 9433 + ", uid=" + Binder.getCallingUid() 9434 + " requires " + r.permission); 9435 return new ServiceLookupResult(null, r.permission); 9436 } 9437 return new ServiceLookupResult(r, null); 9438 } 9439 return null; 9440 } 9441 9442 private final void bumpServiceExecutingLocked(ServiceRecord r) { 9443 long now = SystemClock.uptimeMillis(); 9444 if (r.executeNesting == 0 && r.app != null) { 9445 if (r.app.executingServices.size() == 0) { 9446 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 9447 msg.obj = r.app; 9448 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT); 9449 } 9450 r.app.executingServices.add(r); 9451 } 9452 r.executeNesting++; 9453 r.executingStart = now; 9454 } 9455 9456 private final void sendServiceArgsLocked(ServiceRecord r, 9457 boolean oomAdjusted) { 9458 final int N = r.startArgs.size(); 9459 if (N == 0) { 9460 return; 9461 } 9462 9463 final int BASEID = r.lastStartId - N + 1; 9464 int i = 0; 9465 while (i < N) { 9466 try { 9467 Intent args = r.startArgs.get(i); 9468 if (DEBUG_SERVICE) Log.v(TAG, "Sending arguments to service: " 9469 + r.name + " " + r.intent + " args=" + args); 9470 bumpServiceExecutingLocked(r); 9471 if (!oomAdjusted) { 9472 oomAdjusted = true; 9473 updateOomAdjLocked(r.app); 9474 } 9475 r.app.thread.scheduleServiceArgs(r, BASEID+i, args); 9476 i++; 9477 } catch (Exception e) { 9478 break; 9479 } 9480 } 9481 if (i == N) { 9482 r.startArgs.clear(); 9483 } else { 9484 while (i > 0) { 9485 r.startArgs.remove(0); 9486 i--; 9487 } 9488 } 9489 } 9490 9491 private final boolean requestServiceBindingLocked(ServiceRecord r, 9492 IntentBindRecord i, boolean rebind) { 9493 if (r.app == null || r.app.thread == null) { 9494 // If service is not currently running, can't yet bind. 9495 return false; 9496 } 9497 if ((!i.requested || rebind) && i.apps.size() > 0) { 9498 try { 9499 bumpServiceExecutingLocked(r); 9500 if (DEBUG_SERVICE) Log.v(TAG, "Connecting binding " + i 9501 + ": shouldUnbind=" + i.hasBound); 9502 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind); 9503 if (!rebind) { 9504 i.requested = true; 9505 } 9506 i.hasBound = true; 9507 i.doRebind = false; 9508 } catch (RemoteException e) { 9509 return false; 9510 } 9511 } 9512 return true; 9513 } 9514 9515 private final void requestServiceBindingsLocked(ServiceRecord r) { 9516 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator(); 9517 while (bindings.hasNext()) { 9518 IntentBindRecord i = bindings.next(); 9519 if (!requestServiceBindingLocked(r, i, false)) { 9520 break; 9521 } 9522 } 9523 } 9524 9525 private final void realStartServiceLocked(ServiceRecord r, 9526 ProcessRecord app) throws RemoteException { 9527 if (app.thread == null) { 9528 throw new RemoteException(); 9529 } 9530 9531 r.app = app; 9532 r.restartTime = r.lastActivity = SystemClock.uptimeMillis(); 9533 9534 app.services.add(r); 9535 bumpServiceExecutingLocked(r); 9536 updateLRUListLocked(app, true); 9537 9538 boolean created = false; 9539 try { 9540 if (DEBUG_SERVICE) Log.v(TAG, "Scheduling start service: " 9541 + r.name + " " + r.intent); 9542 EventLog.writeEvent(LOG_AM_CREATE_SERVICE, 9543 System.identityHashCode(r), r.shortName, 9544 r.intent.getIntent().toString(), r.app.pid); 9545 synchronized (r.stats.getBatteryStats()) { 9546 r.stats.startLaunchedLocked(); 9547 } 9548 app.thread.scheduleCreateService(r, r.serviceInfo); 9549 created = true; 9550 } finally { 9551 if (!created) { 9552 app.services.remove(r); 9553 scheduleServiceRestartLocked(r); 9554 } 9555 } 9556 9557 requestServiceBindingsLocked(r); 9558 sendServiceArgsLocked(r, true); 9559 } 9560 9561 private final void scheduleServiceRestartLocked(ServiceRecord r) { 9562 r.totalRestartCount++; 9563 if (r.restartDelay == 0) { 9564 r.restartCount++; 9565 r.restartDelay = SERVICE_RESTART_DURATION; 9566 } else { 9567 // If it has been a "reasonably long time" since the service 9568 // was started, then reset our restart duration back to 9569 // the beginning, so we don't infinitely increase the duration 9570 // on a service that just occasionally gets killed (which is 9571 // a normal case, due to process being killed to reclaim memory). 9572 long now = SystemClock.uptimeMillis(); 9573 if (now > (r.restartTime+(SERVICE_RESTART_DURATION*2*2*2))) { 9574 r.restartCount = 1; 9575 r.restartDelay = SERVICE_RESTART_DURATION; 9576 } else { 9577 r.restartDelay *= 2; 9578 } 9579 } 9580 if (!mRestartingServices.contains(r)) { 9581 mRestartingServices.add(r); 9582 } 9583 mHandler.removeCallbacks(r.restarter); 9584 mHandler.postDelayed(r.restarter, r.restartDelay); 9585 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay; 9586 Log.w(TAG, "Scheduling restart of crashed service " 9587 + r.shortName + " in " + r.restartDelay + "ms"); 9588 EventLog.writeEvent(LOG_AM_SCHEDULE_SERVICE_RESTART, 9589 r.shortName, r.restartDelay); 9590 9591 Message msg = Message.obtain(); 9592 msg.what = SERVICE_ERROR_MSG; 9593 msg.obj = r; 9594 mHandler.sendMessage(msg); 9595 } 9596 9597 final void performServiceRestartLocked(ServiceRecord r) { 9598 if (!mRestartingServices.contains(r)) { 9599 return; 9600 } 9601 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true); 9602 } 9603 9604 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) { 9605 if (r.restartDelay == 0) { 9606 return false; 9607 } 9608 r.resetRestartCounter(); 9609 mRestartingServices.remove(r); 9610 mHandler.removeCallbacks(r.restarter); 9611 return true; 9612 } 9613 9614 private final boolean bringUpServiceLocked(ServiceRecord r, 9615 int intentFlags, boolean whileRestarting) { 9616 //Log.i(TAG, "Bring up service:"); 9617 //r.dump(" "); 9618 9619 if (r.app != null) { 9620 sendServiceArgsLocked(r, false); 9621 return true; 9622 } 9623 9624 if (!whileRestarting && r.restartDelay > 0) { 9625 // If waiting for a restart, then do nothing. 9626 return true; 9627 } 9628 9629 if (DEBUG_SERVICE) Log.v(TAG, "Bringing up service " + r.name 9630 + " " + r.intent); 9631 9632 final String appName = r.processName; 9633 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid); 9634 if (app != null && app.thread != null) { 9635 try { 9636 realStartServiceLocked(r, app); 9637 return true; 9638 } catch (RemoteException e) { 9639 Log.w(TAG, "Exception when starting service " + r.shortName, e); 9640 } 9641 9642 // If a dead object exception was thrown -- fall through to 9643 // restart the application. 9644 } 9645 9646 if (!mPendingServices.contains(r)) { 9647 // Not running -- get it started, and enqueue this service record 9648 // to be executed when the app comes up. 9649 if (startProcessLocked(appName, r.appInfo, true, intentFlags, 9650 "service", r.name) == null) { 9651 Log.w(TAG, "Unable to launch app " 9652 + r.appInfo.packageName + "/" 9653 + r.appInfo.uid + " for service " 9654 + r.intent.getIntent() + ": process is bad"); 9655 bringDownServiceLocked(r, true); 9656 return false; 9657 } 9658 mPendingServices.add(r); 9659 } 9660 return true; 9661 } 9662 9663 private final void bringDownServiceLocked(ServiceRecord r, boolean force) { 9664 //Log.i(TAG, "Bring down service:"); 9665 //r.dump(" "); 9666 9667 // Does it still need to run? 9668 if (!force && r.startRequested) { 9669 return; 9670 } 9671 if (r.connections.size() > 0) { 9672 if (!force) { 9673 // XXX should probably keep a count of the number of auto-create 9674 // connections directly in the service. 9675 Iterator<ConnectionRecord> it = r.connections.values().iterator(); 9676 while (it.hasNext()) { 9677 ConnectionRecord cr = it.next(); 9678 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) { 9679 return; 9680 } 9681 } 9682 } 9683 9684 // Report to all of the connections that the service is no longer 9685 // available. 9686 Iterator<ConnectionRecord> it = r.connections.values().iterator(); 9687 while (it.hasNext()) { 9688 ConnectionRecord c = it.next(); 9689 try { 9690 // todo: shouldn't be a synchronous call! 9691 c.conn.connected(r.name, null); 9692 } catch (Exception e) { 9693 Log.w(TAG, "Failure disconnecting service " + r.name + 9694 " to connection " + c.conn.asBinder() + 9695 " (in " + c.binding.client.processName + ")", e); 9696 } 9697 } 9698 } 9699 9700 // Tell the service that it has been unbound. 9701 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) { 9702 Iterator<IntentBindRecord> it = r.bindings.values().iterator(); 9703 while (it.hasNext()) { 9704 IntentBindRecord ibr = it.next(); 9705 if (DEBUG_SERVICE) Log.v(TAG, "Bringing down binding " + ibr 9706 + ": hasBound=" + ibr.hasBound); 9707 if (r.app != null && r.app.thread != null && ibr.hasBound) { 9708 try { 9709 bumpServiceExecutingLocked(r); 9710 updateOomAdjLocked(r.app); 9711 ibr.hasBound = false; 9712 r.app.thread.scheduleUnbindService(r, 9713 ibr.intent.getIntent()); 9714 } catch (Exception e) { 9715 Log.w(TAG, "Exception when unbinding service " 9716 + r.shortName, e); 9717 serviceDoneExecutingLocked(r, true); 9718 } 9719 } 9720 } 9721 } 9722 9723 if (DEBUG_SERVICE) Log.v(TAG, "Bringing down service " + r.name 9724 + " " + r.intent); 9725 EventLog.writeEvent(LOG_AM_DESTROY_SERVICE, 9726 System.identityHashCode(r), r.shortName, 9727 (r.app != null) ? r.app.pid : -1); 9728 9729 mServices.remove(r.name); 9730 mServicesByIntent.remove(r.intent); 9731 if (localLOGV) Log.v(TAG, "BRING DOWN SERVICE: " + r.shortName); 9732 r.totalRestartCount = 0; 9733 unscheduleServiceRestartLocked(r); 9734 9735 // Also make sure it is not on the pending list. 9736 int N = mPendingServices.size(); 9737 for (int i=0; i<N; i++) { 9738 if (mPendingServices.get(i) == r) { 9739 mPendingServices.remove(i); 9740 if (DEBUG_SERVICE) Log.v( 9741 TAG, "Removed pending service: " + r.shortName); 9742 i--; 9743 N--; 9744 } 9745 } 9746 9747 if (r.app != null) { 9748 synchronized (r.stats.getBatteryStats()) { 9749 r.stats.stopLaunchedLocked(); 9750 } 9751 r.app.services.remove(r); 9752 if (r.app.thread != null) { 9753 updateServiceForegroundLocked(r.app, false); 9754 try { 9755 Log.i(TAG, "Stopping service: " + r.shortName); 9756 bumpServiceExecutingLocked(r); 9757 mStoppingServices.add(r); 9758 updateOomAdjLocked(r.app); 9759 r.app.thread.scheduleStopService(r); 9760 } catch (Exception e) { 9761 Log.w(TAG, "Exception when stopping service " 9762 + r.shortName, e); 9763 serviceDoneExecutingLocked(r, true); 9764 } 9765 } else { 9766 if (DEBUG_SERVICE) Log.v( 9767 TAG, "Removed service that has no process: " + r.shortName); 9768 } 9769 } else { 9770 if (DEBUG_SERVICE) Log.v( 9771 TAG, "Removed service that is not running: " + r.shortName); 9772 } 9773 } 9774 9775 ComponentName startServiceLocked(IApplicationThread caller, 9776 Intent service, String resolvedType, 9777 int callingPid, int callingUid) { 9778 synchronized(this) { 9779 if (DEBUG_SERVICE) Log.v(TAG, "startService: " + service 9780 + " type=" + resolvedType + " args=" + service.getExtras()); 9781 9782 if (caller != null) { 9783 final ProcessRecord callerApp = getRecordForAppLocked(caller); 9784 if (callerApp == null) { 9785 throw new SecurityException( 9786 "Unable to find app for caller " + caller 9787 + " (pid=" + Binder.getCallingPid() 9788 + ") when starting service " + service); 9789 } 9790 } 9791 9792 ServiceLookupResult res = 9793 retrieveServiceLocked(service, resolvedType, 9794 callingPid, callingUid); 9795 if (res == null) { 9796 return null; 9797 } 9798 if (res.record == null) { 9799 return new ComponentName("!", res.permission != null 9800 ? res.permission : "private to package"); 9801 } 9802 ServiceRecord r = res.record; 9803 if (unscheduleServiceRestartLocked(r)) { 9804 if (DEBUG_SERVICE) Log.v(TAG, "START SERVICE WHILE RESTART PENDING: " 9805 + r.shortName); 9806 } 9807 r.startRequested = true; 9808 r.startArgs.add(service); 9809 r.lastStartId++; 9810 if (r.lastStartId < 1) { 9811 r.lastStartId = 1; 9812 } 9813 r.lastActivity = SystemClock.uptimeMillis(); 9814 synchronized (r.stats.getBatteryStats()) { 9815 r.stats.startRunningLocked(); 9816 } 9817 if (!bringUpServiceLocked(r, service.getFlags(), false)) { 9818 return new ComponentName("!", "Service process is bad"); 9819 } 9820 return r.name; 9821 } 9822 } 9823 9824 public ComponentName startService(IApplicationThread caller, Intent service, 9825 String resolvedType) { 9826 // Refuse possible leaked file descriptors 9827 if (service != null && service.hasFileDescriptors() == true) { 9828 throw new IllegalArgumentException("File descriptors passed in Intent"); 9829 } 9830 9831 synchronized(this) { 9832 final int callingPid = Binder.getCallingPid(); 9833 final int callingUid = Binder.getCallingUid(); 9834 final long origId = Binder.clearCallingIdentity(); 9835 ComponentName res = startServiceLocked(caller, service, 9836 resolvedType, callingPid, callingUid); 9837 Binder.restoreCallingIdentity(origId); 9838 return res; 9839 } 9840 } 9841 9842 ComponentName startServiceInPackage(int uid, 9843 Intent service, String resolvedType) { 9844 synchronized(this) { 9845 final long origId = Binder.clearCallingIdentity(); 9846 ComponentName res = startServiceLocked(null, service, 9847 resolvedType, -1, uid); 9848 Binder.restoreCallingIdentity(origId); 9849 return res; 9850 } 9851 } 9852 9853 public int stopService(IApplicationThread caller, Intent service, 9854 String resolvedType) { 9855 // Refuse possible leaked file descriptors 9856 if (service != null && service.hasFileDescriptors() == true) { 9857 throw new IllegalArgumentException("File descriptors passed in Intent"); 9858 } 9859 9860 synchronized(this) { 9861 if (DEBUG_SERVICE) Log.v(TAG, "stopService: " + service 9862 + " type=" + resolvedType); 9863 9864 final ProcessRecord callerApp = getRecordForAppLocked(caller); 9865 if (caller != null && callerApp == null) { 9866 throw new SecurityException( 9867 "Unable to find app for caller " + caller 9868 + " (pid=" + Binder.getCallingPid() 9869 + ") when stopping service " + service); 9870 } 9871 9872 // If this service is active, make sure it is stopped. 9873 ServiceLookupResult r = findServiceLocked(service, resolvedType); 9874 if (r != null) { 9875 if (r.record != null) { 9876 synchronized (r.record.stats.getBatteryStats()) { 9877 r.record.stats.stopRunningLocked(); 9878 } 9879 r.record.startRequested = false; 9880 final long origId = Binder.clearCallingIdentity(); 9881 bringDownServiceLocked(r.record, false); 9882 Binder.restoreCallingIdentity(origId); 9883 return 1; 9884 } 9885 return -1; 9886 } 9887 } 9888 9889 return 0; 9890 } 9891 9892 public IBinder peekService(Intent service, String resolvedType) { 9893 // Refuse possible leaked file descriptors 9894 if (service != null && service.hasFileDescriptors() == true) { 9895 throw new IllegalArgumentException("File descriptors passed in Intent"); 9896 } 9897 9898 IBinder ret = null; 9899 9900 synchronized(this) { 9901 ServiceLookupResult r = findServiceLocked(service, resolvedType); 9902 9903 if (r != null) { 9904 // r.record is null if findServiceLocked() failed the caller permission check 9905 if (r.record == null) { 9906 throw new SecurityException( 9907 "Permission Denial: Accessing service " + r.record.name 9908 + " from pid=" + Binder.getCallingPid() 9909 + ", uid=" + Binder.getCallingUid() 9910 + " requires " + r.permission); 9911 } 9912 IntentBindRecord ib = r.record.bindings.get(r.record.intent); 9913 if (ib != null) { 9914 ret = ib.binder; 9915 } 9916 } 9917 } 9918 9919 return ret; 9920 } 9921 9922 public boolean stopServiceToken(ComponentName className, IBinder token, 9923 int startId) { 9924 synchronized(this) { 9925 if (DEBUG_SERVICE) Log.v(TAG, "stopServiceToken: " + className 9926 + " " + token + " startId=" + startId); 9927 ServiceRecord r = findServiceLocked(className, token); 9928 if (r != null && (startId < 0 || r.lastStartId == startId)) { 9929 synchronized (r.stats.getBatteryStats()) { 9930 r.stats.stopRunningLocked(); 9931 r.startRequested = false; 9932 } 9933 final long origId = Binder.clearCallingIdentity(); 9934 bringDownServiceLocked(r, false); 9935 Binder.restoreCallingIdentity(origId); 9936 return true; 9937 } 9938 } 9939 return false; 9940 } 9941 9942 public void setServiceForeground(ComponentName className, IBinder token, 9943 boolean isForeground) { 9944 synchronized(this) { 9945 ServiceRecord r = findServiceLocked(className, token); 9946 if (r != null) { 9947 if (r.isForeground != isForeground) { 9948 final long origId = Binder.clearCallingIdentity(); 9949 r.isForeground = isForeground; 9950 if (r.app != null) { 9951 updateServiceForegroundLocked(r.app, true); 9952 } 9953 Binder.restoreCallingIdentity(origId); 9954 } 9955 } 9956 } 9957 } 9958 9959 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) { 9960 boolean anyForeground = false; 9961 for (ServiceRecord sr : (HashSet<ServiceRecord>)proc.services) { 9962 if (sr.isForeground) { 9963 anyForeground = true; 9964 break; 9965 } 9966 } 9967 if (anyForeground != proc.foregroundServices) { 9968 proc.foregroundServices = anyForeground; 9969 if (oomAdj) { 9970 updateOomAdjLocked(); 9971 } 9972 } 9973 } 9974 9975 public int bindService(IApplicationThread caller, IBinder token, 9976 Intent service, String resolvedType, 9977 IServiceConnection connection, int flags) { 9978 // Refuse possible leaked file descriptors 9979 if (service != null && service.hasFileDescriptors() == true) { 9980 throw new IllegalArgumentException("File descriptors passed in Intent"); 9981 } 9982 9983 synchronized(this) { 9984 if (DEBUG_SERVICE) Log.v(TAG, "bindService: " + service 9985 + " type=" + resolvedType + " conn=" + connection.asBinder() 9986 + " flags=0x" + Integer.toHexString(flags)); 9987 final ProcessRecord callerApp = getRecordForAppLocked(caller); 9988 if (callerApp == null) { 9989 throw new SecurityException( 9990 "Unable to find app for caller " + caller 9991 + " (pid=" + Binder.getCallingPid() 9992 + ") when binding service " + service); 9993 } 9994 9995 HistoryRecord activity = null; 9996 if (token != null) { 9997 int aindex = indexOfTokenLocked(token, false); 9998 if (aindex < 0) { 9999 Log.w(TAG, "Binding with unknown activity: " + token); 10000 return 0; 10001 } 10002 activity = (HistoryRecord)mHistory.get(aindex); 10003 } 10004 10005 ServiceLookupResult res = 10006 retrieveServiceLocked(service, resolvedType, 10007 Binder.getCallingPid(), Binder.getCallingUid()); 10008 if (res == null) { 10009 return 0; 10010 } 10011 if (res.record == null) { 10012 return -1; 10013 } 10014 ServiceRecord s = res.record; 10015 10016 final long origId = Binder.clearCallingIdentity(); 10017 10018 if (unscheduleServiceRestartLocked(s)) { 10019 if (DEBUG_SERVICE) Log.v(TAG, "BIND SERVICE WHILE RESTART PENDING: " 10020 + s.shortName); 10021 } 10022 10023 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp); 10024 ConnectionRecord c = new ConnectionRecord(b, activity, 10025 connection, flags); 10026 10027 IBinder binder = connection.asBinder(); 10028 s.connections.put(binder, c); 10029 b.connections.add(c); 10030 if (activity != null) { 10031 if (activity.connections == null) { 10032 activity.connections = new HashSet<ConnectionRecord>(); 10033 } 10034 activity.connections.add(c); 10035 } 10036 b.client.connections.add(c); 10037 mServiceConnections.put(binder, c); 10038 10039 if ((flags&Context.BIND_AUTO_CREATE) != 0) { 10040 s.lastActivity = SystemClock.uptimeMillis(); 10041 if (!bringUpServiceLocked(s, service.getFlags(), false)) { 10042 return 0; 10043 } 10044 } 10045 10046 if (s.app != null) { 10047 // This could have made the service more important. 10048 updateOomAdjLocked(s.app); 10049 } 10050 10051 if (DEBUG_SERVICE) Log.v(TAG, "Bind " + s + " with " + b 10052 + ": received=" + b.intent.received 10053 + " apps=" + b.intent.apps.size() 10054 + " doRebind=" + b.intent.doRebind); 10055 10056 if (s.app != null && b.intent.received) { 10057 // Service is already running, so we can immediately 10058 // publish the connection. 10059 try { 10060 c.conn.connected(s.name, b.intent.binder); 10061 } catch (Exception e) { 10062 Log.w(TAG, "Failure sending service " + s.shortName 10063 + " to connection " + c.conn.asBinder() 10064 + " (in " + c.binding.client.processName + ")", e); 10065 } 10066 10067 // If this is the first app connected back to this binding, 10068 // and the service had previously asked to be told when 10069 // rebound, then do so. 10070 if (b.intent.apps.size() == 1 && b.intent.doRebind) { 10071 requestServiceBindingLocked(s, b.intent, true); 10072 } 10073 } else if (!b.intent.requested) { 10074 requestServiceBindingLocked(s, b.intent, false); 10075 } 10076 10077 Binder.restoreCallingIdentity(origId); 10078 } 10079 10080 return 1; 10081 } 10082 10083 private void removeConnectionLocked( 10084 ConnectionRecord c, ProcessRecord skipApp, HistoryRecord skipAct) { 10085 IBinder binder = c.conn.asBinder(); 10086 AppBindRecord b = c.binding; 10087 ServiceRecord s = b.service; 10088 s.connections.remove(binder); 10089 b.connections.remove(c); 10090 if (c.activity != null && c.activity != skipAct) { 10091 if (c.activity.connections != null) { 10092 c.activity.connections.remove(c); 10093 } 10094 } 10095 if (b.client != skipApp) { 10096 b.client.connections.remove(c); 10097 } 10098 mServiceConnections.remove(binder); 10099 10100 if (b.connections.size() == 0) { 10101 b.intent.apps.remove(b.client); 10102 } 10103 10104 if (DEBUG_SERVICE) Log.v(TAG, "Disconnecting binding " + b.intent 10105 + ": shouldUnbind=" + b.intent.hasBound); 10106 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0 10107 && b.intent.hasBound) { 10108 try { 10109 bumpServiceExecutingLocked(s); 10110 updateOomAdjLocked(s.app); 10111 b.intent.hasBound = false; 10112 // Assume the client doesn't want to know about a rebind; 10113 // we will deal with that later if it asks for one. 10114 b.intent.doRebind = false; 10115 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent()); 10116 } catch (Exception e) { 10117 Log.w(TAG, "Exception when unbinding service " + s.shortName, e); 10118 serviceDoneExecutingLocked(s, true); 10119 } 10120 } 10121 10122 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) { 10123 bringDownServiceLocked(s, false); 10124 } 10125 } 10126 10127 public boolean unbindService(IServiceConnection connection) { 10128 synchronized (this) { 10129 IBinder binder = connection.asBinder(); 10130 if (DEBUG_SERVICE) Log.v(TAG, "unbindService: conn=" + binder); 10131 ConnectionRecord r = mServiceConnections.get(binder); 10132 if (r == null) { 10133 Log.w(TAG, "Unbind failed: could not find connection for " 10134 + connection.asBinder()); 10135 return false; 10136 } 10137 10138 final long origId = Binder.clearCallingIdentity(); 10139 10140 removeConnectionLocked(r, null, null); 10141 10142 if (r.binding.service.app != null) { 10143 // This could have made the service less important. 10144 updateOomAdjLocked(r.binding.service.app); 10145 } 10146 10147 Binder.restoreCallingIdentity(origId); 10148 } 10149 10150 return true; 10151 } 10152 10153 public void publishService(IBinder token, Intent intent, IBinder service) { 10154 // Refuse possible leaked file descriptors 10155 if (intent != null && intent.hasFileDescriptors() == true) { 10156 throw new IllegalArgumentException("File descriptors passed in Intent"); 10157 } 10158 10159 synchronized(this) { 10160 if (!(token instanceof ServiceRecord)) { 10161 throw new IllegalArgumentException("Invalid service token"); 10162 } 10163 ServiceRecord r = (ServiceRecord)token; 10164 10165 final long origId = Binder.clearCallingIdentity(); 10166 10167 if (DEBUG_SERVICE) Log.v(TAG, "PUBLISHING SERVICE " + r.name 10168 + " " + intent + ": " + service); 10169 if (r != null) { 10170 Intent.FilterComparison filter 10171 = new Intent.FilterComparison(intent); 10172 IntentBindRecord b = r.bindings.get(filter); 10173 if (b != null && !b.received) { 10174 b.binder = service; 10175 b.requested = true; 10176 b.received = true; 10177 if (r.connections.size() > 0) { 10178 Iterator<ConnectionRecord> it 10179 = r.connections.values().iterator(); 10180 while (it.hasNext()) { 10181 ConnectionRecord c = it.next(); 10182 if (!filter.equals(c.binding.intent.intent)) { 10183 if (DEBUG_SERVICE) Log.v( 10184 TAG, "Not publishing to: " + c); 10185 if (DEBUG_SERVICE) Log.v( 10186 TAG, "Bound intent: " + c.binding.intent.intent); 10187 if (DEBUG_SERVICE) Log.v( 10188 TAG, "Published intent: " + intent); 10189 continue; 10190 } 10191 if (DEBUG_SERVICE) Log.v(TAG, "Publishing to: " + c); 10192 try { 10193 c.conn.connected(r.name, service); 10194 } catch (Exception e) { 10195 Log.w(TAG, "Failure sending service " + r.name + 10196 " to connection " + c.conn.asBinder() + 10197 " (in " + c.binding.client.processName + ")", e); 10198 } 10199 } 10200 } 10201 } 10202 10203 serviceDoneExecutingLocked(r, mStoppingServices.contains(r)); 10204 10205 Binder.restoreCallingIdentity(origId); 10206 } 10207 } 10208 } 10209 10210 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 10211 // Refuse possible leaked file descriptors 10212 if (intent != null && intent.hasFileDescriptors() == true) { 10213 throw new IllegalArgumentException("File descriptors passed in Intent"); 10214 } 10215 10216 synchronized(this) { 10217 if (!(token instanceof ServiceRecord)) { 10218 throw new IllegalArgumentException("Invalid service token"); 10219 } 10220 ServiceRecord r = (ServiceRecord)token; 10221 10222 final long origId = Binder.clearCallingIdentity(); 10223 10224 if (r != null) { 10225 Intent.FilterComparison filter 10226 = new Intent.FilterComparison(intent); 10227 IntentBindRecord b = r.bindings.get(filter); 10228 if (DEBUG_SERVICE) Log.v(TAG, "unbindFinished in " + r 10229 + " at " + b + ": apps=" 10230 + (b != null ? b.apps.size() : 0)); 10231 if (b != null) { 10232 if (b.apps.size() > 0) { 10233 // Applications have already bound since the last 10234 // unbind, so just rebind right here. 10235 requestServiceBindingLocked(r, b, true); 10236 } else { 10237 // Note to tell the service the next time there is 10238 // a new client. 10239 b.doRebind = true; 10240 } 10241 } 10242 10243 serviceDoneExecutingLocked(r, mStoppingServices.contains(r)); 10244 10245 Binder.restoreCallingIdentity(origId); 10246 } 10247 } 10248 } 10249 10250 public void serviceDoneExecuting(IBinder token) { 10251 synchronized(this) { 10252 if (!(token instanceof ServiceRecord)) { 10253 throw new IllegalArgumentException("Invalid service token"); 10254 } 10255 ServiceRecord r = (ServiceRecord)token; 10256 boolean inStopping = mStoppingServices.contains(token); 10257 if (r != null) { 10258 if (DEBUG_SERVICE) Log.v(TAG, "DONE EXECUTING SERVICE " + r.name 10259 + ": nesting=" + r.executeNesting 10260 + ", inStopping=" + inStopping); 10261 if (r != token) { 10262 Log.w(TAG, "Done executing service " + r.name 10263 + " with incorrect token: given " + token 10264 + ", expected " + r); 10265 return; 10266 } 10267 10268 final long origId = Binder.clearCallingIdentity(); 10269 serviceDoneExecutingLocked(r, inStopping); 10270 Binder.restoreCallingIdentity(origId); 10271 } else { 10272 Log.w(TAG, "Done executing unknown service " + r.name 10273 + " with token " + token); 10274 } 10275 } 10276 } 10277 10278 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) { 10279 r.executeNesting--; 10280 if (r.executeNesting <= 0 && r.app != null) { 10281 r.app.executingServices.remove(r); 10282 if (r.app.executingServices.size() == 0) { 10283 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app); 10284 } 10285 if (inStopping) { 10286 mStoppingServices.remove(r); 10287 } 10288 updateOomAdjLocked(r.app); 10289 } 10290 } 10291 10292 void serviceTimeout(ProcessRecord proc) { 10293 synchronized(this) { 10294 if (proc.executingServices.size() == 0 || proc.thread == null) { 10295 return; 10296 } 10297 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT; 10298 Iterator<ServiceRecord> it = proc.executingServices.iterator(); 10299 ServiceRecord timeout = null; 10300 long nextTime = 0; 10301 while (it.hasNext()) { 10302 ServiceRecord sr = it.next(); 10303 if (sr.executingStart < maxTime) { 10304 timeout = sr; 10305 break; 10306 } 10307 if (sr.executingStart > nextTime) { 10308 nextTime = sr.executingStart; 10309 } 10310 } 10311 if (timeout != null && mLRUProcesses.contains(proc)) { 10312 Log.w(TAG, "Timeout executing service: " + timeout); 10313 appNotRespondingLocked(proc, null, "Executing service " 10314 + timeout.name); 10315 } else { 10316 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 10317 msg.obj = proc; 10318 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT); 10319 } 10320 } 10321 } 10322 10323 // ========================================================= 10324 // BACKUP AND RESTORE 10325 // ========================================================= 10326 10327 // Cause the target app to be launched if necessary and its backup agent 10328 // instantiated. The backup agent will invoke backupAgentCreated() on the 10329 // activity manager to announce its creation. 10330 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 10331 if (DEBUG_BACKUP) Log.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 10332 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 10333 10334 synchronized(this) { 10335 // !!! TODO: currently no check here that we're already bound 10336 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10337 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10338 synchronized (stats) { 10339 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 10340 } 10341 10342 BackupRecord r = new BackupRecord(ss, app, backupMode); 10343 ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName); 10344 // startProcessLocked() returns existing proc's record if it's already running 10345 ProcessRecord proc = startProcessLocked(app.processName, app, 10346 false, 0, "backup", hostingName); 10347 if (proc == null) { 10348 Log.e(TAG, "Unable to start backup agent process " + r); 10349 return false; 10350 } 10351 10352 r.app = proc; 10353 mBackupTarget = r; 10354 mBackupAppName = app.packageName; 10355 10356 // Try not to kill the process during backup 10357 updateOomAdjLocked(proc); 10358 10359 // If the process is already attached, schedule the creation of the backup agent now. 10360 // If it is not yet live, this will be done when it attaches to the framework. 10361 if (proc.thread != null) { 10362 if (DEBUG_BACKUP) Log.v(TAG, "Agent proc already running: " + proc); 10363 try { 10364 proc.thread.scheduleCreateBackupAgent(app, backupMode); 10365 } catch (RemoteException e) { 10366 // !!! TODO: notify the backup manager that we crashed, or rely on 10367 // death notices, or...? 10368 } 10369 } else { 10370 if (DEBUG_BACKUP) Log.v(TAG, "Agent proc not running, waiting for attach"); 10371 } 10372 // Invariants: at this point, the target app process exists and the application 10373 // is either already running or in the process of coming up. mBackupTarget and 10374 // mBackupAppName describe the app, so that when it binds back to the AM we 10375 // know that it's scheduled for a backup-agent operation. 10376 } 10377 10378 return true; 10379 } 10380 10381 // A backup agent has just come up 10382 public void backupAgentCreated(String agentPackageName, IBinder agent) { 10383 if (DEBUG_BACKUP) Log.v(TAG, "backupAgentCreated: " + agentPackageName 10384 + " = " + agent); 10385 10386 synchronized(this) { 10387 if (!agentPackageName.equals(mBackupAppName)) { 10388 Log.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 10389 return; 10390 } 10391 10392 long oldIdent = Binder.clearCallingIdentity(); 10393 try { 10394 IBackupManager bm = IBackupManager.Stub.asInterface( 10395 ServiceManager.getService(Context.BACKUP_SERVICE)); 10396 bm.agentConnected(agentPackageName, agent); 10397 } catch (RemoteException e) { 10398 // can't happen; the backup manager service is local 10399 } catch (Exception e) { 10400 Log.w(TAG, "Exception trying to deliver BackupAgent binding: "); 10401 e.printStackTrace(); 10402 } finally { 10403 Binder.restoreCallingIdentity(oldIdent); 10404 } 10405 } 10406 } 10407 10408 // done with this agent 10409 public void unbindBackupAgent(ApplicationInfo appInfo) { 10410 if (DEBUG_BACKUP) Log.v(TAG, "unbindBackupAgent: " + appInfo); 10411 10412 synchronized(this) { 10413 if (!mBackupAppName.equals(appInfo.packageName)) { 10414 Log.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 10415 return; 10416 } 10417 10418 ProcessRecord proc = mBackupTarget.app; 10419 mBackupTarget = null; 10420 mBackupAppName = null; 10421 10422 // Not backing this app up any more; reset its OOM adjustment 10423 updateOomAdjLocked(proc); 10424 10425 // If the app crashed during backup, 'thread' will be null here 10426 if (proc.thread != null) { 10427 try { 10428 proc.thread.scheduleDestroyBackupAgent(appInfo); 10429 } catch (Exception e) { 10430 Log.e(TAG, "Exception when unbinding backup agent:"); 10431 e.printStackTrace(); 10432 } 10433 } 10434 } 10435 } 10436 // ========================================================= 10437 // BROADCASTS 10438 // ========================================================= 10439 10440 private final List getStickies(String action, IntentFilter filter, 10441 List cur) { 10442 final ContentResolver resolver = mContext.getContentResolver(); 10443 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 10444 if (list == null) { 10445 return cur; 10446 } 10447 int N = list.size(); 10448 for (int i=0; i<N; i++) { 10449 Intent intent = list.get(i); 10450 if (filter.match(resolver, intent, true, TAG) >= 0) { 10451 if (cur == null) { 10452 cur = new ArrayList<Intent>(); 10453 } 10454 cur.add(intent); 10455 } 10456 } 10457 return cur; 10458 } 10459 10460 private final void scheduleBroadcastsLocked() { 10461 if (DEBUG_BROADCAST) Log.v(TAG, "Schedule broadcasts: current=" 10462 + mBroadcastsScheduled); 10463 10464 if (mBroadcastsScheduled) { 10465 return; 10466 } 10467 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG); 10468 mBroadcastsScheduled = true; 10469 } 10470 10471 public Intent registerReceiver(IApplicationThread caller, 10472 IIntentReceiver receiver, IntentFilter filter, String permission) { 10473 synchronized(this) { 10474 ProcessRecord callerApp = null; 10475 if (caller != null) { 10476 callerApp = getRecordForAppLocked(caller); 10477 if (callerApp == null) { 10478 throw new SecurityException( 10479 "Unable to find app for caller " + caller 10480 + " (pid=" + Binder.getCallingPid() 10481 + ") when registering receiver " + receiver); 10482 } 10483 } 10484 10485 List allSticky = null; 10486 10487 // Look for any matching sticky broadcasts... 10488 Iterator actions = filter.actionsIterator(); 10489 if (actions != null) { 10490 while (actions.hasNext()) { 10491 String action = (String)actions.next(); 10492 allSticky = getStickies(action, filter, allSticky); 10493 } 10494 } else { 10495 allSticky = getStickies(null, filter, allSticky); 10496 } 10497 10498 // The first sticky in the list is returned directly back to 10499 // the client. 10500 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 10501 10502 if (DEBUG_BROADCAST) Log.v(TAG, "Register receiver " + filter 10503 + ": " + sticky); 10504 10505 if (receiver == null) { 10506 return sticky; 10507 } 10508 10509 ReceiverList rl 10510 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 10511 if (rl == null) { 10512 rl = new ReceiverList(this, callerApp, 10513 Binder.getCallingPid(), 10514 Binder.getCallingUid(), receiver); 10515 if (rl.app != null) { 10516 rl.app.receivers.add(rl); 10517 } else { 10518 try { 10519 receiver.asBinder().linkToDeath(rl, 0); 10520 } catch (RemoteException e) { 10521 return sticky; 10522 } 10523 rl.linkedToDeath = true; 10524 } 10525 mRegisteredReceivers.put(receiver.asBinder(), rl); 10526 } 10527 BroadcastFilter bf = new BroadcastFilter(filter, rl, permission); 10528 rl.add(bf); 10529 if (!bf.debugCheck()) { 10530 Log.w(TAG, "==> For Dynamic broadast"); 10531 } 10532 mReceiverResolver.addFilter(bf); 10533 10534 // Enqueue broadcasts for all existing stickies that match 10535 // this filter. 10536 if (allSticky != null) { 10537 ArrayList receivers = new ArrayList(); 10538 receivers.add(bf); 10539 10540 int N = allSticky.size(); 10541 for (int i=0; i<N; i++) { 10542 Intent intent = (Intent)allSticky.get(i); 10543 BroadcastRecord r = new BroadcastRecord(intent, null, 10544 null, -1, -1, null, receivers, null, 0, null, null, 10545 false); 10546 if (mParallelBroadcasts.size() == 0) { 10547 scheduleBroadcastsLocked(); 10548 } 10549 mParallelBroadcasts.add(r); 10550 } 10551 } 10552 10553 return sticky; 10554 } 10555 } 10556 10557 public void unregisterReceiver(IIntentReceiver receiver) { 10558 if (DEBUG_BROADCAST) Log.v(TAG, "Unregister receiver: " + receiver); 10559 10560 boolean doNext = false; 10561 10562 synchronized(this) { 10563 ReceiverList rl 10564 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 10565 if (rl != null) { 10566 if (rl.curBroadcast != null) { 10567 BroadcastRecord r = rl.curBroadcast; 10568 doNext = finishReceiverLocked( 10569 receiver.asBinder(), r.resultCode, r.resultData, 10570 r.resultExtras, r.resultAbort, true); 10571 } 10572 10573 if (rl.app != null) { 10574 rl.app.receivers.remove(rl); 10575 } 10576 removeReceiverLocked(rl); 10577 if (rl.linkedToDeath) { 10578 rl.linkedToDeath = false; 10579 rl.receiver.asBinder().unlinkToDeath(rl, 0); 10580 } 10581 } 10582 } 10583 10584 if (!doNext) { 10585 return; 10586 } 10587 10588 final long origId = Binder.clearCallingIdentity(); 10589 processNextBroadcast(false); 10590 trimApplications(); 10591 Binder.restoreCallingIdentity(origId); 10592 } 10593 10594 void removeReceiverLocked(ReceiverList rl) { 10595 mRegisteredReceivers.remove(rl.receiver.asBinder()); 10596 int N = rl.size(); 10597 for (int i=0; i<N; i++) { 10598 mReceiverResolver.removeFilter(rl.get(i)); 10599 } 10600 } 10601 10602 private final int broadcastIntentLocked(ProcessRecord callerApp, 10603 String callerPackage, Intent intent, String resolvedType, 10604 IIntentReceiver resultTo, int resultCode, String resultData, 10605 Bundle map, String requiredPermission, 10606 boolean ordered, boolean sticky, int callingPid, int callingUid) { 10607 intent = new Intent(intent); 10608 10609 if (DEBUG_BROADCAST) Log.v( 10610 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 10611 + " ordered=" + ordered); 10612 if ((resultTo != null) && !ordered) { 10613 Log.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 10614 } 10615 10616 // Handle special intents: if this broadcast is from the package 10617 // manager about a package being removed, we need to remove all of 10618 // its activities from the history stack. 10619 final boolean uidRemoved = intent.ACTION_UID_REMOVED.equals( 10620 intent.getAction()); 10621 if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 10622 || intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 10623 || uidRemoved) { 10624 if (checkComponentPermission( 10625 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 10626 callingPid, callingUid, -1) 10627 == PackageManager.PERMISSION_GRANTED) { 10628 if (uidRemoved) { 10629 final Bundle intentExtras = intent.getExtras(); 10630 final int uid = intentExtras != null 10631 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 10632 if (uid >= 0) { 10633 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 10634 synchronized (bs) { 10635 bs.removeUidStatsLocked(uid); 10636 } 10637 } 10638 } else { 10639 Uri data = intent.getData(); 10640 String ssp; 10641 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 10642 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 10643 uninstallPackageLocked(ssp, 10644 intent.getIntExtra(Intent.EXTRA_UID, -1), false); 10645 } 10646 } 10647 } 10648 } else { 10649 String msg = "Permission Denial: " + intent.getAction() 10650 + " broadcast from " + callerPackage + " (pid=" + callingPid 10651 + ", uid=" + callingUid + ")" 10652 + " requires " 10653 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 10654 Log.w(TAG, msg); 10655 throw new SecurityException(msg); 10656 } 10657 } 10658 10659 /* 10660 * If this is the time zone changed action, queue up a message that will reset the timezone 10661 * of all currently running processes. This message will get queued up before the broadcast 10662 * happens. 10663 */ 10664 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 10665 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 10666 } 10667 10668 // Add to the sticky list if requested. 10669 if (sticky) { 10670 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 10671 callingPid, callingUid) 10672 != PackageManager.PERMISSION_GRANTED) { 10673 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 10674 + callingPid + ", uid=" + callingUid 10675 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 10676 Log.w(TAG, msg); 10677 throw new SecurityException(msg); 10678 } 10679 if (requiredPermission != null) { 10680 Log.w(TAG, "Can't broadcast sticky intent " + intent 10681 + " and enforce permission " + requiredPermission); 10682 return BROADCAST_STICKY_CANT_HAVE_PERMISSION; 10683 } 10684 if (intent.getComponent() != null) { 10685 throw new SecurityException( 10686 "Sticky broadcasts can't target a specific component"); 10687 } 10688 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 10689 if (list == null) { 10690 list = new ArrayList<Intent>(); 10691 mStickyBroadcasts.put(intent.getAction(), list); 10692 } 10693 int N = list.size(); 10694 int i; 10695 for (i=0; i<N; i++) { 10696 if (intent.filterEquals(list.get(i))) { 10697 // This sticky already exists, replace it. 10698 list.set(i, new Intent(intent)); 10699 break; 10700 } 10701 } 10702 if (i >= N) { 10703 list.add(new Intent(intent)); 10704 } 10705 } 10706 10707 // Figure out who all will receive this broadcast. 10708 List receivers = null; 10709 List<BroadcastFilter> registeredReceivers = null; 10710 try { 10711 if (intent.getComponent() != null) { 10712 // Broadcast is going to one specific receiver class... 10713 ActivityInfo ai = ActivityThread.getPackageManager(). 10714 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS); 10715 if (ai != null) { 10716 receivers = new ArrayList(); 10717 ResolveInfo ri = new ResolveInfo(); 10718 ri.activityInfo = ai; 10719 receivers.add(ri); 10720 } 10721 } else { 10722 // Need to resolve the intent to interested receivers... 10723 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 10724 == 0) { 10725 receivers = 10726 ActivityThread.getPackageManager().queryIntentReceivers( 10727 intent, resolvedType, STOCK_PM_FLAGS); 10728 } 10729 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false); 10730 } 10731 } catch (RemoteException ex) { 10732 // pm is in same process, this will never happen. 10733 } 10734 10735 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 10736 if (!ordered && NR > 0) { 10737 // If we are not serializing this broadcast, then send the 10738 // registered receivers separately so they don't wait for the 10739 // components to be launched. 10740 BroadcastRecord r = new BroadcastRecord(intent, callerApp, 10741 callerPackage, callingPid, callingUid, requiredPermission, 10742 registeredReceivers, resultTo, resultCode, resultData, map, 10743 ordered); 10744 if (DEBUG_BROADCAST) Log.v( 10745 TAG, "Enqueueing parallel broadcast " + r 10746 + ": prev had " + mParallelBroadcasts.size()); 10747 mParallelBroadcasts.add(r); 10748 scheduleBroadcastsLocked(); 10749 registeredReceivers = null; 10750 NR = 0; 10751 } 10752 10753 // Merge into one list. 10754 int ir = 0; 10755 if (receivers != null) { 10756 // A special case for PACKAGE_ADDED: do not allow the package 10757 // being added to see this broadcast. This prevents them from 10758 // using this as a back door to get run as soon as they are 10759 // installed. Maybe in the future we want to have a special install 10760 // broadcast or such for apps, but we'd like to deliberately make 10761 // this decision. 10762 boolean skip = false; 10763 if (intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 10764 skip = true; 10765 } else if (intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())) { 10766 skip = true; 10767 } else if (intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 10768 skip = true; 10769 } 10770 String skipPackage = (skip && intent.getData() != null) 10771 ? intent.getData().getSchemeSpecificPart() 10772 : null; 10773 if (skipPackage != null && receivers != null) { 10774 int NT = receivers.size(); 10775 for (int it=0; it<NT; it++) { 10776 ResolveInfo curt = (ResolveInfo)receivers.get(it); 10777 if (curt.activityInfo.packageName.equals(skipPackage)) { 10778 receivers.remove(it); 10779 it--; 10780 NT--; 10781 } 10782 } 10783 } 10784 10785 int NT = receivers != null ? receivers.size() : 0; 10786 int it = 0; 10787 ResolveInfo curt = null; 10788 BroadcastFilter curr = null; 10789 while (it < NT && ir < NR) { 10790 if (curt == null) { 10791 curt = (ResolveInfo)receivers.get(it); 10792 } 10793 if (curr == null) { 10794 curr = registeredReceivers.get(ir); 10795 } 10796 if (curr.getPriority() >= curt.priority) { 10797 // Insert this broadcast record into the final list. 10798 receivers.add(it, curr); 10799 ir++; 10800 curr = null; 10801 it++; 10802 NT++; 10803 } else { 10804 // Skip to the next ResolveInfo in the final list. 10805 it++; 10806 curt = null; 10807 } 10808 } 10809 } 10810 while (ir < NR) { 10811 if (receivers == null) { 10812 receivers = new ArrayList(); 10813 } 10814 receivers.add(registeredReceivers.get(ir)); 10815 ir++; 10816 } 10817 10818 if ((receivers != null && receivers.size() > 0) 10819 || resultTo != null) { 10820 BroadcastRecord r = new BroadcastRecord(intent, callerApp, 10821 callerPackage, callingPid, callingUid, requiredPermission, 10822 receivers, resultTo, resultCode, resultData, map, ordered); 10823 if (DEBUG_BROADCAST) Log.v( 10824 TAG, "Enqueueing ordered broadcast " + r 10825 + ": prev had " + mOrderedBroadcasts.size()); 10826 if (DEBUG_BROADCAST) { 10827 int seq = r.intent.getIntExtra("seq", -1); 10828 Log.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 10829 } 10830 mOrderedBroadcasts.add(r); 10831 scheduleBroadcastsLocked(); 10832 } 10833 10834 return BROADCAST_SUCCESS; 10835 } 10836 10837 public final int broadcastIntent(IApplicationThread caller, 10838 Intent intent, String resolvedType, IIntentReceiver resultTo, 10839 int resultCode, String resultData, Bundle map, 10840 String requiredPermission, boolean serialized, boolean sticky) { 10841 // Refuse possible leaked file descriptors 10842 if (intent != null && intent.hasFileDescriptors() == true) { 10843 throw new IllegalArgumentException("File descriptors passed in Intent"); 10844 } 10845 10846 synchronized(this) { 10847 if (!mSystemReady) { 10848 // if the caller really truly claims to know what they're doing, go 10849 // ahead and allow the broadcast without launching any receivers 10850 int flags = intent.getFlags(); 10851 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 10852 intent = new Intent(intent); 10853 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 10854 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0){ 10855 Log.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 10856 + " before boot completion"); 10857 throw new IllegalStateException("Cannot broadcast before boot completed"); 10858 } 10859 } 10860 10861 final ProcessRecord callerApp = getRecordForAppLocked(caller); 10862 final int callingPid = Binder.getCallingPid(); 10863 final int callingUid = Binder.getCallingUid(); 10864 final long origId = Binder.clearCallingIdentity(); 10865 int res = broadcastIntentLocked(callerApp, 10866 callerApp != null ? callerApp.info.packageName : null, 10867 intent, resolvedType, resultTo, 10868 resultCode, resultData, map, requiredPermission, serialized, 10869 sticky, callingPid, callingUid); 10870 Binder.restoreCallingIdentity(origId); 10871 return res; 10872 } 10873 } 10874 10875 int broadcastIntentInPackage(String packageName, int uid, 10876 Intent intent, String resolvedType, IIntentReceiver resultTo, 10877 int resultCode, String resultData, Bundle map, 10878 String requiredPermission, boolean serialized, boolean sticky) { 10879 synchronized(this) { 10880 final long origId = Binder.clearCallingIdentity(); 10881 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 10882 resultTo, resultCode, resultData, map, requiredPermission, 10883 serialized, sticky, -1, uid); 10884 Binder.restoreCallingIdentity(origId); 10885 return res; 10886 } 10887 } 10888 10889 public final void unbroadcastIntent(IApplicationThread caller, 10890 Intent intent) { 10891 // Refuse possible leaked file descriptors 10892 if (intent != null && intent.hasFileDescriptors() == true) { 10893 throw new IllegalArgumentException("File descriptors passed in Intent"); 10894 } 10895 10896 synchronized(this) { 10897 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 10898 != PackageManager.PERMISSION_GRANTED) { 10899 String msg = "Permission Denial: unbroadcastIntent() from pid=" 10900 + Binder.getCallingPid() 10901 + ", uid=" + Binder.getCallingUid() 10902 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 10903 Log.w(TAG, msg); 10904 throw new SecurityException(msg); 10905 } 10906 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 10907 if (list != null) { 10908 int N = list.size(); 10909 int i; 10910 for (i=0; i<N; i++) { 10911 if (intent.filterEquals(list.get(i))) { 10912 list.remove(i); 10913 break; 10914 } 10915 } 10916 } 10917 } 10918 } 10919 10920 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 10921 String resultData, Bundle resultExtras, boolean resultAbort, 10922 boolean explicit) { 10923 if (mOrderedBroadcasts.size() == 0) { 10924 if (explicit) { 10925 Log.w(TAG, "finishReceiver called but no pending broadcasts"); 10926 } 10927 return false; 10928 } 10929 BroadcastRecord r = mOrderedBroadcasts.get(0); 10930 if (r.receiver == null) { 10931 if (explicit) { 10932 Log.w(TAG, "finishReceiver called but none active"); 10933 } 10934 return false; 10935 } 10936 if (r.receiver != receiver) { 10937 Log.w(TAG, "finishReceiver called but active receiver is different"); 10938 return false; 10939 } 10940 int state = r.state; 10941 r.state = r.IDLE; 10942 if (state == r.IDLE) { 10943 if (explicit) { 10944 Log.w(TAG, "finishReceiver called but state is IDLE"); 10945 } 10946 } 10947 r.receiver = null; 10948 r.intent.setComponent(null); 10949 if (r.curApp != null) { 10950 r.curApp.curReceiver = null; 10951 } 10952 if (r.curFilter != null) { 10953 r.curFilter.receiverList.curBroadcast = null; 10954 } 10955 r.curFilter = null; 10956 r.curApp = null; 10957 r.curComponent = null; 10958 r.curReceiver = null; 10959 mPendingBroadcast = null; 10960 10961 r.resultCode = resultCode; 10962 r.resultData = resultData; 10963 r.resultExtras = resultExtras; 10964 r.resultAbort = resultAbort; 10965 10966 // We will process the next receiver right now if this is finishing 10967 // an app receiver (which is always asynchronous) or after we have 10968 // come back from calling a receiver. 10969 return state == BroadcastRecord.APP_RECEIVE 10970 || state == BroadcastRecord.CALL_DONE_RECEIVE; 10971 } 10972 10973 public void finishReceiver(IBinder who, int resultCode, String resultData, 10974 Bundle resultExtras, boolean resultAbort) { 10975 if (DEBUG_BROADCAST) Log.v(TAG, "Finish receiver: " + who); 10976 10977 // Refuse possible leaked file descriptors 10978 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 10979 throw new IllegalArgumentException("File descriptors passed in Bundle"); 10980 } 10981 10982 boolean doNext; 10983 10984 final long origId = Binder.clearCallingIdentity(); 10985 10986 synchronized(this) { 10987 doNext = finishReceiverLocked( 10988 who, resultCode, resultData, resultExtras, resultAbort, true); 10989 } 10990 10991 if (doNext) { 10992 processNextBroadcast(false); 10993 } 10994 trimApplications(); 10995 10996 Binder.restoreCallingIdentity(origId); 10997 } 10998 10999 private final void logBroadcastReceiverDiscard(BroadcastRecord r) { 11000 if (r.nextReceiver > 0) { 11001 Object curReceiver = r.receivers.get(r.nextReceiver-1); 11002 if (curReceiver instanceof BroadcastFilter) { 11003 BroadcastFilter bf = (BroadcastFilter) curReceiver; 11004 EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_FILTER, 11005 System.identityHashCode(r), 11006 r.intent.getAction(), 11007 r.nextReceiver - 1, 11008 System.identityHashCode(bf)); 11009 } else { 11010 EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_APP, 11011 System.identityHashCode(r), 11012 r.intent.getAction(), 11013 r.nextReceiver - 1, 11014 ((ResolveInfo)curReceiver).toString()); 11015 } 11016 } else { 11017 Log.w(TAG, "Discarding broadcast before first receiver is invoked: " 11018 + r); 11019 EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_APP, 11020 System.identityHashCode(r), 11021 r.intent.getAction(), 11022 r.nextReceiver, 11023 "NONE"); 11024 } 11025 } 11026 11027 private final void broadcastTimeout() { 11028 synchronized (this) { 11029 if (mOrderedBroadcasts.size() == 0) { 11030 return; 11031 } 11032 long now = SystemClock.uptimeMillis(); 11033 BroadcastRecord r = mOrderedBroadcasts.get(0); 11034 if ((r.startTime+BROADCAST_TIMEOUT) > now) { 11035 if (DEBUG_BROADCAST) Log.v(TAG, 11036 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for " 11037 + (r.startTime + BROADCAST_TIMEOUT)); 11038 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG); 11039 mHandler.sendMessageAtTime(msg, r.startTime+BROADCAST_TIMEOUT); 11040 return; 11041 } 11042 11043 Log.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver); 11044 r.startTime = now; 11045 r.anrCount++; 11046 11047 // Current receiver has passed its expiration date. 11048 if (r.nextReceiver <= 0) { 11049 Log.w(TAG, "Timeout on receiver with nextReceiver <= 0"); 11050 return; 11051 } 11052 11053 ProcessRecord app = null; 11054 11055 Object curReceiver = r.receivers.get(r.nextReceiver-1); 11056 Log.w(TAG, "Receiver during timeout: " + curReceiver); 11057 logBroadcastReceiverDiscard(r); 11058 if (curReceiver instanceof BroadcastFilter) { 11059 BroadcastFilter bf = (BroadcastFilter)curReceiver; 11060 if (bf.receiverList.pid != 0 11061 && bf.receiverList.pid != MY_PID) { 11062 synchronized (this.mPidsSelfLocked) { 11063 app = this.mPidsSelfLocked.get( 11064 bf.receiverList.pid); 11065 } 11066 } 11067 } else { 11068 app = r.curApp; 11069 } 11070 11071 if (app != null) { 11072 appNotRespondingLocked(app, null, "Broadcast of " + r.intent.toString()); 11073 } 11074 11075 if (mPendingBroadcast == r) { 11076 mPendingBroadcast = null; 11077 } 11078 11079 // Move on to the next receiver. 11080 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 11081 r.resultExtras, r.resultAbort, true); 11082 scheduleBroadcastsLocked(); 11083 } 11084 } 11085 11086 private final void processCurBroadcastLocked(BroadcastRecord r, 11087 ProcessRecord app) throws RemoteException { 11088 if (app.thread == null) { 11089 throw new RemoteException(); 11090 } 11091 r.receiver = app.thread.asBinder(); 11092 r.curApp = app; 11093 app.curReceiver = r; 11094 updateLRUListLocked(app, true); 11095 11096 // Tell the application to launch this receiver. 11097 r.intent.setComponent(r.curComponent); 11098 11099 boolean started = false; 11100 try { 11101 if (DEBUG_BROADCAST) Log.v(TAG, 11102 "Delivering to component " + r.curComponent 11103 + ": " + r); 11104 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver, 11105 r.resultCode, r.resultData, r.resultExtras, r.ordered); 11106 started = true; 11107 } finally { 11108 if (!started) { 11109 r.receiver = null; 11110 r.curApp = null; 11111 app.curReceiver = null; 11112 } 11113 } 11114 11115 } 11116 11117 static void performReceive(ProcessRecord app, IIntentReceiver receiver, 11118 Intent intent, int resultCode, String data, 11119 Bundle extras, boolean ordered) throws RemoteException { 11120 if (app != null && app.thread != null) { 11121 // If we have an app thread, do the call through that so it is 11122 // correctly ordered with other one-way calls. 11123 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode, 11124 data, extras, ordered); 11125 } else { 11126 receiver.performReceive(intent, resultCode, data, extras, ordered); 11127 } 11128 } 11129 11130 private final void deliverToRegisteredReceiver(BroadcastRecord r, 11131 BroadcastFilter filter, boolean ordered) { 11132 boolean skip = false; 11133 if (filter.requiredPermission != null) { 11134 int perm = checkComponentPermission(filter.requiredPermission, 11135 r.callingPid, r.callingUid, -1); 11136 if (perm != PackageManager.PERMISSION_GRANTED) { 11137 Log.w(TAG, "Permission Denial: broadcasting " 11138 + r.intent.toString() 11139 + " from " + r.callerPackage + " (pid=" 11140 + r.callingPid + ", uid=" + r.callingUid + ")" 11141 + " requires " + filter.requiredPermission 11142 + " due to registered receiver " + filter); 11143 skip = true; 11144 } 11145 } 11146 if (r.requiredPermission != null) { 11147 int perm = checkComponentPermission(r.requiredPermission, 11148 filter.receiverList.pid, filter.receiverList.uid, -1); 11149 if (perm != PackageManager.PERMISSION_GRANTED) { 11150 Log.w(TAG, "Permission Denial: receiving " 11151 + r.intent.toString() 11152 + " to " + filter.receiverList.app 11153 + " (pid=" + filter.receiverList.pid 11154 + ", uid=" + filter.receiverList.uid + ")" 11155 + " requires " + r.requiredPermission 11156 + " due to sender " + r.callerPackage 11157 + " (uid " + r.callingUid + ")"); 11158 skip = true; 11159 } 11160 } 11161 11162 if (!skip) { 11163 // If this is not being sent as an ordered broadcast, then we 11164 // don't want to touch the fields that keep track of the current 11165 // state of ordered broadcasts. 11166 if (ordered) { 11167 r.receiver = filter.receiverList.receiver.asBinder(); 11168 r.curFilter = filter; 11169 filter.receiverList.curBroadcast = r; 11170 r.state = BroadcastRecord.CALL_IN_RECEIVE; 11171 } 11172 try { 11173 if (DEBUG_BROADCAST) { 11174 int seq = r.intent.getIntExtra("seq", -1); 11175 Log.i(TAG, "Sending broadcast " + r.intent.getAction() + " seq=" + seq 11176 + " app=" + filter.receiverList.app); 11177 } 11178 performReceive(filter.receiverList.app, filter.receiverList.receiver, 11179 new Intent(r.intent), r.resultCode, 11180 r.resultData, r.resultExtras, r.ordered); 11181 if (ordered) { 11182 r.state = BroadcastRecord.CALL_DONE_RECEIVE; 11183 } 11184 } catch (RemoteException e) { 11185 Log.w(TAG, "Failure sending broadcast " + r.intent, e); 11186 if (ordered) { 11187 r.receiver = null; 11188 r.curFilter = null; 11189 filter.receiverList.curBroadcast = null; 11190 } 11191 } 11192 } 11193 } 11194 11195 private final void processNextBroadcast(boolean fromMsg) { 11196 synchronized(this) { 11197 BroadcastRecord r; 11198 11199 if (DEBUG_BROADCAST) Log.v(TAG, "processNextBroadcast: " 11200 + mParallelBroadcasts.size() + " broadcasts, " 11201 + mOrderedBroadcasts.size() + " serialized broadcasts"); 11202 11203 updateCpuStats(); 11204 11205 if (fromMsg) { 11206 mBroadcastsScheduled = false; 11207 } 11208 11209 // First, deliver any non-serialized broadcasts right away. 11210 while (mParallelBroadcasts.size() > 0) { 11211 r = mParallelBroadcasts.remove(0); 11212 final int N = r.receivers.size(); 11213 for (int i=0; i<N; i++) { 11214 Object target = r.receivers.get(i); 11215 if (DEBUG_BROADCAST) Log.v(TAG, 11216 "Delivering non-serialized to registered " 11217 + target + ": " + r); 11218 deliverToRegisteredReceiver(r, (BroadcastFilter)target, false); 11219 } 11220 } 11221 11222 // Now take care of the next serialized one... 11223 11224 // If we are waiting for a process to come up to handle the next 11225 // broadcast, then do nothing at this point. Just in case, we 11226 // check that the process we're waiting for still exists. 11227 if (mPendingBroadcast != null) { 11228 Log.i(TAG, "processNextBroadcast: waiting for " 11229 + mPendingBroadcast.curApp); 11230 11231 boolean isDead; 11232 synchronized (mPidsSelfLocked) { 11233 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null); 11234 } 11235 if (!isDead) { 11236 // It's still alive, so keep waiting 11237 return; 11238 } else { 11239 Log.w(TAG, "pending app " + mPendingBroadcast.curApp 11240 + " died before responding to broadcast"); 11241 mPendingBroadcast = null; 11242 } 11243 } 11244 11245 do { 11246 if (mOrderedBroadcasts.size() == 0) { 11247 // No more broadcasts pending, so all done! 11248 scheduleAppGcsLocked(); 11249 return; 11250 } 11251 r = mOrderedBroadcasts.get(0); 11252 boolean forceReceive = false; 11253 11254 // Ensure that even if something goes awry with the timeout 11255 // detection, we catch "hung" broadcasts here, discard them, 11256 // and continue to make progress. 11257 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0; 11258 long now = SystemClock.uptimeMillis(); 11259 if (r.dispatchTime > 0) { 11260 if ((numReceivers > 0) && 11261 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) { 11262 Log.w(TAG, "Hung broadcast discarded after timeout failure:" 11263 + " now=" + now 11264 + " dispatchTime=" + r.dispatchTime 11265 + " startTime=" + r.startTime 11266 + " intent=" + r.intent 11267 + " numReceivers=" + numReceivers 11268 + " nextReceiver=" + r.nextReceiver 11269 + " state=" + r.state); 11270 broadcastTimeout(); // forcibly finish this broadcast 11271 forceReceive = true; 11272 r.state = BroadcastRecord.IDLE; 11273 } 11274 } 11275 11276 if (r.state != BroadcastRecord.IDLE) { 11277 if (DEBUG_BROADCAST) Log.d(TAG, 11278 "processNextBroadcast() called when not idle (state=" 11279 + r.state + ")"); 11280 return; 11281 } 11282 11283 if (r.receivers == null || r.nextReceiver >= numReceivers 11284 || r.resultAbort || forceReceive) { 11285 // No more receivers for this broadcast! Send the final 11286 // result if requested... 11287 if (r.resultTo != null) { 11288 try { 11289 if (DEBUG_BROADCAST) { 11290 int seq = r.intent.getIntExtra("seq", -1); 11291 Log.i(TAG, "Finishing broadcast " + r.intent.getAction() 11292 + " seq=" + seq + " app=" + r.callerApp); 11293 } 11294 performReceive(r.callerApp, r.resultTo, 11295 new Intent(r.intent), r.resultCode, 11296 r.resultData, r.resultExtras, false); 11297 } catch (RemoteException e) { 11298 Log.w(TAG, "Failure sending broadcast result of " + r.intent, e); 11299 } 11300 } 11301 11302 if (DEBUG_BROADCAST) Log.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG"); 11303 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG); 11304 11305 // ... and on to the next... 11306 mOrderedBroadcasts.remove(0); 11307 r = null; 11308 continue; 11309 } 11310 } while (r == null); 11311 11312 // Get the next receiver... 11313 int recIdx = r.nextReceiver++; 11314 11315 // Keep track of when this receiver started, and make sure there 11316 // is a timeout message pending to kill it if need be. 11317 r.startTime = SystemClock.uptimeMillis(); 11318 if (recIdx == 0) { 11319 r.dispatchTime = r.startTime; 11320 11321 if (DEBUG_BROADCAST) Log.v(TAG, 11322 "Submitting BROADCAST_TIMEOUT_MSG for " 11323 + (r.startTime + BROADCAST_TIMEOUT)); 11324 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG); 11325 mHandler.sendMessageAtTime(msg, r.startTime+BROADCAST_TIMEOUT); 11326 } 11327 11328 Object nextReceiver = r.receivers.get(recIdx); 11329 if (nextReceiver instanceof BroadcastFilter) { 11330 // Simple case: this is a registered receiver who gets 11331 // a direct call. 11332 BroadcastFilter filter = (BroadcastFilter)nextReceiver; 11333 if (DEBUG_BROADCAST) Log.v(TAG, 11334 "Delivering serialized to registered " 11335 + filter + ": " + r); 11336 deliverToRegisteredReceiver(r, filter, r.ordered); 11337 if (r.receiver == null || !r.ordered) { 11338 // The receiver has already finished, so schedule to 11339 // process the next one. 11340 r.state = BroadcastRecord.IDLE; 11341 scheduleBroadcastsLocked(); 11342 } 11343 return; 11344 } 11345 11346 // Hard case: need to instantiate the receiver, possibly 11347 // starting its application process to host it. 11348 11349 ResolveInfo info = 11350 (ResolveInfo)nextReceiver; 11351 11352 boolean skip = false; 11353 int perm = checkComponentPermission(info.activityInfo.permission, 11354 r.callingPid, r.callingUid, 11355 info.activityInfo.exported 11356 ? -1 : info.activityInfo.applicationInfo.uid); 11357 if (perm != PackageManager.PERMISSION_GRANTED) { 11358 Log.w(TAG, "Permission Denial: broadcasting " 11359 + r.intent.toString() 11360 + " from " + r.callerPackage + " (pid=" + r.callingPid 11361 + ", uid=" + r.callingUid + ")" 11362 + " requires " + info.activityInfo.permission 11363 + " due to receiver " + info.activityInfo.packageName 11364 + "/" + info.activityInfo.name); 11365 skip = true; 11366 } 11367 if (r.callingUid != Process.SYSTEM_UID && 11368 r.requiredPermission != null) { 11369 try { 11370 perm = ActivityThread.getPackageManager(). 11371 checkPermission(r.requiredPermission, 11372 info.activityInfo.applicationInfo.packageName); 11373 } catch (RemoteException e) { 11374 perm = PackageManager.PERMISSION_DENIED; 11375 } 11376 if (perm != PackageManager.PERMISSION_GRANTED) { 11377 Log.w(TAG, "Permission Denial: receiving " 11378 + r.intent + " to " 11379 + info.activityInfo.applicationInfo.packageName 11380 + " requires " + r.requiredPermission 11381 + " due to sender " + r.callerPackage 11382 + " (uid " + r.callingUid + ")"); 11383 skip = true; 11384 } 11385 } 11386 if (r.curApp != null && r.curApp.crashing) { 11387 // If the target process is crashing, just skip it. 11388 skip = true; 11389 } 11390 11391 if (skip) { 11392 r.receiver = null; 11393 r.curFilter = null; 11394 r.state = BroadcastRecord.IDLE; 11395 scheduleBroadcastsLocked(); 11396 return; 11397 } 11398 11399 r.state = BroadcastRecord.APP_RECEIVE; 11400 String targetProcess = info.activityInfo.processName; 11401 r.curComponent = new ComponentName( 11402 info.activityInfo.applicationInfo.packageName, 11403 info.activityInfo.name); 11404 r.curReceiver = info.activityInfo; 11405 11406 // Is this receiver's application already running? 11407 ProcessRecord app = getProcessRecordLocked(targetProcess, 11408 info.activityInfo.applicationInfo.uid); 11409 if (app != null && app.thread != null) { 11410 try { 11411 processCurBroadcastLocked(r, app); 11412 return; 11413 } catch (RemoteException e) { 11414 Log.w(TAG, "Exception when sending broadcast to " 11415 + r.curComponent, e); 11416 } 11417 11418 // If a dead object exception was thrown -- fall through to 11419 // restart the application. 11420 } 11421 11422 // Not running -- get it started, and enqueue this history record 11423 // to be executed when the app comes up. 11424 if ((r.curApp=startProcessLocked(targetProcess, 11425 info.activityInfo.applicationInfo, true, 11426 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND, 11427 "broadcast", r.curComponent)) == null) { 11428 // Ah, this recipient is unavailable. Finish it if necessary, 11429 // and mark the broadcast record as ready for the next. 11430 Log.w(TAG, "Unable to launch app " 11431 + info.activityInfo.applicationInfo.packageName + "/" 11432 + info.activityInfo.applicationInfo.uid + " for broadcast " 11433 + r.intent + ": process is bad"); 11434 logBroadcastReceiverDiscard(r); 11435 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 11436 r.resultExtras, r.resultAbort, true); 11437 scheduleBroadcastsLocked(); 11438 r.state = BroadcastRecord.IDLE; 11439 return; 11440 } 11441 11442 mPendingBroadcast = r; 11443 } 11444 } 11445 11446 // ========================================================= 11447 // INSTRUMENTATION 11448 // ========================================================= 11449 11450 public boolean startInstrumentation(ComponentName className, 11451 String profileFile, int flags, Bundle arguments, 11452 IInstrumentationWatcher watcher) { 11453 // Refuse possible leaked file descriptors 11454 if (arguments != null && arguments.hasFileDescriptors()) { 11455 throw new IllegalArgumentException("File descriptors passed in Bundle"); 11456 } 11457 11458 synchronized(this) { 11459 InstrumentationInfo ii = null; 11460 ApplicationInfo ai = null; 11461 try { 11462 ii = mContext.getPackageManager().getInstrumentationInfo( 11463 className, STOCK_PM_FLAGS); 11464 ai = mContext.getPackageManager().getApplicationInfo( 11465 ii.targetPackage, STOCK_PM_FLAGS); 11466 } catch (PackageManager.NameNotFoundException e) { 11467 } 11468 if (ii == null) { 11469 reportStartInstrumentationFailure(watcher, className, 11470 "Unable to find instrumentation info for: " + className); 11471 return false; 11472 } 11473 if (ai == null) { 11474 reportStartInstrumentationFailure(watcher, className, 11475 "Unable to find instrumentation target package: " + ii.targetPackage); 11476 return false; 11477 } 11478 11479 int match = mContext.getPackageManager().checkSignatures( 11480 ii.targetPackage, ii.packageName); 11481 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 11482 String msg = "Permission Denial: starting instrumentation " 11483 + className + " from pid=" 11484 + Binder.getCallingPid() 11485 + ", uid=" + Binder.getCallingPid() 11486 + " not allowed because package " + ii.packageName 11487 + " does not have a signature matching the target " 11488 + ii.targetPackage; 11489 reportStartInstrumentationFailure(watcher, className, msg); 11490 throw new SecurityException(msg); 11491 } 11492 11493 final long origId = Binder.clearCallingIdentity(); 11494 uninstallPackageLocked(ii.targetPackage, -1, true); 11495 ProcessRecord app = addAppLocked(ai); 11496 app.instrumentationClass = className; 11497 app.instrumentationInfo = ai; 11498 app.instrumentationProfileFile = profileFile; 11499 app.instrumentationArguments = arguments; 11500 app.instrumentationWatcher = watcher; 11501 app.instrumentationResultClass = className; 11502 Binder.restoreCallingIdentity(origId); 11503 } 11504 11505 return true; 11506 } 11507 11508 /** 11509 * Report errors that occur while attempting to start Instrumentation. Always writes the 11510 * error to the logs, but if somebody is watching, send the report there too. This enables 11511 * the "am" command to report errors with more information. 11512 * 11513 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 11514 * @param cn The component name of the instrumentation. 11515 * @param report The error report. 11516 */ 11517 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 11518 ComponentName cn, String report) { 11519 Log.w(TAG, report); 11520 try { 11521 if (watcher != null) { 11522 Bundle results = new Bundle(); 11523 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 11524 results.putString("Error", report); 11525 watcher.instrumentationStatus(cn, -1, results); 11526 } 11527 } catch (RemoteException e) { 11528 Log.w(TAG, e); 11529 } 11530 } 11531 11532 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 11533 if (app.instrumentationWatcher != null) { 11534 try { 11535 // NOTE: IInstrumentationWatcher *must* be oneway here 11536 app.instrumentationWatcher.instrumentationFinished( 11537 app.instrumentationClass, 11538 resultCode, 11539 results); 11540 } catch (RemoteException e) { 11541 } 11542 } 11543 app.instrumentationWatcher = null; 11544 app.instrumentationClass = null; 11545 app.instrumentationInfo = null; 11546 app.instrumentationProfileFile = null; 11547 app.instrumentationArguments = null; 11548 11549 uninstallPackageLocked(app.processName, -1, false); 11550 } 11551 11552 public void finishInstrumentation(IApplicationThread target, 11553 int resultCode, Bundle results) { 11554 // Refuse possible leaked file descriptors 11555 if (results != null && results.hasFileDescriptors()) { 11556 throw new IllegalArgumentException("File descriptors passed in Intent"); 11557 } 11558 11559 synchronized(this) { 11560 ProcessRecord app = getRecordForAppLocked(target); 11561 if (app == null) { 11562 Log.w(TAG, "finishInstrumentation: no app for " + target); 11563 return; 11564 } 11565 final long origId = Binder.clearCallingIdentity(); 11566 finishInstrumentationLocked(app, resultCode, results); 11567 Binder.restoreCallingIdentity(origId); 11568 } 11569 } 11570 11571 // ========================================================= 11572 // CONFIGURATION 11573 // ========================================================= 11574 11575 public ConfigurationInfo getDeviceConfigurationInfo() { 11576 ConfigurationInfo config = new ConfigurationInfo(); 11577 synchronized (this) { 11578 config.reqTouchScreen = mConfiguration.touchscreen; 11579 config.reqKeyboardType = mConfiguration.keyboard; 11580 config.reqNavigation = mConfiguration.navigation; 11581 if (mConfiguration.navigation != Configuration.NAVIGATION_NONAV) { 11582 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 11583 } 11584 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED) { 11585 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 11586 } 11587 } 11588 return config; 11589 } 11590 11591 public Configuration getConfiguration() { 11592 Configuration ci; 11593 synchronized(this) { 11594 ci = new Configuration(mConfiguration); 11595 } 11596 return ci; 11597 } 11598 11599 public void updateConfiguration(Configuration values) { 11600 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 11601 "updateConfiguration()"); 11602 11603 synchronized(this) { 11604 if (values == null && mWindowManager != null) { 11605 // sentinel: fetch the current configuration from the window manager 11606 values = mWindowManager.computeNewConfiguration(); 11607 } 11608 11609 final long origId = Binder.clearCallingIdentity(); 11610 updateConfigurationLocked(values, null); 11611 Binder.restoreCallingIdentity(origId); 11612 } 11613 } 11614 11615 /** 11616 * Do either or both things: (1) change the current configuration, and (2) 11617 * make sure the given activity is running with the (now) current 11618 * configuration. Returns true if the activity has been left running, or 11619 * false if <var>starting</var> is being destroyed to match the new 11620 * configuration. 11621 */ 11622 public boolean updateConfigurationLocked(Configuration values, 11623 HistoryRecord starting) { 11624 int changes = 0; 11625 11626 boolean kept = true; 11627 11628 if (values != null) { 11629 Configuration newConfig = new Configuration(mConfiguration); 11630 changes = newConfig.updateFrom(values); 11631 if (changes != 0) { 11632 if (DEBUG_SWITCH) { 11633 Log.i(TAG, "Updating configuration to: " + values); 11634 } 11635 11636 EventLog.writeEvent(LOG_CONFIGURATION_CHANGED, changes); 11637 11638 if (values.locale != null) { 11639 saveLocaleLocked(values.locale, 11640 !values.locale.equals(mConfiguration.locale), 11641 values.userSetLocale); 11642 } 11643 11644 mConfiguration = newConfig; 11645 11646 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 11647 msg.obj = new Configuration(mConfiguration); 11648 mHandler.sendMessage(msg); 11649 11650 final int N = mLRUProcesses.size(); 11651 for (int i=0; i<N; i++) { 11652 ProcessRecord app = mLRUProcesses.get(i); 11653 try { 11654 if (app.thread != null) { 11655 app.thread.scheduleConfigurationChanged(mConfiguration); 11656 } 11657 } catch (Exception e) { 11658 } 11659 } 11660 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 11661 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 11662 null, false, false, MY_PID, Process.SYSTEM_UID); 11663 } 11664 } 11665 11666 if (changes != 0 && starting == null) { 11667 // If the configuration changed, and the caller is not already 11668 // in the process of starting an activity, then find the top 11669 // activity to check if its configuration needs to change. 11670 starting = topRunningActivityLocked(null); 11671 } 11672 11673 if (starting != null) { 11674 kept = ensureActivityConfigurationLocked(starting, changes); 11675 if (kept) { 11676 // If this didn't result in the starting activity being 11677 // destroyed, then we need to make sure at this point that all 11678 // other activities are made visible. 11679 if (DEBUG_SWITCH) Log.i(TAG, "Config didn't destroy " + starting 11680 + ", ensuring others are correct."); 11681 ensureActivitiesVisibleLocked(starting, changes); 11682 } 11683 } 11684 11685 return kept; 11686 } 11687 11688 private final boolean relaunchActivityLocked(HistoryRecord r, 11689 int changes, boolean andResume) { 11690 List<ResultInfo> results = null; 11691 List<Intent> newIntents = null; 11692 if (andResume) { 11693 results = r.results; 11694 newIntents = r.newIntents; 11695 } 11696 if (DEBUG_SWITCH) Log.v(TAG, "Relaunching: " + r 11697 + " with results=" + results + " newIntents=" + newIntents 11698 + " andResume=" + andResume); 11699 EventLog.writeEvent(andResume ? LOG_AM_RELAUNCH_RESUME_ACTIVITY 11700 : LOG_AM_RELAUNCH_ACTIVITY, System.identityHashCode(r), 11701 r.task.taskId, r.shortComponentName); 11702 11703 r.startFreezingScreenLocked(r.app, 0); 11704 11705 try { 11706 if (DEBUG_SWITCH) Log.i(TAG, "Switch is restarting resumed " + r); 11707 r.app.thread.scheduleRelaunchActivity(r, results, newIntents, 11708 changes, !andResume); 11709 // Note: don't need to call pauseIfSleepingLocked() here, because 11710 // the caller will only pass in 'andResume' if this activity is 11711 // currently resumed, which implies we aren't sleeping. 11712 } catch (RemoteException e) { 11713 return false; 11714 } 11715 11716 if (andResume) { 11717 r.results = null; 11718 r.newIntents = null; 11719 } 11720 11721 return true; 11722 } 11723 11724 /** 11725 * Make sure the given activity matches the current configuration. Returns 11726 * false if the activity had to be destroyed. Returns true if the 11727 * configuration is the same, or the activity will remain running as-is 11728 * for whatever reason. Ensures the HistoryRecord is updated with the 11729 * correct configuration and all other bookkeeping is handled. 11730 */ 11731 private final boolean ensureActivityConfigurationLocked(HistoryRecord r, 11732 int globalChanges) { 11733 if (DEBUG_SWITCH) Log.i(TAG, "Ensuring correct configuration: " + r); 11734 11735 // Short circuit: if the two configurations are the exact same 11736 // object (the common case), then there is nothing to do. 11737 Configuration newConfig = mConfiguration; 11738 if (r.configuration == newConfig) { 11739 if (DEBUG_SWITCH) Log.i(TAG, "Configuration unchanged in " + r); 11740 return true; 11741 } 11742 11743 // We don't worry about activities that are finishing. 11744 if (r.finishing) { 11745 if (DEBUG_SWITCH) Log.i(TAG, 11746 "Configuration doesn't matter in finishing " + r); 11747 r.stopFreezingScreenLocked(false); 11748 return true; 11749 } 11750 11751 // Okay we now are going to make this activity have the new config. 11752 // But then we need to figure out how it needs to deal with that. 11753 Configuration oldConfig = r.configuration; 11754 r.configuration = newConfig; 11755 11756 // If the activity isn't currently running, just leave the new 11757 // configuration and it will pick that up next time it starts. 11758 if (r.app == null || r.app.thread == null) { 11759 if (DEBUG_SWITCH) Log.i(TAG, 11760 "Configuration doesn't matter not running " + r); 11761 r.stopFreezingScreenLocked(false); 11762 return true; 11763 } 11764 11765 // If the activity isn't persistent, there is a chance we will 11766 // need to restart it. 11767 if (!r.persistent) { 11768 11769 // Figure out what has changed between the two configurations. 11770 int changes = oldConfig.diff(newConfig); 11771 if (DEBUG_SWITCH) { 11772 Log.i(TAG, "Checking to restart " + r.info.name + ": changed=0x" 11773 + Integer.toHexString(changes) + ", handles=0x" 11774 + Integer.toHexString(r.info.configChanges)); 11775 } 11776 if ((changes&(~r.info.configChanges)) != 0) { 11777 // Aha, the activity isn't handling the change, so DIE DIE DIE. 11778 r.configChangeFlags |= changes; 11779 r.startFreezingScreenLocked(r.app, globalChanges); 11780 if (r.app == null || r.app.thread == null) { 11781 if (DEBUG_SWITCH) Log.i(TAG, "Switch is destroying non-running " + r); 11782 destroyActivityLocked(r, true); 11783 } else if (r.state == ActivityState.PAUSING) { 11784 // A little annoying: we are waiting for this activity to 11785 // finish pausing. Let's not do anything now, but just 11786 // flag that it needs to be restarted when done pausing. 11787 r.configDestroy = true; 11788 return true; 11789 } else if (r.state == ActivityState.RESUMED) { 11790 // Try to optimize this case: the configuration is changing 11791 // and we need to restart the top, resumed activity. 11792 // Instead of doing the normal handshaking, just say 11793 // "restart!". 11794 if (DEBUG_SWITCH) Log.i(TAG, "Switch is restarting resumed " + r); 11795 relaunchActivityLocked(r, r.configChangeFlags, true); 11796 r.configChangeFlags = 0; 11797 } else { 11798 if (DEBUG_SWITCH) Log.i(TAG, "Switch is restarting non-resumed " + r); 11799 relaunchActivityLocked(r, r.configChangeFlags, false); 11800 r.configChangeFlags = 0; 11801 } 11802 11803 // All done... tell the caller we weren't able to keep this 11804 // activity around. 11805 return false; 11806 } 11807 } 11808 11809 // Default case: the activity can handle this new configuration, so 11810 // hand it over. Note that we don't need to give it the new 11811 // configuration, since we always send configuration changes to all 11812 // process when they happen so it can just use whatever configuration 11813 // it last got. 11814 if (r.app != null && r.app.thread != null) { 11815 try { 11816 r.app.thread.scheduleActivityConfigurationChanged(r); 11817 } catch (RemoteException e) { 11818 // If process died, whatever. 11819 } 11820 } 11821 r.stopFreezingScreenLocked(false); 11822 11823 return true; 11824 } 11825 11826 /** 11827 * Save the locale. You must be inside a synchronized (this) block. 11828 */ 11829 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 11830 if(isDiff) { 11831 SystemProperties.set("user.language", l.getLanguage()); 11832 SystemProperties.set("user.region", l.getCountry()); 11833 } 11834 11835 if(isPersist) { 11836 SystemProperties.set("persist.sys.language", l.getLanguage()); 11837 SystemProperties.set("persist.sys.country", l.getCountry()); 11838 SystemProperties.set("persist.sys.localevar", l.getVariant()); 11839 } 11840 } 11841 11842 // ========================================================= 11843 // LIFETIME MANAGEMENT 11844 // ========================================================= 11845 11846 private final int computeOomAdjLocked( 11847 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) { 11848 if (mAdjSeq == app.adjSeq) { 11849 // This adjustment has already been computed. 11850 return app.curAdj; 11851 } 11852 11853 if (app.thread == null) { 11854 app.adjSeq = mAdjSeq; 11855 return (app.curAdj=EMPTY_APP_ADJ); 11856 } 11857 11858 app.isForeground = false; 11859 11860 // Determine the importance of the process, starting with most 11861 // important to least, and assign an appropriate OOM adjustment. 11862 int adj; 11863 int N; 11864 if (app == TOP_APP || app.instrumentationClass != null 11865 || app.persistentActivities > 0) { 11866 // The last app on the list is the foreground app. 11867 adj = FOREGROUND_APP_ADJ; 11868 app.isForeground = true; 11869 } else if (app.curReceiver != null || 11870 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) { 11871 // An app that is currently receiving a broadcast also 11872 // counts as being in the foreground. 11873 adj = FOREGROUND_APP_ADJ; 11874 } else if (app.executingServices.size() > 0) { 11875 // An app that is currently executing a service callback also 11876 // counts as being in the foreground. 11877 adj = FOREGROUND_APP_ADJ; 11878 } else if (app.foregroundServices || app.forcingToForeground != null) { 11879 // The user is aware of this app, so make it visible. 11880 adj = VISIBLE_APP_ADJ; 11881 } else if (app == mHomeProcess) { 11882 // This process is hosting what we currently consider to be the 11883 // home app, so we don't want to let it go into the background. 11884 adj = HOME_APP_ADJ; 11885 } else if ((N=app.activities.size()) != 0) { 11886 // This app is in the background with paused activities. 11887 adj = hiddenAdj; 11888 for (int j=0; j<N; j++) { 11889 if (((HistoryRecord)app.activities.get(j)).visible) { 11890 // This app has a visible activity! 11891 adj = VISIBLE_APP_ADJ; 11892 break; 11893 } 11894 } 11895 } else { 11896 // A very not-needed process. 11897 adj = EMPTY_APP_ADJ; 11898 } 11899 11900 // By default, we use the computed adjustment. It may be changed if 11901 // there are applications dependent on our services or providers, but 11902 // this gives us a baseline and makes sure we don't get into an 11903 // infinite recursion. 11904 app.adjSeq = mAdjSeq; 11905 app.curRawAdj = adj; 11906 app.curAdj = adj <= app.maxAdj ? adj : app.maxAdj; 11907 11908 if (mBackupTarget != null && app == mBackupTarget.app) { 11909 // If possible we want to avoid killing apps while they're being backed up 11910 if (adj > BACKUP_APP_ADJ) { 11911 if (DEBUG_BACKUP) Log.v(TAG, "oom BACKUP_APP_ADJ for " + app); 11912 adj = BACKUP_APP_ADJ; 11913 } 11914 } 11915 11916 if (app.services.size() != 0 && adj > FOREGROUND_APP_ADJ) { 11917 // If this process has active services running in it, we would 11918 // like to avoid killing it unless it would prevent the current 11919 // application from running. 11920 if (adj > hiddenAdj) { 11921 adj = hiddenAdj; 11922 } 11923 final long now = SystemClock.uptimeMillis(); 11924 // This process is more important if the top activity is 11925 // bound to the service. 11926 Iterator jt = app.services.iterator(); 11927 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) { 11928 ServiceRecord s = (ServiceRecord)jt.next(); 11929 if (s.startRequested) { 11930 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) { 11931 // This service has seen some activity within 11932 // recent memory, so we will keep its process ahead 11933 // of the background processes. 11934 if (adj > SECONDARY_SERVER_ADJ) { 11935 adj = SECONDARY_SERVER_ADJ; 11936 } 11937 } else { 11938 // This service has been inactive for too long, just 11939 // put it with the rest of the background processes. 11940 if (adj > hiddenAdj) { 11941 adj = hiddenAdj; 11942 } 11943 } 11944 } 11945 if (s.connections.size() > 0 && adj > FOREGROUND_APP_ADJ) { 11946 Iterator<ConnectionRecord> kt 11947 = s.connections.values().iterator(); 11948 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) { 11949 // XXX should compute this based on the max of 11950 // all connected clients. 11951 ConnectionRecord cr = kt.next(); 11952 if (cr.binding.client == app) { 11953 // Binding to ourself is not interesting. 11954 continue; 11955 } 11956 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) { 11957 ProcessRecord client = cr.binding.client; 11958 int myHiddenAdj = hiddenAdj; 11959 if (myHiddenAdj > client.hiddenAdj) { 11960 if (client.hiddenAdj > VISIBLE_APP_ADJ) { 11961 myHiddenAdj = client.hiddenAdj; 11962 } else { 11963 myHiddenAdj = VISIBLE_APP_ADJ; 11964 } 11965 } 11966 int clientAdj = computeOomAdjLocked( 11967 client, myHiddenAdj, TOP_APP); 11968 if (adj > clientAdj) { 11969 adj = clientAdj > VISIBLE_APP_ADJ 11970 ? clientAdj : VISIBLE_APP_ADJ; 11971 } 11972 } 11973 HistoryRecord a = cr.activity; 11974 //if (a != null) { 11975 // Log.i(TAG, "Connection to " + a ": state=" + a.state); 11976 //} 11977 if (a != null && adj > FOREGROUND_APP_ADJ && 11978 (a.state == ActivityState.RESUMED 11979 || a.state == ActivityState.PAUSING)) { 11980 adj = FOREGROUND_APP_ADJ; 11981 } 11982 } 11983 } 11984 } 11985 } 11986 11987 if (app.pubProviders.size() != 0 && adj > FOREGROUND_APP_ADJ) { 11988 // If this process has published any content providers, then 11989 // its adjustment makes it at least as important as any of the 11990 // processes using those providers, and no less important than 11991 // CONTENT_PROVIDER_ADJ, which is just shy of EMPTY. 11992 if (adj > CONTENT_PROVIDER_ADJ) { 11993 adj = CONTENT_PROVIDER_ADJ; 11994 } 11995 Iterator jt = app.pubProviders.values().iterator(); 11996 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) { 11997 ContentProviderRecord cpr = (ContentProviderRecord)jt.next(); 11998 if (cpr.clients.size() != 0) { 11999 Iterator<ProcessRecord> kt = cpr.clients.iterator(); 12000 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) { 12001 ProcessRecord client = kt.next(); 12002 if (client == app) { 12003 // Being our own client is not interesting. 12004 continue; 12005 } 12006 int myHiddenAdj = hiddenAdj; 12007 if (myHiddenAdj > client.hiddenAdj) { 12008 if (client.hiddenAdj > FOREGROUND_APP_ADJ) { 12009 myHiddenAdj = client.hiddenAdj; 12010 } else { 12011 myHiddenAdj = FOREGROUND_APP_ADJ; 12012 } 12013 } 12014 int clientAdj = computeOomAdjLocked( 12015 client, myHiddenAdj, TOP_APP); 12016 if (adj > clientAdj) { 12017 adj = clientAdj > FOREGROUND_APP_ADJ 12018 ? clientAdj : FOREGROUND_APP_ADJ; 12019 } 12020 } 12021 } 12022 // If the provider has external (non-framework) process 12023 // dependencies, ensure that its adjustment is at least 12024 // FOREGROUND_APP_ADJ. 12025 if (cpr.externals != 0) { 12026 if (adj > FOREGROUND_APP_ADJ) { 12027 adj = FOREGROUND_APP_ADJ; 12028 } 12029 } 12030 } 12031 } 12032 12033 app.curRawAdj = adj; 12034 12035 //Log.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 12036 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 12037 if (adj > app.maxAdj) { 12038 adj = app.maxAdj; 12039 } 12040 12041 app.curAdj = adj; 12042 app.curSchedGroup = (adj > VISIBLE_APP_ADJ && !app.persistent) 12043 ? Process.THREAD_GROUP_BG_NONINTERACTIVE 12044 : Process.THREAD_GROUP_DEFAULT; 12045 12046 return adj; 12047 } 12048 12049 /** 12050 * Ask a given process to GC right now. 12051 */ 12052 final void performAppGcLocked(ProcessRecord app) { 12053 try { 12054 app.lastRequestedGc = SystemClock.uptimeMillis(); 12055 if (app.thread != null) { 12056 app.thread.processInBackground(); 12057 } 12058 } catch (Exception e) { 12059 // whatever. 12060 } 12061 } 12062 12063 /** 12064 * Returns true if things are idle enough to perform GCs. 12065 */ 12066 private final boolean canGcNow() { 12067 return mParallelBroadcasts.size() == 0 12068 && mOrderedBroadcasts.size() == 0 12069 && (mSleeping || (mResumedActivity != null && 12070 mResumedActivity.idle)); 12071 } 12072 12073 /** 12074 * Perform GCs on all processes that are waiting for it, but only 12075 * if things are idle. 12076 */ 12077 final void performAppGcsLocked() { 12078 final int N = mProcessesToGc.size(); 12079 if (N <= 0) { 12080 return; 12081 } 12082 if (canGcNow()) { 12083 while (mProcessesToGc.size() > 0) { 12084 ProcessRecord proc = mProcessesToGc.remove(0); 12085 if (proc.curRawAdj > VISIBLE_APP_ADJ) { 12086 // To avoid spamming the system, we will GC processes one 12087 // at a time, waiting a few seconds between each. 12088 performAppGcLocked(proc); 12089 scheduleAppGcsLocked(); 12090 return; 12091 } 12092 } 12093 } 12094 } 12095 12096 /** 12097 * If all looks good, perform GCs on all processes waiting for them. 12098 */ 12099 final void performAppGcsIfAppropriateLocked() { 12100 if (canGcNow()) { 12101 performAppGcsLocked(); 12102 return; 12103 } 12104 // Still not idle, wait some more. 12105 scheduleAppGcsLocked(); 12106 } 12107 12108 /** 12109 * Schedule the execution of all pending app GCs. 12110 */ 12111 final void scheduleAppGcsLocked() { 12112 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 12113 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 12114 mHandler.sendMessageDelayed(msg, GC_TIMEOUT); 12115 } 12116 12117 /** 12118 * Set up to ask a process to GC itself. This will either do it 12119 * immediately, or put it on the list of processes to gc the next 12120 * time things are idle. 12121 */ 12122 final void scheduleAppGcLocked(ProcessRecord app) { 12123 long now = SystemClock.uptimeMillis(); 12124 if ((app.lastRequestedGc+5000) > now) { 12125 return; 12126 } 12127 if (!mProcessesToGc.contains(app)) { 12128 mProcessesToGc.add(app); 12129 scheduleAppGcsLocked(); 12130 } 12131 } 12132 12133 private final boolean updateOomAdjLocked( 12134 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) { 12135 app.hiddenAdj = hiddenAdj; 12136 12137 if (app.thread == null) { 12138 return true; 12139 } 12140 12141 int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP); 12142 12143 //Log.i(TAG, "Computed adj " + adj + " for app " + app.processName); 12144 //Thread priority adjustment is disabled out to see 12145 //how the kernel scheduler performs. 12146 if (false) { 12147 if (app.pid != 0 && app.isForeground != app.setIsForeground) { 12148 app.setIsForeground = app.isForeground; 12149 if (app.pid != MY_PID) { 12150 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v(TAG, "Setting priority of " + app 12151 + " to " + (app.isForeground 12152 ? Process.THREAD_PRIORITY_FOREGROUND 12153 : Process.THREAD_PRIORITY_DEFAULT)); 12154 try { 12155 Process.setThreadPriority(app.pid, app.isForeground 12156 ? Process.THREAD_PRIORITY_FOREGROUND 12157 : Process.THREAD_PRIORITY_DEFAULT); 12158 } catch (RuntimeException e) { 12159 Log.w(TAG, "Exception trying to set priority of application thread " 12160 + app.pid, e); 12161 } 12162 } 12163 } 12164 } 12165 if (app.pid != 0 && app.pid != MY_PID) { 12166 if (app.curRawAdj != app.setRawAdj) { 12167 if (app.curRawAdj > FOREGROUND_APP_ADJ 12168 && app.setRawAdj <= FOREGROUND_APP_ADJ) { 12169 // If this app is transitioning from foreground to 12170 // non-foreground, have it do a gc. 12171 scheduleAppGcLocked(app); 12172 } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ 12173 && app.setRawAdj < HIDDEN_APP_MIN_ADJ) { 12174 // Likewise do a gc when an app is moving in to the 12175 // background (such as a service stopping). 12176 scheduleAppGcLocked(app); 12177 } 12178 app.setRawAdj = app.curRawAdj; 12179 } 12180 if (adj != app.setAdj) { 12181 if (Process.setOomAdj(app.pid, adj)) { 12182 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v( 12183 TAG, "Set app " + app.processName + 12184 " oom adj to " + adj); 12185 app.setAdj = adj; 12186 } else { 12187 return false; 12188 } 12189 } 12190 if (app.setSchedGroup != app.curSchedGroup) { 12191 app.setSchedGroup = app.curSchedGroup; 12192 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v(TAG, 12193 "Setting process group of " + app.processName 12194 + " to " + app.curSchedGroup); 12195 if (true) { 12196 long oldId = Binder.clearCallingIdentity(); 12197 try { 12198 Process.setProcessGroup(app.pid, app.curSchedGroup); 12199 } catch (Exception e) { 12200 Log.w(TAG, "Failed setting process group of " + app.pid 12201 + " to " + app.curSchedGroup); 12202 e.printStackTrace(); 12203 } finally { 12204 Binder.restoreCallingIdentity(oldId); 12205 } 12206 } 12207 if (false) { 12208 if (app.thread != null) { 12209 try { 12210 app.thread.setSchedulingGroup(app.curSchedGroup); 12211 } catch (RemoteException e) { 12212 } 12213 } 12214 } 12215 } 12216 } 12217 12218 return true; 12219 } 12220 12221 private final HistoryRecord resumedAppLocked() { 12222 HistoryRecord resumedActivity = mResumedActivity; 12223 if (resumedActivity == null || resumedActivity.app == null) { 12224 resumedActivity = mPausingActivity; 12225 if (resumedActivity == null || resumedActivity.app == null) { 12226 resumedActivity = topRunningActivityLocked(null); 12227 } 12228 } 12229 return resumedActivity; 12230 } 12231 12232 private final boolean updateOomAdjLocked(ProcessRecord app) { 12233 final HistoryRecord TOP_ACT = resumedAppLocked(); 12234 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12235 int curAdj = app.curAdj; 12236 final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ 12237 && app.curAdj <= HIDDEN_APP_MAX_ADJ; 12238 12239 mAdjSeq++; 12240 12241 final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP); 12242 if (res) { 12243 final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ 12244 && app.curAdj <= HIDDEN_APP_MAX_ADJ; 12245 if (nowHidden != wasHidden) { 12246 // Changed to/from hidden state, so apps after it in the LRU 12247 // list may also be changed. 12248 updateOomAdjLocked(); 12249 } 12250 } 12251 return res; 12252 } 12253 12254 private final boolean updateOomAdjLocked() { 12255 boolean didOomAdj = true; 12256 final HistoryRecord TOP_ACT = resumedAppLocked(); 12257 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 12258 12259 if (false) { 12260 RuntimeException e = new RuntimeException(); 12261 e.fillInStackTrace(); 12262 Log.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 12263 } 12264 12265 mAdjSeq++; 12266 12267 // First try updating the OOM adjustment for each of the 12268 // application processes based on their current state. 12269 int i = mLRUProcesses.size(); 12270 int curHiddenAdj = HIDDEN_APP_MIN_ADJ; 12271 while (i > 0) { 12272 i--; 12273 ProcessRecord app = mLRUProcesses.get(i); 12274 if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) { 12275 if (curHiddenAdj < HIDDEN_APP_MAX_ADJ 12276 && app.curAdj == curHiddenAdj) { 12277 curHiddenAdj++; 12278 } 12279 } else { 12280 didOomAdj = false; 12281 } 12282 } 12283 12284 // todo: for now pretend like OOM ADJ didn't work, because things 12285 // aren't behaving as expected on Linux -- it's not killing processes. 12286 return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj; 12287 } 12288 12289 private final void trimApplications() { 12290 synchronized (this) { 12291 int i; 12292 12293 // First remove any unused application processes whose package 12294 // has been removed. 12295 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 12296 final ProcessRecord app = mRemovedProcesses.get(i); 12297 if (app.activities.size() == 0 12298 && app.curReceiver == null && app.services.size() == 0) { 12299 Log.i( 12300 TAG, "Exiting empty application process " 12301 + app.processName + " (" 12302 + (app.thread != null ? app.thread.asBinder() : null) 12303 + ")\n"); 12304 if (app.pid > 0 && app.pid != MY_PID) { 12305 Process.killProcess(app.pid); 12306 } else { 12307 try { 12308 app.thread.scheduleExit(); 12309 } catch (Exception e) { 12310 // Ignore exceptions. 12311 } 12312 } 12313 cleanUpApplicationRecordLocked(app, false, -1); 12314 mRemovedProcesses.remove(i); 12315 12316 if (app.persistent) { 12317 if (app.persistent) { 12318 addAppLocked(app.info); 12319 } 12320 } 12321 } 12322 } 12323 12324 // Now try updating the OOM adjustment for each of the 12325 // application processes based on their current state. 12326 // If the setOomAdj() API is not supported, then go with our 12327 // back-up plan... 12328 if (!updateOomAdjLocked()) { 12329 12330 // Count how many processes are running services. 12331 int numServiceProcs = 0; 12332 for (i=mLRUProcesses.size()-1; i>=0; i--) { 12333 final ProcessRecord app = mLRUProcesses.get(i); 12334 12335 if (app.persistent || app.services.size() != 0 12336 || app.curReceiver != null 12337 || app.persistentActivities > 0) { 12338 // Don't count processes holding services against our 12339 // maximum process count. 12340 if (localLOGV) Log.v( 12341 TAG, "Not trimming app " + app + " with services: " 12342 + app.services); 12343 numServiceProcs++; 12344 } 12345 } 12346 12347 int curMaxProcs = mProcessLimit; 12348 if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES; 12349 if (mAlwaysFinishActivities) { 12350 curMaxProcs = 1; 12351 } 12352 curMaxProcs += numServiceProcs; 12353 12354 // Quit as many processes as we can to get down to the desired 12355 // process count. First remove any processes that no longer 12356 // have activites running in them. 12357 for ( i=0; 12358 i<mLRUProcesses.size() 12359 && mLRUProcesses.size() > curMaxProcs; 12360 i++) { 12361 final ProcessRecord app = mLRUProcesses.get(i); 12362 // Quit an application only if it is not currently 12363 // running any activities. 12364 if (!app.persistent && app.activities.size() == 0 12365 && app.curReceiver == null && app.services.size() == 0) { 12366 Log.i( 12367 TAG, "Exiting empty application process " 12368 + app.processName + " (" 12369 + (app.thread != null ? app.thread.asBinder() : null) 12370 + ")\n"); 12371 if (app.pid > 0 && app.pid != MY_PID) { 12372 Process.killProcess(app.pid); 12373 } else { 12374 try { 12375 app.thread.scheduleExit(); 12376 } catch (Exception e) { 12377 // Ignore exceptions. 12378 } 12379 } 12380 // todo: For now we assume the application is not buggy 12381 // or evil, and will quit as a result of our request. 12382 // Eventually we need to drive this off of the death 12383 // notification, and kill the process if it takes too long. 12384 cleanUpApplicationRecordLocked(app, false, i); 12385 i--; 12386 } 12387 } 12388 12389 // If we still have too many processes, now from the least 12390 // recently used process we start finishing activities. 12391 if (Config.LOGV) Log.v( 12392 TAG, "*** NOW HAVE " + mLRUProcesses.size() + 12393 " of " + curMaxProcs + " processes"); 12394 for ( i=0; 12395 i<mLRUProcesses.size() 12396 && mLRUProcesses.size() > curMaxProcs; 12397 i++) { 12398 final ProcessRecord app = mLRUProcesses.get(i); 12399 // Quit the application only if we have a state saved for 12400 // all of its activities. 12401 boolean canQuit = !app.persistent && app.curReceiver == null 12402 && app.services.size() == 0 12403 && app.persistentActivities == 0; 12404 int NUMA = app.activities.size(); 12405 int j; 12406 if (Config.LOGV) Log.v( 12407 TAG, "Looking to quit " + app.processName); 12408 for (j=0; j<NUMA && canQuit; j++) { 12409 HistoryRecord r = (HistoryRecord)app.activities.get(j); 12410 if (Config.LOGV) Log.v( 12411 TAG, " " + r.intent.getComponent().flattenToShortString() 12412 + ": frozen=" + r.haveState + ", visible=" + r.visible); 12413 canQuit = (r.haveState || !r.stateNotNeeded) 12414 && !r.visible && r.stopped; 12415 } 12416 if (canQuit) { 12417 // Finish all of the activities, and then the app itself. 12418 for (j=0; j<NUMA; j++) { 12419 HistoryRecord r = (HistoryRecord)app.activities.get(j); 12420 if (!r.finishing) { 12421 destroyActivityLocked(r, false); 12422 } 12423 r.resultTo = null; 12424 } 12425 Log.i(TAG, "Exiting application process " 12426 + app.processName + " (" 12427 + (app.thread != null ? app.thread.asBinder() : null) 12428 + ")\n"); 12429 if (app.pid > 0 && app.pid != MY_PID) { 12430 Process.killProcess(app.pid); 12431 } else { 12432 try { 12433 app.thread.scheduleExit(); 12434 } catch (Exception e) { 12435 // Ignore exceptions. 12436 } 12437 } 12438 // todo: For now we assume the application is not buggy 12439 // or evil, and will quit as a result of our request. 12440 // Eventually we need to drive this off of the death 12441 // notification, and kill the process if it takes too long. 12442 cleanUpApplicationRecordLocked(app, false, i); 12443 i--; 12444 //dump(); 12445 } 12446 } 12447 12448 } 12449 12450 int curMaxActivities = MAX_ACTIVITIES; 12451 if (mAlwaysFinishActivities) { 12452 curMaxActivities = 1; 12453 } 12454 12455 // Finally, if there are too many activities now running, try to 12456 // finish as many as we can to get back down to the limit. 12457 for ( i=0; 12458 i<mLRUActivities.size() 12459 && mLRUActivities.size() > curMaxActivities; 12460 i++) { 12461 final HistoryRecord r 12462 = (HistoryRecord)mLRUActivities.get(i); 12463 12464 // We can finish this one if we have its icicle saved and 12465 // it is not persistent. 12466 if ((r.haveState || !r.stateNotNeeded) && !r.visible 12467 && r.stopped && !r.persistent && !r.finishing) { 12468 final int origSize = mLRUActivities.size(); 12469 destroyActivityLocked(r, true); 12470 12471 // This will remove it from the LRU list, so keep 12472 // our index at the same value. Note that this check to 12473 // see if the size changes is just paranoia -- if 12474 // something unexpected happens, we don't want to end up 12475 // in an infinite loop. 12476 if (origSize > mLRUActivities.size()) { 12477 i--; 12478 } 12479 } 12480 } 12481 } 12482 } 12483 12484 /** This method sends the specified signal to each of the persistent apps */ 12485 public void signalPersistentProcesses(int sig) throws RemoteException { 12486 if (sig != Process.SIGNAL_USR1) { 12487 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 12488 } 12489 12490 synchronized (this) { 12491 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 12492 != PackageManager.PERMISSION_GRANTED) { 12493 throw new SecurityException("Requires permission " 12494 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 12495 } 12496 12497 for (int i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) { 12498 ProcessRecord r = mLRUProcesses.get(i); 12499 if (r.thread != null && r.persistent) { 12500 Process.sendSignal(r.pid, sig); 12501 } 12502 } 12503 } 12504 } 12505 12506 public boolean profileControl(String process, boolean start, 12507 String path) throws RemoteException { 12508 12509 synchronized (this) { 12510 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 12511 // its own permission. 12512 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 12513 != PackageManager.PERMISSION_GRANTED) { 12514 throw new SecurityException("Requires permission " 12515 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 12516 } 12517 12518 ProcessRecord proc = null; 12519 try { 12520 int pid = Integer.parseInt(process); 12521 synchronized (mPidsSelfLocked) { 12522 proc = mPidsSelfLocked.get(pid); 12523 } 12524 } catch (NumberFormatException e) { 12525 } 12526 12527 if (proc == null) { 12528 HashMap<String, SparseArray<ProcessRecord>> all 12529 = mProcessNames.getMap(); 12530 SparseArray<ProcessRecord> procs = all.get(process); 12531 if (procs != null && procs.size() > 0) { 12532 proc = procs.valueAt(0); 12533 } 12534 } 12535 12536 if (proc == null || proc.thread == null) { 12537 throw new IllegalArgumentException("Unknown process: " + process); 12538 } 12539 12540 boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0")); 12541 if (isSecure) { 12542 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 12543 throw new SecurityException("Process not debuggable: " + proc); 12544 } 12545 } 12546 12547 try { 12548 proc.thread.profilerControl(start, path); 12549 return true; 12550 } catch (RemoteException e) { 12551 throw new IllegalStateException("Process disappeared"); 12552 } 12553 } 12554 } 12555 12556 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 12557 public void monitor() { 12558 synchronized (this) { } 12559 } 12560} 12561