ActivityManagerService.java revision 23085b781e145ed684e7270af1d5ced6800b8eff
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.server.AttributeCache; 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 dalvik.system.Zygote; 29 30import android.app.Activity; 31import android.app.ActivityManager; 32import android.app.ActivityManagerNative; 33import android.app.ActivityThread; 34import android.app.AlertDialog; 35import android.app.ApplicationErrorReport; 36import android.app.Dialog; 37import android.app.IActivityController; 38import android.app.IActivityWatcher; 39import android.app.IApplicationThread; 40import android.app.IInstrumentationWatcher; 41import android.app.IServiceConnection; 42import android.app.IThumbnailReceiver; 43import android.app.Instrumentation; 44import android.app.Notification; 45import android.app.PendingIntent; 46import android.app.ResultInfo; 47import android.app.Service; 48import android.backup.IBackupManager; 49import android.content.ActivityNotFoundException; 50import android.content.ComponentName; 51import android.content.ContentResolver; 52import android.content.Context; 53import android.content.Intent; 54import android.content.IntentFilter; 55import android.content.IIntentReceiver; 56import android.content.IIntentSender; 57import android.content.IntentSender; 58import android.content.pm.ActivityInfo; 59import android.content.pm.ApplicationInfo; 60import android.content.pm.ConfigurationInfo; 61import android.content.pm.IPackageDataObserver; 62import android.content.pm.IPackageManager; 63import android.content.pm.InstrumentationInfo; 64import android.content.pm.PackageInfo; 65import android.content.pm.PackageManager; 66import android.content.pm.PathPermission; 67import android.content.pm.ProviderInfo; 68import android.content.pm.ResolveInfo; 69import android.content.pm.ServiceInfo; 70import android.content.res.Configuration; 71import android.graphics.Bitmap; 72import android.net.Uri; 73import android.os.Binder; 74import android.os.Build; 75import android.os.Bundle; 76import android.os.Debug; 77import android.os.DropBoxManager; 78import android.os.Environment; 79import android.os.FileObserver; 80import android.os.FileUtils; 81import android.os.Handler; 82import android.os.IBinder; 83import android.os.IPermissionController; 84import android.os.Looper; 85import android.os.Message; 86import android.os.Parcel; 87import android.os.ParcelFileDescriptor; 88import android.os.PowerManager; 89import android.os.Process; 90import android.os.RemoteCallbackList; 91import android.os.RemoteException; 92import android.os.ServiceManager; 93import android.os.SystemClock; 94import android.os.SystemProperties; 95import android.provider.Checkin; 96import android.provider.Settings; 97import android.text.TextUtils; 98import android.util.Config; 99import android.util.EventLog; 100import android.util.Log; 101import android.util.PrintWriterPrinter; 102import android.util.SparseArray; 103import android.view.Gravity; 104import android.view.LayoutInflater; 105import android.view.View; 106import android.view.WindowManager; 107import android.view.WindowManagerPolicy; 108 109import java.io.File; 110import java.io.FileDescriptor; 111import java.io.FileInputStream; 112import java.io.FileNotFoundException; 113import java.io.IOException; 114import java.io.PrintWriter; 115import java.lang.IllegalStateException; 116import java.lang.ref.WeakReference; 117import java.util.ArrayList; 118import java.util.HashMap; 119import java.util.HashSet; 120import java.util.Iterator; 121import java.util.List; 122import java.util.Locale; 123import java.util.Map; 124 125public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor { 126 static final String TAG = "ActivityManager"; 127 static final boolean DEBUG = false; 128 static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV; 129 static final boolean DEBUG_SWITCH = localLOGV || false; 130 static final boolean DEBUG_TASKS = localLOGV || false; 131 static final boolean DEBUG_PAUSE = localLOGV || false; 132 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 133 static final boolean DEBUG_TRANSITION = localLOGV || false; 134 static final boolean DEBUG_BROADCAST = localLOGV || false; 135 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 136 static final boolean DEBUG_SERVICE = localLOGV || false; 137 static final boolean DEBUG_VISBILITY = localLOGV || false; 138 static final boolean DEBUG_PROCESSES = localLOGV || false; 139 static final boolean DEBUG_PROVIDER = localLOGV || false; 140 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 141 static final boolean DEBUG_RESULTS = localLOGV || false; 142 static final boolean DEBUG_BACKUP = localLOGV || false; 143 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 144 static final boolean VALIDATE_TOKENS = false; 145 static final boolean SHOW_ACTIVITY_START_TIME = true; 146 147 // Control over CPU and battery monitoring. 148 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 149 static final boolean MONITOR_CPU_USAGE = true; 150 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 151 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 152 static final boolean MONITOR_THREAD_CPU_USAGE = false; 153 154 // The flags that are set for all calls we make to the package manager. 155 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 156 157 private static final String SYSTEM_SECURE = "ro.secure"; 158 159 // This is the maximum number of application processes we would like 160 // to have running. Due to the asynchronous nature of things, we can 161 // temporarily go beyond this limit. 162 static final int MAX_PROCESSES = 2; 163 164 // Set to false to leave processes running indefinitely, relying on 165 // the kernel killing them as resources are required. 166 static final boolean ENFORCE_PROCESS_LIMIT = false; 167 168 // This is the maximum number of activities that we would like to have 169 // running at a given time. 170 static final int MAX_ACTIVITIES = 20; 171 172 // Maximum number of recent tasks that we can remember. 173 static final int MAX_RECENT_TASKS = 20; 174 175 // Amount of time after a call to stopAppSwitches() during which we will 176 // prevent further untrusted switches from happening. 177 static final long APP_SWITCH_DELAY_TIME = 5*1000; 178 179 // How long until we reset a task when the user returns to it. Currently 180 // 30 minutes. 181 static final long ACTIVITY_INACTIVE_RESET_TIME = 1000*60*30; 182 183 // Set to true to disable the icon that is shown while a new activity 184 // is being started. 185 static final boolean SHOW_APP_STARTING_ICON = true; 186 187 // How long we wait until giving up on the last activity to pause. This 188 // is short because it directly impacts the responsiveness of starting the 189 // next activity. 190 static final int PAUSE_TIMEOUT = 500; 191 192 /** 193 * How long we can hold the launch wake lock before giving up. 194 */ 195 static final int LAUNCH_TIMEOUT = 10*1000; 196 197 // How long we wait for a launched process to attach to the activity manager 198 // before we decide it's never going to come up for real. 199 static final int PROC_START_TIMEOUT = 10*1000; 200 201 // How long we wait until giving up on the last activity telling us it 202 // is idle. 203 static final int IDLE_TIMEOUT = 10*1000; 204 205 // How long to wait after going idle before forcing apps to GC. 206 static final int GC_TIMEOUT = 5*1000; 207 208 // The minimum amount of time between successive GC requests for a process. 209 static final int GC_MIN_INTERVAL = 60*1000; 210 211 // How long we wait until giving up on an activity telling us it has 212 // finished destroying itself. 213 static final int DESTROY_TIMEOUT = 10*1000; 214 215 // How long we allow a receiver to run before giving up on it. 216 static final int BROADCAST_TIMEOUT = 10*1000; 217 218 // How long we wait for a service to finish executing. 219 static final int SERVICE_TIMEOUT = 20*1000; 220 221 // How long a service needs to be running until restarting its process 222 // is no longer considered to be a relaunch of the service. 223 static final int SERVICE_RESTART_DURATION = 5*1000; 224 225 // How long a service needs to be running until it will start back at 226 // SERVICE_RESTART_DURATION after being killed. 227 static final int SERVICE_RESET_RUN_DURATION = 60*1000; 228 229 // Multiplying factor to increase restart duration time by, for each time 230 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION. 231 static final int SERVICE_RESTART_DURATION_FACTOR = 4; 232 233 // The minimum amount of time between restarting services that we allow. 234 // That is, when multiple services are restarting, we won't allow each 235 // to restart less than this amount of time from the last one. 236 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000; 237 238 // Maximum amount of time for there to be no activity on a service before 239 // we consider it non-essential and allow its process to go on the 240 // LRU background list. 241 static final int MAX_SERVICE_INACTIVITY = 30*60*1000; 242 243 // How long we wait until we timeout on key dispatching. 244 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 245 246 // The minimum time we allow between crashes, for us to consider this 247 // application to be bad and stop and its services and reject broadcasts. 248 static final int MIN_CRASH_INTERVAL = 60*1000; 249 250 // How long we wait until we timeout on key dispatching during instrumentation. 251 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 252 253 // OOM adjustments for processes in various states: 254 255 // This is a process without anything currently running in it. Definitely 256 // the first to go! Value set in system/rootdir/init.rc on startup. 257 // This value is initalized in the constructor, careful when refering to 258 // this static variable externally. 259 static final int EMPTY_APP_ADJ; 260 261 // This is a process only hosting activities that are not visible, 262 // so it can be killed without any disruption. Value set in 263 // system/rootdir/init.rc on startup. 264 static final int HIDDEN_APP_MAX_ADJ; 265 static int HIDDEN_APP_MIN_ADJ; 266 267 // This is a process holding the home application -- we want to try 268 // avoiding killing it, even if it would normally be in the background, 269 // because the user interacts with it so much. 270 static final int HOME_APP_ADJ; 271 272 // This is a process currently hosting a backup operation. Killing it 273 // is not entirely fatal but is generally a bad idea. 274 static final int BACKUP_APP_ADJ; 275 276 // This is a process holding a secondary server -- killing it will not 277 // have much of an impact as far as the user is concerned. Value set in 278 // system/rootdir/init.rc on startup. 279 static final int SECONDARY_SERVER_ADJ; 280 281 // This is a process only hosting activities that are visible to the 282 // user, so we'd prefer they don't disappear. Value set in 283 // system/rootdir/init.rc on startup. 284 static final int VISIBLE_APP_ADJ; 285 286 // This is the process running the current foreground app. We'd really 287 // rather not kill it! Value set in system/rootdir/init.rc on startup. 288 static final int FOREGROUND_APP_ADJ; 289 290 // This is a process running a core server, such as telephony. Definitely 291 // don't want to kill it, but doing so is not completely fatal. 292 static final int CORE_SERVER_ADJ = -12; 293 294 // The system process runs at the default adjustment. 295 static final int SYSTEM_ADJ = -16; 296 297 // Memory pages are 4K. 298 static final int PAGE_SIZE = 4*1024; 299 300 // System property defining error report receiver for system apps 301 static final String SYSTEM_APPS_ERROR_RECEIVER_PROPERTY = "ro.error.receiver.system.apps"; 302 303 // System property defining default error report receiver 304 static final String DEFAULT_ERROR_RECEIVER_PROPERTY = "ro.error.receiver.default"; 305 306 // Corresponding memory levels for above adjustments. 307 static final int EMPTY_APP_MEM; 308 static final int HIDDEN_APP_MEM; 309 static final int HOME_APP_MEM; 310 static final int BACKUP_APP_MEM; 311 static final int SECONDARY_SERVER_MEM; 312 static final int VISIBLE_APP_MEM; 313 static final int FOREGROUND_APP_MEM; 314 315 // The minimum number of hidden apps we want to be able to keep around, 316 // without empty apps being able to push them out of memory. 317 static final int MIN_HIDDEN_APPS = 2; 318 319 // We put empty content processes after any hidden processes that have 320 // been idle for less than 30 seconds. 321 static final long CONTENT_APP_IDLE_OFFSET = 30*1000; 322 323 // We put empty content processes after any hidden processes that have 324 // been idle for less than 60 seconds. 325 static final long EMPTY_APP_IDLE_OFFSET = 60*1000; 326 327 static { 328 // These values are set in system/rootdir/init.rc on startup. 329 FOREGROUND_APP_ADJ = 330 Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_ADJ")); 331 VISIBLE_APP_ADJ = 332 Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_ADJ")); 333 SECONDARY_SERVER_ADJ = 334 Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_ADJ")); 335 BACKUP_APP_ADJ = 336 Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_ADJ")); 337 HOME_APP_ADJ = 338 Integer.valueOf(SystemProperties.get("ro.HOME_APP_ADJ")); 339 HIDDEN_APP_MIN_ADJ = 340 Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MIN_ADJ")); 341 EMPTY_APP_ADJ = 342 Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_ADJ")); 343 HIDDEN_APP_MAX_ADJ = EMPTY_APP_ADJ-1; 344 FOREGROUND_APP_MEM = 345 Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_MEM"))*PAGE_SIZE; 346 VISIBLE_APP_MEM = 347 Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_MEM"))*PAGE_SIZE; 348 SECONDARY_SERVER_MEM = 349 Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_MEM"))*PAGE_SIZE; 350 BACKUP_APP_MEM = 351 Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_MEM"))*PAGE_SIZE; 352 HOME_APP_MEM = 353 Integer.valueOf(SystemProperties.get("ro.HOME_APP_MEM"))*PAGE_SIZE; 354 HIDDEN_APP_MEM = 355 Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MEM"))*PAGE_SIZE; 356 EMPTY_APP_MEM = 357 Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_MEM"))*PAGE_SIZE; 358 } 359 360 static final int MY_PID = Process.myPid(); 361 362 static final String[] EMPTY_STRING_ARRAY = new String[0]; 363 364 enum ActivityState { 365 INITIALIZING, 366 RESUMED, 367 PAUSING, 368 PAUSED, 369 STOPPING, 370 STOPPED, 371 FINISHING, 372 DESTROYING, 373 DESTROYED 374 } 375 376 /** 377 * The back history of all previous (and possibly still 378 * running) activities. It contains HistoryRecord objects. 379 */ 380 final ArrayList mHistory = new ArrayList(); 381 382 /** 383 * Description of a request to start a new activity, which has been held 384 * due to app switches being disabled. 385 */ 386 class PendingActivityLaunch { 387 HistoryRecord r; 388 HistoryRecord sourceRecord; 389 Uri[] grantedUriPermissions; 390 int grantedMode; 391 boolean onlyIfNeeded; 392 } 393 394 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 395 = new ArrayList<PendingActivityLaunch>(); 396 397 /** 398 * List of all active broadcasts that are to be executed immediately 399 * (without waiting for another broadcast to finish). Currently this only 400 * contains broadcasts to registered receivers, to avoid spinning up 401 * a bunch of processes to execute IntentReceiver components. 402 */ 403 final ArrayList<BroadcastRecord> mParallelBroadcasts 404 = new ArrayList<BroadcastRecord>(); 405 406 /** 407 * List of all active broadcasts that are to be executed one at a time. 408 * The object at the top of the list is the currently activity broadcasts; 409 * those after it are waiting for the top to finish.. 410 */ 411 final ArrayList<BroadcastRecord> mOrderedBroadcasts 412 = new ArrayList<BroadcastRecord>(); 413 414 /** 415 * Historical data of past broadcasts, for debugging. 416 */ 417 static final int MAX_BROADCAST_HISTORY = 100; 418 final BroadcastRecord[] mBroadcastHistory 419 = new BroadcastRecord[MAX_BROADCAST_HISTORY]; 420 421 /** 422 * Set when we current have a BROADCAST_INTENT_MSG in flight. 423 */ 424 boolean mBroadcastsScheduled = false; 425 426 /** 427 * Set to indicate whether to issue an onUserLeaving callback when a 428 * newly launched activity is being brought in front of us. 429 */ 430 boolean mUserLeaving = false; 431 432 /** 433 * When we are in the process of pausing an activity, before starting the 434 * next one, this variable holds the activity that is currently being paused. 435 */ 436 HistoryRecord mPausingActivity = null; 437 438 /** 439 * Current activity that is resumed, or null if there is none. 440 */ 441 HistoryRecord mResumedActivity = null; 442 443 /** 444 * Activity we have told the window manager to have key focus. 445 */ 446 HistoryRecord mFocusedActivity = null; 447 448 /** 449 * This is the last activity that we put into the paused state. This is 450 * used to determine if we need to do an activity transition while sleeping, 451 * when we normally hold the top activity paused. 452 */ 453 HistoryRecord mLastPausedActivity = null; 454 455 /** 456 * List of activities that are waiting for a new activity 457 * to become visible before completing whatever operation they are 458 * supposed to do. 459 */ 460 final ArrayList mWaitingVisibleActivities = new ArrayList(); 461 462 /** 463 * List of activities that are ready to be stopped, but waiting 464 * for the next activity to settle down before doing so. It contains 465 * HistoryRecord objects. 466 */ 467 final ArrayList<HistoryRecord> mStoppingActivities 468 = new ArrayList<HistoryRecord>(); 469 470 /** 471 * Animations that for the current transition have requested not to 472 * be considered for the transition animation. 473 */ 474 final ArrayList<HistoryRecord> mNoAnimActivities 475 = new ArrayList<HistoryRecord>(); 476 477 /** 478 * List of intents that were used to start the most recent tasks. 479 */ 480 final ArrayList<TaskRecord> mRecentTasks 481 = new ArrayList<TaskRecord>(); 482 483 /** 484 * List of activities that are ready to be finished, but waiting 485 * for the previous activity to settle down before doing so. It contains 486 * HistoryRecord objects. 487 */ 488 final ArrayList mFinishingActivities = new ArrayList(); 489 490 /** 491 * All of the applications we currently have running organized by name. 492 * The keys are strings of the application package name (as 493 * returned by the package manager), and the keys are ApplicationRecord 494 * objects. 495 */ 496 final ProcessMap<ProcessRecord> mProcessNames 497 = new ProcessMap<ProcessRecord>(); 498 499 /** 500 * The last time that various processes have crashed. 501 */ 502 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 503 504 /** 505 * Set of applications that we consider to be bad, and will reject 506 * incoming broadcasts from (which the user has no control over). 507 * Processes are added to this set when they have crashed twice within 508 * a minimum amount of time; they are removed from it when they are 509 * later restarted (hopefully due to some user action). The value is the 510 * time it was added to the list. 511 */ 512 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 513 514 /** 515 * All of the processes we currently have running organized by pid. 516 * The keys are the pid running the application. 517 * 518 * <p>NOTE: This object is protected by its own lock, NOT the global 519 * activity manager lock! 520 */ 521 final SparseArray<ProcessRecord> mPidsSelfLocked 522 = new SparseArray<ProcessRecord>(); 523 524 /** 525 * All of the processes that have been forced to be foreground. The key 526 * is the pid of the caller who requested it (we hold a death 527 * link on it). 528 */ 529 abstract class ForegroundToken implements IBinder.DeathRecipient { 530 int pid; 531 IBinder token; 532 } 533 final SparseArray<ForegroundToken> mForegroundProcesses 534 = new SparseArray<ForegroundToken>(); 535 536 /** 537 * List of records for processes that someone had tried to start before the 538 * system was ready. We don't start them at that point, but ensure they 539 * are started by the time booting is complete. 540 */ 541 final ArrayList<ProcessRecord> mProcessesOnHold 542 = new ArrayList<ProcessRecord>(); 543 544 /** 545 * List of records for processes that we have started and are waiting 546 * for them to call back. This is really only needed when running in 547 * single processes mode, in which case we do not have a unique pid for 548 * each process. 549 */ 550 final ArrayList<ProcessRecord> mStartingProcesses 551 = new ArrayList<ProcessRecord>(); 552 553 /** 554 * List of persistent applications that are in the process 555 * of being started. 556 */ 557 final ArrayList<ProcessRecord> mPersistentStartingProcesses 558 = new ArrayList<ProcessRecord>(); 559 560 /** 561 * Processes that are being forcibly torn down. 562 */ 563 final ArrayList<ProcessRecord> mRemovedProcesses 564 = new ArrayList<ProcessRecord>(); 565 566 /** 567 * List of running applications, sorted by recent usage. 568 * The first entry in the list is the least recently used. 569 * It contains ApplicationRecord objects. This list does NOT include 570 * any persistent application records (since we never want to exit them). 571 */ 572 final ArrayList<ProcessRecord> mLruProcesses 573 = new ArrayList<ProcessRecord>(); 574 575 /** 576 * List of processes that should gc as soon as things are idle. 577 */ 578 final ArrayList<ProcessRecord> mProcessesToGc 579 = new ArrayList<ProcessRecord>(); 580 581 /** 582 * This is the process holding what we currently consider to be 583 * the "home" activity. 584 */ 585 private ProcessRecord mHomeProcess; 586 587 /** 588 * List of running activities, sorted by recent usage. 589 * The first entry in the list is the least recently used. 590 * It contains HistoryRecord objects. 591 */ 592 private final ArrayList mLRUActivities = new ArrayList(); 593 594 /** 595 * Set of PendingResultRecord objects that are currently active. 596 */ 597 final HashSet mPendingResultRecords = new HashSet(); 598 599 /** 600 * Set of IntentSenderRecord objects that are currently active. 601 */ 602 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 603 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 604 605 /** 606 * Intent broadcast that we have tried to start, but are 607 * waiting for its application's process to be created. We only 608 * need one (instead of a list) because we always process broadcasts 609 * one at a time, so no others can be started while waiting for this 610 * one. 611 */ 612 BroadcastRecord mPendingBroadcast = null; 613 614 /** 615 * Keeps track of all IIntentReceivers that have been registered for 616 * broadcasts. Hash keys are the receiver IBinder, hash value is 617 * a ReceiverList. 618 */ 619 final HashMap mRegisteredReceivers = new HashMap(); 620 621 /** 622 * Resolver for broadcast intents to registered receivers. 623 * Holds BroadcastFilter (subclass of IntentFilter). 624 */ 625 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 626 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 627 @Override 628 protected boolean allowFilterResult( 629 BroadcastFilter filter, List<BroadcastFilter> dest) { 630 IBinder target = filter.receiverList.receiver.asBinder(); 631 for (int i=dest.size()-1; i>=0; i--) { 632 if (dest.get(i).receiverList.receiver.asBinder() == target) { 633 return false; 634 } 635 } 636 return true; 637 } 638 }; 639 640 /** 641 * State of all active sticky broadcasts. Keys are the action of the 642 * sticky Intent, values are an ArrayList of all broadcasted intents with 643 * that action (which should usually be one). 644 */ 645 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts = 646 new HashMap<String, ArrayList<Intent>>(); 647 648 /** 649 * All currently running services. 650 */ 651 final HashMap<ComponentName, ServiceRecord> mServices = 652 new HashMap<ComponentName, ServiceRecord>(); 653 654 /** 655 * All currently running services indexed by the Intent used to start them. 656 */ 657 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent = 658 new HashMap<Intent.FilterComparison, ServiceRecord>(); 659 660 /** 661 * All currently bound service connections. Keys are the IBinder of 662 * the client's IServiceConnection. 663 */ 664 final HashMap<IBinder, ConnectionRecord> mServiceConnections 665 = new HashMap<IBinder, ConnectionRecord>(); 666 667 /** 668 * List of services that we have been asked to start, 669 * but haven't yet been able to. It is used to hold start requests 670 * while waiting for their corresponding application thread to get 671 * going. 672 */ 673 final ArrayList<ServiceRecord> mPendingServices 674 = new ArrayList<ServiceRecord>(); 675 676 /** 677 * List of services that are scheduled to restart following a crash. 678 */ 679 final ArrayList<ServiceRecord> mRestartingServices 680 = new ArrayList<ServiceRecord>(); 681 682 /** 683 * List of services that are in the process of being stopped. 684 */ 685 final ArrayList<ServiceRecord> mStoppingServices 686 = new ArrayList<ServiceRecord>(); 687 688 /** 689 * Backup/restore process management 690 */ 691 String mBackupAppName = null; 692 BackupRecord mBackupTarget = null; 693 694 /** 695 * List of PendingThumbnailsRecord objects of clients who are still 696 * waiting to receive all of the thumbnails for a task. 697 */ 698 final ArrayList mPendingThumbnails = new ArrayList(); 699 700 /** 701 * List of HistoryRecord objects that have been finished and must 702 * still report back to a pending thumbnail receiver. 703 */ 704 final ArrayList mCancelledThumbnails = new ArrayList(); 705 706 /** 707 * All of the currently running global content providers. Keys are a 708 * string containing the provider name and values are a 709 * ContentProviderRecord object containing the data about it. Note 710 * that a single provider may be published under multiple names, so 711 * there may be multiple entries here for a single one in mProvidersByClass. 712 */ 713 final HashMap mProvidersByName = new HashMap(); 714 715 /** 716 * All of the currently running global content providers. Keys are a 717 * string containing the provider's implementation class and values are a 718 * ContentProviderRecord object containing the data about it. 719 */ 720 final HashMap mProvidersByClass = new HashMap(); 721 722 /** 723 * List of content providers who have clients waiting for them. The 724 * application is currently being launched and the provider will be 725 * removed from this list once it is published. 726 */ 727 final ArrayList mLaunchingProviders = new ArrayList(); 728 729 /** 730 * Global set of specific Uri permissions that have been granted. 731 */ 732 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 733 = new SparseArray<HashMap<Uri, UriPermission>>(); 734 735 /** 736 * Thread-local storage used to carry caller permissions over through 737 * indirect content-provider access. 738 * @see #ActivityManagerService.openContentUri() 739 */ 740 private class Identity { 741 public int pid; 742 public int uid; 743 744 Identity(int _pid, int _uid) { 745 pid = _pid; 746 uid = _uid; 747 } 748 } 749 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 750 751 /** 752 * All information we have collected about the runtime performance of 753 * any user id that can impact battery performance. 754 */ 755 final BatteryStatsService mBatteryStatsService; 756 757 /** 758 * information about component usage 759 */ 760 final UsageStatsService mUsageStatsService; 761 762 /** 763 * Current configuration information. HistoryRecord objects are given 764 * a reference to this object to indicate which configuration they are 765 * currently running in, so this object must be kept immutable. 766 */ 767 Configuration mConfiguration = new Configuration(); 768 769 /** 770 * Hardware-reported OpenGLES version. 771 */ 772 final int GL_ES_VERSION; 773 774 /** 775 * List of initialization arguments to pass to all processes when binding applications to them. 776 * For example, references to the commonly used services. 777 */ 778 HashMap<String, IBinder> mAppBindArgs; 779 780 /** 781 * Temporary to avoid allocations. Protected by main lock. 782 */ 783 final StringBuilder mStringBuilder = new StringBuilder(256); 784 785 /** 786 * Used to control how we initialize the service. 787 */ 788 boolean mStartRunning = false; 789 ComponentName mTopComponent; 790 String mTopAction; 791 String mTopData; 792 boolean mSystemReady = false; 793 boolean mBooting = false; 794 boolean mWaitingUpdate = false; 795 boolean mDidUpdate = false; 796 797 Context mContext; 798 799 int mFactoryTest; 800 801 boolean mCheckedForSetup; 802 803 /** 804 * The time at which we will allow normal application switches again, 805 * after a call to {@link #stopAppSwitches()}. 806 */ 807 long mAppSwitchesAllowedTime; 808 809 /** 810 * This is set to true after the first switch after mAppSwitchesAllowedTime 811 * is set; any switches after that will clear the time. 812 */ 813 boolean mDidAppSwitch; 814 815 /** 816 * Set while we are wanting to sleep, to prevent any 817 * activities from being started/resumed. 818 */ 819 boolean mSleeping = false; 820 821 /** 822 * Set if we are shutting down the system, similar to sleeping. 823 */ 824 boolean mShuttingDown = false; 825 826 /** 827 * Set when the system is going to sleep, until we have 828 * successfully paused the current activity and released our wake lock. 829 * At that point the system is allowed to actually sleep. 830 */ 831 PowerManager.WakeLock mGoingToSleep; 832 833 /** 834 * We don't want to allow the device to go to sleep while in the process 835 * of launching an activity. This is primarily to allow alarm intent 836 * receivers to launch an activity and get that to run before the device 837 * goes back to sleep. 838 */ 839 PowerManager.WakeLock mLaunchingActivity; 840 841 /** 842 * Task identifier that activities are currently being started 843 * in. Incremented each time a new task is created. 844 * todo: Replace this with a TokenSpace class that generates non-repeating 845 * integers that won't wrap. 846 */ 847 int mCurTask = 1; 848 849 /** 850 * Current sequence id for oom_adj computation traversal. 851 */ 852 int mAdjSeq = 0; 853 854 /** 855 * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar 856 * is set, indicating the user wants processes started in such a way 857 * that they can use ANDROID_PROCESS_WRAPPER and know what will be 858 * running in each process (thus no pre-initialized process, etc). 859 */ 860 boolean mSimpleProcessManagement = false; 861 862 /** 863 * System monitoring: number of processes that died since the last 864 * N procs were started. 865 */ 866 int[] mProcDeaths = new int[20]; 867 868 /** 869 * This is set if we had to do a delayed dexopt of an app before launching 870 * it, to increasing the ANR timeouts in that case. 871 */ 872 boolean mDidDexOpt; 873 874 String mDebugApp = null; 875 boolean mWaitForDebugger = false; 876 boolean mDebugTransient = false; 877 String mOrigDebugApp = null; 878 boolean mOrigWaitForDebugger = false; 879 boolean mAlwaysFinishActivities = false; 880 IActivityController mController = null; 881 882 final RemoteCallbackList<IActivityWatcher> mWatchers 883 = new RemoteCallbackList<IActivityWatcher>(); 884 885 /** 886 * Callback of last caller to {@link #requestPss}. 887 */ 888 Runnable mRequestPssCallback; 889 890 /** 891 * Remaining processes for which we are waiting results from the last 892 * call to {@link #requestPss}. 893 */ 894 final ArrayList<ProcessRecord> mRequestPssList 895 = new ArrayList<ProcessRecord>(); 896 897 /** 898 * Runtime statistics collection thread. This object's lock is used to 899 * protect all related state. 900 */ 901 final Thread mProcessStatsThread; 902 903 /** 904 * Used to collect process stats when showing not responding dialog. 905 * Protected by mProcessStatsThread. 906 */ 907 final ProcessStats mProcessStats = new ProcessStats( 908 MONITOR_THREAD_CPU_USAGE); 909 long mLastCpuTime = 0; 910 long mLastWriteTime = 0; 911 912 long mInitialStartTime = 0; 913 914 /** 915 * Set to true after the system has finished booting. 916 */ 917 boolean mBooted = false; 918 919 int mProcessLimit = 0; 920 921 WindowManagerService mWindowManager; 922 923 static ActivityManagerService mSelf; 924 static ActivityThread mSystemThread; 925 926 private final class AppDeathRecipient implements IBinder.DeathRecipient { 927 final ProcessRecord mApp; 928 final int mPid; 929 final IApplicationThread mAppThread; 930 931 AppDeathRecipient(ProcessRecord app, int pid, 932 IApplicationThread thread) { 933 if (localLOGV) Log.v( 934 TAG, "New death recipient " + this 935 + " for thread " + thread.asBinder()); 936 mApp = app; 937 mPid = pid; 938 mAppThread = thread; 939 } 940 941 public void binderDied() { 942 if (localLOGV) Log.v( 943 TAG, "Death received in " + this 944 + " for thread " + mAppThread.asBinder()); 945 removeRequestedPss(mApp); 946 synchronized(ActivityManagerService.this) { 947 appDiedLocked(mApp, mPid, mAppThread); 948 } 949 } 950 } 951 952 static final int SHOW_ERROR_MSG = 1; 953 static final int SHOW_NOT_RESPONDING_MSG = 2; 954 static final int SHOW_FACTORY_ERROR_MSG = 3; 955 static final int UPDATE_CONFIGURATION_MSG = 4; 956 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 957 static final int WAIT_FOR_DEBUGGER_MSG = 6; 958 static final int BROADCAST_INTENT_MSG = 7; 959 static final int BROADCAST_TIMEOUT_MSG = 8; 960 static final int PAUSE_TIMEOUT_MSG = 9; 961 static final int IDLE_TIMEOUT_MSG = 10; 962 static final int IDLE_NOW_MSG = 11; 963 static final int SERVICE_TIMEOUT_MSG = 12; 964 static final int UPDATE_TIME_ZONE = 13; 965 static final int SHOW_UID_ERROR_MSG = 14; 966 static final int IM_FEELING_LUCKY_MSG = 15; 967 static final int LAUNCH_TIMEOUT_MSG = 16; 968 static final int DESTROY_TIMEOUT_MSG = 17; 969 static final int SERVICE_ERROR_MSG = 18; 970 static final int RESUME_TOP_ACTIVITY_MSG = 19; 971 static final int PROC_START_TIMEOUT_MSG = 20; 972 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 973 static final int KILL_APPLICATION_MSG = 22; 974 975 AlertDialog mUidAlert; 976 977 final Handler mHandler = new Handler() { 978 //public Handler() { 979 // if (localLOGV) Log.v(TAG, "Handler started!"); 980 //} 981 982 public void handleMessage(Message msg) { 983 switch (msg.what) { 984 case SHOW_ERROR_MSG: { 985 HashMap data = (HashMap) msg.obj; 986 synchronized (ActivityManagerService.this) { 987 ProcessRecord proc = (ProcessRecord)data.get("app"); 988 if (proc != null && proc.crashDialog != null) { 989 Log.e(TAG, "App already has crash dialog: " + proc); 990 return; 991 } 992 AppErrorResult res = (AppErrorResult) data.get("result"); 993 if (!mSleeping && !mShuttingDown) { 994 Dialog d = new AppErrorDialog(mContext, res, proc); 995 d.show(); 996 proc.crashDialog = d; 997 } else { 998 // The device is asleep, so just pretend that the user 999 // saw a crash dialog and hit "force quit". 1000 res.set(0); 1001 } 1002 } 1003 1004 ensureBootCompleted(); 1005 } break; 1006 case SHOW_NOT_RESPONDING_MSG: { 1007 synchronized (ActivityManagerService.this) { 1008 HashMap data = (HashMap) msg.obj; 1009 ProcessRecord proc = (ProcessRecord)data.get("app"); 1010 if (proc != null && proc.anrDialog != null) { 1011 Log.e(TAG, "App already has anr dialog: " + proc); 1012 return; 1013 } 1014 1015 broadcastIntentLocked(null, null, new Intent("android.intent.action.ANR"), 1016 null, null, 0, null, null, null, 1017 false, false, MY_PID, Process.SYSTEM_UID); 1018 1019 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1020 mContext, proc, (HistoryRecord)data.get("activity")); 1021 d.show(); 1022 proc.anrDialog = d; 1023 } 1024 1025 ensureBootCompleted(); 1026 } break; 1027 case SHOW_FACTORY_ERROR_MSG: { 1028 Dialog d = new FactoryErrorDialog( 1029 mContext, msg.getData().getCharSequence("msg")); 1030 d.show(); 1031 ensureBootCompleted(); 1032 } break; 1033 case UPDATE_CONFIGURATION_MSG: { 1034 final ContentResolver resolver = mContext.getContentResolver(); 1035 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1036 } break; 1037 case GC_BACKGROUND_PROCESSES_MSG: { 1038 synchronized (ActivityManagerService.this) { 1039 performAppGcsIfAppropriateLocked(); 1040 } 1041 } break; 1042 case WAIT_FOR_DEBUGGER_MSG: { 1043 synchronized (ActivityManagerService.this) { 1044 ProcessRecord app = (ProcessRecord)msg.obj; 1045 if (msg.arg1 != 0) { 1046 if (!app.waitedForDebugger) { 1047 Dialog d = new AppWaitingForDebuggerDialog( 1048 ActivityManagerService.this, 1049 mContext, app); 1050 app.waitDialog = d; 1051 app.waitedForDebugger = true; 1052 d.show(); 1053 } 1054 } else { 1055 if (app.waitDialog != null) { 1056 app.waitDialog.dismiss(); 1057 app.waitDialog = null; 1058 } 1059 } 1060 } 1061 } break; 1062 case BROADCAST_INTENT_MSG: { 1063 if (DEBUG_BROADCAST) Log.v( 1064 TAG, "Received BROADCAST_INTENT_MSG"); 1065 processNextBroadcast(true); 1066 } break; 1067 case BROADCAST_TIMEOUT_MSG: { 1068 if (mDidDexOpt) { 1069 mDidDexOpt = false; 1070 Message nmsg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG); 1071 mHandler.sendMessageDelayed(nmsg, BROADCAST_TIMEOUT); 1072 return; 1073 } 1074 broadcastTimeout(); 1075 } break; 1076 case PAUSE_TIMEOUT_MSG: { 1077 IBinder token = (IBinder)msg.obj; 1078 // We don't at this point know if the activity is fullscreen, 1079 // so we need to be conservative and assume it isn't. 1080 Log.w(TAG, "Activity pause timeout for " + token); 1081 activityPaused(token, null, true); 1082 } break; 1083 case IDLE_TIMEOUT_MSG: { 1084 if (mDidDexOpt) { 1085 mDidDexOpt = false; 1086 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 1087 nmsg.obj = msg.obj; 1088 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); 1089 return; 1090 } 1091 // We don't at this point know if the activity is fullscreen, 1092 // so we need to be conservative and assume it isn't. 1093 IBinder token = (IBinder)msg.obj; 1094 Log.w(TAG, "Activity idle timeout for " + token); 1095 activityIdleInternal(token, true, null); 1096 } break; 1097 case DESTROY_TIMEOUT_MSG: { 1098 IBinder token = (IBinder)msg.obj; 1099 // We don't at this point know if the activity is fullscreen, 1100 // so we need to be conservative and assume it isn't. 1101 Log.w(TAG, "Activity destroy timeout for " + token); 1102 activityDestroyed(token); 1103 } break; 1104 case IDLE_NOW_MSG: { 1105 IBinder token = (IBinder)msg.obj; 1106 activityIdle(token, null); 1107 } break; 1108 case SERVICE_TIMEOUT_MSG: { 1109 if (mDidDexOpt) { 1110 mDidDexOpt = false; 1111 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1112 nmsg.obj = msg.obj; 1113 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT); 1114 return; 1115 } 1116 serviceTimeout((ProcessRecord)msg.obj); 1117 } break; 1118 case UPDATE_TIME_ZONE: { 1119 synchronized (ActivityManagerService.this) { 1120 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1121 ProcessRecord r = mLruProcesses.get(i); 1122 if (r.thread != null) { 1123 try { 1124 r.thread.updateTimeZone(); 1125 } catch (RemoteException ex) { 1126 Log.w(TAG, "Failed to update time zone for: " + r.info.processName); 1127 } 1128 } 1129 } 1130 } 1131 } break; 1132 case SHOW_UID_ERROR_MSG: { 1133 // XXX This is a temporary dialog, no need to localize. 1134 AlertDialog d = new BaseErrorDialog(mContext); 1135 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1136 d.setCancelable(false); 1137 d.setTitle("System UIDs Inconsistent"); 1138 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable."); 1139 d.setButton("I'm Feeling Lucky", 1140 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1141 mUidAlert = d; 1142 d.show(); 1143 } break; 1144 case IM_FEELING_LUCKY_MSG: { 1145 if (mUidAlert != null) { 1146 mUidAlert.dismiss(); 1147 mUidAlert = null; 1148 } 1149 } break; 1150 case LAUNCH_TIMEOUT_MSG: { 1151 if (mDidDexOpt) { 1152 mDidDexOpt = false; 1153 Message nmsg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG); 1154 mHandler.sendMessageDelayed(nmsg, LAUNCH_TIMEOUT); 1155 return; 1156 } 1157 synchronized (ActivityManagerService.this) { 1158 if (mLaunchingActivity.isHeld()) { 1159 Log.w(TAG, "Launch timeout has expired, giving up wake lock!"); 1160 mLaunchingActivity.release(); 1161 } 1162 } 1163 } break; 1164 case SERVICE_ERROR_MSG: { 1165 ServiceRecord srv = (ServiceRecord)msg.obj; 1166 // This needs to be *un*synchronized to avoid deadlock. 1167 Checkin.logEvent(mContext.getContentResolver(), 1168 Checkin.Events.Tag.SYSTEM_SERVICE_LOOPING, 1169 srv.name.toShortString()); 1170 } break; 1171 case RESUME_TOP_ACTIVITY_MSG: { 1172 synchronized (ActivityManagerService.this) { 1173 resumeTopActivityLocked(null); 1174 } 1175 } break; 1176 case PROC_START_TIMEOUT_MSG: { 1177 if (mDidDexOpt) { 1178 mDidDexOpt = false; 1179 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1180 nmsg.obj = msg.obj; 1181 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1182 return; 1183 } 1184 ProcessRecord app = (ProcessRecord)msg.obj; 1185 synchronized (ActivityManagerService.this) { 1186 processStartTimedOutLocked(app); 1187 } 1188 } break; 1189 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1190 synchronized (ActivityManagerService.this) { 1191 doPendingActivityLaunchesLocked(true); 1192 } 1193 } break; 1194 case KILL_APPLICATION_MSG: { 1195 synchronized (ActivityManagerService.this) { 1196 int uid = msg.arg1; 1197 boolean restart = (msg.arg2 == 1); 1198 String pkg = (String) msg.obj; 1199 forceStopPackageLocked(pkg, uid, restart, false); 1200 } 1201 } break; 1202 } 1203 } 1204 }; 1205 1206 public static void setSystemProcess() { 1207 try { 1208 ActivityManagerService m = mSelf; 1209 1210 ServiceManager.addService("activity", m); 1211 ServiceManager.addService("meminfo", new MemBinder(m)); 1212 if (MONITOR_CPU_USAGE) { 1213 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1214 } 1215 ServiceManager.addService("permission", new PermissionController(m)); 1216 1217 ApplicationInfo info = 1218 mSelf.mContext.getPackageManager().getApplicationInfo( 1219 "android", STOCK_PM_FLAGS); 1220 mSystemThread.installSystemApplicationInfo(info); 1221 1222 synchronized (mSelf) { 1223 ProcessRecord app = mSelf.newProcessRecordLocked( 1224 mSystemThread.getApplicationThread(), info, 1225 info.processName); 1226 app.persistent = true; 1227 app.pid = MY_PID; 1228 app.maxAdj = SYSTEM_ADJ; 1229 mSelf.mProcessNames.put(app.processName, app.info.uid, app); 1230 synchronized (mSelf.mPidsSelfLocked) { 1231 mSelf.mPidsSelfLocked.put(app.pid, app); 1232 } 1233 mSelf.updateLruProcessLocked(app, true, true); 1234 } 1235 } catch (PackageManager.NameNotFoundException e) { 1236 throw new RuntimeException( 1237 "Unable to find android system package", e); 1238 } 1239 } 1240 1241 public void setWindowManager(WindowManagerService wm) { 1242 mWindowManager = wm; 1243 } 1244 1245 public static final Context main(int factoryTest) { 1246 AThread thr = new AThread(); 1247 thr.start(); 1248 1249 synchronized (thr) { 1250 while (thr.mService == null) { 1251 try { 1252 thr.wait(); 1253 } catch (InterruptedException e) { 1254 } 1255 } 1256 } 1257 1258 ActivityManagerService m = thr.mService; 1259 mSelf = m; 1260 ActivityThread at = ActivityThread.systemMain(); 1261 mSystemThread = at; 1262 Context context = at.getSystemContext(); 1263 m.mContext = context; 1264 m.mFactoryTest = factoryTest; 1265 PowerManager pm = 1266 (PowerManager)context.getSystemService(Context.POWER_SERVICE); 1267 m.mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep"); 1268 m.mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch"); 1269 m.mLaunchingActivity.setReferenceCounted(false); 1270 1271 m.mBatteryStatsService.publish(context); 1272 m.mUsageStatsService.publish(context); 1273 1274 synchronized (thr) { 1275 thr.mReady = true; 1276 thr.notifyAll(); 1277 } 1278 1279 m.startRunning(null, null, null, null); 1280 1281 return context; 1282 } 1283 1284 public static ActivityManagerService self() { 1285 return mSelf; 1286 } 1287 1288 static class AThread extends Thread { 1289 ActivityManagerService mService; 1290 boolean mReady = false; 1291 1292 public AThread() { 1293 super("ActivityManager"); 1294 } 1295 1296 public void run() { 1297 Looper.prepare(); 1298 1299 android.os.Process.setThreadPriority( 1300 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1301 1302 ActivityManagerService m = new ActivityManagerService(); 1303 1304 synchronized (this) { 1305 mService = m; 1306 notifyAll(); 1307 } 1308 1309 synchronized (this) { 1310 while (!mReady) { 1311 try { 1312 wait(); 1313 } catch (InterruptedException e) { 1314 } 1315 } 1316 } 1317 1318 Looper.loop(); 1319 } 1320 } 1321 1322 static class MemBinder extends Binder { 1323 ActivityManagerService mActivityManagerService; 1324 MemBinder(ActivityManagerService activityManagerService) { 1325 mActivityManagerService = activityManagerService; 1326 } 1327 1328 @Override 1329 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1330 ActivityManagerService service = mActivityManagerService; 1331 ArrayList<ProcessRecord> procs; 1332 synchronized (mActivityManagerService) { 1333 if (args != null && args.length > 0 1334 && args[0].charAt(0) != '-') { 1335 procs = new ArrayList<ProcessRecord>(); 1336 int pid = -1; 1337 try { 1338 pid = Integer.parseInt(args[0]); 1339 } catch (NumberFormatException e) { 1340 1341 } 1342 for (int i=service.mLruProcesses.size()-1; i>=0; i--) { 1343 ProcessRecord proc = service.mLruProcesses.get(i); 1344 if (proc.pid == pid) { 1345 procs.add(proc); 1346 } else if (proc.processName.equals(args[0])) { 1347 procs.add(proc); 1348 } 1349 } 1350 if (procs.size() <= 0) { 1351 pw.println("No process found for: " + args[0]); 1352 return; 1353 } 1354 } else { 1355 procs = service.mLruProcesses; 1356 } 1357 } 1358 dumpApplicationMemoryUsage(fd, pw, procs, " ", args); 1359 } 1360 } 1361 1362 static class CpuBinder extends Binder { 1363 ActivityManagerService mActivityManagerService; 1364 CpuBinder(ActivityManagerService activityManagerService) { 1365 mActivityManagerService = activityManagerService; 1366 } 1367 1368 @Override 1369 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1370 synchronized (mActivityManagerService.mProcessStatsThread) { 1371 pw.print(mActivityManagerService.mProcessStats.printCurrentState()); 1372 } 1373 } 1374 } 1375 1376 private ActivityManagerService() { 1377 String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT"); 1378 if (v != null && Integer.getInteger(v) != 0) { 1379 mSimpleProcessManagement = true; 1380 } 1381 v = System.getenv("ANDROID_DEBUG_APP"); 1382 if (v != null) { 1383 mSimpleProcessManagement = true; 1384 } 1385 1386 Log.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1387 1388 File dataDir = Environment.getDataDirectory(); 1389 File systemDir = new File(dataDir, "system"); 1390 systemDir.mkdirs(); 1391 mBatteryStatsService = new BatteryStatsService(new File( 1392 systemDir, "batterystats.bin").toString()); 1393 mBatteryStatsService.getActiveStatistics().readLocked(); 1394 mBatteryStatsService.getActiveStatistics().writeLocked(); 1395 1396 mUsageStatsService = new UsageStatsService( new File( 1397 systemDir, "usagestats").toString()); 1398 1399 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1400 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1401 1402 mConfiguration.makeDefault(); 1403 mProcessStats.init(); 1404 1405 // Add ourself to the Watchdog monitors. 1406 Watchdog.getInstance().addMonitor(this); 1407 1408 mProcessStatsThread = new Thread("ProcessStats") { 1409 public void run() { 1410 while (true) { 1411 try { 1412 try { 1413 synchronized(this) { 1414 final long now = SystemClock.uptimeMillis(); 1415 long nextCpuDelay = (mLastCpuTime+MONITOR_CPU_MAX_TIME)-now; 1416 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1417 //Log.i(TAG, "Cpu delay=" + nextCpuDelay 1418 // + ", write delay=" + nextWriteDelay); 1419 if (nextWriteDelay < nextCpuDelay) { 1420 nextCpuDelay = nextWriteDelay; 1421 } 1422 if (nextCpuDelay > 0) { 1423 this.wait(nextCpuDelay); 1424 } 1425 } 1426 } catch (InterruptedException e) { 1427 } 1428 1429 updateCpuStatsNow(); 1430 } catch (Exception e) { 1431 Log.e(TAG, "Unexpected exception collecting process stats", e); 1432 } 1433 } 1434 } 1435 }; 1436 mProcessStatsThread.start(); 1437 } 1438 1439 @Override 1440 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1441 throws RemoteException { 1442 try { 1443 return super.onTransact(code, data, reply, flags); 1444 } catch (RuntimeException e) { 1445 // The activity manager only throws security exceptions, so let's 1446 // log all others. 1447 if (!(e instanceof SecurityException)) { 1448 Log.e(TAG, "Activity Manager Crash", e); 1449 } 1450 throw e; 1451 } 1452 } 1453 1454 void updateCpuStats() { 1455 synchronized (mProcessStatsThread) { 1456 final long now = SystemClock.uptimeMillis(); 1457 if (mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) { 1458 mProcessStatsThread.notify(); 1459 } 1460 } 1461 } 1462 1463 void updateCpuStatsNow() { 1464 synchronized (mProcessStatsThread) { 1465 final long now = SystemClock.uptimeMillis(); 1466 boolean haveNewCpuStats = false; 1467 1468 if (MONITOR_CPU_USAGE && 1469 mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) { 1470 mLastCpuTime = now; 1471 haveNewCpuStats = true; 1472 mProcessStats.update(); 1473 //Log.i(TAG, mProcessStats.printCurrentState()); 1474 //Log.i(TAG, "Total CPU usage: " 1475 // + mProcessStats.getTotalCpuPercent() + "%"); 1476 1477 // Log the cpu usage if the property is set. 1478 if ("true".equals(SystemProperties.get("events.cpu"))) { 1479 int user = mProcessStats.getLastUserTime(); 1480 int system = mProcessStats.getLastSystemTime(); 1481 int iowait = mProcessStats.getLastIoWaitTime(); 1482 int irq = mProcessStats.getLastIrqTime(); 1483 int softIrq = mProcessStats.getLastSoftIrqTime(); 1484 int idle = mProcessStats.getLastIdleTime(); 1485 1486 int total = user + system + iowait + irq + softIrq + idle; 1487 if (total == 0) total = 1; 1488 1489 EventLog.writeEvent(EventLogTags.CPU, 1490 ((user+system+iowait+irq+softIrq) * 100) / total, 1491 (user * 100) / total, 1492 (system * 100) / total, 1493 (iowait * 100) / total, 1494 (irq * 100) / total, 1495 (softIrq * 100) / total); 1496 } 1497 } 1498 1499 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1500 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1501 synchronized(bstats) { 1502 synchronized(mPidsSelfLocked) { 1503 if (haveNewCpuStats) { 1504 if (mBatteryStatsService.isOnBattery()) { 1505 final int N = mProcessStats.countWorkingStats(); 1506 for (int i=0; i<N; i++) { 1507 ProcessStats.Stats st 1508 = mProcessStats.getWorkingStats(i); 1509 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1510 if (pr != null) { 1511 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1512 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); 1513 ps.addSpeedStepTimes(cpuSpeedTimes); 1514 } else { 1515 BatteryStatsImpl.Uid.Proc ps = 1516 bstats.getProcessStatsLocked(st.name, st.pid); 1517 if (ps != null) { 1518 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); 1519 ps.addSpeedStepTimes(cpuSpeedTimes); 1520 } 1521 } 1522 } 1523 } 1524 } 1525 } 1526 1527 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1528 mLastWriteTime = now; 1529 mBatteryStatsService.getActiveStatistics().writeLocked(); 1530 } 1531 } 1532 } 1533 } 1534 1535 /** 1536 * Initialize the application bind args. These are passed to each 1537 * process when the bindApplication() IPC is sent to the process. They're 1538 * lazily setup to make sure the services are running when they're asked for. 1539 */ 1540 private HashMap<String, IBinder> getCommonServicesLocked() { 1541 if (mAppBindArgs == null) { 1542 mAppBindArgs = new HashMap<String, IBinder>(); 1543 1544 // Setup the application init args 1545 mAppBindArgs.put("package", ServiceManager.getService("package")); 1546 mAppBindArgs.put("window", ServiceManager.getService("window")); 1547 mAppBindArgs.put(Context.ALARM_SERVICE, 1548 ServiceManager.getService(Context.ALARM_SERVICE)); 1549 } 1550 return mAppBindArgs; 1551 } 1552 1553 private final void setFocusedActivityLocked(HistoryRecord r) { 1554 if (mFocusedActivity != r) { 1555 mFocusedActivity = r; 1556 mWindowManager.setFocusedApp(r, true); 1557 } 1558 } 1559 1560 private final void updateLruProcessLocked(ProcessRecord app, 1561 boolean oomAdj, boolean updateActivityTime) { 1562 // put it on the LRU to keep track of when it should be exited. 1563 int lrui = mLruProcesses.indexOf(app); 1564 if (lrui >= 0) mLruProcesses.remove(lrui); 1565 1566 int i = mLruProcesses.size()-1; 1567 int skipTop = 0; 1568 1569 // compute the new weight for this process. 1570 if (updateActivityTime) { 1571 app.lastActivityTime = SystemClock.uptimeMillis(); 1572 } 1573 if (app.activities.size() > 0) { 1574 // If this process has activities, we more strongly want to keep 1575 // it around. 1576 app.lruWeight = app.lastActivityTime; 1577 } else if (app.pubProviders.size() > 0) { 1578 // If this process contains content providers, we want to keep 1579 // it a little more strongly. 1580 app.lruWeight = app.lastActivityTime - CONTENT_APP_IDLE_OFFSET; 1581 // Also don't let it kick out the first few "real" hidden processes. 1582 skipTop = MIN_HIDDEN_APPS; 1583 } else { 1584 // If this process doesn't have activities, we less strongly 1585 // want to keep it around, and generally want to avoid getting 1586 // in front of any very recently used activities. 1587 app.lruWeight = app.lastActivityTime - EMPTY_APP_IDLE_OFFSET; 1588 // Also don't let it kick out the first few "real" hidden processes. 1589 skipTop = MIN_HIDDEN_APPS; 1590 } 1591 while (i >= 0) { 1592 ProcessRecord p = mLruProcesses.get(i); 1593 // If this app shouldn't be in front of the first N background 1594 // apps, then skip over that many that are currently hidden. 1595 if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) { 1596 skipTop--; 1597 } 1598 if (p.lruWeight <= app.lruWeight){ 1599 mLruProcesses.add(i+1, app); 1600 break; 1601 } 1602 i--; 1603 } 1604 if (i < 0) { 1605 mLruProcesses.add(0, app); 1606 } 1607 1608 //Log.i(TAG, "Putting proc to front: " + app.processName); 1609 if (oomAdj) { 1610 updateOomAdjLocked(); 1611 } 1612 } 1613 1614 private final boolean updateLRUListLocked(HistoryRecord r) { 1615 final boolean hadit = mLRUActivities.remove(r); 1616 mLRUActivities.add(r); 1617 return hadit; 1618 } 1619 1620 private final HistoryRecord topRunningActivityLocked(HistoryRecord notTop) { 1621 int i = mHistory.size()-1; 1622 while (i >= 0) { 1623 HistoryRecord r = (HistoryRecord)mHistory.get(i); 1624 if (!r.finishing && r != notTop) { 1625 return r; 1626 } 1627 i--; 1628 } 1629 return null; 1630 } 1631 1632 private final HistoryRecord topRunningNonDelayedActivityLocked(HistoryRecord notTop) { 1633 int i = mHistory.size()-1; 1634 while (i >= 0) { 1635 HistoryRecord r = (HistoryRecord)mHistory.get(i); 1636 if (!r.finishing && !r.delayedResume && r != notTop) { 1637 return r; 1638 } 1639 i--; 1640 } 1641 return null; 1642 } 1643 1644 /** 1645 * This is a simplified version of topRunningActivityLocked that provides a number of 1646 * optional skip-over modes. It is intended for use with the ActivityController hook only. 1647 * 1648 * @param token If non-null, any history records matching this token will be skipped. 1649 * @param taskId If non-zero, we'll attempt to skip over records with the same task ID. 1650 * 1651 * @return Returns the HistoryRecord of the next activity on the stack. 1652 */ 1653 private final HistoryRecord topRunningActivityLocked(IBinder token, int taskId) { 1654 int i = mHistory.size()-1; 1655 while (i >= 0) { 1656 HistoryRecord r = (HistoryRecord)mHistory.get(i); 1657 // Note: the taskId check depends on real taskId fields being non-zero 1658 if (!r.finishing && (token != r) && (taskId != r.task.taskId)) { 1659 return r; 1660 } 1661 i--; 1662 } 1663 return null; 1664 } 1665 1666 private final ProcessRecord getProcessRecordLocked( 1667 String processName, int uid) { 1668 if (uid == Process.SYSTEM_UID) { 1669 // The system gets to run in any process. If there are multiple 1670 // processes with the same uid, just pick the first (this 1671 // should never happen). 1672 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1673 processName); 1674 return procs != null ? procs.valueAt(0) : null; 1675 } 1676 ProcessRecord proc = mProcessNames.get(processName, uid); 1677 return proc; 1678 } 1679 1680 private void ensurePackageDexOpt(String packageName) { 1681 IPackageManager pm = ActivityThread.getPackageManager(); 1682 try { 1683 if (pm.performDexOpt(packageName)) { 1684 mDidDexOpt = true; 1685 } 1686 } catch (RemoteException e) { 1687 } 1688 } 1689 1690 private boolean isNextTransitionForward() { 1691 int transit = mWindowManager.getPendingAppTransition(); 1692 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1693 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1694 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1695 } 1696 1697 private final boolean realStartActivityLocked(HistoryRecord r, 1698 ProcessRecord app, boolean andResume, boolean checkConfig) 1699 throws RemoteException { 1700 1701 r.startFreezingScreenLocked(app, 0); 1702 mWindowManager.setAppVisibility(r, true); 1703 1704 // Have the window manager re-evaluate the orientation of 1705 // the screen based on the new activity order. Note that 1706 // as a result of this, it can call back into the activity 1707 // manager with a new orientation. We don't care about that, 1708 // because the activity is not currently running so we are 1709 // just restarting it anyway. 1710 if (checkConfig) { 1711 Configuration config = mWindowManager.updateOrientationFromAppTokens( 1712 mConfiguration, 1713 r.mayFreezeScreenLocked(app) ? r : null); 1714 updateConfigurationLocked(config, r); 1715 } 1716 1717 r.app = app; 1718 1719 if (localLOGV) Log.v(TAG, "Launching: " + r); 1720 1721 int idx = app.activities.indexOf(r); 1722 if (idx < 0) { 1723 app.activities.add(r); 1724 } 1725 updateLruProcessLocked(app, true, true); 1726 1727 try { 1728 if (app.thread == null) { 1729 throw new RemoteException(); 1730 } 1731 List<ResultInfo> results = null; 1732 List<Intent> newIntents = null; 1733 if (andResume) { 1734 results = r.results; 1735 newIntents = r.newIntents; 1736 } 1737 if (DEBUG_SWITCH) Log.v(TAG, "Launching: " + r 1738 + " icicle=" + r.icicle 1739 + " with results=" + results + " newIntents=" + newIntents 1740 + " andResume=" + andResume); 1741 if (andResume) { 1742 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY, 1743 System.identityHashCode(r), 1744 r.task.taskId, r.shortComponentName); 1745 } 1746 if (r.isHomeActivity) { 1747 mHomeProcess = app; 1748 } 1749 ensurePackageDexOpt(r.intent.getComponent().getPackageName()); 1750 app.thread.scheduleLaunchActivity(new Intent(r.intent), r, 1751 System.identityHashCode(r), 1752 r.info, r.icicle, results, newIntents, !andResume, 1753 isNextTransitionForward()); 1754 } catch (RemoteException e) { 1755 if (r.launchFailed) { 1756 // This is the second time we failed -- finish activity 1757 // and give up. 1758 Log.e(TAG, "Second failure launching " 1759 + r.intent.getComponent().flattenToShortString() 1760 + ", giving up", e); 1761 appDiedLocked(app, app.pid, app.thread); 1762 requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null, 1763 "2nd-crash"); 1764 return false; 1765 } 1766 1767 // This is the first time we failed -- restart process and 1768 // retry. 1769 app.activities.remove(r); 1770 throw e; 1771 } 1772 1773 r.launchFailed = false; 1774 if (updateLRUListLocked(r)) { 1775 Log.w(TAG, "Activity " + r 1776 + " being launched, but already in LRU list"); 1777 } 1778 1779 if (andResume) { 1780 // As part of the process of launching, ActivityThread also performs 1781 // a resume. 1782 r.state = ActivityState.RESUMED; 1783 r.icicle = null; 1784 r.haveState = false; 1785 r.stopped = false; 1786 mResumedActivity = r; 1787 r.task.touchActiveTime(); 1788 completeResumeLocked(r); 1789 pauseIfSleepingLocked(); 1790 } else { 1791 // This activity is not starting in the resumed state... which 1792 // should look like we asked it to pause+stop (but remain visible), 1793 // and it has done so and reported back the current icicle and 1794 // other state. 1795 r.state = ActivityState.STOPPED; 1796 r.stopped = true; 1797 } 1798 1799 // Launch the new version setup screen if needed. We do this -after- 1800 // launching the initial activity (that is, home), so that it can have 1801 // a chance to initialize itself while in the background, making the 1802 // switch back to it faster and look better. 1803 startSetupActivityLocked(); 1804 1805 return true; 1806 } 1807 1808 private final void startSpecificActivityLocked(HistoryRecord r, 1809 boolean andResume, boolean checkConfig) { 1810 // Is this activity's application already running? 1811 ProcessRecord app = getProcessRecordLocked(r.processName, 1812 r.info.applicationInfo.uid); 1813 1814 if (r.startTime == 0) { 1815 r.startTime = SystemClock.uptimeMillis(); 1816 if (mInitialStartTime == 0) { 1817 mInitialStartTime = r.startTime; 1818 } 1819 } else if (mInitialStartTime == 0) { 1820 mInitialStartTime = SystemClock.uptimeMillis(); 1821 } 1822 1823 if (app != null && app.thread != null) { 1824 try { 1825 realStartActivityLocked(r, app, andResume, checkConfig); 1826 return; 1827 } catch (RemoteException e) { 1828 Log.w(TAG, "Exception when starting activity " 1829 + r.intent.getComponent().flattenToShortString(), e); 1830 } 1831 1832 // If a dead object exception was thrown -- fall through to 1833 // restart the application. 1834 } 1835 1836 startProcessLocked(r.processName, r.info.applicationInfo, true, 0, 1837 "activity", r.intent.getComponent(), false); 1838 } 1839 1840 private final ProcessRecord startProcessLocked(String processName, 1841 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1842 String hostingType, ComponentName hostingName, boolean allowWhileBooting) { 1843 ProcessRecord app = getProcessRecordLocked(processName, info.uid); 1844 // We don't have to do anything more if: 1845 // (1) There is an existing application record; and 1846 // (2) The caller doesn't think it is dead, OR there is no thread 1847 // object attached to it so we know it couldn't have crashed; and 1848 // (3) There is a pid assigned to it, so it is either starting or 1849 // already running. 1850 if (DEBUG_PROCESSES) Log.v(TAG, "startProcess: name=" + processName 1851 + " app=" + app + " knownToBeDead=" + knownToBeDead 1852 + " thread=" + (app != null ? app.thread : null) 1853 + " pid=" + (app != null ? app.pid : -1)); 1854 if (app != null && 1855 (!knownToBeDead || app.thread == null) && app.pid > 0) { 1856 return app; 1857 } 1858 1859 String hostingNameStr = hostingName != null 1860 ? hostingName.flattenToShortString() : null; 1861 1862 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1863 // If we are in the background, then check to see if this process 1864 // is bad. If so, we will just silently fail. 1865 if (mBadProcesses.get(info.processName, info.uid) != null) { 1866 return null; 1867 } 1868 } else { 1869 // When the user is explicitly starting a process, then clear its 1870 // crash count so that we won't make it bad until they see at 1871 // least one crash dialog again, and make the process good again 1872 // if it had been bad. 1873 mProcessCrashTimes.remove(info.processName, info.uid); 1874 if (mBadProcesses.get(info.processName, info.uid) != null) { 1875 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1876 info.processName); 1877 mBadProcesses.remove(info.processName, info.uid); 1878 if (app != null) { 1879 app.bad = false; 1880 } 1881 } 1882 } 1883 1884 if (app == null) { 1885 app = newProcessRecordLocked(null, info, processName); 1886 mProcessNames.put(processName, info.uid, app); 1887 } else { 1888 // If this is a new package in the process, add the package to the list 1889 app.addPackage(info.packageName); 1890 } 1891 1892 // If the system is not ready yet, then hold off on starting this 1893 // process until it is. 1894 if (!mSystemReady 1895 && !isAllowedWhileBooting(info) 1896 && !allowWhileBooting) { 1897 if (!mProcessesOnHold.contains(app)) { 1898 mProcessesOnHold.add(app); 1899 } 1900 return app; 1901 } 1902 1903 startProcessLocked(app, hostingType, hostingNameStr); 1904 return (app.pid != 0) ? app : null; 1905 } 1906 1907 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1908 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1909 } 1910 1911 private final void startProcessLocked(ProcessRecord app, 1912 String hostingType, String hostingNameStr) { 1913 if (app.pid > 0 && app.pid != MY_PID) { 1914 synchronized (mPidsSelfLocked) { 1915 mPidsSelfLocked.remove(app.pid); 1916 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1917 } 1918 app.pid = 0; 1919 } 1920 1921 mProcessesOnHold.remove(app); 1922 1923 updateCpuStats(); 1924 1925 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 1926 mProcDeaths[0] = 0; 1927 1928 try { 1929 int uid = app.info.uid; 1930 int[] gids = null; 1931 try { 1932 gids = mContext.getPackageManager().getPackageGids( 1933 app.info.packageName); 1934 } catch (PackageManager.NameNotFoundException e) { 1935 Log.w(TAG, "Unable to retrieve gids", e); 1936 } 1937 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 1938 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 1939 && mTopComponent != null 1940 && app.processName.equals(mTopComponent.getPackageName())) { 1941 uid = 0; 1942 } 1943 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 1944 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 1945 uid = 0; 1946 } 1947 } 1948 int debugFlags = 0; 1949 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 1950 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 1951 } 1952 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0) { 1953 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 1954 } 1955 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 1956 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 1957 } 1958 if ("1".equals(SystemProperties.get("debug.assert"))) { 1959 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 1960 } 1961 int pid = Process.start("android.app.ActivityThread", 1962 mSimpleProcessManagement ? app.processName : null, uid, uid, 1963 gids, debugFlags, null); 1964 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 1965 synchronized (bs) { 1966 if (bs.isOnBattery()) { 1967 app.batteryStats.incStartsLocked(); 1968 } 1969 } 1970 1971 EventLog.writeEvent(EventLogTags.AM_PROC_START, pid, uid, 1972 app.processName, hostingType, 1973 hostingNameStr != null ? hostingNameStr : ""); 1974 1975 if (app.persistent) { 1976 Watchdog.getInstance().processStarted(app, app.processName, pid); 1977 } 1978 1979 StringBuilder buf = mStringBuilder; 1980 buf.setLength(0); 1981 buf.append("Start proc "); 1982 buf.append(app.processName); 1983 buf.append(" for "); 1984 buf.append(hostingType); 1985 if (hostingNameStr != null) { 1986 buf.append(" "); 1987 buf.append(hostingNameStr); 1988 } 1989 buf.append(": pid="); 1990 buf.append(pid); 1991 buf.append(" uid="); 1992 buf.append(uid); 1993 buf.append(" gids={"); 1994 if (gids != null) { 1995 for (int gi=0; gi<gids.length; gi++) { 1996 if (gi != 0) buf.append(", "); 1997 buf.append(gids[gi]); 1998 1999 } 2000 } 2001 buf.append("}"); 2002 Log.i(TAG, buf.toString()); 2003 if (pid == 0 || pid == MY_PID) { 2004 // Processes are being emulated with threads. 2005 app.pid = MY_PID; 2006 app.removed = false; 2007 mStartingProcesses.add(app); 2008 } else if (pid > 0) { 2009 app.pid = pid; 2010 app.removed = false; 2011 synchronized (mPidsSelfLocked) { 2012 this.mPidsSelfLocked.put(pid, app); 2013 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2014 msg.obj = app; 2015 mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT); 2016 } 2017 } else { 2018 app.pid = 0; 2019 RuntimeException e = new RuntimeException( 2020 "Failure starting process " + app.processName 2021 + ": returned pid=" + pid); 2022 Log.e(TAG, e.getMessage(), e); 2023 } 2024 } catch (RuntimeException e) { 2025 // XXX do better error recovery. 2026 app.pid = 0; 2027 Log.e(TAG, "Failure starting process " + app.processName, e); 2028 } 2029 } 2030 2031 private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) { 2032 if (mPausingActivity != null) { 2033 RuntimeException e = new RuntimeException(); 2034 Log.e(TAG, "Trying to pause when pause is already pending for " 2035 + mPausingActivity, e); 2036 } 2037 HistoryRecord prev = mResumedActivity; 2038 if (prev == null) { 2039 RuntimeException e = new RuntimeException(); 2040 Log.e(TAG, "Trying to pause when nothing is resumed", e); 2041 resumeTopActivityLocked(null); 2042 return; 2043 } 2044 if (DEBUG_PAUSE) Log.v(TAG, "Start pausing: " + prev); 2045 mResumedActivity = null; 2046 mPausingActivity = prev; 2047 mLastPausedActivity = prev; 2048 prev.state = ActivityState.PAUSING; 2049 prev.task.touchActiveTime(); 2050 2051 updateCpuStats(); 2052 2053 if (prev.app != null && prev.app.thread != null) { 2054 if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending pause: " + prev); 2055 try { 2056 EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY, 2057 System.identityHashCode(prev), 2058 prev.shortComponentName); 2059 prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving, 2060 prev.configChangeFlags); 2061 updateUsageStats(prev, false); 2062 } catch (Exception e) { 2063 // Ignore exception, if process died other code will cleanup. 2064 Log.w(TAG, "Exception thrown during pause", e); 2065 mPausingActivity = null; 2066 mLastPausedActivity = null; 2067 } 2068 } else { 2069 mPausingActivity = null; 2070 mLastPausedActivity = null; 2071 } 2072 2073 // If we are not going to sleep, we want to ensure the device is 2074 // awake until the next activity is started. 2075 if (!mSleeping && !mShuttingDown) { 2076 mLaunchingActivity.acquire(); 2077 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) { 2078 // To be safe, don't allow the wake lock to be held for too long. 2079 Message msg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG); 2080 mHandler.sendMessageDelayed(msg, LAUNCH_TIMEOUT); 2081 } 2082 } 2083 2084 2085 if (mPausingActivity != null) { 2086 // Have the window manager pause its key dispatching until the new 2087 // activity has started. If we're pausing the activity just because 2088 // the screen is being turned off and the UI is sleeping, don't interrupt 2089 // key dispatch; the same activity will pick it up again on wakeup. 2090 if (!uiSleeping) { 2091 prev.pauseKeyDispatchingLocked(); 2092 } else { 2093 if (DEBUG_PAUSE) Log.v(TAG, "Key dispatch not paused for screen off"); 2094 } 2095 2096 // Schedule a pause timeout in case the app doesn't respond. 2097 // We don't give it much time because this directly impacts the 2098 // responsiveness seen by the user. 2099 Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG); 2100 msg.obj = prev; 2101 mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT); 2102 if (DEBUG_PAUSE) Log.v(TAG, "Waiting for pause to complete..."); 2103 } else { 2104 // This activity failed to schedule the 2105 // pause, so just treat it as being paused now. 2106 if (DEBUG_PAUSE) Log.v(TAG, "Activity not running, resuming next."); 2107 resumeTopActivityLocked(null); 2108 } 2109 } 2110 2111 private final void completePauseLocked() { 2112 HistoryRecord prev = mPausingActivity; 2113 if (DEBUG_PAUSE) Log.v(TAG, "Complete pause: " + prev); 2114 2115 if (prev != null) { 2116 if (prev.finishing) { 2117 if (DEBUG_PAUSE) Log.v(TAG, "Executing finish of activity: " + prev); 2118 prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE); 2119 } else if (prev.app != null) { 2120 if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending stop: " + prev); 2121 if (prev.waitingVisible) { 2122 prev.waitingVisible = false; 2123 mWaitingVisibleActivities.remove(prev); 2124 if (DEBUG_SWITCH || DEBUG_PAUSE) Log.v( 2125 TAG, "Complete pause, no longer waiting: " + prev); 2126 } 2127 if (prev.configDestroy) { 2128 // The previous is being paused because the configuration 2129 // is changing, which means it is actually stopping... 2130 // To juggle the fact that we are also starting a new 2131 // instance right now, we need to first completely stop 2132 // the current instance before starting the new one. 2133 if (DEBUG_PAUSE) Log.v(TAG, "Destroying after pause: " + prev); 2134 destroyActivityLocked(prev, true); 2135 } else { 2136 mStoppingActivities.add(prev); 2137 if (mStoppingActivities.size() > 3) { 2138 // If we already have a few activities waiting to stop, 2139 // then give up on things going idle and start clearing 2140 // them out. 2141 if (DEBUG_PAUSE) Log.v(TAG, "To many pending stops, forcing idle"); 2142 Message msg = Message.obtain(); 2143 msg.what = ActivityManagerService.IDLE_NOW_MSG; 2144 mHandler.sendMessage(msg); 2145 } 2146 } 2147 } else { 2148 if (DEBUG_PAUSE) Log.v(TAG, "App died during pause, not stopping: " + prev); 2149 prev = null; 2150 } 2151 mPausingActivity = null; 2152 } 2153 2154 if (!mSleeping && !mShuttingDown) { 2155 resumeTopActivityLocked(prev); 2156 } else { 2157 if (mGoingToSleep.isHeld()) { 2158 mGoingToSleep.release(); 2159 } 2160 if (mShuttingDown) { 2161 notifyAll(); 2162 } 2163 } 2164 2165 if (prev != null) { 2166 prev.resumeKeyDispatchingLocked(); 2167 } 2168 2169 if (prev.app != null && prev.cpuTimeAtResume > 0 && mBatteryStatsService.isOnBattery()) { 2170 long diff = 0; 2171 synchronized (mProcessStatsThread) { 2172 diff = mProcessStats.getCpuTimeForPid(prev.app.pid) - prev.cpuTimeAtResume; 2173 } 2174 if (diff > 0) { 2175 BatteryStatsImpl bsi = mBatteryStatsService.getActiveStatistics(); 2176 synchronized (bsi) { 2177 BatteryStatsImpl.Uid.Proc ps = 2178 bsi.getProcessStatsLocked(prev.info.applicationInfo.uid, 2179 prev.info.packageName); 2180 if (ps != null) { 2181 ps.addForegroundTimeLocked(diff); 2182 } 2183 } 2184 } 2185 } 2186 prev.cpuTimeAtResume = 0; // reset it 2187 } 2188 2189 /** 2190 * Once we know that we have asked an application to put an activity in 2191 * the resumed state (either by launching it or explicitly telling it), 2192 * this function updates the rest of our state to match that fact. 2193 */ 2194 private final void completeResumeLocked(HistoryRecord next) { 2195 next.idle = false; 2196 next.results = null; 2197 next.newIntents = null; 2198 2199 // schedule an idle timeout in case the app doesn't do it for us. 2200 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 2201 msg.obj = next; 2202 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 2203 2204 if (false) { 2205 // The activity was never told to pause, so just keep 2206 // things going as-is. To maintain our own state, 2207 // we need to emulate it coming back and saying it is 2208 // idle. 2209 msg = mHandler.obtainMessage(IDLE_NOW_MSG); 2210 msg.obj = next; 2211 mHandler.sendMessage(msg); 2212 } 2213 2214 reportResumedActivityLocked(next); 2215 2216 next.thumbnail = null; 2217 setFocusedActivityLocked(next); 2218 next.resumeKeyDispatchingLocked(); 2219 ensureActivitiesVisibleLocked(null, 0); 2220 mWindowManager.executeAppTransition(); 2221 mNoAnimActivities.clear(); 2222 2223 // Mark the point when the activity is resuming 2224 // TODO: To be more accurate, the mark should be before the onCreate, 2225 // not after the onResume. But for subsequent starts, onResume is fine. 2226 if (next.app != null) { 2227 synchronized (mProcessStatsThread) { 2228 next.cpuTimeAtResume = mProcessStats.getCpuTimeForPid(next.app.pid); 2229 } 2230 } else { 2231 next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process 2232 } 2233 } 2234 2235 /** 2236 * Make sure that all activities that need to be visible (that is, they 2237 * currently can be seen by the user) actually are. 2238 */ 2239 private final void ensureActivitiesVisibleLocked(HistoryRecord top, 2240 HistoryRecord starting, String onlyThisProcess, int configChanges) { 2241 if (DEBUG_VISBILITY) Log.v( 2242 TAG, "ensureActivitiesVisible behind " + top 2243 + " configChanges=0x" + Integer.toHexString(configChanges)); 2244 2245 // If the top activity is not fullscreen, then we need to 2246 // make sure any activities under it are now visible. 2247 final int count = mHistory.size(); 2248 int i = count-1; 2249 while (mHistory.get(i) != top) { 2250 i--; 2251 } 2252 HistoryRecord r; 2253 boolean behindFullscreen = false; 2254 for (; i>=0; i--) { 2255 r = (HistoryRecord)mHistory.get(i); 2256 if (DEBUG_VISBILITY) Log.v( 2257 TAG, "Make visible? " + r + " finishing=" + r.finishing 2258 + " state=" + r.state); 2259 if (r.finishing) { 2260 continue; 2261 } 2262 2263 final boolean doThisProcess = onlyThisProcess == null 2264 || onlyThisProcess.equals(r.processName); 2265 2266 // First: if this is not the current activity being started, make 2267 // sure it matches the current configuration. 2268 if (r != starting && doThisProcess) { 2269 ensureActivityConfigurationLocked(r, 0); 2270 } 2271 2272 if (r.app == null || r.app.thread == null) { 2273 if (onlyThisProcess == null 2274 || onlyThisProcess.equals(r.processName)) { 2275 // This activity needs to be visible, but isn't even 2276 // running... get it started, but don't resume it 2277 // at this point. 2278 if (DEBUG_VISBILITY) Log.v( 2279 TAG, "Start and freeze screen for " + r); 2280 if (r != starting) { 2281 r.startFreezingScreenLocked(r.app, configChanges); 2282 } 2283 if (!r.visible) { 2284 if (DEBUG_VISBILITY) Log.v( 2285 TAG, "Starting and making visible: " + r); 2286 mWindowManager.setAppVisibility(r, true); 2287 } 2288 if (r != starting) { 2289 startSpecificActivityLocked(r, false, false); 2290 } 2291 } 2292 2293 } else if (r.visible) { 2294 // If this activity is already visible, then there is nothing 2295 // else to do here. 2296 if (DEBUG_VISBILITY) Log.v( 2297 TAG, "Skipping: already visible at " + r); 2298 r.stopFreezingScreenLocked(false); 2299 2300 } else if (onlyThisProcess == null) { 2301 // This activity is not currently visible, but is running. 2302 // Tell it to become visible. 2303 r.visible = true; 2304 if (r.state != ActivityState.RESUMED && r != starting) { 2305 // If this activity is paused, tell it 2306 // to now show its window. 2307 if (DEBUG_VISBILITY) Log.v( 2308 TAG, "Making visible and scheduling visibility: " + r); 2309 try { 2310 mWindowManager.setAppVisibility(r, true); 2311 r.app.thread.scheduleWindowVisibility(r, true); 2312 r.stopFreezingScreenLocked(false); 2313 } catch (Exception e) { 2314 // Just skip on any failure; we'll make it 2315 // visible when it next restarts. 2316 Log.w(TAG, "Exception thrown making visibile: " 2317 + r.intent.getComponent(), e); 2318 } 2319 } 2320 } 2321 2322 // Aggregate current change flags. 2323 configChanges |= r.configChangeFlags; 2324 2325 if (r.fullscreen) { 2326 // At this point, nothing else needs to be shown 2327 if (DEBUG_VISBILITY) Log.v( 2328 TAG, "Stopping: fullscreen at " + r); 2329 behindFullscreen = true; 2330 i--; 2331 break; 2332 } 2333 } 2334 2335 // Now for any activities that aren't visible to the user, make 2336 // sure they no longer are keeping the screen frozen. 2337 while (i >= 0) { 2338 r = (HistoryRecord)mHistory.get(i); 2339 if (DEBUG_VISBILITY) Log.v( 2340 TAG, "Make invisible? " + r + " finishing=" + r.finishing 2341 + " state=" + r.state 2342 + " behindFullscreen=" + behindFullscreen); 2343 if (!r.finishing) { 2344 if (behindFullscreen) { 2345 if (r.visible) { 2346 if (DEBUG_VISBILITY) Log.v( 2347 TAG, "Making invisible: " + r); 2348 r.visible = false; 2349 try { 2350 mWindowManager.setAppVisibility(r, false); 2351 if ((r.state == ActivityState.STOPPING 2352 || r.state == ActivityState.STOPPED) 2353 && r.app != null && r.app.thread != null) { 2354 if (DEBUG_VISBILITY) Log.v( 2355 TAG, "Scheduling invisibility: " + r); 2356 r.app.thread.scheduleWindowVisibility(r, false); 2357 } 2358 } catch (Exception e) { 2359 // Just skip on any failure; we'll make it 2360 // visible when it next restarts. 2361 Log.w(TAG, "Exception thrown making hidden: " 2362 + r.intent.getComponent(), e); 2363 } 2364 } else { 2365 if (DEBUG_VISBILITY) Log.v( 2366 TAG, "Already invisible: " + r); 2367 } 2368 } else if (r.fullscreen) { 2369 if (DEBUG_VISBILITY) Log.v( 2370 TAG, "Now behindFullscreen: " + r); 2371 behindFullscreen = true; 2372 } 2373 } 2374 i--; 2375 } 2376 } 2377 2378 /** 2379 * Version of ensureActivitiesVisible that can easily be called anywhere. 2380 */ 2381 private final void ensureActivitiesVisibleLocked(HistoryRecord starting, 2382 int configChanges) { 2383 HistoryRecord r = topRunningActivityLocked(null); 2384 if (r != null) { 2385 ensureActivitiesVisibleLocked(r, starting, null, configChanges); 2386 } 2387 } 2388 2389 private void updateUsageStats(HistoryRecord resumedComponent, boolean resumed) { 2390 if (resumed) { 2391 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2392 } else { 2393 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2394 } 2395 } 2396 2397 private boolean startHomeActivityLocked() { 2398 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2399 && mTopAction == null) { 2400 // We are running in factory test mode, but unable to find 2401 // the factory test app, so just sit around displaying the 2402 // error message and don't try to start anything. 2403 return false; 2404 } 2405 Intent intent = new Intent( 2406 mTopAction, 2407 mTopData != null ? Uri.parse(mTopData) : null); 2408 intent.setComponent(mTopComponent); 2409 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2410 intent.addCategory(Intent.CATEGORY_HOME); 2411 } 2412 ActivityInfo aInfo = 2413 intent.resolveActivityInfo(mContext.getPackageManager(), 2414 STOCK_PM_FLAGS); 2415 if (aInfo != null) { 2416 intent.setComponent(new ComponentName( 2417 aInfo.applicationInfo.packageName, aInfo.name)); 2418 // Don't do this if the home app is currently being 2419 // instrumented. 2420 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2421 aInfo.applicationInfo.uid); 2422 if (app == null || app.instrumentationClass == null) { 2423 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2424 startActivityLocked(null, intent, null, null, 0, aInfo, 2425 null, null, 0, 0, 0, false, false); 2426 } 2427 } 2428 2429 2430 return true; 2431 } 2432 2433 /** 2434 * Starts the "new version setup screen" if appropriate. 2435 */ 2436 private void startSetupActivityLocked() { 2437 // Only do this once per boot. 2438 if (mCheckedForSetup) { 2439 return; 2440 } 2441 2442 // We will show this screen if the current one is a different 2443 // version than the last one shown, and we are not running in 2444 // low-level factory test mode. 2445 final ContentResolver resolver = mContext.getContentResolver(); 2446 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2447 Settings.Secure.getInt(resolver, 2448 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2449 mCheckedForSetup = true; 2450 2451 // See if we should be showing the platform update setup UI. 2452 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2453 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2454 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2455 2456 // We don't allow third party apps to replace this. 2457 ResolveInfo ri = null; 2458 for (int i=0; ris != null && i<ris.size(); i++) { 2459 if ((ris.get(i).activityInfo.applicationInfo.flags 2460 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2461 ri = ris.get(i); 2462 break; 2463 } 2464 } 2465 2466 if (ri != null) { 2467 String vers = ri.activityInfo.metaData != null 2468 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2469 : null; 2470 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2471 vers = ri.activityInfo.applicationInfo.metaData.getString( 2472 Intent.METADATA_SETUP_VERSION); 2473 } 2474 String lastVers = Settings.Secure.getString( 2475 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2476 if (vers != null && !vers.equals(lastVers)) { 2477 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2478 intent.setComponent(new ComponentName( 2479 ri.activityInfo.packageName, ri.activityInfo.name)); 2480 startActivityLocked(null, intent, null, null, 0, ri.activityInfo, 2481 null, null, 0, 0, 0, false, false); 2482 } 2483 } 2484 } 2485 } 2486 2487 private void reportResumedActivityLocked(HistoryRecord r) { 2488 //Log.i(TAG, "**** REPORT RESUME: " + r); 2489 2490 final int identHash = System.identityHashCode(r); 2491 updateUsageStats(r, true); 2492 2493 int i = mWatchers.beginBroadcast(); 2494 while (i > 0) { 2495 i--; 2496 IActivityWatcher w = mWatchers.getBroadcastItem(i); 2497 if (w != null) { 2498 try { 2499 w.activityResuming(identHash); 2500 } catch (RemoteException e) { 2501 } 2502 } 2503 } 2504 mWatchers.finishBroadcast(); 2505 } 2506 2507 /** 2508 * Ensure that the top activity in the stack is resumed. 2509 * 2510 * @param prev The previously resumed activity, for when in the process 2511 * of pausing; can be null to call from elsewhere. 2512 * 2513 * @return Returns true if something is being resumed, or false if 2514 * nothing happened. 2515 */ 2516 private final boolean resumeTopActivityLocked(HistoryRecord prev) { 2517 // Find the first activity that is not finishing. 2518 HistoryRecord next = topRunningActivityLocked(null); 2519 2520 // Remember how we'll process this pause/resume situation, and ensure 2521 // that the state is reset however we wind up proceeding. 2522 final boolean userLeaving = mUserLeaving; 2523 mUserLeaving = false; 2524 2525 if (next == null) { 2526 // There are no more activities! Let's just start up the 2527 // Launcher... 2528 return startHomeActivityLocked(); 2529 } 2530 2531 next.delayedResume = false; 2532 2533 // If the top activity is the resumed one, nothing to do. 2534 if (mResumedActivity == next && next.state == ActivityState.RESUMED) { 2535 // Make sure we have executed any pending transitions, since there 2536 // should be nothing left to do at this point. 2537 mWindowManager.executeAppTransition(); 2538 mNoAnimActivities.clear(); 2539 return false; 2540 } 2541 2542 // If we are sleeping, and there is no resumed activity, and the top 2543 // activity is paused, well that is the state we want. 2544 if ((mSleeping || mShuttingDown) 2545 && mLastPausedActivity == next && next.state == ActivityState.PAUSED) { 2546 // Make sure we have executed any pending transitions, since there 2547 // should be nothing left to do at this point. 2548 mWindowManager.executeAppTransition(); 2549 mNoAnimActivities.clear(); 2550 return false; 2551 } 2552 2553 // The activity may be waiting for stop, but that is no longer 2554 // appropriate for it. 2555 mStoppingActivities.remove(next); 2556 mWaitingVisibleActivities.remove(next); 2557 2558 if (DEBUG_SWITCH) Log.v(TAG, "Resuming " + next); 2559 2560 // If we are currently pausing an activity, then don't do anything 2561 // until that is done. 2562 if (mPausingActivity != null) { 2563 if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: pausing=" + mPausingActivity); 2564 return false; 2565 } 2566 2567 // We need to start pausing the current activity so the top one 2568 // can be resumed... 2569 if (mResumedActivity != null) { 2570 if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: need to start pausing"); 2571 startPausingLocked(userLeaving, false); 2572 return true; 2573 } 2574 2575 if (prev != null && prev != next) { 2576 if (!prev.waitingVisible && next != null && !next.nowVisible) { 2577 prev.waitingVisible = true; 2578 mWaitingVisibleActivities.add(prev); 2579 if (DEBUG_SWITCH) Log.v( 2580 TAG, "Resuming top, waiting visible to hide: " + prev); 2581 } else { 2582 // The next activity is already visible, so hide the previous 2583 // activity's windows right now so we can show the new one ASAP. 2584 // We only do this if the previous is finishing, which should mean 2585 // it is on top of the one being resumed so hiding it quickly 2586 // is good. Otherwise, we want to do the normal route of allowing 2587 // the resumed activity to be shown so we can decide if the 2588 // previous should actually be hidden depending on whether the 2589 // new one is found to be full-screen or not. 2590 if (prev.finishing) { 2591 mWindowManager.setAppVisibility(prev, false); 2592 if (DEBUG_SWITCH) Log.v(TAG, "Not waiting for visible to hide: " 2593 + prev + ", waitingVisible=" 2594 + (prev != null ? prev.waitingVisible : null) 2595 + ", nowVisible=" + next.nowVisible); 2596 } else { 2597 if (DEBUG_SWITCH) Log.v(TAG, "Previous already visible but still waiting to hide: " 2598 + prev + ", waitingVisible=" 2599 + (prev != null ? prev.waitingVisible : null) 2600 + ", nowVisible=" + next.nowVisible); 2601 } 2602 } 2603 } 2604 2605 // We are starting up the next activity, so tell the window manager 2606 // that the previous one will be hidden soon. This way it can know 2607 // to ignore it when computing the desired screen orientation. 2608 if (prev != null) { 2609 if (prev.finishing) { 2610 if (DEBUG_TRANSITION) Log.v(TAG, 2611 "Prepare close transition: prev=" + prev); 2612 if (mNoAnimActivities.contains(prev)) { 2613 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 2614 } else { 2615 mWindowManager.prepareAppTransition(prev.task == next.task 2616 ? WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE 2617 : WindowManagerPolicy.TRANSIT_TASK_CLOSE); 2618 } 2619 mWindowManager.setAppWillBeHidden(prev); 2620 mWindowManager.setAppVisibility(prev, false); 2621 } else { 2622 if (DEBUG_TRANSITION) Log.v(TAG, 2623 "Prepare open transition: prev=" + prev); 2624 if (mNoAnimActivities.contains(next)) { 2625 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 2626 } else { 2627 mWindowManager.prepareAppTransition(prev.task == next.task 2628 ? WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 2629 : WindowManagerPolicy.TRANSIT_TASK_OPEN); 2630 } 2631 } 2632 if (false) { 2633 mWindowManager.setAppWillBeHidden(prev); 2634 mWindowManager.setAppVisibility(prev, false); 2635 } 2636 } else if (mHistory.size() > 1) { 2637 if (DEBUG_TRANSITION) Log.v(TAG, 2638 "Prepare open transition: no previous"); 2639 if (mNoAnimActivities.contains(next)) { 2640 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 2641 } else { 2642 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN); 2643 } 2644 } 2645 2646 if (next.app != null && next.app.thread != null) { 2647 if (DEBUG_SWITCH) Log.v(TAG, "Resume running: " + next); 2648 2649 // This activity is now becoming visible. 2650 mWindowManager.setAppVisibility(next, true); 2651 2652 HistoryRecord lastResumedActivity = mResumedActivity; 2653 ActivityState lastState = next.state; 2654 2655 updateCpuStats(); 2656 2657 next.state = ActivityState.RESUMED; 2658 mResumedActivity = next; 2659 next.task.touchActiveTime(); 2660 updateLruProcessLocked(next.app, true, true); 2661 updateLRUListLocked(next); 2662 2663 // Have the window manager re-evaluate the orientation of 2664 // the screen based on the new activity order. 2665 boolean updated; 2666 synchronized (this) { 2667 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2668 mConfiguration, 2669 next.mayFreezeScreenLocked(next.app) ? next : null); 2670 if (config != null) { 2671 /* 2672 * Explicitly restore the locale to the one from the 2673 * old configuration, since the one that comes back from 2674 * the window manager has the default (boot) locale. 2675 * 2676 * It looks like previously the locale picker only worked 2677 * by coincidence: usually it would do its setting of 2678 * the locale after the activity transition, so it didn't 2679 * matter that this lost it. With the synchronized 2680 * block now keeping them from happening at the same time, 2681 * this one always would happen second and undo what the 2682 * locale picker had just done. 2683 */ 2684 config.locale = mConfiguration.locale; 2685 next.frozenBeforeDestroy = true; 2686 } 2687 updated = updateConfigurationLocked(config, next); 2688 } 2689 if (!updated) { 2690 // The configuration update wasn't able to keep the existing 2691 // instance of the activity, and instead started a new one. 2692 // We should be all done, but let's just make sure our activity 2693 // is still at the top and schedule another run if something 2694 // weird happened. 2695 HistoryRecord nextNext = topRunningActivityLocked(null); 2696 if (DEBUG_SWITCH) Log.i(TAG, 2697 "Activity config changed during resume: " + next 2698 + ", new next: " + nextNext); 2699 if (nextNext != next) { 2700 // Do over! 2701 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 2702 } 2703 setFocusedActivityLocked(next); 2704 ensureActivitiesVisibleLocked(null, 0); 2705 mWindowManager.executeAppTransition(); 2706 mNoAnimActivities.clear(); 2707 return true; 2708 } 2709 2710 try { 2711 // Deliver all pending results. 2712 ArrayList a = next.results; 2713 if (a != null) { 2714 final int N = a.size(); 2715 if (!next.finishing && N > 0) { 2716 if (DEBUG_RESULTS) Log.v( 2717 TAG, "Delivering results to " + next 2718 + ": " + a); 2719 next.app.thread.scheduleSendResult(next, a); 2720 } 2721 } 2722 2723 if (next.newIntents != null) { 2724 next.app.thread.scheduleNewIntent(next.newIntents, next); 2725 } 2726 2727 EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, 2728 System.identityHashCode(next), 2729 next.task.taskId, next.shortComponentName); 2730 2731 next.app.thread.scheduleResumeActivity(next, 2732 isNextTransitionForward()); 2733 2734 pauseIfSleepingLocked(); 2735 2736 } catch (Exception e) { 2737 // Whoops, need to restart this activity! 2738 next.state = lastState; 2739 mResumedActivity = lastResumedActivity; 2740 Log.i(TAG, "Restarting because process died: " + next); 2741 if (!next.hasBeenLaunched) { 2742 next.hasBeenLaunched = true; 2743 } else { 2744 if (SHOW_APP_STARTING_ICON) { 2745 mWindowManager.setAppStartingWindow( 2746 next, next.packageName, next.theme, 2747 next.nonLocalizedLabel, 2748 next.labelRes, next.icon, null, true); 2749 } 2750 } 2751 startSpecificActivityLocked(next, true, false); 2752 return true; 2753 } 2754 2755 // From this point on, if something goes wrong there is no way 2756 // to recover the activity. 2757 try { 2758 next.visible = true; 2759 completeResumeLocked(next); 2760 } catch (Exception e) { 2761 // If any exception gets thrown, toss away this 2762 // activity and try the next one. 2763 Log.w(TAG, "Exception thrown during resume of " + next, e); 2764 requestFinishActivityLocked(next, Activity.RESULT_CANCELED, null, 2765 "resume-exception"); 2766 return true; 2767 } 2768 2769 // Didn't need to use the icicle, and it is now out of date. 2770 next.icicle = null; 2771 next.haveState = false; 2772 next.stopped = false; 2773 2774 } else { 2775 // Whoops, need to restart this activity! 2776 if (!next.hasBeenLaunched) { 2777 next.hasBeenLaunched = true; 2778 } else { 2779 if (SHOW_APP_STARTING_ICON) { 2780 mWindowManager.setAppStartingWindow( 2781 next, next.packageName, next.theme, 2782 next.nonLocalizedLabel, 2783 next.labelRes, next.icon, null, true); 2784 } 2785 if (DEBUG_SWITCH) Log.v(TAG, "Restarting: " + next); 2786 } 2787 startSpecificActivityLocked(next, true, true); 2788 } 2789 2790 return true; 2791 } 2792 2793 private final void startActivityLocked(HistoryRecord r, boolean newTask, 2794 boolean doResume) { 2795 final int NH = mHistory.size(); 2796 2797 int addPos = -1; 2798 2799 if (!newTask) { 2800 // If starting in an existing task, find where that is... 2801 HistoryRecord next = null; 2802 boolean startIt = true; 2803 for (int i = NH-1; i >= 0; i--) { 2804 HistoryRecord p = (HistoryRecord)mHistory.get(i); 2805 if (p.finishing) { 2806 continue; 2807 } 2808 if (p.task == r.task) { 2809 // Here it is! Now, if this is not yet visible to the 2810 // user, then just add it without starting; it will 2811 // get started when the user navigates back to it. 2812 addPos = i+1; 2813 if (!startIt) { 2814 mHistory.add(addPos, r); 2815 r.inHistory = true; 2816 r.task.numActivities++; 2817 mWindowManager.addAppToken(addPos, r, r.task.taskId, 2818 r.info.screenOrientation, r.fullscreen); 2819 if (VALIDATE_TOKENS) { 2820 mWindowManager.validateAppTokens(mHistory); 2821 } 2822 return; 2823 } 2824 break; 2825 } 2826 if (p.fullscreen) { 2827 startIt = false; 2828 } 2829 next = p; 2830 } 2831 } 2832 2833 // Place a new activity at top of stack, so it is next to interact 2834 // with the user. 2835 if (addPos < 0) { 2836 addPos = mHistory.size(); 2837 } 2838 2839 // If we are not placing the new activity frontmost, we do not want 2840 // to deliver the onUserLeaving callback to the actual frontmost 2841 // activity 2842 if (addPos < NH) { 2843 mUserLeaving = false; 2844 if (DEBUG_USER_LEAVING) Log.v(TAG, "startActivity() behind front, mUserLeaving=false"); 2845 } 2846 2847 // Slot the activity into the history stack and proceed 2848 mHistory.add(addPos, r); 2849 r.inHistory = true; 2850 r.frontOfTask = newTask; 2851 r.task.numActivities++; 2852 if (NH > 0) { 2853 // We want to show the starting preview window if we are 2854 // switching to a new task, or the next activity's process is 2855 // not currently running. 2856 boolean showStartingIcon = newTask; 2857 ProcessRecord proc = r.app; 2858 if (proc == null) { 2859 proc = mProcessNames.get(r.processName, r.info.applicationInfo.uid); 2860 } 2861 if (proc == null || proc.thread == null) { 2862 showStartingIcon = true; 2863 } 2864 if (DEBUG_TRANSITION) Log.v(TAG, 2865 "Prepare open transition: starting " + r); 2866 if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { 2867 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 2868 mNoAnimActivities.add(r); 2869 } else if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) { 2870 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_OPEN); 2871 mNoAnimActivities.remove(r); 2872 } else { 2873 mWindowManager.prepareAppTransition(newTask 2874 ? WindowManagerPolicy.TRANSIT_TASK_OPEN 2875 : WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN); 2876 mNoAnimActivities.remove(r); 2877 } 2878 mWindowManager.addAppToken( 2879 addPos, r, r.task.taskId, r.info.screenOrientation, r.fullscreen); 2880 boolean doShow = true; 2881 if (newTask) { 2882 // Even though this activity is starting fresh, we still need 2883 // to reset it to make sure we apply affinities to move any 2884 // existing activities from other tasks in to it. 2885 // If the caller has requested that the target task be 2886 // reset, then do so. 2887 if ((r.intent.getFlags() 2888 &Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 2889 resetTaskIfNeededLocked(r, r); 2890 doShow = topRunningNonDelayedActivityLocked(null) == r; 2891 } 2892 } 2893 if (SHOW_APP_STARTING_ICON && doShow) { 2894 // Figure out if we are transitioning from another activity that is 2895 // "has the same starting icon" as the next one. This allows the 2896 // window manager to keep the previous window it had previously 2897 // created, if it still had one. 2898 HistoryRecord prev = mResumedActivity; 2899 if (prev != null) { 2900 // We don't want to reuse the previous starting preview if: 2901 // (1) The current activity is in a different task. 2902 if (prev.task != r.task) prev = null; 2903 // (2) The current activity is already displayed. 2904 else if (prev.nowVisible) prev = null; 2905 } 2906 mWindowManager.setAppStartingWindow( 2907 r, r.packageName, r.theme, r.nonLocalizedLabel, 2908 r.labelRes, r.icon, prev, showStartingIcon); 2909 } 2910 } else { 2911 // If this is the first activity, don't do any fancy animations, 2912 // because there is nothing for it to animate on top of. 2913 mWindowManager.addAppToken(addPos, r, r.task.taskId, 2914 r.info.screenOrientation, r.fullscreen); 2915 } 2916 if (VALIDATE_TOKENS) { 2917 mWindowManager.validateAppTokens(mHistory); 2918 } 2919 2920 if (doResume) { 2921 resumeTopActivityLocked(null); 2922 } 2923 } 2924 2925 /** 2926 * Perform clear operation as requested by 2927 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the 2928 * stack to the given task, then look for 2929 * an instance of that activity in the stack and, if found, finish all 2930 * activities on top of it and return the instance. 2931 * 2932 * @param newR Description of the new activity being started. 2933 * @return Returns the old activity that should be continue to be used, 2934 * or null if none was found. 2935 */ 2936 private final HistoryRecord performClearTaskLocked(int taskId, 2937 HistoryRecord newR, int launchFlags, boolean doClear) { 2938 int i = mHistory.size(); 2939 2940 // First find the requested task. 2941 while (i > 0) { 2942 i--; 2943 HistoryRecord r = (HistoryRecord)mHistory.get(i); 2944 if (r.task.taskId == taskId) { 2945 i++; 2946 break; 2947 } 2948 } 2949 2950 // Now clear it. 2951 while (i > 0) { 2952 i--; 2953 HistoryRecord r = (HistoryRecord)mHistory.get(i); 2954 if (r.finishing) { 2955 continue; 2956 } 2957 if (r.task.taskId != taskId) { 2958 return null; 2959 } 2960 if (r.realActivity.equals(newR.realActivity)) { 2961 // Here it is! Now finish everything in front... 2962 HistoryRecord ret = r; 2963 if (doClear) { 2964 while (i < (mHistory.size()-1)) { 2965 i++; 2966 r = (HistoryRecord)mHistory.get(i); 2967 if (r.finishing) { 2968 continue; 2969 } 2970 if (finishActivityLocked(r, i, Activity.RESULT_CANCELED, 2971 null, "clear")) { 2972 i--; 2973 } 2974 } 2975 } 2976 2977 // Finally, if this is a normal launch mode (that is, not 2978 // expecting onNewIntent()), then we will finish the current 2979 // instance of the activity so a new fresh one can be started. 2980 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE 2981 && (launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) { 2982 if (!ret.finishing) { 2983 int index = indexOfTokenLocked(ret); 2984 if (index >= 0) { 2985 finishActivityLocked(ret, 0, Activity.RESULT_CANCELED, 2986 null, "clear"); 2987 } 2988 return null; 2989 } 2990 } 2991 2992 return ret; 2993 } 2994 } 2995 2996 return null; 2997 } 2998 2999 /** 3000 * Find the activity in the history stack within the given task. Returns 3001 * the index within the history at which it's found, or < 0 if not found. 3002 */ 3003 private final int findActivityInHistoryLocked(HistoryRecord r, int task) { 3004 int i = mHistory.size(); 3005 while (i > 0) { 3006 i--; 3007 HistoryRecord candidate = (HistoryRecord)mHistory.get(i); 3008 if (candidate.task.taskId != task) { 3009 break; 3010 } 3011 if (candidate.realActivity.equals(r.realActivity)) { 3012 return i; 3013 } 3014 } 3015 3016 return -1; 3017 } 3018 3019 /** 3020 * Reorder the history stack so that the activity at the given index is 3021 * brought to the front. 3022 */ 3023 private final HistoryRecord moveActivityToFrontLocked(int where) { 3024 HistoryRecord newTop = (HistoryRecord)mHistory.remove(where); 3025 int top = mHistory.size(); 3026 HistoryRecord oldTop = (HistoryRecord)mHistory.get(top-1); 3027 mHistory.add(top, newTop); 3028 oldTop.frontOfTask = false; 3029 newTop.frontOfTask = true; 3030 return newTop; 3031 } 3032 3033 /** 3034 * Deliver a new Intent to an existing activity, so that its onNewIntent() 3035 * method will be called at the proper time. 3036 */ 3037 private final void deliverNewIntentLocked(HistoryRecord r, Intent intent) { 3038 boolean sent = false; 3039 if (r.state == ActivityState.RESUMED 3040 && r.app != null && r.app.thread != null) { 3041 try { 3042 ArrayList<Intent> ar = new ArrayList<Intent>(); 3043 ar.add(new Intent(intent)); 3044 r.app.thread.scheduleNewIntent(ar, r); 3045 sent = true; 3046 } catch (Exception e) { 3047 Log.w(TAG, "Exception thrown sending new intent to " + r, e); 3048 } 3049 } 3050 if (!sent) { 3051 r.addNewIntentLocked(new Intent(intent)); 3052 } 3053 } 3054 3055 private final void logStartActivity(int tag, HistoryRecord r, 3056 TaskRecord task) { 3057 EventLog.writeEvent(tag, 3058 System.identityHashCode(r), task.taskId, 3059 r.shortComponentName, r.intent.getAction(), 3060 r.intent.getType(), r.intent.getDataString(), 3061 r.intent.getFlags()); 3062 } 3063 3064 private final int startActivityLocked(IApplicationThread caller, 3065 Intent intent, String resolvedType, 3066 Uri[] grantedUriPermissions, 3067 int grantedMode, ActivityInfo aInfo, IBinder resultTo, 3068 String resultWho, int requestCode, 3069 int callingPid, int callingUid, boolean onlyIfNeeded, 3070 boolean componentSpecified) { 3071 Log.i(TAG, "Starting activity: " + intent); 3072 3073 HistoryRecord sourceRecord = null; 3074 HistoryRecord resultRecord = null; 3075 if (resultTo != null) { 3076 int index = indexOfTokenLocked(resultTo); 3077 if (DEBUG_RESULTS) Log.v( 3078 TAG, "Sending result to " + resultTo + " (index " + index + ")"); 3079 if (index >= 0) { 3080 sourceRecord = (HistoryRecord)mHistory.get(index); 3081 if (requestCode >= 0 && !sourceRecord.finishing) { 3082 resultRecord = sourceRecord; 3083 } 3084 } 3085 } 3086 3087 int launchFlags = intent.getFlags(); 3088 3089 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 3090 && sourceRecord != null) { 3091 // Transfer the result target from the source activity to the new 3092 // one being started, including any failures. 3093 if (requestCode >= 0) { 3094 return START_FORWARD_AND_REQUEST_CONFLICT; 3095 } 3096 resultRecord = sourceRecord.resultTo; 3097 resultWho = sourceRecord.resultWho; 3098 requestCode = sourceRecord.requestCode; 3099 sourceRecord.resultTo = null; 3100 if (resultRecord != null) { 3101 resultRecord.removeResultsLocked( 3102 sourceRecord, resultWho, requestCode); 3103 } 3104 } 3105 3106 int err = START_SUCCESS; 3107 3108 if (intent.getComponent() == null) { 3109 // We couldn't find a class that can handle the given Intent. 3110 // That's the end of that! 3111 err = START_INTENT_NOT_RESOLVED; 3112 } 3113 3114 if (err == START_SUCCESS && aInfo == null) { 3115 // We couldn't find the specific class specified in the Intent. 3116 // Also the end of the line. 3117 err = START_CLASS_NOT_FOUND; 3118 } 3119 3120 ProcessRecord callerApp = null; 3121 if (err == START_SUCCESS && caller != null) { 3122 callerApp = getRecordForAppLocked(caller); 3123 if (callerApp != null) { 3124 callingPid = callerApp.pid; 3125 callingUid = callerApp.info.uid; 3126 } else { 3127 Log.w(TAG, "Unable to find app for caller " + caller 3128 + " (pid=" + callingPid + ") when starting: " 3129 + intent.toString()); 3130 err = START_PERMISSION_DENIED; 3131 } 3132 } 3133 3134 if (err != START_SUCCESS) { 3135 if (resultRecord != null) { 3136 sendActivityResultLocked(-1, 3137 resultRecord, resultWho, requestCode, 3138 Activity.RESULT_CANCELED, null); 3139 } 3140 return err; 3141 } 3142 3143 final int perm = checkComponentPermission(aInfo.permission, callingPid, 3144 callingUid, aInfo.exported ? -1 : aInfo.applicationInfo.uid); 3145 if (perm != PackageManager.PERMISSION_GRANTED) { 3146 if (resultRecord != null) { 3147 sendActivityResultLocked(-1, 3148 resultRecord, resultWho, requestCode, 3149 Activity.RESULT_CANCELED, null); 3150 } 3151 String msg = "Permission Denial: starting " + intent.toString() 3152 + " from " + callerApp + " (pid=" + callingPid 3153 + ", uid=" + callingUid + ")" 3154 + " requires " + aInfo.permission; 3155 Log.w(TAG, msg); 3156 throw new SecurityException(msg); 3157 } 3158 3159 if (mController != null) { 3160 boolean abort = false; 3161 try { 3162 // The Intent we give to the watcher has the extra data 3163 // stripped off, since it can contain private information. 3164 Intent watchIntent = intent.cloneFilter(); 3165 abort = !mController.activityStarting(watchIntent, 3166 aInfo.applicationInfo.packageName); 3167 } catch (RemoteException e) { 3168 mController = null; 3169 } 3170 3171 if (abort) { 3172 if (resultRecord != null) { 3173 sendActivityResultLocked(-1, 3174 resultRecord, resultWho, requestCode, 3175 Activity.RESULT_CANCELED, null); 3176 } 3177 // We pretend to the caller that it was really started, but 3178 // they will just get a cancel result. 3179 return START_SUCCESS; 3180 } 3181 } 3182 3183 HistoryRecord r = new HistoryRecord(this, callerApp, callingUid, 3184 intent, resolvedType, aInfo, mConfiguration, 3185 resultRecord, resultWho, requestCode, componentSpecified); 3186 3187 if (mResumedActivity == null 3188 || mResumedActivity.info.applicationInfo.uid != callingUid) { 3189 if (!checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) { 3190 PendingActivityLaunch pal = new PendingActivityLaunch(); 3191 pal.r = r; 3192 pal.sourceRecord = sourceRecord; 3193 pal.grantedUriPermissions = grantedUriPermissions; 3194 pal.grantedMode = grantedMode; 3195 pal.onlyIfNeeded = onlyIfNeeded; 3196 mPendingActivityLaunches.add(pal); 3197 return START_SWITCHES_CANCELED; 3198 } 3199 } 3200 3201 if (mDidAppSwitch) { 3202 // This is the second allowed switch since we stopped switches, 3203 // so now just generally allow switches. Use case: user presses 3204 // home (switches disabled, switch to home, mDidAppSwitch now true); 3205 // user taps a home icon (coming from home so allowed, we hit here 3206 // and now allow anyone to switch again). 3207 mAppSwitchesAllowedTime = 0; 3208 } else { 3209 mDidAppSwitch = true; 3210 } 3211 3212 doPendingActivityLaunchesLocked(false); 3213 3214 return startActivityUncheckedLocked(r, sourceRecord, 3215 grantedUriPermissions, grantedMode, onlyIfNeeded, true); 3216 } 3217 3218 private final void doPendingActivityLaunchesLocked(boolean doResume) { 3219 final int N = mPendingActivityLaunches.size(); 3220 if (N <= 0) { 3221 return; 3222 } 3223 for (int i=0; i<N; i++) { 3224 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3225 startActivityUncheckedLocked(pal.r, pal.sourceRecord, 3226 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded, 3227 doResume && i == (N-1)); 3228 } 3229 mPendingActivityLaunches.clear(); 3230 } 3231 3232 private final int startActivityUncheckedLocked(HistoryRecord r, 3233 HistoryRecord sourceRecord, Uri[] grantedUriPermissions, 3234 int grantedMode, boolean onlyIfNeeded, boolean doResume) { 3235 final Intent intent = r.intent; 3236 final int callingUid = r.launchedFromUid; 3237 3238 int launchFlags = intent.getFlags(); 3239 3240 // We'll invoke onUserLeaving before onPause only if the launching 3241 // activity did not explicitly state that this is an automated launch. 3242 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0; 3243 if (DEBUG_USER_LEAVING) Log.v(TAG, 3244 "startActivity() => mUserLeaving=" + mUserLeaving); 3245 3246 // If the caller has asked not to resume at this point, we make note 3247 // of this in the record so that we can skip it when trying to find 3248 // the top running activity. 3249 if (!doResume) { 3250 r.delayedResume = true; 3251 } 3252 3253 HistoryRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) 3254 != 0 ? r : null; 3255 3256 // If the onlyIfNeeded flag is set, then we can do this if the activity 3257 // being launched is the same as the one making the call... or, as 3258 // a special case, if we do not know the caller then we count the 3259 // current top activity as the caller. 3260 if (onlyIfNeeded) { 3261 HistoryRecord checkedCaller = sourceRecord; 3262 if (checkedCaller == null) { 3263 checkedCaller = topRunningNonDelayedActivityLocked(notTop); 3264 } 3265 if (!checkedCaller.realActivity.equals(r.realActivity)) { 3266 // Caller is not the same as launcher, so always needed. 3267 onlyIfNeeded = false; 3268 } 3269 } 3270 3271 if (grantedUriPermissions != null && callingUid > 0) { 3272 for (int i=0; i<grantedUriPermissions.length; i++) { 3273 grantUriPermissionLocked(callingUid, r.packageName, 3274 grantedUriPermissions[i], grantedMode, r); 3275 } 3276 } 3277 3278 grantUriPermissionFromIntentLocked(callingUid, r.packageName, 3279 intent, r); 3280 3281 if (sourceRecord == null) { 3282 // This activity is not being started from another... in this 3283 // case we -always- start a new task. 3284 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 3285 Log.w(TAG, "startActivity called from non-Activity context; forcing Intent.FLAG_ACTIVITY_NEW_TASK for: " 3286 + intent); 3287 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 3288 } 3289 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 3290 // The original activity who is starting us is running as a single 3291 // instance... this new activity it is starting must go on its 3292 // own task. 3293 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 3294 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE 3295 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 3296 // The activity being started is a single instance... it always 3297 // gets launched into its own task. 3298 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 3299 } 3300 3301 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 3302 // For whatever reason this activity is being launched into a new 3303 // task... yet the caller has requested a result back. Well, that 3304 // is pretty messed up, so instead immediately send back a cancel 3305 // and let the new task continue launched as normal without a 3306 // dependency on its originator. 3307 Log.w(TAG, "Activity is launching as a new task, so cancelling activity result."); 3308 sendActivityResultLocked(-1, 3309 r.resultTo, r.resultWho, r.requestCode, 3310 Activity.RESULT_CANCELED, null); 3311 r.resultTo = null; 3312 } 3313 3314 boolean addingToTask = false; 3315 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && 3316 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) 3317 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 3318 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 3319 // If bring to front is requested, and no result is requested, and 3320 // we can find a task that was started with this same 3321 // component, then instead of launching bring that one to the front. 3322 if (r.resultTo == null) { 3323 // See if there is a task to bring to the front. If this is 3324 // a SINGLE_INSTANCE activity, there can be one and only one 3325 // instance of it in the history, and it is always in its own 3326 // unique task, so we do a special search. 3327 HistoryRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE 3328 ? findTaskLocked(intent, r.info) 3329 : findActivityLocked(intent, r.info); 3330 if (taskTop != null) { 3331 if (taskTop.task.intent == null) { 3332 // This task was started because of movement of 3333 // the activity based on affinity... now that we 3334 // are actually launching it, we can assign the 3335 // base intent. 3336 taskTop.task.setIntent(intent, r.info); 3337 } 3338 // If the target task is not in the front, then we need 3339 // to bring it to the front... except... well, with 3340 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like 3341 // to have the same behavior as if a new instance was 3342 // being started, which means not bringing it to the front 3343 // if the caller is not itself in the front. 3344 HistoryRecord curTop = topRunningNonDelayedActivityLocked(notTop); 3345 if (curTop.task != taskTop.task) { 3346 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); 3347 boolean callerAtFront = sourceRecord == null 3348 || curTop.task == sourceRecord.task; 3349 if (callerAtFront) { 3350 // We really do want to push this one into the 3351 // user's face, right now. 3352 moveTaskToFrontLocked(taskTop.task, r); 3353 } 3354 } 3355 // If the caller has requested that the target task be 3356 // reset, then do so. 3357 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 3358 taskTop = resetTaskIfNeededLocked(taskTop, r); 3359 } 3360 if (onlyIfNeeded) { 3361 // We don't need to start a new activity, and 3362 // the client said not to do anything if that 3363 // is the case, so this is it! And for paranoia, make 3364 // sure we have correctly resumed the top activity. 3365 if (doResume) { 3366 resumeTopActivityLocked(null); 3367 } 3368 return START_RETURN_INTENT_TO_CALLER; 3369 } 3370 if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0 3371 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 3372 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 3373 // In this situation we want to remove all activities 3374 // from the task up to the one being started. In most 3375 // cases this means we are resetting the task to its 3376 // initial state. 3377 HistoryRecord top = performClearTaskLocked( 3378 taskTop.task.taskId, r, launchFlags, true); 3379 if (top != null) { 3380 if (top.frontOfTask) { 3381 // Activity aliases may mean we use different 3382 // intents for the top activity, so make sure 3383 // the task now has the identity of the new 3384 // intent. 3385 top.task.setIntent(r.intent, r.info); 3386 } 3387 logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); 3388 deliverNewIntentLocked(top, r.intent); 3389 } else { 3390 // A special case: we need to 3391 // start the activity because it is not currently 3392 // running, and the caller has asked to clear the 3393 // current task to have this activity at the top. 3394 addingToTask = true; 3395 // Now pretend like this activity is being started 3396 // by the top of its task, so it is put in the 3397 // right place. 3398 sourceRecord = taskTop; 3399 } 3400 } else if (r.realActivity.equals(taskTop.task.realActivity)) { 3401 // In this case the top activity on the task is the 3402 // same as the one being launched, so we take that 3403 // as a request to bring the task to the foreground. 3404 // If the top activity in the task is the root 3405 // activity, deliver this new intent to it if it 3406 // desires. 3407 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 3408 && taskTop.realActivity.equals(r.realActivity)) { 3409 logStartActivity(EventLogTags.AM_NEW_INTENT, r, taskTop.task); 3410 if (taskTop.frontOfTask) { 3411 taskTop.task.setIntent(r.intent, r.info); 3412 } 3413 deliverNewIntentLocked(taskTop, r.intent); 3414 } else if (!r.intent.filterEquals(taskTop.task.intent)) { 3415 // In this case we are launching the root activity 3416 // of the task, but with a different intent. We 3417 // should start a new instance on top. 3418 addingToTask = true; 3419 sourceRecord = taskTop; 3420 } 3421 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) { 3422 // In this case an activity is being launched in to an 3423 // existing task, without resetting that task. This 3424 // is typically the situation of launching an activity 3425 // from a notification or shortcut. We want to place 3426 // the new activity on top of the current task. 3427 addingToTask = true; 3428 sourceRecord = taskTop; 3429 } else if (!taskTop.task.rootWasReset) { 3430 // In this case we are launching in to an existing task 3431 // that has not yet been started from its front door. 3432 // The current task has been brought to the front. 3433 // Ideally, we'd probably like to place this new task 3434 // at the bottom of its stack, but that's a little hard 3435 // to do with the current organization of the code so 3436 // for now we'll just drop it. 3437 taskTop.task.setIntent(r.intent, r.info); 3438 } 3439 if (!addingToTask) { 3440 // We didn't do anything... but it was needed (a.k.a., client 3441 // don't use that intent!) And for paranoia, make 3442 // sure we have correctly resumed the top activity. 3443 if (doResume) { 3444 resumeTopActivityLocked(null); 3445 } 3446 return START_TASK_TO_FRONT; 3447 } 3448 } 3449 } 3450 } 3451 3452 //String uri = r.intent.toURI(); 3453 //Intent intent2 = new Intent(uri); 3454 //Log.i(TAG, "Given intent: " + r.intent); 3455 //Log.i(TAG, "URI is: " + uri); 3456 //Log.i(TAG, "To intent: " + intent2); 3457 3458 if (r.packageName != null) { 3459 // If the activity being launched is the same as the one currently 3460 // at the top, then we need to check if it should only be launched 3461 // once. 3462 HistoryRecord top = topRunningNonDelayedActivityLocked(notTop); 3463 if (top != null && r.resultTo == null) { 3464 if (top.realActivity.equals(r.realActivity)) { 3465 if (top.app != null && top.app.thread != null) { 3466 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 3467 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP 3468 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 3469 logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task); 3470 // For paranoia, make sure we have correctly 3471 // resumed the top activity. 3472 if (doResume) { 3473 resumeTopActivityLocked(null); 3474 } 3475 if (onlyIfNeeded) { 3476 // We don't need to start a new activity, and 3477 // the client said not to do anything if that 3478 // is the case, so this is it! 3479 return START_RETURN_INTENT_TO_CALLER; 3480 } 3481 deliverNewIntentLocked(top, r.intent); 3482 return START_DELIVERED_TO_TOP; 3483 } 3484 } 3485 } 3486 } 3487 3488 } else { 3489 if (r.resultTo != null) { 3490 sendActivityResultLocked(-1, 3491 r.resultTo, r.resultWho, r.requestCode, 3492 Activity.RESULT_CANCELED, null); 3493 } 3494 return START_CLASS_NOT_FOUND; 3495 } 3496 3497 boolean newTask = false; 3498 3499 // Should this be considered a new task? 3500 if (r.resultTo == null && !addingToTask 3501 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 3502 // todo: should do better management of integers. 3503 mCurTask++; 3504 if (mCurTask <= 0) { 3505 mCurTask = 1; 3506 } 3507 r.task = new TaskRecord(mCurTask, r.info, intent, 3508 (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0); 3509 if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r 3510 + " in new task " + r.task); 3511 newTask = true; 3512 addRecentTask(r.task); 3513 3514 } else if (sourceRecord != null) { 3515 if (!addingToTask && 3516 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 3517 // In this case, we are adding the activity to an existing 3518 // task, but the caller has asked to clear that task if the 3519 // activity is already running. 3520 HistoryRecord top = performClearTaskLocked( 3521 sourceRecord.task.taskId, r, launchFlags, true); 3522 if (top != null) { 3523 logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); 3524 deliverNewIntentLocked(top, r.intent); 3525 // For paranoia, make sure we have correctly 3526 // resumed the top activity. 3527 if (doResume) { 3528 resumeTopActivityLocked(null); 3529 } 3530 return START_DELIVERED_TO_TOP; 3531 } 3532 } else if (!addingToTask && 3533 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { 3534 // In this case, we are launching an activity in our own task 3535 // that may already be running somewhere in the history, and 3536 // we want to shuffle it to the front of the stack if so. 3537 int where = findActivityInHistoryLocked(r, sourceRecord.task.taskId); 3538 if (where >= 0) { 3539 HistoryRecord top = moveActivityToFrontLocked(where); 3540 logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); 3541 deliverNewIntentLocked(top, r.intent); 3542 if (doResume) { 3543 resumeTopActivityLocked(null); 3544 } 3545 return START_DELIVERED_TO_TOP; 3546 } 3547 } 3548 // An existing activity is starting this new activity, so we want 3549 // to keep the new one in the same task as the one that is starting 3550 // it. 3551 r.task = sourceRecord.task; 3552 if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r 3553 + " in existing task " + r.task); 3554 3555 } else { 3556 // This not being started from an existing activity, and not part 3557 // of a new task... just put it in the top task, though these days 3558 // this case should never happen. 3559 final int N = mHistory.size(); 3560 HistoryRecord prev = 3561 N > 0 ? (HistoryRecord)mHistory.get(N-1) : null; 3562 r.task = prev != null 3563 ? prev.task 3564 : new TaskRecord(mCurTask, r.info, intent, 3565 (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0); 3566 if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r 3567 + " in new guessed " + r.task); 3568 } 3569 if (newTask) { 3570 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.task.taskId); 3571 } 3572 logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task); 3573 startActivityLocked(r, newTask, doResume); 3574 return START_SUCCESS; 3575 } 3576 3577 public final int startActivity(IApplicationThread caller, 3578 Intent intent, String resolvedType, Uri[] grantedUriPermissions, 3579 int grantedMode, IBinder resultTo, 3580 String resultWho, int requestCode, boolean onlyIfNeeded, 3581 boolean debug) { 3582 // Refuse possible leaked file descriptors 3583 if (intent != null && intent.hasFileDescriptors()) { 3584 throw new IllegalArgumentException("File descriptors passed in Intent"); 3585 } 3586 3587 final boolean componentSpecified = intent.getComponent() != null; 3588 3589 // Don't modify the client's object! 3590 intent = new Intent(intent); 3591 3592 // Collect information about the target of the Intent. 3593 ActivityInfo aInfo; 3594 try { 3595 ResolveInfo rInfo = 3596 ActivityThread.getPackageManager().resolveIntent( 3597 intent, resolvedType, 3598 PackageManager.MATCH_DEFAULT_ONLY 3599 | STOCK_PM_FLAGS); 3600 aInfo = rInfo != null ? rInfo.activityInfo : null; 3601 } catch (RemoteException e) { 3602 aInfo = null; 3603 } 3604 3605 if (aInfo != null) { 3606 // Store the found target back into the intent, because now that 3607 // we have it we never want to do this again. For example, if the 3608 // user navigates back to this point in the history, we should 3609 // always restart the exact same activity. 3610 intent.setComponent(new ComponentName( 3611 aInfo.applicationInfo.packageName, aInfo.name)); 3612 3613 // Don't debug things in the system process 3614 if (debug) { 3615 if (!aInfo.processName.equals("system")) { 3616 setDebugApp(aInfo.processName, true, false); 3617 } 3618 } 3619 } 3620 3621 synchronized(this) { 3622 final long origId = Binder.clearCallingIdentity(); 3623 int res = startActivityLocked(caller, intent, resolvedType, 3624 grantedUriPermissions, grantedMode, aInfo, 3625 resultTo, resultWho, requestCode, -1, -1, 3626 onlyIfNeeded, componentSpecified); 3627 Binder.restoreCallingIdentity(origId); 3628 return res; 3629 } 3630 } 3631 3632 public int startActivityIntentSender(IApplicationThread caller, 3633 IntentSender intent, Intent fillInIntent, String resolvedType, 3634 IBinder resultTo, String resultWho, int requestCode, 3635 int flagsMask, int flagsValues) { 3636 // Refuse possible leaked file descriptors 3637 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3638 throw new IllegalArgumentException("File descriptors passed in Intent"); 3639 } 3640 3641 IIntentSender sender = intent.getTarget(); 3642 if (!(sender instanceof PendingIntentRecord)) { 3643 throw new IllegalArgumentException("Bad PendingIntent object"); 3644 } 3645 3646 PendingIntentRecord pir = (PendingIntentRecord)sender; 3647 3648 synchronized (this) { 3649 // If this is coming from the currently resumed activity, it is 3650 // effectively saying that app switches are allowed at this point. 3651 if (mResumedActivity != null 3652 && mResumedActivity.info.applicationInfo.uid == 3653 Binder.getCallingUid()) { 3654 mAppSwitchesAllowedTime = 0; 3655 } 3656 } 3657 3658 return pir.sendInner(0, fillInIntent, resolvedType, 3659 null, resultTo, resultWho, requestCode, flagsMask, flagsValues); 3660 } 3661 3662 public boolean startNextMatchingActivity(IBinder callingActivity, 3663 Intent intent) { 3664 // Refuse possible leaked file descriptors 3665 if (intent != null && intent.hasFileDescriptors() == true) { 3666 throw new IllegalArgumentException("File descriptors passed in Intent"); 3667 } 3668 3669 synchronized (this) { 3670 int index = indexOfTokenLocked(callingActivity); 3671 if (index < 0) { 3672 return false; 3673 } 3674 HistoryRecord r = (HistoryRecord)mHistory.get(index); 3675 if (r.app == null || r.app.thread == null) { 3676 // The caller is not running... d'oh! 3677 return false; 3678 } 3679 intent = new Intent(intent); 3680 // The caller is not allowed to change the data. 3681 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3682 // And we are resetting to find the next component... 3683 intent.setComponent(null); 3684 3685 ActivityInfo aInfo = null; 3686 try { 3687 List<ResolveInfo> resolves = 3688 ActivityThread.getPackageManager().queryIntentActivities( 3689 intent, r.resolvedType, 3690 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS); 3691 3692 // Look for the original activity in the list... 3693 final int N = resolves != null ? resolves.size() : 0; 3694 for (int i=0; i<N; i++) { 3695 ResolveInfo rInfo = resolves.get(i); 3696 if (rInfo.activityInfo.packageName.equals(r.packageName) 3697 && rInfo.activityInfo.name.equals(r.info.name)) { 3698 // We found the current one... the next matching is 3699 // after it. 3700 i++; 3701 if (i<N) { 3702 aInfo = resolves.get(i).activityInfo; 3703 } 3704 break; 3705 } 3706 } 3707 } catch (RemoteException e) { 3708 } 3709 3710 if (aInfo == null) { 3711 // Nobody who is next! 3712 return false; 3713 } 3714 3715 intent.setComponent(new ComponentName( 3716 aInfo.applicationInfo.packageName, aInfo.name)); 3717 intent.setFlags(intent.getFlags()&~( 3718 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3719 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3720 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3721 Intent.FLAG_ACTIVITY_NEW_TASK)); 3722 3723 // Okay now we need to start the new activity, replacing the 3724 // currently running activity. This is a little tricky because 3725 // we want to start the new one as if the current one is finished, 3726 // but not finish the current one first so that there is no flicker. 3727 // And thus... 3728 final boolean wasFinishing = r.finishing; 3729 r.finishing = true; 3730 3731 // Propagate reply information over to the new activity. 3732 final HistoryRecord resultTo = r.resultTo; 3733 final String resultWho = r.resultWho; 3734 final int requestCode = r.requestCode; 3735 r.resultTo = null; 3736 if (resultTo != null) { 3737 resultTo.removeResultsLocked(r, resultWho, requestCode); 3738 } 3739 3740 final long origId = Binder.clearCallingIdentity(); 3741 // XXX we are not dealing with propagating grantedUriPermissions... 3742 // those are not yet exposed to user code, so there is no need. 3743 int res = startActivityLocked(r.app.thread, intent, 3744 r.resolvedType, null, 0, aInfo, resultTo, resultWho, 3745 requestCode, -1, r.launchedFromUid, false, false); 3746 Binder.restoreCallingIdentity(origId); 3747 3748 r.finishing = wasFinishing; 3749 if (res != START_SUCCESS) { 3750 return false; 3751 } 3752 return true; 3753 } 3754 } 3755 3756 public final int startActivityInPackage(int uid, 3757 Intent intent, String resolvedType, IBinder resultTo, 3758 String resultWho, int requestCode, boolean onlyIfNeeded) { 3759 3760 // This is so super not safe, that only the system (or okay root) 3761 // can do it. 3762 final int callingUid = Binder.getCallingUid(); 3763 if (callingUid != 0 && callingUid != Process.myUid()) { 3764 throw new SecurityException( 3765 "startActivityInPackage only available to the system"); 3766 } 3767 3768 final boolean componentSpecified = intent.getComponent() != null; 3769 3770 // Don't modify the client's object! 3771 intent = new Intent(intent); 3772 3773 // Collect information about the target of the Intent. 3774 ActivityInfo aInfo; 3775 try { 3776 ResolveInfo rInfo = 3777 ActivityThread.getPackageManager().resolveIntent( 3778 intent, resolvedType, 3779 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS); 3780 aInfo = rInfo != null ? rInfo.activityInfo : null; 3781 } catch (RemoteException e) { 3782 aInfo = null; 3783 } 3784 3785 if (aInfo != null) { 3786 // Store the found target back into the intent, because now that 3787 // we have it we never want to do this again. For example, if the 3788 // user navigates back to this point in the history, we should 3789 // always restart the exact same activity. 3790 intent.setComponent(new ComponentName( 3791 aInfo.applicationInfo.packageName, aInfo.name)); 3792 } 3793 3794 synchronized(this) { 3795 return startActivityLocked(null, intent, resolvedType, 3796 null, 0, aInfo, resultTo, resultWho, requestCode, -1, uid, 3797 onlyIfNeeded, componentSpecified); 3798 } 3799 } 3800 3801 private final void addRecentTask(TaskRecord task) { 3802 // Remove any existing entries that are the same kind of task. 3803 int N = mRecentTasks.size(); 3804 for (int i=0; i<N; i++) { 3805 TaskRecord tr = mRecentTasks.get(i); 3806 if ((task.affinity != null && task.affinity.equals(tr.affinity)) 3807 || (task.intent != null && task.intent.filterEquals(tr.intent))) { 3808 mRecentTasks.remove(i); 3809 i--; 3810 N--; 3811 if (task.intent == null) { 3812 // If the new recent task we are adding is not fully 3813 // specified, then replace it with the existing recent task. 3814 task = tr; 3815 } 3816 } 3817 } 3818 if (N >= MAX_RECENT_TASKS) { 3819 mRecentTasks.remove(N-1); 3820 } 3821 mRecentTasks.add(0, task); 3822 } 3823 3824 public void setRequestedOrientation(IBinder token, 3825 int requestedOrientation) { 3826 synchronized (this) { 3827 int index = indexOfTokenLocked(token); 3828 if (index < 0) { 3829 return; 3830 } 3831 HistoryRecord r = (HistoryRecord)mHistory.get(index); 3832 final long origId = Binder.clearCallingIdentity(); 3833 mWindowManager.setAppOrientation(r, requestedOrientation); 3834 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3835 mConfiguration, 3836 r.mayFreezeScreenLocked(r.app) ? r : null); 3837 if (config != null) { 3838 r.frozenBeforeDestroy = true; 3839 if (!updateConfigurationLocked(config, r)) { 3840 resumeTopActivityLocked(null); 3841 } 3842 } 3843 Binder.restoreCallingIdentity(origId); 3844 } 3845 } 3846 3847 public int getRequestedOrientation(IBinder token) { 3848 synchronized (this) { 3849 int index = indexOfTokenLocked(token); 3850 if (index < 0) { 3851 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3852 } 3853 HistoryRecord r = (HistoryRecord)mHistory.get(index); 3854 return mWindowManager.getAppOrientation(r); 3855 } 3856 } 3857 3858 private final void stopActivityLocked(HistoryRecord r) { 3859 if (DEBUG_SWITCH) Log.d(TAG, "Stopping: " + r); 3860 if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0 3861 || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) { 3862 if (!r.finishing) { 3863 requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null, 3864 "no-history"); 3865 } 3866 } else if (r.app != null && r.app.thread != null) { 3867 if (mFocusedActivity == r) { 3868 setFocusedActivityLocked(topRunningActivityLocked(null)); 3869 } 3870 r.resumeKeyDispatchingLocked(); 3871 try { 3872 r.stopped = false; 3873 r.state = ActivityState.STOPPING; 3874 if (DEBUG_VISBILITY) Log.v( 3875 TAG, "Stopping visible=" + r.visible + " for " + r); 3876 if (!r.visible) { 3877 mWindowManager.setAppVisibility(r, false); 3878 } 3879 r.app.thread.scheduleStopActivity(r, r.visible, r.configChangeFlags); 3880 } catch (Exception e) { 3881 // Maybe just ignore exceptions here... if the process 3882 // has crashed, our death notification will clean things 3883 // up. 3884 Log.w(TAG, "Exception thrown during pause", e); 3885 // Just in case, assume it to be stopped. 3886 r.stopped = true; 3887 r.state = ActivityState.STOPPED; 3888 if (r.configDestroy) { 3889 destroyActivityLocked(r, true); 3890 } 3891 } 3892 } 3893 } 3894 3895 /** 3896 * @return Returns true if the activity is being finished, false if for 3897 * some reason it is being left as-is. 3898 */ 3899 private final boolean requestFinishActivityLocked(IBinder token, int resultCode, 3900 Intent resultData, String reason) { 3901 if (DEBUG_RESULTS) Log.v( 3902 TAG, "Finishing activity: token=" + token 3903 + ", result=" + resultCode + ", data=" + resultData); 3904 3905 int index = indexOfTokenLocked(token); 3906 if (index < 0) { 3907 return false; 3908 } 3909 HistoryRecord r = (HistoryRecord)mHistory.get(index); 3910 3911 // Is this the last activity left? 3912 boolean lastActivity = true; 3913 for (int i=mHistory.size()-1; i>=0; i--) { 3914 HistoryRecord p = (HistoryRecord)mHistory.get(i); 3915 if (!p.finishing && p != r) { 3916 lastActivity = false; 3917 break; 3918 } 3919 } 3920 3921 // If this is the last activity, but it is the home activity, then 3922 // just don't finish it. 3923 if (lastActivity) { 3924 if (r.intent.hasCategory(Intent.CATEGORY_HOME)) { 3925 return false; 3926 } 3927 } 3928 3929 finishActivityLocked(r, index, resultCode, resultData, reason); 3930 return true; 3931 } 3932 3933 /** 3934 * @return Returns true if this activity has been removed from the history 3935 * list, or false if it is still in the list and will be removed later. 3936 */ 3937 private final boolean finishActivityLocked(HistoryRecord r, int index, 3938 int resultCode, Intent resultData, String reason) { 3939 if (r.finishing) { 3940 Log.w(TAG, "Duplicate finish request for " + r); 3941 return false; 3942 } 3943 3944 r.finishing = true; 3945 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 3946 System.identityHashCode(r), 3947 r.task.taskId, r.shortComponentName, reason); 3948 r.task.numActivities--; 3949 if (r.frontOfTask && index < (mHistory.size()-1)) { 3950 HistoryRecord next = (HistoryRecord)mHistory.get(index+1); 3951 if (next.task == r.task) { 3952 next.frontOfTask = true; 3953 } 3954 } 3955 3956 r.pauseKeyDispatchingLocked(); 3957 if (mFocusedActivity == r) { 3958 setFocusedActivityLocked(topRunningActivityLocked(null)); 3959 } 3960 3961 // send the result 3962 HistoryRecord resultTo = r.resultTo; 3963 if (resultTo != null) { 3964 if (DEBUG_RESULTS) Log.v(TAG, "Adding result to " + resultTo 3965 + " who=" + r.resultWho + " req=" + r.requestCode 3966 + " res=" + resultCode + " data=" + resultData); 3967 if (r.info.applicationInfo.uid > 0) { 3968 grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid, 3969 r.packageName, resultData, r); 3970 } 3971 resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode, 3972 resultData); 3973 r.resultTo = null; 3974 } 3975 else if (DEBUG_RESULTS) Log.v(TAG, "No result destination from " + r); 3976 3977 // Make sure this HistoryRecord is not holding on to other resources, 3978 // because clients have remote IPC references to this object so we 3979 // can't assume that will go away and want to avoid circular IPC refs. 3980 r.results = null; 3981 r.pendingResults = null; 3982 r.newIntents = null; 3983 r.icicle = null; 3984 3985 if (mPendingThumbnails.size() > 0) { 3986 // There are clients waiting to receive thumbnails so, in case 3987 // this is an activity that someone is waiting for, add it 3988 // to the pending list so we can correctly update the clients. 3989 mCancelledThumbnails.add(r); 3990 } 3991 3992 if (mResumedActivity == r) { 3993 boolean endTask = index <= 0 3994 || ((HistoryRecord)mHistory.get(index-1)).task != r.task; 3995 if (DEBUG_TRANSITION) Log.v(TAG, 3996 "Prepare close transition: finishing " + r); 3997 mWindowManager.prepareAppTransition(endTask 3998 ? WindowManagerPolicy.TRANSIT_TASK_CLOSE 3999 : WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE); 4000 4001 // Tell window manager to prepare for this one to be removed. 4002 mWindowManager.setAppVisibility(r, false); 4003 4004 if (mPausingActivity == null) { 4005 if (DEBUG_PAUSE) Log.v(TAG, "Finish needs to pause: " + r); 4006 if (DEBUG_USER_LEAVING) Log.v(TAG, "finish() => pause with userLeaving=false"); 4007 startPausingLocked(false, false); 4008 } 4009 4010 } else if (r.state != ActivityState.PAUSING) { 4011 // If the activity is PAUSING, we will complete the finish once 4012 // it is done pausing; else we can just directly finish it here. 4013 if (DEBUG_PAUSE) Log.v(TAG, "Finish not pausing: " + r); 4014 return finishCurrentActivityLocked(r, index, 4015 FINISH_AFTER_PAUSE) == null; 4016 } else { 4017 if (DEBUG_PAUSE) Log.v(TAG, "Finish waiting for pause of: " + r); 4018 } 4019 4020 return false; 4021 } 4022 4023 private static final int FINISH_IMMEDIATELY = 0; 4024 private static final int FINISH_AFTER_PAUSE = 1; 4025 private static final int FINISH_AFTER_VISIBLE = 2; 4026 4027 private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r, 4028 int mode) { 4029 final int index = indexOfTokenLocked(r); 4030 if (index < 0) { 4031 return null; 4032 } 4033 4034 return finishCurrentActivityLocked(r, index, mode); 4035 } 4036 4037 private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r, 4038 int index, int mode) { 4039 // First things first: if this activity is currently visible, 4040 // and the resumed activity is not yet visible, then hold off on 4041 // finishing until the resumed one becomes visible. 4042 if (mode == FINISH_AFTER_VISIBLE && r.nowVisible) { 4043 if (!mStoppingActivities.contains(r)) { 4044 mStoppingActivities.add(r); 4045 if (mStoppingActivities.size() > 3) { 4046 // If we already have a few activities waiting to stop, 4047 // then give up on things going idle and start clearing 4048 // them out. 4049 Message msg = Message.obtain(); 4050 msg.what = ActivityManagerService.IDLE_NOW_MSG; 4051 mHandler.sendMessage(msg); 4052 } 4053 } 4054 r.state = ActivityState.STOPPING; 4055 updateOomAdjLocked(); 4056 return r; 4057 } 4058 4059 // make sure the record is cleaned out of other places. 4060 mStoppingActivities.remove(r); 4061 mWaitingVisibleActivities.remove(r); 4062 if (mResumedActivity == r) { 4063 mResumedActivity = null; 4064 } 4065 final ActivityState prevState = r.state; 4066 r.state = ActivityState.FINISHING; 4067 4068 if (mode == FINISH_IMMEDIATELY 4069 || prevState == ActivityState.STOPPED 4070 || prevState == ActivityState.INITIALIZING) { 4071 // If this activity is already stopped, we can just finish 4072 // it right now. 4073 return destroyActivityLocked(r, true) ? null : r; 4074 } else { 4075 // Need to go through the full pause cycle to get this 4076 // activity into the stopped state and then finish it. 4077 if (localLOGV) Log.v(TAG, "Enqueueing pending finish: " + r); 4078 mFinishingActivities.add(r); 4079 resumeTopActivityLocked(null); 4080 } 4081 return r; 4082 } 4083 4084 /** 4085 * This is the internal entry point for handling Activity.finish(). 4086 * 4087 * @param token The Binder token referencing the Activity we want to finish. 4088 * @param resultCode Result code, if any, from this Activity. 4089 * @param resultData Result data (Intent), if any, from this Activity. 4090 * 4091 * @return Returns true if the activity successfully finished, or false if it is still running. 4092 */ 4093 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 4094 // Refuse possible leaked file descriptors 4095 if (resultData != null && resultData.hasFileDescriptors() == true) { 4096 throw new IllegalArgumentException("File descriptors passed in Intent"); 4097 } 4098 4099 synchronized(this) { 4100 if (mController != null) { 4101 // Find the first activity that is not finishing. 4102 HistoryRecord next = topRunningActivityLocked(token, 0); 4103 if (next != null) { 4104 // ask watcher if this is allowed 4105 boolean resumeOK = true; 4106 try { 4107 resumeOK = mController.activityResuming(next.packageName); 4108 } catch (RemoteException e) { 4109 mController = null; 4110 } 4111 4112 if (!resumeOK) { 4113 return false; 4114 } 4115 } 4116 } 4117 final long origId = Binder.clearCallingIdentity(); 4118 boolean res = requestFinishActivityLocked(token, resultCode, 4119 resultData, "app-request"); 4120 Binder.restoreCallingIdentity(origId); 4121 return res; 4122 } 4123 } 4124 4125 void sendActivityResultLocked(int callingUid, HistoryRecord r, 4126 String resultWho, int requestCode, int resultCode, Intent data) { 4127 4128 if (callingUid > 0) { 4129 grantUriPermissionFromIntentLocked(callingUid, r.packageName, 4130 data, r); 4131 } 4132 4133 if (DEBUG_RESULTS) Log.v(TAG, "Send activity result to " + r 4134 + " : who=" + resultWho + " req=" + requestCode 4135 + " res=" + resultCode + " data=" + data); 4136 if (mResumedActivity == r && r.app != null && r.app.thread != null) { 4137 try { 4138 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>(); 4139 list.add(new ResultInfo(resultWho, requestCode, 4140 resultCode, data)); 4141 r.app.thread.scheduleSendResult(r, list); 4142 return; 4143 } catch (Exception e) { 4144 Log.w(TAG, "Exception thrown sending result to " + r, e); 4145 } 4146 } 4147 4148 r.addResultLocked(null, resultWho, requestCode, resultCode, data); 4149 } 4150 4151 public final void finishSubActivity(IBinder token, String resultWho, 4152 int requestCode) { 4153 synchronized(this) { 4154 int index = indexOfTokenLocked(token); 4155 if (index < 0) { 4156 return; 4157 } 4158 HistoryRecord self = (HistoryRecord)mHistory.get(index); 4159 4160 final long origId = Binder.clearCallingIdentity(); 4161 4162 int i; 4163 for (i=mHistory.size()-1; i>=0; i--) { 4164 HistoryRecord r = (HistoryRecord)mHistory.get(i); 4165 if (r.resultTo == self && r.requestCode == requestCode) { 4166 if ((r.resultWho == null && resultWho == null) || 4167 (r.resultWho != null && r.resultWho.equals(resultWho))) { 4168 finishActivityLocked(r, i, 4169 Activity.RESULT_CANCELED, null, "request-sub"); 4170 } 4171 } 4172 } 4173 4174 Binder.restoreCallingIdentity(origId); 4175 } 4176 } 4177 4178 public void overridePendingTransition(IBinder token, String packageName, 4179 int enterAnim, int exitAnim) { 4180 synchronized(this) { 4181 int index = indexOfTokenLocked(token); 4182 if (index < 0) { 4183 return; 4184 } 4185 HistoryRecord self = (HistoryRecord)mHistory.get(index); 4186 4187 final long origId = Binder.clearCallingIdentity(); 4188 4189 if (self.state == ActivityState.RESUMED 4190 || self.state == ActivityState.PAUSING) { 4191 mWindowManager.overridePendingAppTransition(packageName, 4192 enterAnim, exitAnim); 4193 } 4194 4195 Binder.restoreCallingIdentity(origId); 4196 } 4197 } 4198 4199 /** 4200 * Perform clean-up of service connections in an activity record. 4201 */ 4202 private final void cleanUpActivityServicesLocked(HistoryRecord r) { 4203 // Throw away any services that have been bound by this activity. 4204 if (r.connections != null) { 4205 Iterator<ConnectionRecord> it = r.connections.iterator(); 4206 while (it.hasNext()) { 4207 ConnectionRecord c = it.next(); 4208 removeConnectionLocked(c, null, r); 4209 } 4210 r.connections = null; 4211 } 4212 } 4213 4214 /** 4215 * Perform the common clean-up of an activity record. This is called both 4216 * as part of destroyActivityLocked() (when destroying the client-side 4217 * representation) and cleaning things up as a result of its hosting 4218 * processing going away, in which case there is no remaining client-side 4219 * state to destroy so only the cleanup here is needed. 4220 */ 4221 private final void cleanUpActivityLocked(HistoryRecord r, boolean cleanServices) { 4222 if (mResumedActivity == r) { 4223 mResumedActivity = null; 4224 } 4225 if (mFocusedActivity == r) { 4226 mFocusedActivity = null; 4227 } 4228 4229 r.configDestroy = false; 4230 r.frozenBeforeDestroy = false; 4231 4232 // Make sure this record is no longer in the pending finishes list. 4233 // This could happen, for example, if we are trimming activities 4234 // down to the max limit while they are still waiting to finish. 4235 mFinishingActivities.remove(r); 4236 mWaitingVisibleActivities.remove(r); 4237 4238 // Remove any pending results. 4239 if (r.finishing && r.pendingResults != null) { 4240 for (WeakReference<PendingIntentRecord> apr : r.pendingResults) { 4241 PendingIntentRecord rec = apr.get(); 4242 if (rec != null) { 4243 cancelIntentSenderLocked(rec, false); 4244 } 4245 } 4246 r.pendingResults = null; 4247 } 4248 4249 if (cleanServices) { 4250 cleanUpActivityServicesLocked(r); 4251 } 4252 4253 if (mPendingThumbnails.size() > 0) { 4254 // There are clients waiting to receive thumbnails so, in case 4255 // this is an activity that someone is waiting for, add it 4256 // to the pending list so we can correctly update the clients. 4257 mCancelledThumbnails.add(r); 4258 } 4259 4260 // Get rid of any pending idle timeouts. 4261 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); 4262 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 4263 } 4264 4265 private final void removeActivityFromHistoryLocked(HistoryRecord r) { 4266 if (r.state != ActivityState.DESTROYED) { 4267 mHistory.remove(r); 4268 r.inHistory = false; 4269 r.state = ActivityState.DESTROYED; 4270 mWindowManager.removeAppToken(r); 4271 if (VALIDATE_TOKENS) { 4272 mWindowManager.validateAppTokens(mHistory); 4273 } 4274 cleanUpActivityServicesLocked(r); 4275 removeActivityUriPermissionsLocked(r); 4276 } 4277 } 4278 4279 /** 4280 * Destroy the current CLIENT SIDE instance of an activity. This may be 4281 * called both when actually finishing an activity, or when performing 4282 * a configuration switch where we destroy the current client-side object 4283 * but then create a new client-side object for this same HistoryRecord. 4284 */ 4285 private final boolean destroyActivityLocked(HistoryRecord r, 4286 boolean removeFromApp) { 4287 if (DEBUG_SWITCH) Log.v( 4288 TAG, "Removing activity: token=" + r 4289 + ", app=" + (r.app != null ? r.app.processName : "(null)")); 4290 EventLog.writeEvent(EventLogTags.AM_DESTROY_ACTIVITY, 4291 System.identityHashCode(r), 4292 r.task.taskId, r.shortComponentName); 4293 4294 boolean removedFromHistory = false; 4295 4296 cleanUpActivityLocked(r, false); 4297 4298 final boolean hadApp = r.app != null; 4299 4300 if (hadApp) { 4301 if (removeFromApp) { 4302 int idx = r.app.activities.indexOf(r); 4303 if (idx >= 0) { 4304 r.app.activities.remove(idx); 4305 } 4306 if (r.persistent) { 4307 decPersistentCountLocked(r.app); 4308 } 4309 if (r.app.activities.size() == 0) { 4310 // No longer have activities, so update location in 4311 // LRU list. 4312 updateLruProcessLocked(r.app, true, false); 4313 } 4314 } 4315 4316 boolean skipDestroy = false; 4317 4318 try { 4319 if (DEBUG_SWITCH) Log.i(TAG, "Destroying: " + r); 4320 r.app.thread.scheduleDestroyActivity(r, r.finishing, 4321 r.configChangeFlags); 4322 } catch (Exception e) { 4323 // We can just ignore exceptions here... if the process 4324 // has crashed, our death notification will clean things 4325 // up. 4326 //Log.w(TAG, "Exception thrown during finish", e); 4327 if (r.finishing) { 4328 removeActivityFromHistoryLocked(r); 4329 removedFromHistory = true; 4330 skipDestroy = true; 4331 } 4332 } 4333 4334 r.app = null; 4335 r.nowVisible = false; 4336 4337 if (r.finishing && !skipDestroy) { 4338 r.state = ActivityState.DESTROYING; 4339 Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG); 4340 msg.obj = r; 4341 mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT); 4342 } else { 4343 r.state = ActivityState.DESTROYED; 4344 } 4345 } else { 4346 // remove this record from the history. 4347 if (r.finishing) { 4348 removeActivityFromHistoryLocked(r); 4349 removedFromHistory = true; 4350 } else { 4351 r.state = ActivityState.DESTROYED; 4352 } 4353 } 4354 4355 r.configChangeFlags = 0; 4356 4357 if (!mLRUActivities.remove(r) && hadApp) { 4358 Log.w(TAG, "Activity " + r + " being finished, but not in LRU list"); 4359 } 4360 4361 return removedFromHistory; 4362 } 4363 4364 private static void removeHistoryRecordsForAppLocked(ArrayList list, ProcessRecord app) { 4365 int i = list.size(); 4366 if (localLOGV) Log.v( 4367 TAG, "Removing app " + app + " from list " + list 4368 + " with " + i + " entries"); 4369 while (i > 0) { 4370 i--; 4371 HistoryRecord r = (HistoryRecord)list.get(i); 4372 if (localLOGV) Log.v( 4373 TAG, "Record #" + i + " " + r + ": app=" + r.app); 4374 if (r.app == app) { 4375 if (localLOGV) Log.v(TAG, "Removing this entry!"); 4376 list.remove(i); 4377 } 4378 } 4379 } 4380 4381 /** 4382 * Main function for removing an existing process from the activity manager 4383 * as a result of that process going away. Clears out all connections 4384 * to the process. 4385 */ 4386 private final void handleAppDiedLocked(ProcessRecord app, 4387 boolean restarting) { 4388 cleanUpApplicationRecordLocked(app, restarting, -1); 4389 if (!restarting) { 4390 mLruProcesses.remove(app); 4391 } 4392 4393 // Just in case... 4394 if (mPausingActivity != null && mPausingActivity.app == app) { 4395 if (DEBUG_PAUSE) Log.v(TAG, "App died while pausing: " + mPausingActivity); 4396 mPausingActivity = null; 4397 } 4398 if (mLastPausedActivity != null && mLastPausedActivity.app == app) { 4399 mLastPausedActivity = null; 4400 } 4401 4402 // Remove this application's activities from active lists. 4403 removeHistoryRecordsForAppLocked(mLRUActivities, app); 4404 removeHistoryRecordsForAppLocked(mStoppingActivities, app); 4405 removeHistoryRecordsForAppLocked(mWaitingVisibleActivities, app); 4406 removeHistoryRecordsForAppLocked(mFinishingActivities, app); 4407 4408 boolean atTop = true; 4409 boolean hasVisibleActivities = false; 4410 4411 // Clean out the history list. 4412 int i = mHistory.size(); 4413 if (localLOGV) Log.v( 4414 TAG, "Removing app " + app + " from history with " + i + " entries"); 4415 while (i > 0) { 4416 i--; 4417 HistoryRecord r = (HistoryRecord)mHistory.get(i); 4418 if (localLOGV) Log.v( 4419 TAG, "Record #" + i + " " + r + ": app=" + r.app); 4420 if (r.app == app) { 4421 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 4422 if (localLOGV) Log.v( 4423 TAG, "Removing this entry! frozen=" + r.haveState 4424 + " finishing=" + r.finishing); 4425 mHistory.remove(i); 4426 4427 r.inHistory = false; 4428 mWindowManager.removeAppToken(r); 4429 if (VALIDATE_TOKENS) { 4430 mWindowManager.validateAppTokens(mHistory); 4431 } 4432 removeActivityUriPermissionsLocked(r); 4433 4434 } else { 4435 // We have the current state for this activity, so 4436 // it can be restarted later when needed. 4437 if (localLOGV) Log.v( 4438 TAG, "Keeping entry, setting app to null"); 4439 if (r.visible) { 4440 hasVisibleActivities = true; 4441 } 4442 r.app = null; 4443 r.nowVisible = false; 4444 if (!r.haveState) { 4445 r.icicle = null; 4446 } 4447 } 4448 4449 cleanUpActivityLocked(r, true); 4450 r.state = ActivityState.STOPPED; 4451 } 4452 atTop = false; 4453 } 4454 4455 app.activities.clear(); 4456 4457 if (app.instrumentationClass != null) { 4458 Log.w(TAG, "Crash of app " + app.processName 4459 + " running instrumentation " + app.instrumentationClass); 4460 Bundle info = new Bundle(); 4461 info.putString("shortMsg", "Process crashed."); 4462 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4463 } 4464 4465 if (!restarting) { 4466 if (!resumeTopActivityLocked(null)) { 4467 // If there was nothing to resume, and we are not already 4468 // restarting this process, but there is a visible activity that 4469 // is hosted by the process... then make sure all visible 4470 // activities are running, taking care of restarting this 4471 // process. 4472 if (hasVisibleActivities) { 4473 ensureActivitiesVisibleLocked(null, 0); 4474 } 4475 } 4476 } 4477 } 4478 4479 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4480 IBinder threadBinder = thread.asBinder(); 4481 4482 // Find the application record. 4483 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4484 ProcessRecord rec = mLruProcesses.get(i); 4485 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4486 return i; 4487 } 4488 } 4489 return -1; 4490 } 4491 4492 private final ProcessRecord getRecordForAppLocked( 4493 IApplicationThread thread) { 4494 if (thread == null) { 4495 return null; 4496 } 4497 4498 int appIndex = getLRURecordIndexForAppLocked(thread); 4499 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4500 } 4501 4502 private final void appDiedLocked(ProcessRecord app, int pid, 4503 IApplicationThread thread) { 4504 4505 mProcDeaths[0]++; 4506 4507 if (app.thread != null && app.thread.asBinder() == thread.asBinder()) { 4508 Log.i(TAG, "Process " + app.processName + " (pid " + pid 4509 + ") has died."); 4510 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 4511 if (localLOGV) Log.v( 4512 TAG, "Dying app: " + app + ", pid: " + pid 4513 + ", thread: " + thread.asBinder()); 4514 boolean doLowMem = app.instrumentationClass == null; 4515 handleAppDiedLocked(app, false); 4516 4517 if (doLowMem) { 4518 // If there are no longer any background processes running, 4519 // and the app that died was not running instrumentation, 4520 // then tell everyone we are now low on memory. 4521 boolean haveBg = false; 4522 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4523 ProcessRecord rec = mLruProcesses.get(i); 4524 if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) { 4525 haveBg = true; 4526 break; 4527 } 4528 } 4529 4530 if (!haveBg) { 4531 Log.i(TAG, "Low Memory: No more background processes."); 4532 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4533 long now = SystemClock.uptimeMillis(); 4534 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4535 ProcessRecord rec = mLruProcesses.get(i); 4536 if (rec != app && rec.thread != null && 4537 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4538 // The low memory report is overriding any current 4539 // state for a GC request. Make sure to do 4540 // visible/foreground processes first. 4541 if (rec.setAdj <= VISIBLE_APP_ADJ) { 4542 rec.lastRequestedGc = 0; 4543 } else { 4544 rec.lastRequestedGc = rec.lastLowMemory; 4545 } 4546 rec.reportLowMemory = true; 4547 rec.lastLowMemory = now; 4548 mProcessesToGc.remove(rec); 4549 addProcessToGcListLocked(rec); 4550 } 4551 } 4552 scheduleAppGcsLocked(); 4553 } 4554 } 4555 } else if (DEBUG_PROCESSES) { 4556 Log.d(TAG, "Received spurious death notification for thread " 4557 + thread.asBinder()); 4558 } 4559 } 4560 4561 /** 4562 * If a stack trace dump file is configured, dump process stack traces. 4563 * @param pids of dalvik VM processes to dump stack traces for 4564 * @return file containing stack traces, or null if no dump file is configured 4565 */ 4566 private static File dumpStackTraces(ArrayList<Integer> pids) { 4567 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4568 if (tracesPath == null || tracesPath.length() == 0) { 4569 return null; 4570 } 4571 4572 File tracesFile = new File(tracesPath); 4573 try { 4574 File tracesDir = tracesFile.getParentFile(); 4575 if (!tracesDir.exists()) tracesFile.mkdirs(); 4576 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4577 4578 if (tracesFile.exists()) tracesFile.delete(); 4579 tracesFile.createNewFile(); 4580 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4581 } catch (IOException e) { 4582 Log.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4583 return null; 4584 } 4585 4586 // Use a FileObserver to detect when traces finish writing. 4587 // The order of traces is considered important to maintain for legibility. 4588 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4589 public synchronized void onEvent(int event, String path) { notify(); } 4590 }; 4591 4592 try { 4593 observer.startWatching(); 4594 int num = pids.size(); 4595 for (int i = 0; i < num; i++) { 4596 synchronized (observer) { 4597 Process.sendSignal(pids.get(i), Process.SIGNAL_QUIT); 4598 observer.wait(200); // Wait for write-close, give up after 200msec 4599 } 4600 } 4601 } catch (InterruptedException e) { 4602 Log.wtf(TAG, e); 4603 } finally { 4604 observer.stopWatching(); 4605 } 4606 4607 return tracesFile; 4608 } 4609 4610 final void appNotRespondingLocked(ProcessRecord app, HistoryRecord activity, 4611 HistoryRecord parent, final String annotation) { 4612 if (app.notResponding || app.crashing) { 4613 return; 4614 } 4615 4616 // Log the ANR to the event log. 4617 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 4618 annotation); 4619 4620 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4621 ArrayList<Integer> pids = new ArrayList<Integer>(20); 4622 pids.add(app.pid); 4623 4624 int parentPid = app.pid; 4625 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4626 if (parentPid != app.pid) pids.add(parentPid); 4627 4628 if (MY_PID != app.pid && MY_PID != parentPid) pids.add(MY_PID); 4629 4630 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4631 ProcessRecord r = mLruProcesses.get(i); 4632 if (r != null && r.thread != null) { 4633 int pid = r.pid; 4634 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) pids.add(pid); 4635 } 4636 } 4637 4638 File tracesFile = dumpStackTraces(pids); 4639 4640 // Log the ANR to the main log. 4641 StringBuilder info = mStringBuilder; 4642 info.setLength(0); 4643 info.append("ANR in ").append(app.processName); 4644 if (activity != null && activity.shortComponentName != null) { 4645 info.append(" (").append(activity.shortComponentName).append(")"); 4646 } 4647 if (annotation != null) { 4648 info.append("\nReason: ").append(annotation).append("\n"); 4649 } 4650 if (parent != null && parent != activity) { 4651 info.append("\nParent: ").append(parent.shortComponentName); 4652 } 4653 4654 String cpuInfo = null; 4655 if (MONITOR_CPU_USAGE) { 4656 updateCpuStatsNow(); 4657 synchronized (mProcessStatsThread) { cpuInfo = mProcessStats.printCurrentState(); } 4658 info.append(cpuInfo); 4659 } 4660 4661 Log.e(TAG, info.toString()); 4662 if (tracesFile == null) { 4663 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4664 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4665 } 4666 4667 addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null); 4668 4669 if (mController != null) { 4670 try { 4671 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4672 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4673 if (res != 0) { 4674 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4675 return; 4676 } 4677 } catch (RemoteException e) { 4678 mController = null; 4679 } 4680 } 4681 4682 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4683 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4684 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4685 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4686 Process.killProcess(app.pid); 4687 return; 4688 } 4689 4690 // Set the app's notResponding state, and look up the errorReportReceiver 4691 makeAppNotRespondingLocked(app, 4692 activity != null ? activity.shortComponentName : null, 4693 annotation != null ? "ANR " + annotation : "ANR", 4694 info.toString()); 4695 4696 // Bring up the infamous App Not Responding dialog 4697 Message msg = Message.obtain(); 4698 HashMap map = new HashMap(); 4699 msg.what = SHOW_NOT_RESPONDING_MSG; 4700 msg.obj = map; 4701 map.put("app", app); 4702 if (activity != null) { 4703 map.put("activity", activity); 4704 } 4705 4706 mHandler.sendMessage(msg); 4707 return; 4708 } 4709 4710 private final void decPersistentCountLocked(ProcessRecord app) 4711 { 4712 app.persistentActivities--; 4713 if (app.persistentActivities > 0) { 4714 // Still more of 'em... 4715 return; 4716 } 4717 if (app.persistent) { 4718 // Ah, but the application itself is persistent. Whatever! 4719 return; 4720 } 4721 4722 // App is no longer persistent... make sure it and the ones 4723 // following it in the LRU list have the correc oom_adj. 4724 updateOomAdjLocked(); 4725 } 4726 4727 public void setPersistent(IBinder token, boolean isPersistent) { 4728 if (checkCallingPermission(android.Manifest.permission.PERSISTENT_ACTIVITY) 4729 != PackageManager.PERMISSION_GRANTED) { 4730 String msg = "Permission Denial: setPersistent() from pid=" 4731 + Binder.getCallingPid() 4732 + ", uid=" + Binder.getCallingUid() 4733 + " requires " + android.Manifest.permission.PERSISTENT_ACTIVITY; 4734 Log.w(TAG, msg); 4735 throw new SecurityException(msg); 4736 } 4737 4738 synchronized(this) { 4739 int index = indexOfTokenLocked(token); 4740 if (index < 0) { 4741 return; 4742 } 4743 HistoryRecord r = (HistoryRecord)mHistory.get(index); 4744 ProcessRecord app = r.app; 4745 4746 if (localLOGV) Log.v( 4747 TAG, "Setting persistence " + isPersistent + ": " + r); 4748 4749 if (isPersistent) { 4750 if (r.persistent) { 4751 // Okay okay, I heard you already! 4752 if (localLOGV) Log.v(TAG, "Already persistent!"); 4753 return; 4754 } 4755 r.persistent = true; 4756 app.persistentActivities++; 4757 if (localLOGV) Log.v(TAG, "Num persistent now: " + app.persistentActivities); 4758 if (app.persistentActivities > 1) { 4759 // We aren't the first... 4760 if (localLOGV) Log.v(TAG, "Not the first!"); 4761 return; 4762 } 4763 if (app.persistent) { 4764 // This would be redundant. 4765 if (localLOGV) Log.v(TAG, "App is persistent!"); 4766 return; 4767 } 4768 4769 // App is now persistent... make sure it and the ones 4770 // following it now have the correct oom_adj. 4771 final long origId = Binder.clearCallingIdentity(); 4772 updateOomAdjLocked(); 4773 Binder.restoreCallingIdentity(origId); 4774 4775 } else { 4776 if (!r.persistent) { 4777 // Okay okay, I heard you already! 4778 return; 4779 } 4780 r.persistent = false; 4781 final long origId = Binder.clearCallingIdentity(); 4782 decPersistentCountLocked(app); 4783 Binder.restoreCallingIdentity(origId); 4784 4785 } 4786 } 4787 } 4788 4789 public boolean clearApplicationUserData(final String packageName, 4790 final IPackageDataObserver observer) { 4791 int uid = Binder.getCallingUid(); 4792 int pid = Binder.getCallingPid(); 4793 long callingId = Binder.clearCallingIdentity(); 4794 try { 4795 IPackageManager pm = ActivityThread.getPackageManager(); 4796 int pkgUid = -1; 4797 synchronized(this) { 4798 try { 4799 pkgUid = pm.getPackageUid(packageName); 4800 } catch (RemoteException e) { 4801 } 4802 if (pkgUid == -1) { 4803 Log.w(TAG, "Invalid packageName:" + packageName); 4804 return false; 4805 } 4806 if (uid == pkgUid || checkComponentPermission( 4807 android.Manifest.permission.CLEAR_APP_USER_DATA, 4808 pid, uid, -1) 4809 == PackageManager.PERMISSION_GRANTED) { 4810 forceStopPackageLocked(packageName, pkgUid); 4811 } else { 4812 throw new SecurityException(pid+" does not have permission:"+ 4813 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 4814 "for process:"+packageName); 4815 } 4816 } 4817 4818 try { 4819 //clear application user data 4820 pm.clearApplicationUserData(packageName, observer); 4821 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4822 Uri.fromParts("package", packageName, null)); 4823 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4824 broadcastIntentLocked(null, null, intent, 4825 null, null, 0, null, null, null, 4826 false, false, MY_PID, Process.SYSTEM_UID); 4827 } catch (RemoteException e) { 4828 } 4829 } finally { 4830 Binder.restoreCallingIdentity(callingId); 4831 } 4832 return true; 4833 } 4834 4835 public void killBackgroundProcesses(final String packageName) { 4836 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4837 != PackageManager.PERMISSION_GRANTED && 4838 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4839 != PackageManager.PERMISSION_GRANTED) { 4840 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4841 + Binder.getCallingPid() 4842 + ", uid=" + Binder.getCallingUid() 4843 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4844 Log.w(TAG, msg); 4845 throw new SecurityException(msg); 4846 } 4847 4848 long callingId = Binder.clearCallingIdentity(); 4849 try { 4850 IPackageManager pm = ActivityThread.getPackageManager(); 4851 int pkgUid = -1; 4852 synchronized(this) { 4853 try { 4854 pkgUid = pm.getPackageUid(packageName); 4855 } catch (RemoteException e) { 4856 } 4857 if (pkgUid == -1) { 4858 Log.w(TAG, "Invalid packageName: " + packageName); 4859 return; 4860 } 4861 killPackageProcessesLocked(packageName, pkgUid, 4862 SECONDARY_SERVER_ADJ, false); 4863 } 4864 } finally { 4865 Binder.restoreCallingIdentity(callingId); 4866 } 4867 } 4868 4869 public void forceStopPackage(final String packageName) { 4870 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4871 != PackageManager.PERMISSION_GRANTED) { 4872 String msg = "Permission Denial: forceStopPackage() from pid=" 4873 + Binder.getCallingPid() 4874 + ", uid=" + Binder.getCallingUid() 4875 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4876 Log.w(TAG, msg); 4877 throw new SecurityException(msg); 4878 } 4879 4880 long callingId = Binder.clearCallingIdentity(); 4881 try { 4882 IPackageManager pm = ActivityThread.getPackageManager(); 4883 int pkgUid = -1; 4884 synchronized(this) { 4885 try { 4886 pkgUid = pm.getPackageUid(packageName); 4887 } catch (RemoteException e) { 4888 } 4889 if (pkgUid == -1) { 4890 Log.w(TAG, "Invalid packageName: " + packageName); 4891 return; 4892 } 4893 forceStopPackageLocked(packageName, pkgUid); 4894 } 4895 } finally { 4896 Binder.restoreCallingIdentity(callingId); 4897 } 4898 } 4899 4900 /* 4901 * The pkg name and uid have to be specified. 4902 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 4903 */ 4904 public void killApplicationWithUid(String pkg, int uid) { 4905 if (pkg == null) { 4906 return; 4907 } 4908 // Make sure the uid is valid. 4909 if (uid < 0) { 4910 Log.w(TAG, "Invalid uid specified for pkg : " + pkg); 4911 return; 4912 } 4913 int callerUid = Binder.getCallingUid(); 4914 // Only the system server can kill an application 4915 if (callerUid == Process.SYSTEM_UID) { 4916 // Post an aysnc message to kill the application 4917 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4918 msg.arg1 = uid; 4919 msg.arg2 = 0; 4920 msg.obj = pkg; 4921 mHandler.sendMessage(msg); 4922 } else { 4923 throw new SecurityException(callerUid + " cannot kill pkg: " + 4924 pkg); 4925 } 4926 } 4927 4928 public void closeSystemDialogs(String reason) { 4929 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4930 if (reason != null) { 4931 intent.putExtra("reason", reason); 4932 } 4933 4934 final int uid = Binder.getCallingUid(); 4935 final long origId = Binder.clearCallingIdentity(); 4936 synchronized (this) { 4937 int i = mWatchers.beginBroadcast(); 4938 while (i > 0) { 4939 i--; 4940 IActivityWatcher w = mWatchers.getBroadcastItem(i); 4941 if (w != null) { 4942 try { 4943 w.closingSystemDialogs(reason); 4944 } catch (RemoteException e) { 4945 } 4946 } 4947 } 4948 mWatchers.finishBroadcast(); 4949 4950 mWindowManager.closeSystemDialogs(reason); 4951 4952 for (i=mHistory.size()-1; i>=0; i--) { 4953 HistoryRecord r = (HistoryRecord)mHistory.get(i); 4954 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 4955 finishActivityLocked(r, i, 4956 Activity.RESULT_CANCELED, null, "close-sys"); 4957 } 4958 } 4959 4960 broadcastIntentLocked(null, null, intent, null, 4961 null, 0, null, null, null, false, false, -1, uid); 4962 } 4963 Binder.restoreCallingIdentity(origId); 4964 } 4965 4966 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 4967 throws RemoteException { 4968 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4969 for (int i=pids.length-1; i>=0; i--) { 4970 infos[i] = new Debug.MemoryInfo(); 4971 Debug.getMemoryInfo(pids[i], infos[i]); 4972 } 4973 return infos; 4974 } 4975 4976 public void killApplicationProcess(String processName, int uid) { 4977 if (processName == null) { 4978 return; 4979 } 4980 4981 int callerUid = Binder.getCallingUid(); 4982 // Only the system server can kill an application 4983 if (callerUid == Process.SYSTEM_UID) { 4984 synchronized (this) { 4985 ProcessRecord app = getProcessRecordLocked(processName, uid); 4986 if (app != null) { 4987 try { 4988 app.thread.scheduleSuicide(); 4989 } catch (RemoteException e) { 4990 // If the other end already died, then our work here is done. 4991 } 4992 } else { 4993 Log.w(TAG, "Process/uid not found attempting kill of " 4994 + processName + " / " + uid); 4995 } 4996 } 4997 } else { 4998 throw new SecurityException(callerUid + " cannot kill app process: " + 4999 processName); 5000 } 5001 } 5002 5003 private void forceStopPackageLocked(final String packageName, int uid) { 5004 forceStopPackageLocked(packageName, uid, false, false); 5005 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5006 Uri.fromParts("package", packageName, null)); 5007 intent.putExtra(Intent.EXTRA_UID, uid); 5008 broadcastIntentLocked(null, null, intent, 5009 null, null, 0, null, null, null, 5010 false, false, MY_PID, Process.SYSTEM_UID); 5011 } 5012 5013 private final void killPackageProcessesLocked(String packageName, int uid, 5014 int minOomAdj, boolean callerWillRestart) { 5015 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5016 5017 // Remove all processes this package may have touched: all with the 5018 // same UID (except for the system or root user), and all whose name 5019 // matches the package name. 5020 final String procNamePrefix = packageName + ":"; 5021 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 5022 final int NA = apps.size(); 5023 for (int ia=0; ia<NA; ia++) { 5024 ProcessRecord app = apps.valueAt(ia); 5025 if (app.removed) { 5026 procs.add(app); 5027 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 5028 || app.processName.equals(packageName) 5029 || app.processName.startsWith(procNamePrefix)) { 5030 if (app.setAdj >= minOomAdj) { 5031 app.removed = true; 5032 procs.add(app); 5033 } 5034 } 5035 } 5036 } 5037 5038 int N = procs.size(); 5039 for (int i=0; i<N; i++) { 5040 removeProcessLocked(procs.get(i), callerWillRestart); 5041 } 5042 } 5043 5044 private final void forceStopPackageLocked(String name, int uid, 5045 boolean callerWillRestart, boolean purgeCache) { 5046 int i, N; 5047 5048 if (uid < 0) { 5049 try { 5050 uid = ActivityThread.getPackageManager().getPackageUid(name); 5051 } catch (RemoteException e) { 5052 } 5053 } 5054 5055 Log.i(TAG, "Force stopping package " + name + " uid=" + uid); 5056 5057 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 5058 while (badApps.hasNext()) { 5059 SparseArray<Long> ba = badApps.next(); 5060 if (ba.get(uid) != null) { 5061 badApps.remove(); 5062 } 5063 } 5064 5065 killPackageProcessesLocked(name, uid, -100, callerWillRestart); 5066 5067 for (i=mHistory.size()-1; i>=0; i--) { 5068 HistoryRecord r = (HistoryRecord)mHistory.get(i); 5069 if (r.packageName.equals(name)) { 5070 Log.i(TAG, " Force finishing activity " + r); 5071 if (r.app != null) { 5072 r.app.removed = true; 5073 } 5074 r.app = null; 5075 finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall"); 5076 } 5077 } 5078 5079 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 5080 for (ServiceRecord service : mServices.values()) { 5081 if (service.packageName.equals(name)) { 5082 Log.i(TAG, " Force stopping service " + service); 5083 if (service.app != null) { 5084 service.app.removed = true; 5085 } 5086 service.app = null; 5087 services.add(service); 5088 } 5089 } 5090 5091 N = services.size(); 5092 for (i=0; i<N; i++) { 5093 bringDownServiceLocked(services.get(i), true); 5094 } 5095 5096 resumeTopActivityLocked(null); 5097 if (purgeCache) { 5098 AttributeCache ac = AttributeCache.instance(); 5099 if (ac != null) { 5100 ac.removePackage(name); 5101 } 5102 } 5103 } 5104 5105 private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) { 5106 final String name = app.processName; 5107 final int uid = app.info.uid; 5108 if (DEBUG_PROCESSES) Log.d( 5109 TAG, "Force removing process " + app + " (" + name 5110 + "/" + uid + ")"); 5111 5112 mProcessNames.remove(name, uid); 5113 boolean needRestart = false; 5114 if (app.pid > 0 && app.pid != MY_PID) { 5115 int pid = app.pid; 5116 synchronized (mPidsSelfLocked) { 5117 mPidsSelfLocked.remove(pid); 5118 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5119 } 5120 handleAppDiedLocked(app, true); 5121 mLruProcesses.remove(app); 5122 Process.killProcess(pid); 5123 5124 if (app.persistent) { 5125 if (!callerWillRestart) { 5126 addAppLocked(app.info); 5127 } else { 5128 needRestart = true; 5129 } 5130 } 5131 } else { 5132 mRemovedProcesses.add(app); 5133 } 5134 5135 return needRestart; 5136 } 5137 5138 private final void processStartTimedOutLocked(ProcessRecord app) { 5139 final int pid = app.pid; 5140 boolean gone = false; 5141 synchronized (mPidsSelfLocked) { 5142 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5143 if (knownApp != null && knownApp.thread == null) { 5144 mPidsSelfLocked.remove(pid); 5145 gone = true; 5146 } 5147 } 5148 5149 if (gone) { 5150 Log.w(TAG, "Process " + app + " failed to attach"); 5151 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid, 5152 app.processName); 5153 mProcessNames.remove(app.processName, app.info.uid); 5154 // Take care of any launching providers waiting for this process. 5155 checkAppInLaunchingProvidersLocked(app, true); 5156 // Take care of any services that are waiting for the process. 5157 for (int i=0; i<mPendingServices.size(); i++) { 5158 ServiceRecord sr = mPendingServices.get(i); 5159 if (app.info.uid == sr.appInfo.uid 5160 && app.processName.equals(sr.processName)) { 5161 Log.w(TAG, "Forcing bringing down service: " + sr); 5162 mPendingServices.remove(i); 5163 i--; 5164 bringDownServiceLocked(sr, true); 5165 } 5166 } 5167 Process.killProcess(pid); 5168 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5169 Log.w(TAG, "Unattached app died before backup, skipping"); 5170 try { 5171 IBackupManager bm = IBackupManager.Stub.asInterface( 5172 ServiceManager.getService(Context.BACKUP_SERVICE)); 5173 bm.agentDisconnected(app.info.packageName); 5174 } catch (RemoteException e) { 5175 // Can't happen; the backup manager is local 5176 } 5177 } 5178 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) { 5179 Log.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5180 mPendingBroadcast = null; 5181 scheduleBroadcastsLocked(); 5182 } 5183 } else { 5184 Log.w(TAG, "Spurious process start timeout - pid not known for " + app); 5185 } 5186 } 5187 5188 private final boolean attachApplicationLocked(IApplicationThread thread, 5189 int pid) { 5190 5191 // Find the application record that is being attached... either via 5192 // the pid if we are running in multiple processes, or just pull the 5193 // next app record if we are emulating process with anonymous threads. 5194 ProcessRecord app; 5195 if (pid != MY_PID && pid >= 0) { 5196 synchronized (mPidsSelfLocked) { 5197 app = mPidsSelfLocked.get(pid); 5198 } 5199 } else if (mStartingProcesses.size() > 0) { 5200 app = mStartingProcesses.remove(0); 5201 app.setPid(pid); 5202 } else { 5203 app = null; 5204 } 5205 5206 if (app == null) { 5207 Log.w(TAG, "No pending application record for pid " + pid 5208 + " (IApplicationThread " + thread + "); dropping process"); 5209 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5210 if (pid > 0 && pid != MY_PID) { 5211 Process.killProcess(pid); 5212 } else { 5213 try { 5214 thread.scheduleExit(); 5215 } catch (Exception e) { 5216 // Ignore exceptions. 5217 } 5218 } 5219 return false; 5220 } 5221 5222 // If this application record is still attached to a previous 5223 // process, clean it up now. 5224 if (app.thread != null) { 5225 handleAppDiedLocked(app, true); 5226 } 5227 5228 // Tell the process all about itself. 5229 5230 if (localLOGV) Log.v( 5231 TAG, "Binding process pid " + pid + " to record " + app); 5232 5233 String processName = app.processName; 5234 try { 5235 thread.asBinder().linkToDeath(new AppDeathRecipient( 5236 app, pid, thread), 0); 5237 } catch (RemoteException e) { 5238 app.resetPackageList(); 5239 startProcessLocked(app, "link fail", processName); 5240 return false; 5241 } 5242 5243 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 5244 5245 app.thread = thread; 5246 app.curAdj = app.setAdj = -100; 5247 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 5248 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 5249 app.forcingToForeground = null; 5250 app.foregroundServices = false; 5251 app.debugging = false; 5252 5253 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5254 5255 boolean normalMode = mSystemReady || isAllowedWhileBooting(app.info); 5256 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5257 5258 if (!normalMode) { 5259 Log.i(TAG, "Launching preboot mode app: " + app); 5260 } 5261 5262 if (localLOGV) Log.v( 5263 TAG, "New app record " + app 5264 + " thread=" + thread.asBinder() + " pid=" + pid); 5265 try { 5266 int testMode = IApplicationThread.DEBUG_OFF; 5267 if (mDebugApp != null && mDebugApp.equals(processName)) { 5268 testMode = mWaitForDebugger 5269 ? IApplicationThread.DEBUG_WAIT 5270 : IApplicationThread.DEBUG_ON; 5271 app.debugging = true; 5272 if (mDebugTransient) { 5273 mDebugApp = mOrigDebugApp; 5274 mWaitForDebugger = mOrigWaitForDebugger; 5275 } 5276 } 5277 5278 // If the app is being launched for restore or full backup, set it up specially 5279 boolean isRestrictedBackupMode = false; 5280 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5281 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5282 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5283 } 5284 5285 ensurePackageDexOpt(app.instrumentationInfo != null 5286 ? app.instrumentationInfo.packageName 5287 : app.info.packageName); 5288 if (app.instrumentationClass != null) { 5289 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5290 } 5291 if (DEBUG_CONFIGURATION) Log.v(TAG, "Binding proc " 5292 + processName + " with config " + mConfiguration); 5293 thread.bindApplication(processName, app.instrumentationInfo != null 5294 ? app.instrumentationInfo : app.info, providers, 5295 app.instrumentationClass, app.instrumentationProfileFile, 5296 app.instrumentationArguments, app.instrumentationWatcher, testMode, 5297 isRestrictedBackupMode || !normalMode, 5298 mConfiguration, getCommonServicesLocked()); 5299 updateLruProcessLocked(app, false, true); 5300 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5301 } catch (Exception e) { 5302 // todo: Yikes! What should we do? For now we will try to 5303 // start another process, but that could easily get us in 5304 // an infinite loop of restarting processes... 5305 Log.w(TAG, "Exception thrown during bind!", e); 5306 5307 app.resetPackageList(); 5308 startProcessLocked(app, "bind fail", processName); 5309 return false; 5310 } 5311 5312 // Remove this record from the list of starting applications. 5313 mPersistentStartingProcesses.remove(app); 5314 mProcessesOnHold.remove(app); 5315 5316 boolean badApp = false; 5317 boolean didSomething = false; 5318 5319 // See if the top visible activity is waiting to run in this process... 5320 HistoryRecord hr = topRunningActivityLocked(null); 5321 if (hr != null) { 5322 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid 5323 && processName.equals(hr.processName)) { 5324 try { 5325 if (realStartActivityLocked(hr, app, true, true)) { 5326 didSomething = true; 5327 } 5328 } catch (Exception e) { 5329 Log.w(TAG, "Exception in new application when starting activity " 5330 + hr.intent.getComponent().flattenToShortString(), e); 5331 badApp = true; 5332 } 5333 } else { 5334 ensureActivitiesVisibleLocked(hr, null, processName, 0); 5335 } 5336 } 5337 5338 // Find any services that should be running in this process... 5339 if (!badApp && mPendingServices.size() > 0) { 5340 ServiceRecord sr = null; 5341 try { 5342 for (int i=0; i<mPendingServices.size(); i++) { 5343 sr = mPendingServices.get(i); 5344 if (app.info.uid != sr.appInfo.uid 5345 || !processName.equals(sr.processName)) { 5346 continue; 5347 } 5348 5349 mPendingServices.remove(i); 5350 i--; 5351 realStartServiceLocked(sr, app); 5352 didSomething = true; 5353 } 5354 } catch (Exception e) { 5355 Log.w(TAG, "Exception in new application when starting service " 5356 + sr.shortName, e); 5357 badApp = true; 5358 } 5359 } 5360 5361 // Check if the next broadcast receiver is in this process... 5362 BroadcastRecord br = mPendingBroadcast; 5363 if (!badApp && br != null && br.curApp == app) { 5364 try { 5365 mPendingBroadcast = null; 5366 processCurBroadcastLocked(br, app); 5367 didSomething = true; 5368 } catch (Exception e) { 5369 Log.w(TAG, "Exception in new application when starting receiver " 5370 + br.curComponent.flattenToShortString(), e); 5371 badApp = true; 5372 logBroadcastReceiverDiscard(br); 5373 finishReceiverLocked(br.receiver, br.resultCode, br.resultData, 5374 br.resultExtras, br.resultAbort, true); 5375 scheduleBroadcastsLocked(); 5376 } 5377 } 5378 5379 // Check whether the next backup agent is in this process... 5380 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) { 5381 if (DEBUG_BACKUP) Log.v(TAG, "New app is backup target, launching agent for " + app); 5382 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5383 try { 5384 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, mBackupTarget.backupMode); 5385 } catch (Exception e) { 5386 Log.w(TAG, "Exception scheduling backup agent creation: "); 5387 e.printStackTrace(); 5388 } 5389 } 5390 5391 if (badApp) { 5392 // todo: Also need to kill application to deal with all 5393 // kinds of exceptions. 5394 handleAppDiedLocked(app, false); 5395 return false; 5396 } 5397 5398 if (!didSomething) { 5399 updateOomAdjLocked(); 5400 } 5401 5402 return true; 5403 } 5404 5405 public final void attachApplication(IApplicationThread thread) { 5406 synchronized (this) { 5407 int callingPid = Binder.getCallingPid(); 5408 final long origId = Binder.clearCallingIdentity(); 5409 attachApplicationLocked(thread, callingPid); 5410 Binder.restoreCallingIdentity(origId); 5411 } 5412 } 5413 5414 public final void activityIdle(IBinder token, Configuration config) { 5415 final long origId = Binder.clearCallingIdentity(); 5416 activityIdleInternal(token, false, config); 5417 Binder.restoreCallingIdentity(origId); 5418 } 5419 5420 final ArrayList<HistoryRecord> processStoppingActivitiesLocked( 5421 boolean remove) { 5422 int N = mStoppingActivities.size(); 5423 if (N <= 0) return null; 5424 5425 ArrayList<HistoryRecord> stops = null; 5426 5427 final boolean nowVisible = mResumedActivity != null 5428 && mResumedActivity.nowVisible 5429 && !mResumedActivity.waitingVisible; 5430 for (int i=0; i<N; i++) { 5431 HistoryRecord s = mStoppingActivities.get(i); 5432 if (localLOGV) Log.v(TAG, "Stopping " + s + ": nowVisible=" 5433 + nowVisible + " waitingVisible=" + s.waitingVisible 5434 + " finishing=" + s.finishing); 5435 if (s.waitingVisible && nowVisible) { 5436 mWaitingVisibleActivities.remove(s); 5437 s.waitingVisible = false; 5438 if (s.finishing) { 5439 // If this activity is finishing, it is sitting on top of 5440 // everyone else but we now know it is no longer needed... 5441 // so get rid of it. Otherwise, we need to go through the 5442 // normal flow and hide it once we determine that it is 5443 // hidden by the activities in front of it. 5444 if (localLOGV) Log.v(TAG, "Before stopping, can hide: " + s); 5445 mWindowManager.setAppVisibility(s, false); 5446 } 5447 } 5448 if (!s.waitingVisible && remove) { 5449 if (localLOGV) Log.v(TAG, "Ready to stop: " + s); 5450 if (stops == null) { 5451 stops = new ArrayList<HistoryRecord>(); 5452 } 5453 stops.add(s); 5454 mStoppingActivities.remove(i); 5455 N--; 5456 i--; 5457 } 5458 } 5459 5460 return stops; 5461 } 5462 5463 void enableScreenAfterBoot() { 5464 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5465 SystemClock.uptimeMillis()); 5466 mWindowManager.enableScreenAfterBoot(); 5467 } 5468 5469 final void activityIdleInternal(IBinder token, boolean fromTimeout, 5470 Configuration config) { 5471 if (localLOGV) Log.v(TAG, "Activity idle: " + token); 5472 5473 ArrayList<HistoryRecord> stops = null; 5474 ArrayList<HistoryRecord> finishes = null; 5475 ArrayList<HistoryRecord> thumbnails = null; 5476 int NS = 0; 5477 int NF = 0; 5478 int NT = 0; 5479 IApplicationThread sendThumbnail = null; 5480 boolean booting = false; 5481 boolean enableScreen = false; 5482 5483 synchronized (this) { 5484 if (token != null) { 5485 mHandler.removeMessages(IDLE_TIMEOUT_MSG, token); 5486 } 5487 5488 // Get the activity record. 5489 int index = indexOfTokenLocked(token); 5490 if (index >= 0) { 5491 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5492 5493 // This is a hack to semi-deal with a race condition 5494 // in the client where it can be constructed with a 5495 // newer configuration from when we asked it to launch. 5496 // We'll update with whatever configuration it now says 5497 // it used to launch. 5498 if (config != null) { 5499 r.configuration = config; 5500 } 5501 5502 // No longer need to keep the device awake. 5503 if (mResumedActivity == r && mLaunchingActivity.isHeld()) { 5504 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 5505 mLaunchingActivity.release(); 5506 } 5507 5508 // We are now idle. If someone is waiting for a thumbnail from 5509 // us, we can now deliver. 5510 r.idle = true; 5511 scheduleAppGcsLocked(); 5512 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) { 5513 sendThumbnail = r.app.thread; 5514 r.thumbnailNeeded = false; 5515 } 5516 5517 // If this activity is fullscreen, set up to hide those under it. 5518 5519 if (DEBUG_VISBILITY) Log.v(TAG, "Idle activity for " + r); 5520 ensureActivitiesVisibleLocked(null, 0); 5521 5522 //Log.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); 5523 if (!mBooted && !fromTimeout) { 5524 mBooted = true; 5525 enableScreen = true; 5526 } 5527 } 5528 5529 // Atomically retrieve all of the other things to do. 5530 stops = processStoppingActivitiesLocked(true); 5531 NS = stops != null ? stops.size() : 0; 5532 if ((NF=mFinishingActivities.size()) > 0) { 5533 finishes = new ArrayList<HistoryRecord>(mFinishingActivities); 5534 mFinishingActivities.clear(); 5535 } 5536 if ((NT=mCancelledThumbnails.size()) > 0) { 5537 thumbnails = new ArrayList<HistoryRecord>(mCancelledThumbnails); 5538 mCancelledThumbnails.clear(); 5539 } 5540 5541 booting = mBooting; 5542 mBooting = false; 5543 } 5544 5545 int i; 5546 5547 // Send thumbnail if requested. 5548 if (sendThumbnail != null) { 5549 try { 5550 sendThumbnail.requestThumbnail(token); 5551 } catch (Exception e) { 5552 Log.w(TAG, "Exception thrown when requesting thumbnail", e); 5553 sendPendingThumbnail(null, token, null, null, true); 5554 } 5555 } 5556 5557 // Stop any activities that are scheduled to do so but have been 5558 // waiting for the next one to start. 5559 for (i=0; i<NS; i++) { 5560 HistoryRecord r = (HistoryRecord)stops.get(i); 5561 synchronized (this) { 5562 if (r.finishing) { 5563 finishCurrentActivityLocked(r, FINISH_IMMEDIATELY); 5564 } else { 5565 stopActivityLocked(r); 5566 } 5567 } 5568 } 5569 5570 // Finish any activities that are scheduled to do so but have been 5571 // waiting for the next one to start. 5572 for (i=0; i<NF; i++) { 5573 HistoryRecord r = (HistoryRecord)finishes.get(i); 5574 synchronized (this) { 5575 destroyActivityLocked(r, true); 5576 } 5577 } 5578 5579 // Report back to any thumbnail receivers. 5580 for (i=0; i<NT; i++) { 5581 HistoryRecord r = (HistoryRecord)thumbnails.get(i); 5582 sendPendingThumbnail(r, null, null, null, true); 5583 } 5584 5585 if (booting) { 5586 finishBooting(); 5587 } 5588 5589 trimApplications(); 5590 //dump(); 5591 //mWindowManager.dump(); 5592 5593 if (enableScreen) { 5594 enableScreenAfterBoot(); 5595 } 5596 } 5597 5598 final void finishBooting() { 5599 // Ensure that any processes we had put on hold are now started 5600 // up. 5601 final int NP = mProcessesOnHold.size(); 5602 if (NP > 0) { 5603 ArrayList<ProcessRecord> procs = 5604 new ArrayList<ProcessRecord>(mProcessesOnHold); 5605 for (int ip=0; ip<NP; ip++) { 5606 this.startProcessLocked(procs.get(ip), "on-hold", null); 5607 } 5608 } 5609 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 5610 // Tell anyone interested that we are done booting! 5611 synchronized (this) { 5612 broadcastIntentLocked(null, null, 5613 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 5614 null, null, 0, null, null, 5615 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5616 false, false, MY_PID, Process.SYSTEM_UID); 5617 } 5618 } 5619 } 5620 5621 final void ensureBootCompleted() { 5622 boolean booting; 5623 boolean enableScreen; 5624 synchronized (this) { 5625 booting = mBooting; 5626 mBooting = false; 5627 enableScreen = !mBooted; 5628 mBooted = true; 5629 } 5630 5631 if (booting) { 5632 finishBooting(); 5633 } 5634 5635 if (enableScreen) { 5636 enableScreenAfterBoot(); 5637 } 5638 } 5639 5640 public final void activityPaused(IBinder token, Bundle icicle) { 5641 // Refuse possible leaked file descriptors 5642 if (icicle != null && icicle.hasFileDescriptors()) { 5643 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5644 } 5645 5646 final long origId = Binder.clearCallingIdentity(); 5647 activityPaused(token, icicle, false); 5648 Binder.restoreCallingIdentity(origId); 5649 } 5650 5651 final void activityPaused(IBinder token, Bundle icicle, boolean timeout) { 5652 if (DEBUG_PAUSE) Log.v( 5653 TAG, "Activity paused: token=" + token + ", icicle=" + icicle 5654 + ", timeout=" + timeout); 5655 5656 HistoryRecord r = null; 5657 5658 synchronized (this) { 5659 int index = indexOfTokenLocked(token); 5660 if (index >= 0) { 5661 r = (HistoryRecord)mHistory.get(index); 5662 if (!timeout) { 5663 r.icicle = icicle; 5664 r.haveState = true; 5665 } 5666 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); 5667 if (mPausingActivity == r) { 5668 r.state = ActivityState.PAUSED; 5669 completePauseLocked(); 5670 } else { 5671 EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE, 5672 System.identityHashCode(r), r.shortComponentName, 5673 mPausingActivity != null 5674 ? mPausingActivity.shortComponentName : "(none)"); 5675 } 5676 } 5677 } 5678 } 5679 5680 public final void activityStopped(IBinder token, Bitmap thumbnail, 5681 CharSequence description) { 5682 if (localLOGV) Log.v( 5683 TAG, "Activity stopped: token=" + token); 5684 5685 HistoryRecord r = null; 5686 5687 final long origId = Binder.clearCallingIdentity(); 5688 5689 synchronized (this) { 5690 int index = indexOfTokenLocked(token); 5691 if (index >= 0) { 5692 r = (HistoryRecord)mHistory.get(index); 5693 r.thumbnail = thumbnail; 5694 r.description = description; 5695 r.stopped = true; 5696 r.state = ActivityState.STOPPED; 5697 if (!r.finishing) { 5698 if (r.configDestroy) { 5699 destroyActivityLocked(r, true); 5700 resumeTopActivityLocked(null); 5701 } 5702 } 5703 } 5704 } 5705 5706 if (r != null) { 5707 sendPendingThumbnail(r, null, null, null, false); 5708 } 5709 5710 trimApplications(); 5711 5712 Binder.restoreCallingIdentity(origId); 5713 } 5714 5715 public final void activityDestroyed(IBinder token) { 5716 if (DEBUG_SWITCH) Log.v(TAG, "ACTIVITY DESTROYED: " + token); 5717 synchronized (this) { 5718 mHandler.removeMessages(DESTROY_TIMEOUT_MSG, token); 5719 5720 int index = indexOfTokenLocked(token); 5721 if (index >= 0) { 5722 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5723 if (r.state == ActivityState.DESTROYING) { 5724 final long origId = Binder.clearCallingIdentity(); 5725 removeActivityFromHistoryLocked(r); 5726 Binder.restoreCallingIdentity(origId); 5727 } 5728 } 5729 } 5730 } 5731 5732 public String getCallingPackage(IBinder token) { 5733 synchronized (this) { 5734 HistoryRecord r = getCallingRecordLocked(token); 5735 return r != null && r.app != null ? r.info.packageName : null; 5736 } 5737 } 5738 5739 public ComponentName getCallingActivity(IBinder token) { 5740 synchronized (this) { 5741 HistoryRecord r = getCallingRecordLocked(token); 5742 return r != null ? r.intent.getComponent() : null; 5743 } 5744 } 5745 5746 private HistoryRecord getCallingRecordLocked(IBinder token) { 5747 int index = indexOfTokenLocked(token); 5748 if (index >= 0) { 5749 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5750 if (r != null) { 5751 return r.resultTo; 5752 } 5753 } 5754 return null; 5755 } 5756 5757 public ComponentName getActivityClassForToken(IBinder token) { 5758 synchronized(this) { 5759 int index = indexOfTokenLocked(token); 5760 if (index >= 0) { 5761 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5762 return r.intent.getComponent(); 5763 } 5764 return null; 5765 } 5766 } 5767 5768 public String getPackageForToken(IBinder token) { 5769 synchronized(this) { 5770 int index = indexOfTokenLocked(token); 5771 if (index >= 0) { 5772 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5773 return r.packageName; 5774 } 5775 return null; 5776 } 5777 } 5778 5779 public IIntentSender getIntentSender(int type, 5780 String packageName, IBinder token, String resultWho, 5781 int requestCode, Intent intent, String resolvedType, int flags) { 5782 // Refuse possible leaked file descriptors 5783 if (intent != null && intent.hasFileDescriptors() == true) { 5784 throw new IllegalArgumentException("File descriptors passed in Intent"); 5785 } 5786 5787 if (type == INTENT_SENDER_BROADCAST) { 5788 if ((intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5789 throw new IllegalArgumentException( 5790 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5791 } 5792 } 5793 5794 synchronized(this) { 5795 int callingUid = Binder.getCallingUid(); 5796 try { 5797 if (callingUid != 0 && callingUid != Process.SYSTEM_UID && 5798 Process.supportsProcesses()) { 5799 int uid = ActivityThread.getPackageManager() 5800 .getPackageUid(packageName); 5801 if (uid != Binder.getCallingUid()) { 5802 String msg = "Permission Denial: getIntentSender() from pid=" 5803 + Binder.getCallingPid() 5804 + ", uid=" + Binder.getCallingUid() 5805 + ", (need uid=" + uid + ")" 5806 + " is not allowed to send as package " + packageName; 5807 Log.w(TAG, msg); 5808 throw new SecurityException(msg); 5809 } 5810 } 5811 } catch (RemoteException e) { 5812 throw new SecurityException(e); 5813 } 5814 HistoryRecord activity = null; 5815 if (type == INTENT_SENDER_ACTIVITY_RESULT) { 5816 int index = indexOfTokenLocked(token); 5817 if (index < 0) { 5818 return null; 5819 } 5820 activity = (HistoryRecord)mHistory.get(index); 5821 if (activity.finishing) { 5822 return null; 5823 } 5824 } 5825 5826 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5827 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5828 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5829 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5830 |PendingIntent.FLAG_UPDATE_CURRENT); 5831 5832 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5833 type, packageName, activity, resultWho, 5834 requestCode, intent, resolvedType, flags); 5835 WeakReference<PendingIntentRecord> ref; 5836 ref = mIntentSenderRecords.get(key); 5837 PendingIntentRecord rec = ref != null ? ref.get() : null; 5838 if (rec != null) { 5839 if (!cancelCurrent) { 5840 if (updateCurrent) { 5841 rec.key.requestIntent.replaceExtras(intent); 5842 } 5843 return rec; 5844 } 5845 rec.canceled = true; 5846 mIntentSenderRecords.remove(key); 5847 } 5848 if (noCreate) { 5849 return rec; 5850 } 5851 rec = new PendingIntentRecord(this, key, callingUid); 5852 mIntentSenderRecords.put(key, rec.ref); 5853 if (type == INTENT_SENDER_ACTIVITY_RESULT) { 5854 if (activity.pendingResults == null) { 5855 activity.pendingResults 5856 = new HashSet<WeakReference<PendingIntentRecord>>(); 5857 } 5858 activity.pendingResults.add(rec.ref); 5859 } 5860 return rec; 5861 } 5862 } 5863 5864 public void cancelIntentSender(IIntentSender sender) { 5865 if (!(sender instanceof PendingIntentRecord)) { 5866 return; 5867 } 5868 synchronized(this) { 5869 PendingIntentRecord rec = (PendingIntentRecord)sender; 5870 try { 5871 int uid = ActivityThread.getPackageManager() 5872 .getPackageUid(rec.key.packageName); 5873 if (uid != Binder.getCallingUid()) { 5874 String msg = "Permission Denial: cancelIntentSender() from pid=" 5875 + Binder.getCallingPid() 5876 + ", uid=" + Binder.getCallingUid() 5877 + " is not allowed to cancel packges " 5878 + rec.key.packageName; 5879 Log.w(TAG, msg); 5880 throw new SecurityException(msg); 5881 } 5882 } catch (RemoteException e) { 5883 throw new SecurityException(e); 5884 } 5885 cancelIntentSenderLocked(rec, true); 5886 } 5887 } 5888 5889 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5890 rec.canceled = true; 5891 mIntentSenderRecords.remove(rec.key); 5892 if (cleanActivity && rec.key.activity != null) { 5893 rec.key.activity.pendingResults.remove(rec.ref); 5894 } 5895 } 5896 5897 public String getPackageForIntentSender(IIntentSender pendingResult) { 5898 if (!(pendingResult instanceof PendingIntentRecord)) { 5899 return null; 5900 } 5901 synchronized(this) { 5902 try { 5903 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5904 return res.key.packageName; 5905 } catch (ClassCastException e) { 5906 } 5907 } 5908 return null; 5909 } 5910 5911 public void setProcessLimit(int max) { 5912 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5913 "setProcessLimit()"); 5914 mProcessLimit = max; 5915 } 5916 5917 public int getProcessLimit() { 5918 return mProcessLimit; 5919 } 5920 5921 void foregroundTokenDied(ForegroundToken token) { 5922 synchronized (ActivityManagerService.this) { 5923 synchronized (mPidsSelfLocked) { 5924 ForegroundToken cur 5925 = mForegroundProcesses.get(token.pid); 5926 if (cur != token) { 5927 return; 5928 } 5929 mForegroundProcesses.remove(token.pid); 5930 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5931 if (pr == null) { 5932 return; 5933 } 5934 pr.forcingToForeground = null; 5935 pr.foregroundServices = false; 5936 } 5937 updateOomAdjLocked(); 5938 } 5939 } 5940 5941 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5942 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5943 "setProcessForeground()"); 5944 synchronized(this) { 5945 boolean changed = false; 5946 5947 synchronized (mPidsSelfLocked) { 5948 ProcessRecord pr = mPidsSelfLocked.get(pid); 5949 if (pr == null) { 5950 Log.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5951 return; 5952 } 5953 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5954 if (oldToken != null) { 5955 oldToken.token.unlinkToDeath(oldToken, 0); 5956 mForegroundProcesses.remove(pid); 5957 pr.forcingToForeground = null; 5958 changed = true; 5959 } 5960 if (isForeground && token != null) { 5961 ForegroundToken newToken = new ForegroundToken() { 5962 public void binderDied() { 5963 foregroundTokenDied(this); 5964 } 5965 }; 5966 newToken.pid = pid; 5967 newToken.token = token; 5968 try { 5969 token.linkToDeath(newToken, 0); 5970 mForegroundProcesses.put(pid, newToken); 5971 pr.forcingToForeground = token; 5972 changed = true; 5973 } catch (RemoteException e) { 5974 // If the process died while doing this, we will later 5975 // do the cleanup with the process death link. 5976 } 5977 } 5978 } 5979 5980 if (changed) { 5981 updateOomAdjLocked(); 5982 } 5983 } 5984 } 5985 5986 // ========================================================= 5987 // PERMISSIONS 5988 // ========================================================= 5989 5990 static class PermissionController extends IPermissionController.Stub { 5991 ActivityManagerService mActivityManagerService; 5992 PermissionController(ActivityManagerService activityManagerService) { 5993 mActivityManagerService = activityManagerService; 5994 } 5995 5996 public boolean checkPermission(String permission, int pid, int uid) { 5997 return mActivityManagerService.checkPermission(permission, pid, 5998 uid) == PackageManager.PERMISSION_GRANTED; 5999 } 6000 } 6001 6002 /** 6003 * This can be called with or without the global lock held. 6004 */ 6005 int checkComponentPermission(String permission, int pid, int uid, 6006 int reqUid) { 6007 // We might be performing an operation on behalf of an indirect binder 6008 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6009 // client identity accordingly before proceeding. 6010 Identity tlsIdentity = sCallerIdentity.get(); 6011 if (tlsIdentity != null) { 6012 Log.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6013 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6014 uid = tlsIdentity.uid; 6015 pid = tlsIdentity.pid; 6016 } 6017 6018 // Root, system server and our own process get to do everything. 6019 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID || 6020 !Process.supportsProcesses()) { 6021 return PackageManager.PERMISSION_GRANTED; 6022 } 6023 // If the target requires a specific UID, always fail for others. 6024 if (reqUid >= 0 && uid != reqUid) { 6025 Log.w(TAG, "Permission denied: checkComponentPermission() reqUid=" + reqUid); 6026 return PackageManager.PERMISSION_DENIED; 6027 } 6028 if (permission == null) { 6029 return PackageManager.PERMISSION_GRANTED; 6030 } 6031 try { 6032 return ActivityThread.getPackageManager() 6033 .checkUidPermission(permission, uid); 6034 } catch (RemoteException e) { 6035 // Should never happen, but if it does... deny! 6036 Log.e(TAG, "PackageManager is dead?!?", e); 6037 } 6038 return PackageManager.PERMISSION_DENIED; 6039 } 6040 6041 /** 6042 * As the only public entry point for permissions checking, this method 6043 * can enforce the semantic that requesting a check on a null global 6044 * permission is automatically denied. (Internally a null permission 6045 * string is used when calling {@link #checkComponentPermission} in cases 6046 * when only uid-based security is needed.) 6047 * 6048 * This can be called with or without the global lock held. 6049 */ 6050 public int checkPermission(String permission, int pid, int uid) { 6051 if (permission == null) { 6052 return PackageManager.PERMISSION_DENIED; 6053 } 6054 return checkComponentPermission(permission, pid, uid, -1); 6055 } 6056 6057 /** 6058 * Binder IPC calls go through the public entry point. 6059 * This can be called with or without the global lock held. 6060 */ 6061 int checkCallingPermission(String permission) { 6062 return checkPermission(permission, 6063 Binder.getCallingPid(), 6064 Binder.getCallingUid()); 6065 } 6066 6067 /** 6068 * This can be called with or without the global lock held. 6069 */ 6070 void enforceCallingPermission(String permission, String func) { 6071 if (checkCallingPermission(permission) 6072 == PackageManager.PERMISSION_GRANTED) { 6073 return; 6074 } 6075 6076 String msg = "Permission Denial: " + func + " from pid=" 6077 + Binder.getCallingPid() 6078 + ", uid=" + Binder.getCallingUid() 6079 + " requires " + permission; 6080 Log.w(TAG, msg); 6081 throw new SecurityException(msg); 6082 } 6083 6084 private final boolean checkHoldingPermissionsLocked(IPackageManager pm, 6085 ProviderInfo pi, int uid, int modeFlags) { 6086 try { 6087 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6088 if ((pi.readPermission != null) && 6089 (pm.checkUidPermission(pi.readPermission, uid) 6090 != PackageManager.PERMISSION_GRANTED)) { 6091 return false; 6092 } 6093 } 6094 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6095 if ((pi.writePermission != null) && 6096 (pm.checkUidPermission(pi.writePermission, uid) 6097 != PackageManager.PERMISSION_GRANTED)) { 6098 return false; 6099 } 6100 } 6101 return true; 6102 } catch (RemoteException e) { 6103 return false; 6104 } 6105 } 6106 6107 private final boolean checkUriPermissionLocked(Uri uri, int uid, 6108 int modeFlags) { 6109 // Root gets to do everything. 6110 if (uid == 0 || !Process.supportsProcesses()) { 6111 return true; 6112 } 6113 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6114 if (perms == null) return false; 6115 UriPermission perm = perms.get(uri); 6116 if (perm == null) return false; 6117 return (modeFlags&perm.modeFlags) == modeFlags; 6118 } 6119 6120 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 6121 // Another redirected-binder-call permissions check as in 6122 // {@link checkComponentPermission}. 6123 Identity tlsIdentity = sCallerIdentity.get(); 6124 if (tlsIdentity != null) { 6125 uid = tlsIdentity.uid; 6126 pid = tlsIdentity.pid; 6127 } 6128 6129 // Our own process gets to do everything. 6130 if (pid == MY_PID) { 6131 return PackageManager.PERMISSION_GRANTED; 6132 } 6133 synchronized(this) { 6134 return checkUriPermissionLocked(uri, uid, modeFlags) 6135 ? PackageManager.PERMISSION_GRANTED 6136 : PackageManager.PERMISSION_DENIED; 6137 } 6138 } 6139 6140 private void grantUriPermissionLocked(int callingUid, 6141 String targetPkg, Uri uri, int modeFlags, HistoryRecord activity) { 6142 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6143 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6144 if (modeFlags == 0) { 6145 return; 6146 } 6147 6148 final IPackageManager pm = ActivityThread.getPackageManager(); 6149 6150 // If this is not a content: uri, we can't do anything with it. 6151 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 6152 return; 6153 } 6154 6155 String name = uri.getAuthority(); 6156 ProviderInfo pi = null; 6157 ContentProviderRecord cpr 6158 = (ContentProviderRecord)mProvidersByName.get(name); 6159 if (cpr != null) { 6160 pi = cpr.info; 6161 } else { 6162 try { 6163 pi = pm.resolveContentProvider(name, 6164 PackageManager.GET_URI_PERMISSION_PATTERNS); 6165 } catch (RemoteException ex) { 6166 } 6167 } 6168 if (pi == null) { 6169 Log.w(TAG, "No content provider found for: " + name); 6170 return; 6171 } 6172 6173 int targetUid; 6174 try { 6175 targetUid = pm.getPackageUid(targetPkg); 6176 if (targetUid < 0) { 6177 return; 6178 } 6179 } catch (RemoteException ex) { 6180 return; 6181 } 6182 6183 // First... does the target actually need this permission? 6184 if (checkHoldingPermissionsLocked(pm, pi, targetUid, modeFlags)) { 6185 // No need to grant the target this permission. 6186 return; 6187 } 6188 6189 // Second... maybe someone else has already granted the 6190 // permission? 6191 if (checkUriPermissionLocked(uri, targetUid, modeFlags)) { 6192 // No need to grant the target this permission. 6193 return; 6194 } 6195 6196 // Third... is the provider allowing granting of URI permissions? 6197 if (!pi.grantUriPermissions) { 6198 throw new SecurityException("Provider " + pi.packageName 6199 + "/" + pi.name 6200 + " does not allow granting of Uri permissions (uri " 6201 + uri + ")"); 6202 } 6203 if (pi.uriPermissionPatterns != null) { 6204 final int N = pi.uriPermissionPatterns.length; 6205 boolean allowed = false; 6206 for (int i=0; i<N; i++) { 6207 if (pi.uriPermissionPatterns[i] != null 6208 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6209 allowed = true; 6210 break; 6211 } 6212 } 6213 if (!allowed) { 6214 throw new SecurityException("Provider " + pi.packageName 6215 + "/" + pi.name 6216 + " does not allow granting of permission to path of Uri " 6217 + uri); 6218 } 6219 } 6220 6221 // Fourth... does the caller itself have permission to access 6222 // this uri? 6223 if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) { 6224 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6225 throw new SecurityException("Uid " + callingUid 6226 + " does not have permission to uri " + uri); 6227 } 6228 } 6229 6230 // Okay! So here we are: the caller has the assumed permission 6231 // to the uri, and the target doesn't. Let's now give this to 6232 // the target. 6233 6234 HashMap<Uri, UriPermission> targetUris 6235 = mGrantedUriPermissions.get(targetUid); 6236 if (targetUris == null) { 6237 targetUris = new HashMap<Uri, UriPermission>(); 6238 mGrantedUriPermissions.put(targetUid, targetUris); 6239 } 6240 6241 UriPermission perm = targetUris.get(uri); 6242 if (perm == null) { 6243 perm = new UriPermission(targetUid, uri); 6244 targetUris.put(uri, perm); 6245 6246 } 6247 perm.modeFlags |= modeFlags; 6248 if (activity == null) { 6249 perm.globalModeFlags |= modeFlags; 6250 } else if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6251 perm.readActivities.add(activity); 6252 if (activity.readUriPermissions == null) { 6253 activity.readUriPermissions = new HashSet<UriPermission>(); 6254 } 6255 activity.readUriPermissions.add(perm); 6256 } else if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6257 perm.writeActivities.add(activity); 6258 if (activity.writeUriPermissions == null) { 6259 activity.writeUriPermissions = new HashSet<UriPermission>(); 6260 } 6261 activity.writeUriPermissions.add(perm); 6262 } 6263 } 6264 6265 private void grantUriPermissionFromIntentLocked(int callingUid, 6266 String targetPkg, Intent intent, HistoryRecord activity) { 6267 if (intent == null) { 6268 return; 6269 } 6270 Uri data = intent.getData(); 6271 if (data == null) { 6272 return; 6273 } 6274 grantUriPermissionLocked(callingUid, targetPkg, data, 6275 intent.getFlags(), activity); 6276 } 6277 6278 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6279 Uri uri, int modeFlags) { 6280 synchronized(this) { 6281 final ProcessRecord r = getRecordForAppLocked(caller); 6282 if (r == null) { 6283 throw new SecurityException("Unable to find app for caller " 6284 + caller 6285 + " when granting permission to uri " + uri); 6286 } 6287 if (targetPkg == null) { 6288 Log.w(TAG, "grantUriPermission: null target"); 6289 return; 6290 } 6291 if (uri == null) { 6292 Log.w(TAG, "grantUriPermission: null uri"); 6293 return; 6294 } 6295 6296 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags, 6297 null); 6298 } 6299 } 6300 6301 private void removeUriPermissionIfNeededLocked(UriPermission perm) { 6302 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6303 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6304 HashMap<Uri, UriPermission> perms 6305 = mGrantedUriPermissions.get(perm.uid); 6306 if (perms != null) { 6307 perms.remove(perm.uri); 6308 if (perms.size() == 0) { 6309 mGrantedUriPermissions.remove(perm.uid); 6310 } 6311 } 6312 } 6313 } 6314 6315 private void removeActivityUriPermissionsLocked(HistoryRecord activity) { 6316 if (activity.readUriPermissions != null) { 6317 for (UriPermission perm : activity.readUriPermissions) { 6318 perm.readActivities.remove(activity); 6319 if (perm.readActivities.size() == 0 && (perm.globalModeFlags 6320 &Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0) { 6321 perm.modeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION; 6322 removeUriPermissionIfNeededLocked(perm); 6323 } 6324 } 6325 } 6326 if (activity.writeUriPermissions != null) { 6327 for (UriPermission perm : activity.writeUriPermissions) { 6328 perm.writeActivities.remove(activity); 6329 if (perm.writeActivities.size() == 0 && (perm.globalModeFlags 6330 &Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0) { 6331 perm.modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION; 6332 removeUriPermissionIfNeededLocked(perm); 6333 } 6334 } 6335 } 6336 } 6337 6338 private void revokeUriPermissionLocked(int callingUid, Uri uri, 6339 int modeFlags) { 6340 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6341 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6342 if (modeFlags == 0) { 6343 return; 6344 } 6345 6346 final IPackageManager pm = ActivityThread.getPackageManager(); 6347 6348 final String authority = uri.getAuthority(); 6349 ProviderInfo pi = null; 6350 ContentProviderRecord cpr 6351 = (ContentProviderRecord)mProvidersByName.get(authority); 6352 if (cpr != null) { 6353 pi = cpr.info; 6354 } else { 6355 try { 6356 pi = pm.resolveContentProvider(authority, 6357 PackageManager.GET_URI_PERMISSION_PATTERNS); 6358 } catch (RemoteException ex) { 6359 } 6360 } 6361 if (pi == null) { 6362 Log.w(TAG, "No content provider found for: " + authority); 6363 return; 6364 } 6365 6366 // Does the caller have this permission on the URI? 6367 if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) { 6368 // Right now, if you are not the original owner of the permission, 6369 // you are not allowed to revoke it. 6370 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6371 throw new SecurityException("Uid " + callingUid 6372 + " does not have permission to uri " + uri); 6373 //} 6374 } 6375 6376 // Go through all of the permissions and remove any that match. 6377 final List<String> SEGMENTS = uri.getPathSegments(); 6378 if (SEGMENTS != null) { 6379 final int NS = SEGMENTS.size(); 6380 int N = mGrantedUriPermissions.size(); 6381 for (int i=0; i<N; i++) { 6382 HashMap<Uri, UriPermission> perms 6383 = mGrantedUriPermissions.valueAt(i); 6384 Iterator<UriPermission> it = perms.values().iterator(); 6385 toploop: 6386 while (it.hasNext()) { 6387 UriPermission perm = it.next(); 6388 Uri targetUri = perm.uri; 6389 if (!authority.equals(targetUri.getAuthority())) { 6390 continue; 6391 } 6392 List<String> targetSegments = targetUri.getPathSegments(); 6393 if (targetSegments == null) { 6394 continue; 6395 } 6396 if (targetSegments.size() < NS) { 6397 continue; 6398 } 6399 for (int j=0; j<NS; j++) { 6400 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6401 continue toploop; 6402 } 6403 } 6404 perm.clearModes(modeFlags); 6405 if (perm.modeFlags == 0) { 6406 it.remove(); 6407 } 6408 } 6409 if (perms.size() == 0) { 6410 mGrantedUriPermissions.remove( 6411 mGrantedUriPermissions.keyAt(i)); 6412 N--; 6413 i--; 6414 } 6415 } 6416 } 6417 } 6418 6419 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6420 int modeFlags) { 6421 synchronized(this) { 6422 final ProcessRecord r = getRecordForAppLocked(caller); 6423 if (r == null) { 6424 throw new SecurityException("Unable to find app for caller " 6425 + caller 6426 + " when revoking permission to uri " + uri); 6427 } 6428 if (uri == null) { 6429 Log.w(TAG, "revokeUriPermission: null uri"); 6430 return; 6431 } 6432 6433 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6434 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6435 if (modeFlags == 0) { 6436 return; 6437 } 6438 6439 final IPackageManager pm = ActivityThread.getPackageManager(); 6440 6441 final String authority = uri.getAuthority(); 6442 ProviderInfo pi = null; 6443 ContentProviderRecord cpr 6444 = (ContentProviderRecord)mProvidersByName.get(authority); 6445 if (cpr != null) { 6446 pi = cpr.info; 6447 } else { 6448 try { 6449 pi = pm.resolveContentProvider(authority, 6450 PackageManager.GET_URI_PERMISSION_PATTERNS); 6451 } catch (RemoteException ex) { 6452 } 6453 } 6454 if (pi == null) { 6455 Log.w(TAG, "No content provider found for: " + authority); 6456 return; 6457 } 6458 6459 revokeUriPermissionLocked(r.info.uid, uri, modeFlags); 6460 } 6461 } 6462 6463 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6464 synchronized (this) { 6465 ProcessRecord app = 6466 who != null ? getRecordForAppLocked(who) : null; 6467 if (app == null) return; 6468 6469 Message msg = Message.obtain(); 6470 msg.what = WAIT_FOR_DEBUGGER_MSG; 6471 msg.obj = app; 6472 msg.arg1 = waiting ? 1 : 0; 6473 mHandler.sendMessage(msg); 6474 } 6475 } 6476 6477 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6478 outInfo.availMem = Process.getFreeMemory(); 6479 outInfo.threshold = HOME_APP_MEM; 6480 outInfo.lowMemory = outInfo.availMem < 6481 (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2)); 6482 } 6483 6484 // ========================================================= 6485 // TASK MANAGEMENT 6486 // ========================================================= 6487 6488 public List getTasks(int maxNum, int flags, 6489 IThumbnailReceiver receiver) { 6490 ArrayList list = new ArrayList(); 6491 6492 PendingThumbnailsRecord pending = null; 6493 IApplicationThread topThumbnail = null; 6494 HistoryRecord topRecord = null; 6495 6496 synchronized(this) { 6497 if (localLOGV) Log.v( 6498 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6499 + ", receiver=" + receiver); 6500 6501 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6502 != PackageManager.PERMISSION_GRANTED) { 6503 if (receiver != null) { 6504 // If the caller wants to wait for pending thumbnails, 6505 // it ain't gonna get them. 6506 try { 6507 receiver.finished(); 6508 } catch (RemoteException ex) { 6509 } 6510 } 6511 String msg = "Permission Denial: getTasks() from pid=" 6512 + Binder.getCallingPid() 6513 + ", uid=" + Binder.getCallingUid() 6514 + " requires " + android.Manifest.permission.GET_TASKS; 6515 Log.w(TAG, msg); 6516 throw new SecurityException(msg); 6517 } 6518 6519 int pos = mHistory.size()-1; 6520 HistoryRecord next = 6521 pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null; 6522 HistoryRecord top = null; 6523 CharSequence topDescription = null; 6524 TaskRecord curTask = null; 6525 int numActivities = 0; 6526 int numRunning = 0; 6527 while (pos >= 0 && maxNum > 0) { 6528 final HistoryRecord r = next; 6529 pos--; 6530 next = pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null; 6531 6532 // Initialize state for next task if needed. 6533 if (top == null || 6534 (top.state == ActivityState.INITIALIZING 6535 && top.task == r.task)) { 6536 top = r; 6537 topDescription = r.description; 6538 curTask = r.task; 6539 numActivities = numRunning = 0; 6540 } 6541 6542 // Add 'r' into the current task. 6543 numActivities++; 6544 if (r.app != null && r.app.thread != null) { 6545 numRunning++; 6546 } 6547 if (topDescription == null) { 6548 topDescription = r.description; 6549 } 6550 6551 if (localLOGV) Log.v( 6552 TAG, r.intent.getComponent().flattenToShortString() 6553 + ": task=" + r.task); 6554 6555 // If the next one is a different task, generate a new 6556 // TaskInfo entry for what we have. 6557 if (next == null || next.task != curTask) { 6558 ActivityManager.RunningTaskInfo ci 6559 = new ActivityManager.RunningTaskInfo(); 6560 ci.id = curTask.taskId; 6561 ci.baseActivity = r.intent.getComponent(); 6562 ci.topActivity = top.intent.getComponent(); 6563 ci.thumbnail = top.thumbnail; 6564 ci.description = topDescription; 6565 ci.numActivities = numActivities; 6566 ci.numRunning = numRunning; 6567 //System.out.println( 6568 // "#" + maxNum + ": " + " descr=" + ci.description); 6569 if (ci.thumbnail == null && receiver != null) { 6570 if (localLOGV) Log.v( 6571 TAG, "State=" + top.state + "Idle=" + top.idle 6572 + " app=" + top.app 6573 + " thr=" + (top.app != null ? top.app.thread : null)); 6574 if (top.state == ActivityState.RESUMED 6575 || top.state == ActivityState.PAUSING) { 6576 if (top.idle && top.app != null 6577 && top.app.thread != null) { 6578 topRecord = top; 6579 topThumbnail = top.app.thread; 6580 } else { 6581 top.thumbnailNeeded = true; 6582 } 6583 } 6584 if (pending == null) { 6585 pending = new PendingThumbnailsRecord(receiver); 6586 } 6587 pending.pendingRecords.add(top); 6588 } 6589 list.add(ci); 6590 maxNum--; 6591 top = null; 6592 } 6593 } 6594 6595 if (pending != null) { 6596 mPendingThumbnails.add(pending); 6597 } 6598 } 6599 6600 if (localLOGV) Log.v(TAG, "We have pending thumbnails: " + pending); 6601 6602 if (topThumbnail != null) { 6603 if (localLOGV) Log.v(TAG, "Requesting top thumbnail"); 6604 try { 6605 topThumbnail.requestThumbnail(topRecord); 6606 } catch (Exception e) { 6607 Log.w(TAG, "Exception thrown when requesting thumbnail", e); 6608 sendPendingThumbnail(null, topRecord, null, null, true); 6609 } 6610 } 6611 6612 if (pending == null && receiver != null) { 6613 // In this case all thumbnails were available and the client 6614 // is being asked to be told when the remaining ones come in... 6615 // which is unusually, since the top-most currently running 6616 // activity should never have a canned thumbnail! Oh well. 6617 try { 6618 receiver.finished(); 6619 } catch (RemoteException ex) { 6620 } 6621 } 6622 6623 return list; 6624 } 6625 6626 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6627 int flags) { 6628 synchronized (this) { 6629 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6630 "getRecentTasks()"); 6631 6632 final int N = mRecentTasks.size(); 6633 ArrayList<ActivityManager.RecentTaskInfo> res 6634 = new ArrayList<ActivityManager.RecentTaskInfo>( 6635 maxNum < N ? maxNum : N); 6636 for (int i=0; i<N && maxNum > 0; i++) { 6637 TaskRecord tr = mRecentTasks.get(i); 6638 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6639 || (tr.intent == null) 6640 || ((tr.intent.getFlags() 6641 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6642 ActivityManager.RecentTaskInfo rti 6643 = new ActivityManager.RecentTaskInfo(); 6644 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6645 rti.baseIntent = new Intent( 6646 tr.intent != null ? tr.intent : tr.affinityIntent); 6647 rti.origActivity = tr.origActivity; 6648 res.add(rti); 6649 maxNum--; 6650 } 6651 } 6652 return res; 6653 } 6654 } 6655 6656 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 6657 int j; 6658 TaskRecord startTask = ((HistoryRecord)mHistory.get(startIndex)).task; 6659 TaskRecord jt = startTask; 6660 6661 // First look backwards 6662 for (j=startIndex-1; j>=0; j--) { 6663 HistoryRecord r = (HistoryRecord)mHistory.get(j); 6664 if (r.task != jt) { 6665 jt = r.task; 6666 if (affinity.equals(jt.affinity)) { 6667 return j; 6668 } 6669 } 6670 } 6671 6672 // Now look forwards 6673 final int N = mHistory.size(); 6674 jt = startTask; 6675 for (j=startIndex+1; j<N; j++) { 6676 HistoryRecord r = (HistoryRecord)mHistory.get(j); 6677 if (r.task != jt) { 6678 if (affinity.equals(jt.affinity)) { 6679 return j; 6680 } 6681 jt = r.task; 6682 } 6683 } 6684 6685 // Might it be at the top? 6686 if (affinity.equals(((HistoryRecord)mHistory.get(N-1)).task.affinity)) { 6687 return N-1; 6688 } 6689 6690 return -1; 6691 } 6692 6693 /** 6694 * Perform a reset of the given task, if needed as part of launching it. 6695 * Returns the new HistoryRecord at the top of the task. 6696 */ 6697 private final HistoryRecord resetTaskIfNeededLocked(HistoryRecord taskTop, 6698 HistoryRecord newActivity) { 6699 boolean forceReset = (newActivity.info.flags 6700 &ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0; 6701 if (taskTop.task.getInactiveDuration() > ACTIVITY_INACTIVE_RESET_TIME) { 6702 if ((newActivity.info.flags 6703 &ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE) == 0) { 6704 forceReset = true; 6705 } 6706 } 6707 6708 final TaskRecord task = taskTop.task; 6709 6710 // We are going to move through the history list so that we can look 6711 // at each activity 'target' with 'below' either the interesting 6712 // activity immediately below it in the stack or null. 6713 HistoryRecord target = null; 6714 int targetI = 0; 6715 int taskTopI = -1; 6716 int replyChainEnd = -1; 6717 int lastReparentPos = -1; 6718 for (int i=mHistory.size()-1; i>=-1; i--) { 6719 HistoryRecord below = i >= 0 ? (HistoryRecord)mHistory.get(i) : null; 6720 6721 if (below != null && below.finishing) { 6722 continue; 6723 } 6724 if (target == null) { 6725 target = below; 6726 targetI = i; 6727 // If we were in the middle of a reply chain before this 6728 // task, it doesn't appear like the root of the chain wants 6729 // anything interesting, so drop it. 6730 replyChainEnd = -1; 6731 continue; 6732 } 6733 6734 final int flags = target.info.flags; 6735 6736 final boolean finishOnTaskLaunch = 6737 (flags&ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0; 6738 final boolean allowTaskReparenting = 6739 (flags&ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0; 6740 6741 if (target.task == task) { 6742 // We are inside of the task being reset... we'll either 6743 // finish this activity, push it out for another task, 6744 // or leave it as-is. We only do this 6745 // for activities that are not the root of the task (since 6746 // if we finish the root, we may no longer have the task!). 6747 if (taskTopI < 0) { 6748 taskTopI = targetI; 6749 } 6750 if (below != null && below.task == task) { 6751 final boolean clearWhenTaskReset = 6752 (target.intent.getFlags() 6753 &Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0; 6754 if (!finishOnTaskLaunch && !clearWhenTaskReset && target.resultTo != null) { 6755 // If this activity is sending a reply to a previous 6756 // activity, we can't do anything with it now until 6757 // we reach the start of the reply chain. 6758 // XXX note that we are assuming the result is always 6759 // to the previous activity, which is almost always 6760 // the case but we really shouldn't count on. 6761 if (replyChainEnd < 0) { 6762 replyChainEnd = targetI; 6763 } 6764 } else if (!finishOnTaskLaunch && !clearWhenTaskReset && allowTaskReparenting 6765 && target.taskAffinity != null 6766 && !target.taskAffinity.equals(task.affinity)) { 6767 // If this activity has an affinity for another 6768 // task, then we need to move it out of here. We will 6769 // move it as far out of the way as possible, to the 6770 // bottom of the activity stack. This also keeps it 6771 // correctly ordered with any activities we previously 6772 // moved. 6773 HistoryRecord p = (HistoryRecord)mHistory.get(0); 6774 if (target.taskAffinity != null 6775 && target.taskAffinity.equals(p.task.affinity)) { 6776 // If the activity currently at the bottom has the 6777 // same task affinity as the one we are moving, 6778 // then merge it into the same task. 6779 target.task = p.task; 6780 if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target 6781 + " out to bottom task " + p.task); 6782 } else { 6783 mCurTask++; 6784 if (mCurTask <= 0) { 6785 mCurTask = 1; 6786 } 6787 target.task = new TaskRecord(mCurTask, target.info, null, 6788 (target.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0); 6789 target.task.affinityIntent = target.intent; 6790 if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target 6791 + " out to new task " + target.task); 6792 } 6793 mWindowManager.setAppGroupId(target, task.taskId); 6794 if (replyChainEnd < 0) { 6795 replyChainEnd = targetI; 6796 } 6797 int dstPos = 0; 6798 for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) { 6799 p = (HistoryRecord)mHistory.get(srcPos); 6800 if (p.finishing) { 6801 continue; 6802 } 6803 if (DEBUG_TASKS) Log.v(TAG, "Pushing next activity " + p 6804 + " out to target's task " + target.task); 6805 task.numActivities--; 6806 p.task = target.task; 6807 target.task.numActivities++; 6808 mHistory.remove(srcPos); 6809 mHistory.add(dstPos, p); 6810 mWindowManager.moveAppToken(dstPos, p); 6811 mWindowManager.setAppGroupId(p, p.task.taskId); 6812 dstPos++; 6813 if (VALIDATE_TOKENS) { 6814 mWindowManager.validateAppTokens(mHistory); 6815 } 6816 i++; 6817 } 6818 if (taskTop == p) { 6819 taskTop = below; 6820 } 6821 if (taskTopI == replyChainEnd) { 6822 taskTopI = -1; 6823 } 6824 replyChainEnd = -1; 6825 addRecentTask(target.task); 6826 } else if (forceReset || finishOnTaskLaunch 6827 || clearWhenTaskReset) { 6828 // If the activity should just be removed -- either 6829 // because it asks for it, or the task should be 6830 // cleared -- then finish it and anything that is 6831 // part of its reply chain. 6832 if (clearWhenTaskReset) { 6833 // In this case, we want to finish this activity 6834 // and everything above it, so be sneaky and pretend 6835 // like these are all in the reply chain. 6836 replyChainEnd = targetI+1; 6837 while (replyChainEnd < mHistory.size() && 6838 ((HistoryRecord)mHistory.get( 6839 replyChainEnd)).task == task) { 6840 replyChainEnd++; 6841 } 6842 replyChainEnd--; 6843 } else if (replyChainEnd < 0) { 6844 replyChainEnd = targetI; 6845 } 6846 HistoryRecord p = null; 6847 for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) { 6848 p = (HistoryRecord)mHistory.get(srcPos); 6849 if (p.finishing) { 6850 continue; 6851 } 6852 if (finishActivityLocked(p, srcPos, 6853 Activity.RESULT_CANCELED, null, "reset")) { 6854 replyChainEnd--; 6855 srcPos--; 6856 } 6857 } 6858 if (taskTop == p) { 6859 taskTop = below; 6860 } 6861 if (taskTopI == replyChainEnd) { 6862 taskTopI = -1; 6863 } 6864 replyChainEnd = -1; 6865 } else { 6866 // If we were in the middle of a chain, well the 6867 // activity that started it all doesn't want anything 6868 // special, so leave it all as-is. 6869 replyChainEnd = -1; 6870 } 6871 } else { 6872 // Reached the bottom of the task -- any reply chain 6873 // should be left as-is. 6874 replyChainEnd = -1; 6875 } 6876 6877 } else if (target.resultTo != null) { 6878 // If this activity is sending a reply to a previous 6879 // activity, we can't do anything with it now until 6880 // we reach the start of the reply chain. 6881 // XXX note that we are assuming the result is always 6882 // to the previous activity, which is almost always 6883 // the case but we really shouldn't count on. 6884 if (replyChainEnd < 0) { 6885 replyChainEnd = targetI; 6886 } 6887 6888 } else if (taskTopI >= 0 && allowTaskReparenting 6889 && task.affinity != null 6890 && task.affinity.equals(target.taskAffinity)) { 6891 // We are inside of another task... if this activity has 6892 // an affinity for our task, then either remove it if we are 6893 // clearing or move it over to our task. Note that 6894 // we currently punt on the case where we are resetting a 6895 // task that is not at the top but who has activities above 6896 // with an affinity to it... this is really not a normal 6897 // case, and we will need to later pull that task to the front 6898 // and usually at that point we will do the reset and pick 6899 // up those remaining activities. (This only happens if 6900 // someone starts an activity in a new task from an activity 6901 // in a task that is not currently on top.) 6902 if (forceReset || finishOnTaskLaunch) { 6903 if (replyChainEnd < 0) { 6904 replyChainEnd = targetI; 6905 } 6906 HistoryRecord p = null; 6907 for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) { 6908 p = (HistoryRecord)mHistory.get(srcPos); 6909 if (p.finishing) { 6910 continue; 6911 } 6912 if (finishActivityLocked(p, srcPos, 6913 Activity.RESULT_CANCELED, null, "reset")) { 6914 taskTopI--; 6915 lastReparentPos--; 6916 replyChainEnd--; 6917 srcPos--; 6918 } 6919 } 6920 replyChainEnd = -1; 6921 } else { 6922 if (replyChainEnd < 0) { 6923 replyChainEnd = targetI; 6924 } 6925 for (int srcPos=replyChainEnd; srcPos>=targetI; srcPos--) { 6926 HistoryRecord p = (HistoryRecord)mHistory.get(srcPos); 6927 if (p.finishing) { 6928 continue; 6929 } 6930 if (lastReparentPos < 0) { 6931 lastReparentPos = taskTopI; 6932 taskTop = p; 6933 } else { 6934 lastReparentPos--; 6935 } 6936 mHistory.remove(srcPos); 6937 p.task.numActivities--; 6938 p.task = task; 6939 mHistory.add(lastReparentPos, p); 6940 if (DEBUG_TASKS) Log.v(TAG, "Pulling activity " + p 6941 + " in to resetting task " + task); 6942 task.numActivities++; 6943 mWindowManager.moveAppToken(lastReparentPos, p); 6944 mWindowManager.setAppGroupId(p, p.task.taskId); 6945 if (VALIDATE_TOKENS) { 6946 mWindowManager.validateAppTokens(mHistory); 6947 } 6948 } 6949 replyChainEnd = -1; 6950 6951 // Now we've moved it in to place... but what if this is 6952 // a singleTop activity and we have put it on top of another 6953 // instance of the same activity? Then we drop the instance 6954 // below so it remains singleTop. 6955 if (target.info.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) { 6956 for (int j=lastReparentPos-1; j>=0; j--) { 6957 HistoryRecord p = (HistoryRecord)mHistory.get(j); 6958 if (p.finishing) { 6959 continue; 6960 } 6961 if (p.intent.getComponent().equals(target.intent.getComponent())) { 6962 if (finishActivityLocked(p, j, 6963 Activity.RESULT_CANCELED, null, "replace")) { 6964 taskTopI--; 6965 lastReparentPos--; 6966 } 6967 } 6968 } 6969 } 6970 } 6971 } 6972 6973 target = below; 6974 targetI = i; 6975 } 6976 6977 return taskTop; 6978 } 6979 6980 /** 6981 * TODO: Add mController hook 6982 */ 6983 public void moveTaskToFront(int task) { 6984 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6985 "moveTaskToFront()"); 6986 6987 synchronized(this) { 6988 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6989 Binder.getCallingUid(), "Task to front")) { 6990 return; 6991 } 6992 final long origId = Binder.clearCallingIdentity(); 6993 try { 6994 int N = mRecentTasks.size(); 6995 for (int i=0; i<N; i++) { 6996 TaskRecord tr = mRecentTasks.get(i); 6997 if (tr.taskId == task) { 6998 moveTaskToFrontLocked(tr, null); 6999 return; 7000 } 7001 } 7002 for (int i=mHistory.size()-1; i>=0; i--) { 7003 HistoryRecord hr = (HistoryRecord)mHistory.get(i); 7004 if (hr.task.taskId == task) { 7005 moveTaskToFrontLocked(hr.task, null); 7006 return; 7007 } 7008 } 7009 } finally { 7010 Binder.restoreCallingIdentity(origId); 7011 } 7012 } 7013 } 7014 7015 private final void moveTaskToFrontLocked(TaskRecord tr, HistoryRecord reason) { 7016 if (DEBUG_SWITCH) Log.v(TAG, "moveTaskToFront: " + tr); 7017 7018 final int task = tr.taskId; 7019 int top = mHistory.size()-1; 7020 7021 if (top < 0 || ((HistoryRecord)mHistory.get(top)).task.taskId == task) { 7022 // nothing to do! 7023 return; 7024 } 7025 7026 ArrayList moved = new ArrayList(); 7027 7028 // Applying the affinities may have removed entries from the history, 7029 // so get the size again. 7030 top = mHistory.size()-1; 7031 int pos = top; 7032 7033 // Shift all activities with this task up to the top 7034 // of the stack, keeping them in the same internal order. 7035 while (pos >= 0) { 7036 HistoryRecord r = (HistoryRecord)mHistory.get(pos); 7037 if (localLOGV) Log.v( 7038 TAG, "At " + pos + " ckp " + r.task + ": " + r); 7039 boolean first = true; 7040 if (r.task.taskId == task) { 7041 if (localLOGV) Log.v(TAG, "Removing and adding at " + top); 7042 mHistory.remove(pos); 7043 mHistory.add(top, r); 7044 moved.add(0, r); 7045 top--; 7046 if (first) { 7047 addRecentTask(r.task); 7048 first = false; 7049 } 7050 } 7051 pos--; 7052 } 7053 7054 if (DEBUG_TRANSITION) Log.v(TAG, 7055 "Prepare to front transition: task=" + tr); 7056 if (reason != null && 7057 (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { 7058 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 7059 HistoryRecord r = topRunningActivityLocked(null); 7060 if (r != null) { 7061 mNoAnimActivities.add(r); 7062 } 7063 } else { 7064 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT); 7065 } 7066 7067 mWindowManager.moveAppTokensToTop(moved); 7068 if (VALIDATE_TOKENS) { 7069 mWindowManager.validateAppTokens(mHistory); 7070 } 7071 7072 finishTaskMove(task); 7073 EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, task); 7074 } 7075 7076 private final void finishTaskMove(int task) { 7077 resumeTopActivityLocked(null); 7078 } 7079 7080 public void moveTaskToBack(int task) { 7081 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7082 "moveTaskToBack()"); 7083 7084 synchronized(this) { 7085 if (mResumedActivity != null && mResumedActivity.task.taskId == task) { 7086 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7087 Binder.getCallingUid(), "Task to back")) { 7088 return; 7089 } 7090 } 7091 final long origId = Binder.clearCallingIdentity(); 7092 moveTaskToBackLocked(task, null); 7093 Binder.restoreCallingIdentity(origId); 7094 } 7095 } 7096 7097 /** 7098 * Moves an activity, and all of the other activities within the same task, to the bottom 7099 * of the history stack. The activity's order within the task is unchanged. 7100 * 7101 * @param token A reference to the activity we wish to move 7102 * @param nonRoot If false then this only works if the activity is the root 7103 * of a task; if true it will work for any activity in a task. 7104 * @return Returns true if the move completed, false if not. 7105 */ 7106 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7107 synchronized(this) { 7108 final long origId = Binder.clearCallingIdentity(); 7109 int taskId = getTaskForActivityLocked(token, !nonRoot); 7110 if (taskId >= 0) { 7111 return moveTaskToBackLocked(taskId, null); 7112 } 7113 Binder.restoreCallingIdentity(origId); 7114 } 7115 return false; 7116 } 7117 7118 /** 7119 * Worker method for rearranging history stack. Implements the function of moving all 7120 * activities for a specific task (gathering them if disjoint) into a single group at the 7121 * bottom of the stack. 7122 * 7123 * If a watcher is installed, the action is preflighted and the watcher has an opportunity 7124 * to premeptively cancel the move. 7125 * 7126 * @param task The taskId to collect and move to the bottom. 7127 * @return Returns true if the move completed, false if not. 7128 */ 7129 private final boolean moveTaskToBackLocked(int task, HistoryRecord reason) { 7130 Log.i(TAG, "moveTaskToBack: " + task); 7131 7132 // If we have a watcher, preflight the move before committing to it. First check 7133 // for *other* available tasks, but if none are available, then try again allowing the 7134 // current task to be selected. 7135 if (mController != null) { 7136 HistoryRecord next = topRunningActivityLocked(null, task); 7137 if (next == null) { 7138 next = topRunningActivityLocked(null, 0); 7139 } 7140 if (next != null) { 7141 // ask watcher if this is allowed 7142 boolean moveOK = true; 7143 try { 7144 moveOK = mController.activityResuming(next.packageName); 7145 } catch (RemoteException e) { 7146 mController = null; 7147 } 7148 if (!moveOK) { 7149 return false; 7150 } 7151 } 7152 } 7153 7154 ArrayList moved = new ArrayList(); 7155 7156 if (DEBUG_TRANSITION) Log.v(TAG, 7157 "Prepare to back transition: task=" + task); 7158 7159 final int N = mHistory.size(); 7160 int bottom = 0; 7161 int pos = 0; 7162 7163 // Shift all activities with this task down to the bottom 7164 // of the stack, keeping them in the same internal order. 7165 while (pos < N) { 7166 HistoryRecord r = (HistoryRecord)mHistory.get(pos); 7167 if (localLOGV) Log.v( 7168 TAG, "At " + pos + " ckp " + r.task + ": " + r); 7169 if (r.task.taskId == task) { 7170 if (localLOGV) Log.v(TAG, "Removing and adding at " + (N-1)); 7171 mHistory.remove(pos); 7172 mHistory.add(bottom, r); 7173 moved.add(r); 7174 bottom++; 7175 } 7176 pos++; 7177 } 7178 7179 if (reason != null && 7180 (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { 7181 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 7182 HistoryRecord r = topRunningActivityLocked(null); 7183 if (r != null) { 7184 mNoAnimActivities.add(r); 7185 } 7186 } else { 7187 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_BACK); 7188 } 7189 mWindowManager.moveAppTokensToBottom(moved); 7190 if (VALIDATE_TOKENS) { 7191 mWindowManager.validateAppTokens(mHistory); 7192 } 7193 7194 finishTaskMove(task); 7195 return true; 7196 } 7197 7198 public void moveTaskBackwards(int task) { 7199 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7200 "moveTaskBackwards()"); 7201 7202 synchronized(this) { 7203 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7204 Binder.getCallingUid(), "Task backwards")) { 7205 return; 7206 } 7207 final long origId = Binder.clearCallingIdentity(); 7208 moveTaskBackwardsLocked(task); 7209 Binder.restoreCallingIdentity(origId); 7210 } 7211 } 7212 7213 private final void moveTaskBackwardsLocked(int task) { 7214 Log.e(TAG, "moveTaskBackwards not yet implemented!"); 7215 } 7216 7217 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7218 synchronized(this) { 7219 return getTaskForActivityLocked(token, onlyRoot); 7220 } 7221 } 7222 7223 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 7224 final int N = mHistory.size(); 7225 TaskRecord lastTask = null; 7226 for (int i=0; i<N; i++) { 7227 HistoryRecord r = (HistoryRecord)mHistory.get(i); 7228 if (r == token) { 7229 if (!onlyRoot || lastTask != r.task) { 7230 return r.task.taskId; 7231 } 7232 return -1; 7233 } 7234 lastTask = r.task; 7235 } 7236 7237 return -1; 7238 } 7239 7240 /** 7241 * Returns the top activity in any existing task matching the given 7242 * Intent. Returns null if no such task is found. 7243 */ 7244 private HistoryRecord findTaskLocked(Intent intent, ActivityInfo info) { 7245 ComponentName cls = intent.getComponent(); 7246 if (info.targetActivity != null) { 7247 cls = new ComponentName(info.packageName, info.targetActivity); 7248 } 7249 7250 TaskRecord cp = null; 7251 7252 final int N = mHistory.size(); 7253 for (int i=(N-1); i>=0; i--) { 7254 HistoryRecord r = (HistoryRecord)mHistory.get(i); 7255 if (!r.finishing && r.task != cp 7256 && r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 7257 cp = r.task; 7258 //Log.i(TAG, "Comparing existing cls=" + r.task.intent.getComponent().flattenToShortString() 7259 // + "/aff=" + r.task.affinity + " to new cls=" 7260 // + intent.getComponent().flattenToShortString() + "/aff=" + taskAffinity); 7261 if (r.task.affinity != null) { 7262 if (r.task.affinity.equals(info.taskAffinity)) { 7263 //Log.i(TAG, "Found matching affinity!"); 7264 return r; 7265 } 7266 } else if (r.task.intent != null 7267 && r.task.intent.getComponent().equals(cls)) { 7268 //Log.i(TAG, "Found matching class!"); 7269 //dump(); 7270 //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent); 7271 return r; 7272 } else if (r.task.affinityIntent != null 7273 && r.task.affinityIntent.getComponent().equals(cls)) { 7274 //Log.i(TAG, "Found matching class!"); 7275 //dump(); 7276 //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent); 7277 return r; 7278 } 7279 } 7280 } 7281 7282 return null; 7283 } 7284 7285 /** 7286 * Returns the first activity (starting from the top of the stack) that 7287 * is the same as the given activity. Returns null if no such activity 7288 * is found. 7289 */ 7290 private HistoryRecord findActivityLocked(Intent intent, ActivityInfo info) { 7291 ComponentName cls = intent.getComponent(); 7292 if (info.targetActivity != null) { 7293 cls = new ComponentName(info.packageName, info.targetActivity); 7294 } 7295 7296 final int N = mHistory.size(); 7297 for (int i=(N-1); i>=0; i--) { 7298 HistoryRecord r = (HistoryRecord)mHistory.get(i); 7299 if (!r.finishing) { 7300 if (r.intent.getComponent().equals(cls)) { 7301 //Log.i(TAG, "Found matching class!"); 7302 //dump(); 7303 //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent); 7304 return r; 7305 } 7306 } 7307 } 7308 7309 return null; 7310 } 7311 7312 public void finishOtherInstances(IBinder token, ComponentName className) { 7313 synchronized(this) { 7314 final long origId = Binder.clearCallingIdentity(); 7315 7316 int N = mHistory.size(); 7317 TaskRecord lastTask = null; 7318 for (int i=0; i<N; i++) { 7319 HistoryRecord r = (HistoryRecord)mHistory.get(i); 7320 if (r.realActivity.equals(className) 7321 && r != token && lastTask != r.task) { 7322 if (finishActivityLocked(r, i, Activity.RESULT_CANCELED, 7323 null, "others")) { 7324 i--; 7325 N--; 7326 } 7327 } 7328 lastTask = r.task; 7329 } 7330 7331 Binder.restoreCallingIdentity(origId); 7332 } 7333 } 7334 7335 // ========================================================= 7336 // THUMBNAILS 7337 // ========================================================= 7338 7339 public void reportThumbnail(IBinder token, 7340 Bitmap thumbnail, CharSequence description) { 7341 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7342 final long origId = Binder.clearCallingIdentity(); 7343 sendPendingThumbnail(null, token, thumbnail, description, true); 7344 Binder.restoreCallingIdentity(origId); 7345 } 7346 7347 final void sendPendingThumbnail(HistoryRecord r, IBinder token, 7348 Bitmap thumbnail, CharSequence description, boolean always) { 7349 TaskRecord task = null; 7350 ArrayList receivers = null; 7351 7352 //System.out.println("Send pending thumbnail: " + r); 7353 7354 synchronized(this) { 7355 if (r == null) { 7356 int index = indexOfTokenLocked(token); 7357 if (index < 0) { 7358 return; 7359 } 7360 r = (HistoryRecord)mHistory.get(index); 7361 } 7362 if (thumbnail == null) { 7363 thumbnail = r.thumbnail; 7364 description = r.description; 7365 } 7366 if (thumbnail == null && !always) { 7367 // If there is no thumbnail, and this entry is not actually 7368 // going away, then abort for now and pick up the next 7369 // thumbnail we get. 7370 return; 7371 } 7372 task = r.task; 7373 7374 int N = mPendingThumbnails.size(); 7375 int i=0; 7376 while (i<N) { 7377 PendingThumbnailsRecord pr = 7378 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 7379 //System.out.println("Looking in " + pr.pendingRecords); 7380 if (pr.pendingRecords.remove(r)) { 7381 if (receivers == null) { 7382 receivers = new ArrayList(); 7383 } 7384 receivers.add(pr); 7385 if (pr.pendingRecords.size() == 0) { 7386 pr.finished = true; 7387 mPendingThumbnails.remove(i); 7388 N--; 7389 continue; 7390 } 7391 } 7392 i++; 7393 } 7394 } 7395 7396 if (receivers != null) { 7397 final int N = receivers.size(); 7398 for (int i=0; i<N; i++) { 7399 try { 7400 PendingThumbnailsRecord pr = 7401 (PendingThumbnailsRecord)receivers.get(i); 7402 pr.receiver.newThumbnail( 7403 task != null ? task.taskId : -1, thumbnail, description); 7404 if (pr.finished) { 7405 pr.receiver.finished(); 7406 } 7407 } catch (Exception e) { 7408 Log.w(TAG, "Exception thrown when sending thumbnail", e); 7409 } 7410 } 7411 } 7412 } 7413 7414 // ========================================================= 7415 // CONTENT PROVIDERS 7416 // ========================================================= 7417 7418 private final List generateApplicationProvidersLocked(ProcessRecord app) { 7419 List providers = null; 7420 try { 7421 providers = ActivityThread.getPackageManager(). 7422 queryContentProviders(app.processName, app.info.uid, 7423 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7424 } catch (RemoteException ex) { 7425 } 7426 if (providers != null) { 7427 final int N = providers.size(); 7428 for (int i=0; i<N; i++) { 7429 ProviderInfo cpi = 7430 (ProviderInfo)providers.get(i); 7431 ContentProviderRecord cpr = 7432 (ContentProviderRecord)mProvidersByClass.get(cpi.name); 7433 if (cpr == null) { 7434 cpr = new ContentProviderRecord(cpi, app.info); 7435 mProvidersByClass.put(cpi.name, cpr); 7436 } 7437 app.pubProviders.put(cpi.name, cpr); 7438 app.addPackage(cpi.applicationInfo.packageName); 7439 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7440 } 7441 } 7442 return providers; 7443 } 7444 7445 private final String checkContentProviderPermissionLocked( 7446 ProviderInfo cpi, ProcessRecord r, int mode) { 7447 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7448 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid(); 7449 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7450 cpi.exported ? -1 : cpi.applicationInfo.uid) 7451 == PackageManager.PERMISSION_GRANTED 7452 && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) { 7453 return null; 7454 } 7455 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7456 cpi.exported ? -1 : cpi.applicationInfo.uid) 7457 == PackageManager.PERMISSION_GRANTED) { 7458 return null; 7459 } 7460 7461 PathPermission[] pps = cpi.pathPermissions; 7462 if (pps != null) { 7463 int i = pps.length; 7464 while (i > 0) { 7465 i--; 7466 PathPermission pp = pps[i]; 7467 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7468 cpi.exported ? -1 : cpi.applicationInfo.uid) 7469 == PackageManager.PERMISSION_GRANTED 7470 && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) { 7471 return null; 7472 } 7473 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7474 cpi.exported ? -1 : cpi.applicationInfo.uid) 7475 == PackageManager.PERMISSION_GRANTED) { 7476 return null; 7477 } 7478 } 7479 } 7480 7481 String msg = "Permission Denial: opening provider " + cpi.name 7482 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7483 + ", uid=" + callingUid + ") requires " 7484 + cpi.readPermission + " or " + cpi.writePermission; 7485 Log.w(TAG, msg); 7486 return msg; 7487 } 7488 7489 private final ContentProviderHolder getContentProviderImpl( 7490 IApplicationThread caller, String name) { 7491 ContentProviderRecord cpr; 7492 ProviderInfo cpi = null; 7493 7494 synchronized(this) { 7495 ProcessRecord r = null; 7496 if (caller != null) { 7497 r = getRecordForAppLocked(caller); 7498 if (r == null) { 7499 throw new SecurityException( 7500 "Unable to find app for caller " + caller 7501 + " (pid=" + Binder.getCallingPid() 7502 + ") when getting content provider " + name); 7503 } 7504 } 7505 7506 // First check if this content provider has been published... 7507 cpr = (ContentProviderRecord)mProvidersByName.get(name); 7508 if (cpr != null) { 7509 cpi = cpr.info; 7510 if (checkContentProviderPermissionLocked(cpi, r, -1) != null) { 7511 return new ContentProviderHolder(cpi, 7512 cpi.readPermission != null 7513 ? cpi.readPermission : cpi.writePermission); 7514 } 7515 7516 if (r != null && cpr.canRunHere(r)) { 7517 // This provider has been published or is in the process 7518 // of being published... but it is also allowed to run 7519 // in the caller's process, so don't make a connection 7520 // and just let the caller instantiate its own instance. 7521 if (cpr.provider != null) { 7522 // don't give caller the provider object, it needs 7523 // to make its own. 7524 cpr = new ContentProviderRecord(cpr); 7525 } 7526 return cpr; 7527 } 7528 7529 final long origId = Binder.clearCallingIdentity(); 7530 7531 // In this case the provider instance already exists, so we can 7532 // return it right away. 7533 if (r != null) { 7534 if (DEBUG_PROVIDER) Log.v(TAG, 7535 "Adding provider requested by " 7536 + r.processName + " from process " 7537 + cpr.info.processName); 7538 Integer cnt = r.conProviders.get(cpr); 7539 if (cnt == null) { 7540 r.conProviders.put(cpr, new Integer(1)); 7541 } else { 7542 r.conProviders.put(cpr, new Integer(cnt.intValue()+1)); 7543 } 7544 cpr.clients.add(r); 7545 } else { 7546 cpr.externals++; 7547 } 7548 7549 if (cpr.app != null) { 7550 updateOomAdjLocked(cpr.app); 7551 } 7552 7553 Binder.restoreCallingIdentity(origId); 7554 7555 } else { 7556 try { 7557 cpi = ActivityThread.getPackageManager(). 7558 resolveContentProvider(name, 7559 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7560 } catch (RemoteException ex) { 7561 } 7562 if (cpi == null) { 7563 return null; 7564 } 7565 7566 if (checkContentProviderPermissionLocked(cpi, r, -1) != null) { 7567 return new ContentProviderHolder(cpi, 7568 cpi.readPermission != null 7569 ? cpi.readPermission : cpi.writePermission); 7570 } 7571 7572 cpr = (ContentProviderRecord)mProvidersByClass.get(cpi.name); 7573 final boolean firstClass = cpr == null; 7574 if (firstClass) { 7575 try { 7576 ApplicationInfo ai = 7577 ActivityThread.getPackageManager(). 7578 getApplicationInfo( 7579 cpi.applicationInfo.packageName, 7580 STOCK_PM_FLAGS); 7581 if (ai == null) { 7582 Log.w(TAG, "No package info for content provider " 7583 + cpi.name); 7584 return null; 7585 } 7586 cpr = new ContentProviderRecord(cpi, ai); 7587 } catch (RemoteException ex) { 7588 // pm is in same process, this will never happen. 7589 } 7590 } 7591 7592 if (r != null && cpr.canRunHere(r)) { 7593 // If this is a multiprocess provider, then just return its 7594 // info and allow the caller to instantiate it. Only do 7595 // this if the provider is the same user as the caller's 7596 // process, or can run as root (so can be in any process). 7597 return cpr; 7598 } 7599 7600 if (DEBUG_PROVIDER) { 7601 RuntimeException e = new RuntimeException("here"); 7602 Log.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid 7603 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7604 } 7605 7606 // This is single process, and our app is now connecting to it. 7607 // See if we are already in the process of launching this 7608 // provider. 7609 final int N = mLaunchingProviders.size(); 7610 int i; 7611 for (i=0; i<N; i++) { 7612 if (mLaunchingProviders.get(i) == cpr) { 7613 break; 7614 } 7615 } 7616 7617 // If the provider is not already being launched, then get it 7618 // started. 7619 if (i >= N) { 7620 final long origId = Binder.clearCallingIdentity(); 7621 ProcessRecord proc = startProcessLocked(cpi.processName, 7622 cpr.appInfo, false, 0, "content provider", 7623 new ComponentName(cpi.applicationInfo.packageName, 7624 cpi.name), false); 7625 if (proc == null) { 7626 Log.w(TAG, "Unable to launch app " 7627 + cpi.applicationInfo.packageName + "/" 7628 + cpi.applicationInfo.uid + " for provider " 7629 + name + ": process is bad"); 7630 return null; 7631 } 7632 cpr.launchingApp = proc; 7633 mLaunchingProviders.add(cpr); 7634 Binder.restoreCallingIdentity(origId); 7635 } 7636 7637 // Make sure the provider is published (the same provider class 7638 // may be published under multiple names). 7639 if (firstClass) { 7640 mProvidersByClass.put(cpi.name, cpr); 7641 } 7642 mProvidersByName.put(name, cpr); 7643 7644 if (r != null) { 7645 if (DEBUG_PROVIDER) Log.v(TAG, 7646 "Adding provider requested by " 7647 + r.processName + " from process " 7648 + cpr.info.processName); 7649 Integer cnt = r.conProviders.get(cpr); 7650 if (cnt == null) { 7651 r.conProviders.put(cpr, new Integer(1)); 7652 } else { 7653 r.conProviders.put(cpr, new Integer(cnt.intValue()+1)); 7654 } 7655 cpr.clients.add(r); 7656 } else { 7657 cpr.externals++; 7658 } 7659 } 7660 } 7661 7662 // Wait for the provider to be published... 7663 synchronized (cpr) { 7664 while (cpr.provider == null) { 7665 if (cpr.launchingApp == null) { 7666 Log.w(TAG, "Unable to launch app " 7667 + cpi.applicationInfo.packageName + "/" 7668 + cpi.applicationInfo.uid + " for provider " 7669 + name + ": launching app became null"); 7670 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7671 cpi.applicationInfo.packageName, 7672 cpi.applicationInfo.uid, name); 7673 return null; 7674 } 7675 try { 7676 cpr.wait(); 7677 } catch (InterruptedException ex) { 7678 } 7679 } 7680 } 7681 return cpr; 7682 } 7683 7684 public final ContentProviderHolder getContentProvider( 7685 IApplicationThread caller, String name) { 7686 if (caller == null) { 7687 String msg = "null IApplicationThread when getting content provider " 7688 + name; 7689 Log.w(TAG, msg); 7690 throw new SecurityException(msg); 7691 } 7692 7693 return getContentProviderImpl(caller, name); 7694 } 7695 7696 private ContentProviderHolder getContentProviderExternal(String name) { 7697 return getContentProviderImpl(null, name); 7698 } 7699 7700 /** 7701 * Drop a content provider from a ProcessRecord's bookkeeping 7702 * @param cpr 7703 */ 7704 public void removeContentProvider(IApplicationThread caller, String name) { 7705 synchronized (this) { 7706 ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name); 7707 if(cpr == null) { 7708 // remove from mProvidersByClass 7709 if (DEBUG_PROVIDER) Log.v(TAG, name + 7710 " provider not found in providers list"); 7711 return; 7712 } 7713 final ProcessRecord r = getRecordForAppLocked(caller); 7714 if (r == null) { 7715 throw new SecurityException( 7716 "Unable to find app for caller " + caller + 7717 " when removing content provider " + name); 7718 } 7719 //update content provider record entry info 7720 ContentProviderRecord localCpr = (ContentProviderRecord) 7721 mProvidersByClass.get(cpr.info.name); 7722 if (DEBUG_PROVIDER) Log.v(TAG, "Removing provider requested by " 7723 + r.info.processName + " from process " 7724 + localCpr.appInfo.processName); 7725 if (localCpr.app == r) { 7726 //should not happen. taken care of as a local provider 7727 Log.w(TAG, "removeContentProvider called on local provider: " 7728 + cpr.info.name + " in process " + r.processName); 7729 return; 7730 } else { 7731 Integer cnt = r.conProviders.get(localCpr); 7732 if (cnt == null || cnt.intValue() <= 1) { 7733 localCpr.clients.remove(r); 7734 r.conProviders.remove(localCpr); 7735 } else { 7736 r.conProviders.put(localCpr, new Integer(cnt.intValue()-1)); 7737 } 7738 } 7739 updateOomAdjLocked(); 7740 } 7741 } 7742 7743 private void removeContentProviderExternal(String name) { 7744 synchronized (this) { 7745 ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name); 7746 if(cpr == null) { 7747 //remove from mProvidersByClass 7748 if(localLOGV) Log.v(TAG, name+" content provider not found in providers list"); 7749 return; 7750 } 7751 7752 //update content provider record entry info 7753 ContentProviderRecord localCpr = (ContentProviderRecord) mProvidersByClass.get(cpr.info.name); 7754 localCpr.externals--; 7755 if (localCpr.externals < 0) { 7756 Log.e(TAG, "Externals < 0 for content provider " + localCpr); 7757 } 7758 updateOomAdjLocked(); 7759 } 7760 } 7761 7762 public final void publishContentProviders(IApplicationThread caller, 7763 List<ContentProviderHolder> providers) { 7764 if (providers == null) { 7765 return; 7766 } 7767 7768 synchronized(this) { 7769 final ProcessRecord r = getRecordForAppLocked(caller); 7770 if (r == null) { 7771 throw new SecurityException( 7772 "Unable to find app for caller " + caller 7773 + " (pid=" + Binder.getCallingPid() 7774 + ") when publishing content providers"); 7775 } 7776 7777 final long origId = Binder.clearCallingIdentity(); 7778 7779 final int N = providers.size(); 7780 for (int i=0; i<N; i++) { 7781 ContentProviderHolder src = providers.get(i); 7782 if (src == null || src.info == null || src.provider == null) { 7783 continue; 7784 } 7785 ContentProviderRecord dst = 7786 (ContentProviderRecord)r.pubProviders.get(src.info.name); 7787 if (dst != null) { 7788 mProvidersByClass.put(dst.info.name, dst); 7789 String names[] = dst.info.authority.split(";"); 7790 for (int j = 0; j < names.length; j++) { 7791 mProvidersByName.put(names[j], dst); 7792 } 7793 7794 int NL = mLaunchingProviders.size(); 7795 int j; 7796 for (j=0; j<NL; j++) { 7797 if (mLaunchingProviders.get(j) == dst) { 7798 mLaunchingProviders.remove(j); 7799 j--; 7800 NL--; 7801 } 7802 } 7803 synchronized (dst) { 7804 dst.provider = src.provider; 7805 dst.app = r; 7806 dst.notifyAll(); 7807 } 7808 updateOomAdjLocked(r); 7809 } 7810 } 7811 7812 Binder.restoreCallingIdentity(origId); 7813 } 7814 } 7815 7816 public static final void installSystemProviders() { 7817 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 7818 List providers = mSelf.generateApplicationProvidersLocked(app); 7819 mSystemThread.installSystemProviders(providers); 7820 } 7821 7822 // ========================================================= 7823 // GLOBAL MANAGEMENT 7824 // ========================================================= 7825 7826 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 7827 ApplicationInfo info, String customProcess) { 7828 String proc = customProcess != null ? customProcess : info.processName; 7829 BatteryStatsImpl.Uid.Proc ps = null; 7830 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7831 synchronized (stats) { 7832 ps = stats.getProcessStatsLocked(info.uid, proc); 7833 } 7834 return new ProcessRecord(ps, thread, info, proc); 7835 } 7836 7837 final ProcessRecord addAppLocked(ApplicationInfo info) { 7838 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid); 7839 7840 if (app == null) { 7841 app = newProcessRecordLocked(null, info, null); 7842 mProcessNames.put(info.processName, info.uid, app); 7843 updateLruProcessLocked(app, true, true); 7844 } 7845 7846 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 7847 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 7848 app.persistent = true; 7849 app.maxAdj = CORE_SERVER_ADJ; 7850 } 7851 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 7852 mPersistentStartingProcesses.add(app); 7853 startProcessLocked(app, "added application", app.processName); 7854 } 7855 7856 return app; 7857 } 7858 7859 public void unhandledBack() { 7860 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 7861 "unhandledBack()"); 7862 7863 synchronized(this) { 7864 int count = mHistory.size(); 7865 if (DEBUG_SWITCH) Log.d( 7866 TAG, "Performing unhandledBack(): stack size = " + count); 7867 if (count > 1) { 7868 final long origId = Binder.clearCallingIdentity(); 7869 finishActivityLocked((HistoryRecord)mHistory.get(count-1), 7870 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 7871 Binder.restoreCallingIdentity(origId); 7872 } 7873 } 7874 } 7875 7876 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 7877 String name = uri.getAuthority(); 7878 ContentProviderHolder cph = getContentProviderExternal(name); 7879 ParcelFileDescriptor pfd = null; 7880 if (cph != null) { 7881 // We record the binder invoker's uid in thread-local storage before 7882 // going to the content provider to open the file. Later, in the code 7883 // that handles all permissions checks, we look for this uid and use 7884 // that rather than the Activity Manager's own uid. The effect is that 7885 // we do the check against the caller's permissions even though it looks 7886 // to the content provider like the Activity Manager itself is making 7887 // the request. 7888 sCallerIdentity.set(new Identity( 7889 Binder.getCallingPid(), Binder.getCallingUid())); 7890 try { 7891 pfd = cph.provider.openFile(uri, "r"); 7892 } catch (FileNotFoundException e) { 7893 // do nothing; pfd will be returned null 7894 } finally { 7895 // Ensure that whatever happens, we clean up the identity state 7896 sCallerIdentity.remove(); 7897 } 7898 7899 // We've got the fd now, so we're done with the provider. 7900 removeContentProviderExternal(name); 7901 } else { 7902 Log.d(TAG, "Failed to get provider for authority '" + name + "'"); 7903 } 7904 return pfd; 7905 } 7906 7907 public void goingToSleep() { 7908 synchronized(this) { 7909 mSleeping = true; 7910 mWindowManager.setEventDispatching(false); 7911 7912 if (mResumedActivity != null) { 7913 pauseIfSleepingLocked(); 7914 } else { 7915 Log.w(TAG, "goingToSleep with no resumed activity!"); 7916 } 7917 } 7918 } 7919 7920 public boolean shutdown(int timeout) { 7921 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 7922 != PackageManager.PERMISSION_GRANTED) { 7923 throw new SecurityException("Requires permission " 7924 + android.Manifest.permission.SHUTDOWN); 7925 } 7926 7927 boolean timedout = false; 7928 7929 synchronized(this) { 7930 mShuttingDown = true; 7931 mWindowManager.setEventDispatching(false); 7932 7933 if (mResumedActivity != null) { 7934 pauseIfSleepingLocked(); 7935 final long endTime = System.currentTimeMillis() + timeout; 7936 while (mResumedActivity != null || mPausingActivity != null) { 7937 long delay = endTime - System.currentTimeMillis(); 7938 if (delay <= 0) { 7939 Log.w(TAG, "Activity manager shutdown timed out"); 7940 timedout = true; 7941 break; 7942 } 7943 try { 7944 this.wait(); 7945 } catch (InterruptedException e) { 7946 } 7947 } 7948 } 7949 } 7950 7951 mUsageStatsService.shutdown(); 7952 mBatteryStatsService.shutdown(); 7953 7954 return timedout; 7955 } 7956 7957 void pauseIfSleepingLocked() { 7958 if (mSleeping || mShuttingDown) { 7959 if (!mGoingToSleep.isHeld()) { 7960 mGoingToSleep.acquire(); 7961 if (mLaunchingActivity.isHeld()) { 7962 mLaunchingActivity.release(); 7963 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 7964 } 7965 } 7966 7967 // If we are not currently pausing an activity, get the current 7968 // one to pause. If we are pausing one, we will just let that stuff 7969 // run and release the wake lock when all done. 7970 if (mPausingActivity == null) { 7971 if (DEBUG_PAUSE) Log.v(TAG, "Sleep needs to pause..."); 7972 if (DEBUG_USER_LEAVING) Log.v(TAG, "Sleep => pause with userLeaving=false"); 7973 startPausingLocked(false, true); 7974 } 7975 } 7976 } 7977 7978 public void wakingUp() { 7979 synchronized(this) { 7980 if (mGoingToSleep.isHeld()) { 7981 mGoingToSleep.release(); 7982 } 7983 mWindowManager.setEventDispatching(true); 7984 mSleeping = false; 7985 resumeTopActivityLocked(null); 7986 } 7987 } 7988 7989 public void stopAppSwitches() { 7990 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7991 != PackageManager.PERMISSION_GRANTED) { 7992 throw new SecurityException("Requires permission " 7993 + android.Manifest.permission.STOP_APP_SWITCHES); 7994 } 7995 7996 synchronized(this) { 7997 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 7998 + APP_SWITCH_DELAY_TIME; 7999 mDidAppSwitch = false; 8000 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8001 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8002 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8003 } 8004 } 8005 8006 public void resumeAppSwitches() { 8007 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8008 != PackageManager.PERMISSION_GRANTED) { 8009 throw new SecurityException("Requires permission " 8010 + android.Manifest.permission.STOP_APP_SWITCHES); 8011 } 8012 8013 synchronized(this) { 8014 // Note that we don't execute any pending app switches... we will 8015 // let those wait until either the timeout, or the next start 8016 // activity request. 8017 mAppSwitchesAllowedTime = 0; 8018 } 8019 } 8020 8021 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8022 String name) { 8023 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8024 return true; 8025 } 8026 8027 final int perm = checkComponentPermission( 8028 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8029 callingUid, -1); 8030 if (perm == PackageManager.PERMISSION_GRANTED) { 8031 return true; 8032 } 8033 8034 Log.w(TAG, name + " request from " + callingUid + " stopped"); 8035 return false; 8036 } 8037 8038 public void setDebugApp(String packageName, boolean waitForDebugger, 8039 boolean persistent) { 8040 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8041 "setDebugApp()"); 8042 8043 // Note that this is not really thread safe if there are multiple 8044 // callers into it at the same time, but that's not a situation we 8045 // care about. 8046 if (persistent) { 8047 final ContentResolver resolver = mContext.getContentResolver(); 8048 Settings.System.putString( 8049 resolver, Settings.System.DEBUG_APP, 8050 packageName); 8051 Settings.System.putInt( 8052 resolver, Settings.System.WAIT_FOR_DEBUGGER, 8053 waitForDebugger ? 1 : 0); 8054 } 8055 8056 synchronized (this) { 8057 if (!persistent) { 8058 mOrigDebugApp = mDebugApp; 8059 mOrigWaitForDebugger = mWaitForDebugger; 8060 } 8061 mDebugApp = packageName; 8062 mWaitForDebugger = waitForDebugger; 8063 mDebugTransient = !persistent; 8064 if (packageName != null) { 8065 final long origId = Binder.clearCallingIdentity(); 8066 forceStopPackageLocked(packageName, -1, false, false); 8067 Binder.restoreCallingIdentity(origId); 8068 } 8069 } 8070 } 8071 8072 public void setAlwaysFinish(boolean enabled) { 8073 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8074 "setAlwaysFinish()"); 8075 8076 Settings.System.putInt( 8077 mContext.getContentResolver(), 8078 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8079 8080 synchronized (this) { 8081 mAlwaysFinishActivities = enabled; 8082 } 8083 } 8084 8085 public void setActivityController(IActivityController controller) { 8086 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8087 "setActivityController()"); 8088 synchronized (this) { 8089 mController = controller; 8090 } 8091 } 8092 8093 public boolean isUserAMonkey() { 8094 // For now the fact that there is a controller implies 8095 // we have a monkey. 8096 synchronized (this) { 8097 return mController != null; 8098 } 8099 } 8100 8101 public void registerActivityWatcher(IActivityWatcher watcher) { 8102 mWatchers.register(watcher); 8103 } 8104 8105 public void unregisterActivityWatcher(IActivityWatcher watcher) { 8106 mWatchers.unregister(watcher); 8107 } 8108 8109 public final void enterSafeMode() { 8110 synchronized(this) { 8111 // It only makes sense to do this before the system is ready 8112 // and started launching other packages. 8113 if (!mSystemReady) { 8114 try { 8115 ActivityThread.getPackageManager().enterSafeMode(); 8116 } catch (RemoteException e) { 8117 } 8118 8119 View v = LayoutInflater.from(mContext).inflate( 8120 com.android.internal.R.layout.safe_mode, null); 8121 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8122 lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; 8123 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8124 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8125 lp.gravity = Gravity.BOTTOM | Gravity.LEFT; 8126 lp.format = v.getBackground().getOpacity(); 8127 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8128 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8129 ((WindowManager)mContext.getSystemService( 8130 Context.WINDOW_SERVICE)).addView(v, lp); 8131 } 8132 } 8133 } 8134 8135 public void noteWakeupAlarm(IIntentSender sender) { 8136 if (!(sender instanceof PendingIntentRecord)) { 8137 return; 8138 } 8139 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8140 synchronized (stats) { 8141 if (mBatteryStatsService.isOnBattery()) { 8142 mBatteryStatsService.enforceCallingPermission(); 8143 PendingIntentRecord rec = (PendingIntentRecord)sender; 8144 int MY_UID = Binder.getCallingUid(); 8145 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8146 BatteryStatsImpl.Uid.Pkg pkg = 8147 stats.getPackageStatsLocked(uid, rec.key.packageName); 8148 pkg.incWakeupsLocked(); 8149 } 8150 } 8151 } 8152 8153 public boolean killPidsForMemory(int[] pids) { 8154 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8155 throw new SecurityException("killPidsForMemory only available to the system"); 8156 } 8157 8158 // XXX Note: don't acquire main activity lock here, because the window 8159 // manager calls in with its locks held. 8160 8161 boolean killed = false; 8162 synchronized (mPidsSelfLocked) { 8163 int[] types = new int[pids.length]; 8164 int worstType = 0; 8165 for (int i=0; i<pids.length; i++) { 8166 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8167 if (proc != null) { 8168 int type = proc.setAdj; 8169 types[i] = type; 8170 if (type > worstType) { 8171 worstType = type; 8172 } 8173 } 8174 } 8175 8176 // If the worse oom_adj is somewhere in the hidden proc LRU range, 8177 // then constrain it so we will kill all hidden procs. 8178 if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) { 8179 worstType = HIDDEN_APP_MIN_ADJ; 8180 } 8181 Log.w(TAG, "Killing processes for memory at adjustment " + worstType); 8182 for (int i=0; i<pids.length; i++) { 8183 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8184 if (proc == null) { 8185 continue; 8186 } 8187 int adj = proc.setAdj; 8188 if (adj >= worstType) { 8189 Log.w(TAG, "Killing for memory: " + proc + " (adj " 8190 + adj + ")"); 8191 EventLog.writeEvent(EventLogTags.AM_KILL_FOR_MEMORY, proc.pid, 8192 proc.processName, adj); 8193 killed = true; 8194 Process.killProcess(pids[i]); 8195 } 8196 } 8197 } 8198 return killed; 8199 } 8200 8201 public void reportPss(IApplicationThread caller, int pss) { 8202 Watchdog.PssRequestor req; 8203 String name; 8204 ProcessRecord callerApp; 8205 synchronized (this) { 8206 if (caller == null) { 8207 return; 8208 } 8209 callerApp = getRecordForAppLocked(caller); 8210 if (callerApp == null) { 8211 return; 8212 } 8213 callerApp.lastPss = pss; 8214 req = callerApp; 8215 name = callerApp.processName; 8216 } 8217 Watchdog.getInstance().reportPss(req, name, pss); 8218 if (!callerApp.persistent) { 8219 removeRequestedPss(callerApp); 8220 } 8221 } 8222 8223 public void requestPss(Runnable completeCallback) { 8224 ArrayList<ProcessRecord> procs; 8225 synchronized (this) { 8226 mRequestPssCallback = completeCallback; 8227 mRequestPssList.clear(); 8228 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8229 ProcessRecord proc = mLruProcesses.get(i); 8230 if (!proc.persistent) { 8231 mRequestPssList.add(proc); 8232 } 8233 } 8234 procs = new ArrayList<ProcessRecord>(mRequestPssList); 8235 } 8236 8237 int oldPri = Process.getThreadPriority(Process.myTid()); 8238 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 8239 for (int i=procs.size()-1; i>=0; i--) { 8240 ProcessRecord proc = procs.get(i); 8241 proc.lastPss = 0; 8242 proc.requestPss(); 8243 } 8244 Process.setThreadPriority(oldPri); 8245 } 8246 8247 void removeRequestedPss(ProcessRecord proc) { 8248 Runnable callback = null; 8249 synchronized (this) { 8250 if (mRequestPssList.remove(proc)) { 8251 if (mRequestPssList.size() == 0) { 8252 callback = mRequestPssCallback; 8253 mRequestPssCallback = null; 8254 } 8255 } 8256 } 8257 8258 if (callback != null) { 8259 callback.run(); 8260 } 8261 } 8262 8263 public void collectPss(Watchdog.PssStats stats) { 8264 stats.mEmptyPss = 0; 8265 stats.mEmptyCount = 0; 8266 stats.mBackgroundPss = 0; 8267 stats.mBackgroundCount = 0; 8268 stats.mServicePss = 0; 8269 stats.mServiceCount = 0; 8270 stats.mVisiblePss = 0; 8271 stats.mVisibleCount = 0; 8272 stats.mForegroundPss = 0; 8273 stats.mForegroundCount = 0; 8274 stats.mNoPssCount = 0; 8275 synchronized (this) { 8276 int i; 8277 int NPD = mProcDeaths.length < stats.mProcDeaths.length 8278 ? mProcDeaths.length : stats.mProcDeaths.length; 8279 int aggr = 0; 8280 for (i=0; i<NPD; i++) { 8281 aggr += mProcDeaths[i]; 8282 stats.mProcDeaths[i] = aggr; 8283 } 8284 while (i<stats.mProcDeaths.length) { 8285 stats.mProcDeaths[i] = 0; 8286 i++; 8287 } 8288 8289 for (i=mLruProcesses.size()-1; i>=0; i--) { 8290 ProcessRecord proc = mLruProcesses.get(i); 8291 if (proc.persistent) { 8292 continue; 8293 } 8294 //Log.i(TAG, "Proc " + proc + ": pss=" + proc.lastPss); 8295 if (proc.lastPss == 0) { 8296 stats.mNoPssCount++; 8297 continue; 8298 } 8299 if (proc.setAdj >= HIDDEN_APP_MIN_ADJ) { 8300 if (proc.empty) { 8301 stats.mEmptyPss += proc.lastPss; 8302 stats.mEmptyCount++; 8303 } else { 8304 stats.mBackgroundPss += proc.lastPss; 8305 stats.mBackgroundCount++; 8306 } 8307 } else if (proc.setAdj >= VISIBLE_APP_ADJ) { 8308 stats.mVisiblePss += proc.lastPss; 8309 stats.mVisibleCount++; 8310 } else { 8311 stats.mForegroundPss += proc.lastPss; 8312 stats.mForegroundCount++; 8313 } 8314 } 8315 } 8316 } 8317 8318 public final void startRunning(String pkg, String cls, String action, 8319 String data) { 8320 synchronized(this) { 8321 if (mStartRunning) { 8322 return; 8323 } 8324 mStartRunning = true; 8325 mTopComponent = pkg != null && cls != null 8326 ? new ComponentName(pkg, cls) : null; 8327 mTopAction = action != null ? action : Intent.ACTION_MAIN; 8328 mTopData = data; 8329 if (!mSystemReady) { 8330 return; 8331 } 8332 } 8333 8334 systemReady(null); 8335 } 8336 8337 private void retrieveSettings() { 8338 final ContentResolver resolver = mContext.getContentResolver(); 8339 String debugApp = Settings.System.getString( 8340 resolver, Settings.System.DEBUG_APP); 8341 boolean waitForDebugger = Settings.System.getInt( 8342 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 8343 boolean alwaysFinishActivities = Settings.System.getInt( 8344 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 8345 8346 Configuration configuration = new Configuration(); 8347 Settings.System.getConfiguration(resolver, configuration); 8348 8349 synchronized (this) { 8350 mDebugApp = mOrigDebugApp = debugApp; 8351 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 8352 mAlwaysFinishActivities = alwaysFinishActivities; 8353 // This happens before any activities are started, so we can 8354 // change mConfiguration in-place. 8355 mConfiguration.updateFrom(configuration); 8356 if (DEBUG_CONFIGURATION) Log.v(TAG, "Initial config: " + mConfiguration); 8357 } 8358 } 8359 8360 public boolean testIsSystemReady() { 8361 // no need to synchronize(this) just to read & return the value 8362 return mSystemReady; 8363 } 8364 8365 public void systemReady(final Runnable goingCallback) { 8366 // In the simulator, startRunning will never have been called, which 8367 // normally sets a few crucial variables. Do it here instead. 8368 if (!Process.supportsProcesses()) { 8369 mStartRunning = true; 8370 mTopAction = Intent.ACTION_MAIN; 8371 } 8372 8373 synchronized(this) { 8374 if (mSystemReady) { 8375 if (goingCallback != null) goingCallback.run(); 8376 return; 8377 } 8378 8379 // Check to see if there are any update receivers to run. 8380 if (!mDidUpdate) { 8381 if (mWaitingUpdate) { 8382 return; 8383 } 8384 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 8385 List<ResolveInfo> ris = null; 8386 try { 8387 ris = ActivityThread.getPackageManager().queryIntentReceivers( 8388 intent, null, 0); 8389 } catch (RemoteException e) { 8390 } 8391 if (ris != null) { 8392 for (int i=ris.size()-1; i>=0; i--) { 8393 if ((ris.get(i).activityInfo.applicationInfo.flags 8394 &ApplicationInfo.FLAG_SYSTEM) == 0) { 8395 ris.remove(i); 8396 } 8397 } 8398 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 8399 for (int i=0; i<ris.size(); i++) { 8400 ActivityInfo ai = ris.get(i).activityInfo; 8401 intent.setComponent(new ComponentName(ai.packageName, ai.name)); 8402 IIntentReceiver finisher = null; 8403 if (i == ris.size()-1) { 8404 finisher = new IIntentReceiver.Stub() { 8405 public void performReceive(Intent intent, int resultCode, 8406 String data, Bundle extras, boolean ordered, 8407 boolean sticky) 8408 throws RemoteException { 8409 synchronized (ActivityManagerService.this) { 8410 mDidUpdate = true; 8411 } 8412 systemReady(goingCallback); 8413 } 8414 }; 8415 } 8416 Log.i(TAG, "Sending system update to: " + intent.getComponent()); 8417 broadcastIntentLocked(null, null, intent, null, finisher, 8418 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID); 8419 if (finisher != null) { 8420 mWaitingUpdate = true; 8421 } 8422 } 8423 } 8424 if (mWaitingUpdate) { 8425 return; 8426 } 8427 mDidUpdate = true; 8428 } 8429 8430 mSystemReady = true; 8431 if (!mStartRunning) { 8432 return; 8433 } 8434 } 8435 8436 ArrayList<ProcessRecord> procsToKill = null; 8437 synchronized(mPidsSelfLocked) { 8438 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 8439 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8440 if (!isAllowedWhileBooting(proc.info)){ 8441 if (procsToKill == null) { 8442 procsToKill = new ArrayList<ProcessRecord>(); 8443 } 8444 procsToKill.add(proc); 8445 } 8446 } 8447 } 8448 8449 if (procsToKill != null) { 8450 synchronized(this) { 8451 for (int i=procsToKill.size()-1; i>=0; i--) { 8452 ProcessRecord proc = procsToKill.get(i); 8453 Log.i(TAG, "Removing system update proc: " + proc); 8454 removeProcessLocked(proc, true); 8455 } 8456 } 8457 } 8458 8459 Log.i(TAG, "System now ready"); 8460 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 8461 SystemClock.uptimeMillis()); 8462 8463 synchronized(this) { 8464 // Make sure we have no pre-ready processes sitting around. 8465 8466 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 8467 ResolveInfo ri = mContext.getPackageManager() 8468 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 8469 STOCK_PM_FLAGS); 8470 CharSequence errorMsg = null; 8471 if (ri != null) { 8472 ActivityInfo ai = ri.activityInfo; 8473 ApplicationInfo app = ai.applicationInfo; 8474 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 8475 mTopAction = Intent.ACTION_FACTORY_TEST; 8476 mTopData = null; 8477 mTopComponent = new ComponentName(app.packageName, 8478 ai.name); 8479 } else { 8480 errorMsg = mContext.getResources().getText( 8481 com.android.internal.R.string.factorytest_not_system); 8482 } 8483 } else { 8484 errorMsg = mContext.getResources().getText( 8485 com.android.internal.R.string.factorytest_no_action); 8486 } 8487 if (errorMsg != null) { 8488 mTopAction = null; 8489 mTopData = null; 8490 mTopComponent = null; 8491 Message msg = Message.obtain(); 8492 msg.what = SHOW_FACTORY_ERROR_MSG; 8493 msg.getData().putCharSequence("msg", errorMsg); 8494 mHandler.sendMessage(msg); 8495 } 8496 } 8497 } 8498 8499 retrieveSettings(); 8500 8501 if (goingCallback != null) goingCallback.run(); 8502 8503 synchronized (this) { 8504 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 8505 try { 8506 List apps = ActivityThread.getPackageManager(). 8507 getPersistentApplications(STOCK_PM_FLAGS); 8508 if (apps != null) { 8509 int N = apps.size(); 8510 int i; 8511 for (i=0; i<N; i++) { 8512 ApplicationInfo info 8513 = (ApplicationInfo)apps.get(i); 8514 if (info != null && 8515 !info.packageName.equals("android")) { 8516 addAppLocked(info); 8517 } 8518 } 8519 } 8520 } catch (RemoteException ex) { 8521 // pm is in same process, this will never happen. 8522 } 8523 } 8524 8525 // Start up initial activity. 8526 mBooting = true; 8527 8528 try { 8529 if (ActivityThread.getPackageManager().hasSystemUidErrors()) { 8530 Message msg = Message.obtain(); 8531 msg.what = SHOW_UID_ERROR_MSG; 8532 mHandler.sendMessage(msg); 8533 } 8534 } catch (RemoteException e) { 8535 } 8536 8537 resumeTopActivityLocked(null); 8538 } 8539 } 8540 8541 private boolean makeAppCrashingLocked(ProcessRecord app, 8542 String shortMsg, String longMsg, String stackTrace) { 8543 app.crashing = true; 8544 app.crashingReport = generateProcessError(app, 8545 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 8546 startAppProblemLocked(app); 8547 app.stopFreezingAllLocked(); 8548 return handleAppCrashLocked(app); 8549 } 8550 8551 private ComponentName getErrorReportReceiver(ProcessRecord app) { 8552 // check if error reporting is enabled in secure settings 8553 int enabled = Settings.Secure.getInt(mContext.getContentResolver(), 8554 Settings.Secure.SEND_ACTION_APP_ERROR, 0); 8555 if (enabled == 0) { 8556 return null; 8557 } 8558 8559 IPackageManager pm = ActivityThread.getPackageManager(); 8560 8561 try { 8562 // look for receiver in the installer package 8563 String candidate = pm.getInstallerPackageName(app.info.packageName); 8564 ComponentName result = getErrorReportReceiver(pm, app.info.packageName, candidate); 8565 if (result != null) { 8566 return result; 8567 } 8568 8569 // if the error app is on the system image, look for system apps 8570 // error receiver 8571 if ((app.info.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 8572 candidate = SystemProperties.get(SYSTEM_APPS_ERROR_RECEIVER_PROPERTY); 8573 result = getErrorReportReceiver(pm, app.info.packageName, candidate); 8574 if (result != null) { 8575 return result; 8576 } 8577 } 8578 8579 // if there is a default receiver, try that 8580 candidate = SystemProperties.get(DEFAULT_ERROR_RECEIVER_PROPERTY); 8581 return getErrorReportReceiver(pm, app.info.packageName, candidate); 8582 } catch (RemoteException e) { 8583 // should not happen 8584 Log.e(TAG, "error talking to PackageManager", e); 8585 return null; 8586 } 8587 } 8588 8589 /** 8590 * Return activity in receiverPackage that handles ACTION_APP_ERROR. 8591 * 8592 * @param pm PackageManager isntance 8593 * @param errorPackage package which caused the error 8594 * @param receiverPackage candidate package to receive the error 8595 * @return activity component within receiverPackage which handles 8596 * ACTION_APP_ERROR, or null if not found 8597 */ 8598 private ComponentName getErrorReportReceiver(IPackageManager pm, String errorPackage, 8599 String receiverPackage) throws RemoteException { 8600 if (receiverPackage == null || receiverPackage.length() == 0) { 8601 return null; 8602 } 8603 8604 // break the loop if it's the error report receiver package that crashed 8605 if (receiverPackage.equals(errorPackage)) { 8606 return null; 8607 } 8608 8609 Intent intent = new Intent(Intent.ACTION_APP_ERROR); 8610 intent.setPackage(receiverPackage); 8611 ResolveInfo info = pm.resolveIntent(intent, null, 0); 8612 if (info == null || info.activityInfo == null) { 8613 return null; 8614 } 8615 return new ComponentName(receiverPackage, info.activityInfo.name); 8616 } 8617 8618 private void makeAppNotRespondingLocked(ProcessRecord app, 8619 String activity, String shortMsg, String longMsg) { 8620 app.notResponding = true; 8621 app.notRespondingReport = generateProcessError(app, 8622 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 8623 activity, shortMsg, longMsg, null); 8624 startAppProblemLocked(app); 8625 app.stopFreezingAllLocked(); 8626 } 8627 8628 /** 8629 * Generate a process error record, suitable for attachment to a ProcessRecord. 8630 * 8631 * @param app The ProcessRecord in which the error occurred. 8632 * @param condition Crashing, Application Not Responding, etc. Values are defined in 8633 * ActivityManager.AppErrorStateInfo 8634 * @param activity The activity associated with the crash, if known. 8635 * @param shortMsg Short message describing the crash. 8636 * @param longMsg Long message describing the crash. 8637 * @param stackTrace Full crash stack trace, may be null. 8638 * 8639 * @return Returns a fully-formed AppErrorStateInfo record. 8640 */ 8641 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 8642 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 8643 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 8644 8645 report.condition = condition; 8646 report.processName = app.processName; 8647 report.pid = app.pid; 8648 report.uid = app.info.uid; 8649 report.tag = activity; 8650 report.shortMsg = shortMsg; 8651 report.longMsg = longMsg; 8652 report.stackTrace = stackTrace; 8653 8654 return report; 8655 } 8656 8657 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 8658 synchronized (this) { 8659 app.crashing = false; 8660 app.crashingReport = null; 8661 app.notResponding = false; 8662 app.notRespondingReport = null; 8663 if (app.anrDialog == fromDialog) { 8664 app.anrDialog = null; 8665 } 8666 if (app.waitDialog == fromDialog) { 8667 app.waitDialog = null; 8668 } 8669 if (app.pid > 0 && app.pid != MY_PID) { 8670 handleAppCrashLocked(app); 8671 Log.i(ActivityManagerService.TAG, "Killing process " 8672 + app.processName 8673 + " (pid=" + app.pid + ") at user's request"); 8674 Process.killProcess(app.pid); 8675 } 8676 } 8677 } 8678 8679 private boolean handleAppCrashLocked(ProcessRecord app) { 8680 long now = SystemClock.uptimeMillis(); 8681 8682 Long crashTime = mProcessCrashTimes.get(app.info.processName, 8683 app.info.uid); 8684 if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) { 8685 // This process loses! 8686 Log.w(TAG, "Process " + app.info.processName 8687 + " has crashed too many times: killing!"); 8688 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 8689 app.info.processName, app.info.uid); 8690 killServicesLocked(app, false); 8691 for (int i=mHistory.size()-1; i>=0; i--) { 8692 HistoryRecord r = (HistoryRecord)mHistory.get(i); 8693 if (r.app == app) { 8694 Log.w(TAG, " Force finishing activity " 8695 + r.intent.getComponent().flattenToShortString()); 8696 finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 8697 } 8698 } 8699 if (!app.persistent) { 8700 // We don't want to start this process again until the user 8701 // explicitly does so... but for persistent process, we really 8702 // need to keep it running. If a persistent process is actually 8703 // repeatedly crashing, then badness for everyone. 8704 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid, 8705 app.info.processName); 8706 mBadProcesses.put(app.info.processName, app.info.uid, now); 8707 app.bad = true; 8708 mProcessCrashTimes.remove(app.info.processName, app.info.uid); 8709 app.removed = true; 8710 removeProcessLocked(app, false); 8711 return false; 8712 } 8713 } 8714 8715 // Bump up the crash count of any services currently running in the proc. 8716 if (app.services.size() != 0) { 8717 // Any services running in the application need to be placed 8718 // back in the pending list. 8719 Iterator it = app.services.iterator(); 8720 while (it.hasNext()) { 8721 ServiceRecord sr = (ServiceRecord)it.next(); 8722 sr.crashCount++; 8723 } 8724 } 8725 8726 mProcessCrashTimes.put(app.info.processName, app.info.uid, now); 8727 return true; 8728 } 8729 8730 void startAppProblemLocked(ProcessRecord app) { 8731 app.errorReportReceiver = getErrorReportReceiver(app); 8732 skipCurrentReceiverLocked(app); 8733 } 8734 8735 void skipCurrentReceiverLocked(ProcessRecord app) { 8736 boolean reschedule = false; 8737 BroadcastRecord r = app.curReceiver; 8738 if (r != null) { 8739 // The current broadcast is waiting for this app's receiver 8740 // to be finished. Looks like that's not going to happen, so 8741 // let the broadcast continue. 8742 logBroadcastReceiverDiscard(r); 8743 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 8744 r.resultExtras, r.resultAbort, true); 8745 reschedule = true; 8746 } 8747 r = mPendingBroadcast; 8748 if (r != null && r.curApp == app) { 8749 if (DEBUG_BROADCAST) Log.v(TAG, 8750 "skip & discard pending app " + r); 8751 logBroadcastReceiverDiscard(r); 8752 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 8753 r.resultExtras, r.resultAbort, true); 8754 reschedule = true; 8755 } 8756 if (reschedule) { 8757 scheduleBroadcastsLocked(); 8758 } 8759 } 8760 8761 /** 8762 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 8763 * The application process will exit immediately after this call returns. 8764 * @param app object of the crashing app, null for the system server 8765 * @param crashInfo describing the exception 8766 */ 8767 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 8768 ProcessRecord r = findAppProcess(app); 8769 8770 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 8771 app == null ? "system" : (r == null ? "unknown" : r.processName), 8772 r == null ? -1 : r.info.flags, 8773 crashInfo.exceptionClassName, 8774 crashInfo.exceptionMessage, 8775 crashInfo.throwFileName, 8776 crashInfo.throwLineNumber); 8777 8778 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo); 8779 8780 crashApplication(r, crashInfo); 8781 } 8782 8783 /** 8784 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8785 * @param app object of the crashing app, null for the system server 8786 * @param tag reported by the caller 8787 * @param crashInfo describing the context of the error 8788 * @return true if the process should exit immediately (WTF is fatal) 8789 */ 8790 public boolean handleApplicationWtf(IBinder app, String tag, 8791 ApplicationErrorReport.CrashInfo crashInfo) { 8792 ProcessRecord r = findAppProcess(app); 8793 8794 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8795 app == null ? "system" : (r == null ? "unknown" : r.processName), 8796 r == null ? -1 : r.info.flags, 8797 tag, crashInfo.exceptionMessage); 8798 8799 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo); 8800 8801 if (Settings.Secure.getInt(mContext.getContentResolver(), 8802 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 8803 crashApplication(r, crashInfo); 8804 return true; 8805 } else { 8806 return false; 8807 } 8808 } 8809 8810 /** 8811 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8812 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8813 */ 8814 private ProcessRecord findAppProcess(IBinder app) { 8815 if (app == null) { 8816 return null; 8817 } 8818 8819 synchronized (this) { 8820 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8821 final int NA = apps.size(); 8822 for (int ia=0; ia<NA; ia++) { 8823 ProcessRecord p = apps.valueAt(ia); 8824 if (p.thread != null && p.thread.asBinder() == app) { 8825 return p; 8826 } 8827 } 8828 } 8829 8830 Log.w(TAG, "Can't find mystery application: " + app); 8831 return null; 8832 } 8833 } 8834 8835 /** 8836 * Write a description of an error (crash, WTF, ANR) to the drop box. 8837 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8838 * @param process which caused the error, null means the system server 8839 * @param activity which triggered the error, null if unknown 8840 * @param parent activity related to the error, null if unknown 8841 * @param subject line related to the error, null if absent 8842 * @param report in long form describing the error, null if absent 8843 * @param logFile to include in the report, null if none 8844 * @param crashInfo giving an application stack trace, null if absent 8845 */ 8846 private void addErrorToDropBox(String eventType, 8847 ProcessRecord process, HistoryRecord activity, HistoryRecord parent, 8848 String subject, String report, File logFile, 8849 ApplicationErrorReport.CrashInfo crashInfo) { 8850 String dropboxTag; 8851 if (process == null || process.pid == MY_PID) { 8852 dropboxTag = "system_server_" + eventType; 8853 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8854 dropboxTag = "system_app_" + eventType; 8855 } else { 8856 dropboxTag = "data_app_" + eventType; 8857 } 8858 8859 DropBoxManager dbox = (DropBoxManager) mContext.getSystemService(Context.DROPBOX_SERVICE); 8860 if (dbox != null && dbox.isTagEnabled(dropboxTag)) { 8861 StringBuilder sb = new StringBuilder(1024); 8862 if (process == null || process.pid == MY_PID) { 8863 sb.append("Process: system_server\n"); 8864 } else { 8865 sb.append("Process: ").append(process.processName).append("\n"); 8866 } 8867 if (process != null) { 8868 int flags = process.info.flags; 8869 IPackageManager pm = ActivityThread.getPackageManager(); 8870 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 8871 for (String pkg : process.pkgList) { 8872 sb.append("Package: ").append(pkg); 8873 try { 8874 PackageInfo pi = pm.getPackageInfo(pkg, 0); 8875 if (pi != null) { 8876 sb.append(" v").append(pi.versionCode); 8877 if (pi.versionName != null) { 8878 sb.append(" (").append(pi.versionName).append(")"); 8879 } 8880 } 8881 } catch (RemoteException e) { 8882 Log.e(TAG, "Error getting package info: " + pkg, e); 8883 } 8884 sb.append("\n"); 8885 } 8886 } 8887 if (activity != null) { 8888 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 8889 } 8890 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 8891 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 8892 } 8893 if (parent != null && parent != activity) { 8894 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 8895 } 8896 if (subject != null) { 8897 sb.append("Subject: ").append(subject).append("\n"); 8898 } 8899 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8900 sb.append("\n"); 8901 if (report != null) { 8902 sb.append(report); 8903 } 8904 if (logFile != null) { 8905 try { 8906 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 8907 } catch (IOException e) { 8908 Log.e(TAG, "Error reading " + logFile, e); 8909 } 8910 } 8911 if (crashInfo != null && crashInfo.stackTrace != null) { 8912 sb.append(crashInfo.stackTrace); 8913 } 8914 dbox.addText(dropboxTag, sb.toString()); 8915 } 8916 } 8917 8918 /** 8919 * Bring up the "unexpected error" dialog box for a crashing app. 8920 * Deal with edge cases (intercepts from instrumented applications, 8921 * ActivityController, error intent receivers, that sort of thing). 8922 * @param r the application crashing 8923 * @param crashInfo describing the failure 8924 */ 8925 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8926 long timeMillis = System.currentTimeMillis(); 8927 String shortMsg = crashInfo.exceptionClassName; 8928 String longMsg = crashInfo.exceptionMessage; 8929 String stackTrace = crashInfo.stackTrace; 8930 if (shortMsg != null && longMsg != null) { 8931 longMsg = shortMsg + ": " + longMsg; 8932 } else if (shortMsg != null) { 8933 longMsg = shortMsg; 8934 } 8935 8936 AppErrorResult result = new AppErrorResult(); 8937 synchronized (this) { 8938 if (mController != null) { 8939 try { 8940 String name = r != null ? r.processName : null; 8941 int pid = r != null ? r.pid : Binder.getCallingPid(); 8942 if (!mController.appCrashed(name, pid, 8943 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8944 Log.w(TAG, "Force-killing crashed app " + name 8945 + " at watcher's request"); 8946 Process.killProcess(pid); 8947 return; 8948 } 8949 } catch (RemoteException e) { 8950 mController = null; 8951 } 8952 } 8953 8954 final long origId = Binder.clearCallingIdentity(); 8955 8956 // If this process is running instrumentation, finish it. 8957 if (r != null && r.instrumentationClass != null) { 8958 Log.w(TAG, "Error in app " + r.processName 8959 + " running instrumentation " + r.instrumentationClass + ":"); 8960 if (shortMsg != null) Log.w(TAG, " " + shortMsg); 8961 if (longMsg != null) Log.w(TAG, " " + longMsg); 8962 Bundle info = new Bundle(); 8963 info.putString("shortMsg", shortMsg); 8964 info.putString("longMsg", longMsg); 8965 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8966 Binder.restoreCallingIdentity(origId); 8967 return; 8968 } 8969 8970 // If we can't identify the process or it's already exceeded its crash quota, 8971 // quit right away without showing a crash dialog. 8972 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8973 Binder.restoreCallingIdentity(origId); 8974 return; 8975 } 8976 8977 Message msg = Message.obtain(); 8978 msg.what = SHOW_ERROR_MSG; 8979 HashMap data = new HashMap(); 8980 data.put("result", result); 8981 data.put("app", r); 8982 msg.obj = data; 8983 mHandler.sendMessage(msg); 8984 8985 Binder.restoreCallingIdentity(origId); 8986 } 8987 8988 int res = result.get(); 8989 8990 Intent appErrorIntent = null; 8991 synchronized (this) { 8992 if (r != null) { 8993 mProcessCrashTimes.put(r.info.processName, r.info.uid, 8994 SystemClock.uptimeMillis()); 8995 } 8996 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8997 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8998 } 8999 } 9000 9001 if (appErrorIntent != null) { 9002 try { 9003 mContext.startActivity(appErrorIntent); 9004 } catch (ActivityNotFoundException e) { 9005 Log.w(TAG, "bug report receiver dissappeared", e); 9006 } 9007 } 9008 } 9009 9010 Intent createAppErrorIntentLocked(ProcessRecord r, 9011 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 9012 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 9013 if (report == null) { 9014 return null; 9015 } 9016 Intent result = new Intent(Intent.ACTION_APP_ERROR); 9017 result.setComponent(r.errorReportReceiver); 9018 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 9019 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 9020 return result; 9021 } 9022 9023 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 9024 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 9025 if (r.errorReportReceiver == null) { 9026 return null; 9027 } 9028 9029 if (!r.crashing && !r.notResponding) { 9030 return null; 9031 } 9032 9033 ApplicationErrorReport report = new ApplicationErrorReport(); 9034 report.packageName = r.info.packageName; 9035 report.installerPackageName = r.errorReportReceiver.getPackageName(); 9036 report.processName = r.processName; 9037 report.time = timeMillis; 9038 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 9039 9040 if (r.crashing) { 9041 report.type = ApplicationErrorReport.TYPE_CRASH; 9042 report.crashInfo = crashInfo; 9043 } else if (r.notResponding) { 9044 report.type = ApplicationErrorReport.TYPE_ANR; 9045 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 9046 9047 report.anrInfo.activity = r.notRespondingReport.tag; 9048 report.anrInfo.cause = r.notRespondingReport.shortMsg; 9049 report.anrInfo.info = r.notRespondingReport.longMsg; 9050 } 9051 9052 return report; 9053 } 9054 9055 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 9056 // assume our apps are happy - lazy create the list 9057 List<ActivityManager.ProcessErrorStateInfo> errList = null; 9058 9059 synchronized (this) { 9060 9061 // iterate across all processes 9062 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9063 ProcessRecord app = mLruProcesses.get(i); 9064 if ((app.thread != null) && (app.crashing || app.notResponding)) { 9065 // This one's in trouble, so we'll generate a report for it 9066 // crashes are higher priority (in case there's a crash *and* an anr) 9067 ActivityManager.ProcessErrorStateInfo report = null; 9068 if (app.crashing) { 9069 report = app.crashingReport; 9070 } else if (app.notResponding) { 9071 report = app.notRespondingReport; 9072 } 9073 9074 if (report != null) { 9075 if (errList == null) { 9076 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 9077 } 9078 errList.add(report); 9079 } else { 9080 Log.w(TAG, "Missing app error report, app = " + app.processName + 9081 " crashing = " + app.crashing + 9082 " notResponding = " + app.notResponding); 9083 } 9084 } 9085 } 9086 } 9087 9088 return errList; 9089 } 9090 9091 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 9092 // Lazy instantiation of list 9093 List<ActivityManager.RunningAppProcessInfo> runList = null; 9094 synchronized (this) { 9095 // Iterate across all processes 9096 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9097 ProcessRecord app = mLruProcesses.get(i); 9098 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 9099 // Generate process state info for running application 9100 ActivityManager.RunningAppProcessInfo currApp = 9101 new ActivityManager.RunningAppProcessInfo(app.processName, 9102 app.pid, app.getPackageList()); 9103 currApp.uid = app.info.uid; 9104 int adj = app.curAdj; 9105 if (adj >= EMPTY_APP_ADJ) { 9106 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY; 9107 } else if (adj >= HIDDEN_APP_MIN_ADJ) { 9108 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 9109 currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1; 9110 } else if (adj >= HOME_APP_ADJ) { 9111 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 9112 currApp.lru = 0; 9113 } else if (adj >= SECONDARY_SERVER_ADJ) { 9114 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 9115 } else if (adj >= VISIBLE_APP_ADJ) { 9116 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 9117 } else { 9118 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 9119 } 9120 currApp.importanceReasonCode = app.adjTypeCode; 9121 if (app.adjSource instanceof ProcessRecord) { 9122 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 9123 } else if (app.adjSource instanceof HistoryRecord) { 9124 HistoryRecord r = (HistoryRecord)app.adjSource; 9125 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 9126 } 9127 if (app.adjTarget instanceof ComponentName) { 9128 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 9129 } 9130 //Log.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 9131 // + " lru=" + currApp.lru); 9132 if (runList == null) { 9133 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 9134 } 9135 runList.add(currApp); 9136 } 9137 } 9138 } 9139 return runList; 9140 } 9141 9142 @Override 9143 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 9144 if (checkCallingPermission(android.Manifest.permission.DUMP) 9145 != PackageManager.PERMISSION_GRANTED) { 9146 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 9147 + Binder.getCallingPid() 9148 + ", uid=" + Binder.getCallingUid() 9149 + " without permission " 9150 + android.Manifest.permission.DUMP); 9151 return; 9152 } 9153 9154 boolean dumpAll = false; 9155 9156 int opti = 0; 9157 while (opti < args.length) { 9158 String opt = args[opti]; 9159 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 9160 break; 9161 } 9162 opti++; 9163 if ("-a".equals(opt)) { 9164 dumpAll = true; 9165 } else if ("-h".equals(opt)) { 9166 pw.println("Activity manager dump options:"); 9167 pw.println(" [-a] [h- [cmd] ..."); 9168 pw.println(" cmd may be one of:"); 9169 pw.println(" activities: activity stack state"); 9170 pw.println(" broadcasts: broadcast state"); 9171 pw.println(" intents: pending intent state"); 9172 pw.println(" processes: process state"); 9173 pw.println(" providers: content provider state"); 9174 pw.println(" services: service state"); 9175 pw.println(" service [name]: service client-side state"); 9176 return; 9177 } else { 9178 pw.println("Unknown argument: " + opt + "; use -h for help"); 9179 } 9180 } 9181 9182 // Is the caller requesting to dump a particular piece of data? 9183 if (opti < args.length) { 9184 String cmd = args[opti]; 9185 opti++; 9186 if ("activities".equals(cmd) || "a".equals(cmd)) { 9187 synchronized (this) { 9188 dumpActivitiesLocked(fd, pw, args, opti, true, true); 9189 } 9190 return; 9191 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 9192 synchronized (this) { 9193 dumpBroadcastsLocked(fd, pw, args, opti, true); 9194 } 9195 return; 9196 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 9197 synchronized (this) { 9198 dumpPendingIntentsLocked(fd, pw, args, opti, true); 9199 } 9200 return; 9201 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 9202 synchronized (this) { 9203 dumpProcessesLocked(fd, pw, args, opti, true); 9204 } 9205 return; 9206 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 9207 synchronized (this) { 9208 dumpProvidersLocked(fd, pw, args, opti, true); 9209 } 9210 return; 9211 } else if ("service".equals(cmd)) { 9212 dumpService(fd, pw, args, opti, true); 9213 return; 9214 } else if ("services".equals(cmd) || "s".equals(cmd)) { 9215 synchronized (this) { 9216 dumpServicesLocked(fd, pw, args, opti, true); 9217 } 9218 return; 9219 } 9220 } 9221 9222 // No piece of data specified, dump everything. 9223 synchronized (this) { 9224 boolean needSep; 9225 if (dumpAll) { 9226 pw.println("Providers in Current Activity Manager State:"); 9227 } 9228 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll); 9229 if (needSep) { 9230 pw.println(" "); 9231 } 9232 if (dumpAll) { 9233 pw.println("-------------------------------------------------------------------------------"); 9234 pw.println("Broadcasts in Current Activity Manager State:"); 9235 } 9236 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll); 9237 if (needSep) { 9238 pw.println(" "); 9239 } 9240 if (dumpAll) { 9241 pw.println("-------------------------------------------------------------------------------"); 9242 pw.println("Services in Current Activity Manager State:"); 9243 } 9244 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll); 9245 if (needSep) { 9246 pw.println(" "); 9247 } 9248 if (dumpAll) { 9249 pw.println("-------------------------------------------------------------------------------"); 9250 pw.println("PendingIntents in Current Activity Manager State:"); 9251 } 9252 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll); 9253 if (needSep) { 9254 pw.println(" "); 9255 } 9256 if (dumpAll) { 9257 pw.println("-------------------------------------------------------------------------------"); 9258 pw.println("Activities in Current Activity Manager State:"); 9259 } 9260 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, !dumpAll); 9261 if (needSep) { 9262 pw.println(" "); 9263 } 9264 if (dumpAll) { 9265 pw.println("-------------------------------------------------------------------------------"); 9266 pw.println("Processes in Current Activity Manager State:"); 9267 } 9268 dumpProcessesLocked(fd, pw, args, opti, dumpAll); 9269 } 9270 } 9271 9272 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9273 int opti, boolean dumpAll, boolean needHeader) { 9274 if (needHeader) { 9275 pw.println(" Activity stack:"); 9276 } 9277 dumpHistoryList(pw, mHistory, " ", "Hist", true); 9278 pw.println(" "); 9279 pw.println(" Running activities (most recent first):"); 9280 dumpHistoryList(pw, mLRUActivities, " ", "Run", false); 9281 if (mWaitingVisibleActivities.size() > 0) { 9282 pw.println(" "); 9283 pw.println(" Activities waiting for another to become visible:"); 9284 dumpHistoryList(pw, mWaitingVisibleActivities, " ", "Wait", false); 9285 } 9286 if (mStoppingActivities.size() > 0) { 9287 pw.println(" "); 9288 pw.println(" Activities waiting to stop:"); 9289 dumpHistoryList(pw, mStoppingActivities, " ", "Stop", false); 9290 } 9291 if (mFinishingActivities.size() > 0) { 9292 pw.println(" "); 9293 pw.println(" Activities waiting to finish:"); 9294 dumpHistoryList(pw, mFinishingActivities, " ", "Fin", false); 9295 } 9296 9297 pw.println(" "); 9298 pw.println(" mPausingActivity: " + mPausingActivity); 9299 pw.println(" mResumedActivity: " + mResumedActivity); 9300 pw.println(" mFocusedActivity: " + mFocusedActivity); 9301 pw.println(" mLastPausedActivity: " + mLastPausedActivity); 9302 9303 if (dumpAll && mRecentTasks.size() > 0) { 9304 pw.println(" "); 9305 pw.println("Recent tasks in Current Activity Manager State:"); 9306 9307 final int N = mRecentTasks.size(); 9308 for (int i=0; i<N; i++) { 9309 TaskRecord tr = mRecentTasks.get(i); 9310 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 9311 pw.println(tr); 9312 mRecentTasks.get(i).dump(pw, " "); 9313 } 9314 } 9315 9316 pw.println(" "); 9317 pw.println(" mCurTask: " + mCurTask); 9318 9319 return true; 9320 } 9321 9322 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9323 int opti, boolean dumpAll) { 9324 boolean needSep = false; 9325 int numPers = 0; 9326 9327 if (dumpAll) { 9328 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 9329 final int NA = procs.size(); 9330 for (int ia=0; ia<NA; ia++) { 9331 if (!needSep) { 9332 pw.println(" All known processes:"); 9333 needSep = true; 9334 } 9335 ProcessRecord r = procs.valueAt(ia); 9336 pw.print(r.persistent ? " *PERS*" : " *APP*"); 9337 pw.print(" UID "); pw.print(procs.keyAt(ia)); 9338 pw.print(" "); pw.println(r); 9339 r.dump(pw, " "); 9340 if (r.persistent) { 9341 numPers++; 9342 } 9343 } 9344 } 9345 } 9346 9347 if (mLruProcesses.size() > 0) { 9348 if (needSep) pw.println(" "); 9349 needSep = true; 9350 pw.println(" Running processes (most recent first):"); 9351 dumpProcessList(pw, this, mLruProcesses, " ", 9352 "App ", "PERS", true); 9353 needSep = true; 9354 } 9355 9356 synchronized (mPidsSelfLocked) { 9357 if (mPidsSelfLocked.size() > 0) { 9358 if (needSep) pw.println(" "); 9359 needSep = true; 9360 pw.println(" PID mappings:"); 9361 for (int i=0; i<mPidsSelfLocked.size(); i++) { 9362 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 9363 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 9364 } 9365 } 9366 } 9367 9368 if (mForegroundProcesses.size() > 0) { 9369 if (needSep) pw.println(" "); 9370 needSep = true; 9371 pw.println(" Foreground Processes:"); 9372 for (int i=0; i<mForegroundProcesses.size(); i++) { 9373 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 9374 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 9375 } 9376 } 9377 9378 if (mPersistentStartingProcesses.size() > 0) { 9379 if (needSep) pw.println(" "); 9380 needSep = true; 9381 pw.println(" Persisent processes that are starting:"); 9382 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 9383 "Starting Norm", "Restarting PERS", false); 9384 } 9385 9386 if (mStartingProcesses.size() > 0) { 9387 if (needSep) pw.println(" "); 9388 needSep = true; 9389 pw.println(" Processes that are starting:"); 9390 dumpProcessList(pw, this, mStartingProcesses, " ", 9391 "Starting Norm", "Starting PERS", false); 9392 } 9393 9394 if (mRemovedProcesses.size() > 0) { 9395 if (needSep) pw.println(" "); 9396 needSep = true; 9397 pw.println(" Processes that are being removed:"); 9398 dumpProcessList(pw, this, mRemovedProcesses, " ", 9399 "Removed Norm", "Removed PERS", false); 9400 } 9401 9402 if (mProcessesOnHold.size() > 0) { 9403 if (needSep) pw.println(" "); 9404 needSep = true; 9405 pw.println(" Processes that are on old until the system is ready:"); 9406 dumpProcessList(pw, this, mProcessesOnHold, " ", 9407 "OnHold Norm", "OnHold PERS", false); 9408 } 9409 9410 if (mProcessesToGc.size() > 0) { 9411 if (needSep) pw.println(" "); 9412 needSep = true; 9413 pw.println(" Processes that are waiting to GC:"); 9414 long now = SystemClock.uptimeMillis(); 9415 for (int i=0; i<mProcessesToGc.size(); i++) { 9416 ProcessRecord proc = mProcessesToGc.get(i); 9417 pw.print(" Process "); pw.println(proc); 9418 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9419 pw.print(", last gced="); 9420 pw.print(now-proc.lastRequestedGc); 9421 pw.print(" ms ago, last lowMem="); 9422 pw.print(now-proc.lastLowMemory); 9423 pw.println(" ms ago"); 9424 9425 } 9426 } 9427 9428 if (mProcessCrashTimes.getMap().size() > 0) { 9429 if (needSep) pw.println(" "); 9430 needSep = true; 9431 pw.println(" Time since processes crashed:"); 9432 long now = SystemClock.uptimeMillis(); 9433 for (Map.Entry<String, SparseArray<Long>> procs 9434 : mProcessCrashTimes.getMap().entrySet()) { 9435 SparseArray<Long> uids = procs.getValue(); 9436 final int N = uids.size(); 9437 for (int i=0; i<N; i++) { 9438 pw.print(" Process "); pw.print(procs.getKey()); 9439 pw.print(" uid "); pw.print(uids.keyAt(i)); 9440 pw.print(": last crashed "); 9441 pw.print((now-uids.valueAt(i))); 9442 pw.println(" ms ago"); 9443 } 9444 } 9445 } 9446 9447 if (mBadProcesses.getMap().size() > 0) { 9448 if (needSep) pw.println(" "); 9449 needSep = true; 9450 pw.println(" Bad processes:"); 9451 for (Map.Entry<String, SparseArray<Long>> procs 9452 : mBadProcesses.getMap().entrySet()) { 9453 SparseArray<Long> uids = procs.getValue(); 9454 final int N = uids.size(); 9455 for (int i=0; i<N; i++) { 9456 pw.print(" Bad process "); pw.print(procs.getKey()); 9457 pw.print(" uid "); pw.print(uids.keyAt(i)); 9458 pw.print(": crashed at time "); 9459 pw.println(uids.valueAt(i)); 9460 } 9461 } 9462 } 9463 9464 pw.println(" "); 9465 pw.println(" mHomeProcess: " + mHomeProcess); 9466 pw.println(" mConfiguration: " + mConfiguration); 9467 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown); 9468 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9469 || mOrigWaitForDebugger) { 9470 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9471 + " mDebugTransient=" + mDebugTransient 9472 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9473 } 9474 if (mAlwaysFinishActivities || mController != null) { 9475 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9476 + " mController=" + mController); 9477 } 9478 if (dumpAll) { 9479 pw.println(" Total persistent processes: " + numPers); 9480 pw.println(" mStartRunning=" + mStartRunning 9481 + " mSystemReady=" + mSystemReady 9482 + " mBooting=" + mBooting 9483 + " mBooted=" + mBooted 9484 + " mFactoryTest=" + mFactoryTest); 9485 pw.println(" mGoingToSleep=" + mGoingToSleep); 9486 pw.println(" mLaunchingActivity=" + mLaunchingActivity); 9487 } 9488 9489 return true; 9490 } 9491 9492 /** 9493 * There are three ways to call this: 9494 * - no service specified: dump all the services 9495 * - a flattened component name that matched an existing service was specified as the 9496 * first arg: dump that one service 9497 * - the first arg isn't the flattened component name of an existing service: 9498 * dump all services whose component contains the first arg as a substring 9499 */ 9500 protected void dumpService(FileDescriptor fd, PrintWriter pw, String[] args, 9501 int opti, boolean dumpAll) { 9502 String[] newArgs; 9503 String componentNameString; 9504 ServiceRecord r; 9505 if (opti <= args.length) { 9506 componentNameString = null; 9507 newArgs = EMPTY_STRING_ARRAY; 9508 r = null; 9509 } else { 9510 componentNameString = args[opti]; 9511 opti++; 9512 ComponentName componentName = ComponentName.unflattenFromString(componentNameString); 9513 r = componentName != null ? mServices.get(componentName) : null; 9514 newArgs = new String[args.length - opti]; 9515 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9516 } 9517 9518 if (r != null) { 9519 dumpService(fd, pw, r, newArgs); 9520 } else { 9521 for (ServiceRecord r1 : mServices.values()) { 9522 if (componentNameString == null 9523 || r1.name.flattenToString().contains(componentNameString)) { 9524 dumpService(fd, pw, r1, newArgs); 9525 } 9526 } 9527 } 9528 } 9529 9530 /** 9531 * Invokes IApplicationThread.dumpService() on the thread of the specified service if 9532 * there is a thread associated with the service. 9533 */ 9534 private void dumpService(FileDescriptor fd, PrintWriter pw, ServiceRecord r, String[] args) { 9535 pw.println(" Service " + r.name.flattenToString()); 9536 if (r.app != null && r.app.thread != null) { 9537 try { 9538 // flush anything that is already in the PrintWriter since the thread is going 9539 // to write to the file descriptor directly 9540 pw.flush(); 9541 r.app.thread.dumpService(fd, r, args); 9542 pw.print("\n"); 9543 } catch (RemoteException e) { 9544 pw.println("got a RemoteException while dumping the service"); 9545 } 9546 } 9547 } 9548 9549 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9550 int opti, boolean dumpAll) { 9551 boolean needSep = false; 9552 9553 if (dumpAll) { 9554 if (mRegisteredReceivers.size() > 0) { 9555 pw.println(" "); 9556 pw.println(" Registered Receivers:"); 9557 Iterator it = mRegisteredReceivers.values().iterator(); 9558 while (it.hasNext()) { 9559 ReceiverList r = (ReceiverList)it.next(); 9560 pw.print(" * "); pw.println(r); 9561 r.dump(pw, " "); 9562 } 9563 } 9564 9565 pw.println(" "); 9566 pw.println("Receiver Resolver Table:"); 9567 mReceiverResolver.dump(pw, " "); 9568 needSep = true; 9569 } 9570 9571 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0 9572 || mPendingBroadcast != null) { 9573 if (mParallelBroadcasts.size() > 0) { 9574 pw.println(" "); 9575 pw.println(" Active broadcasts:"); 9576 } 9577 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) { 9578 pw.println(" Broadcast #" + i + ":"); 9579 mParallelBroadcasts.get(i).dump(pw, " "); 9580 } 9581 if (mOrderedBroadcasts.size() > 0) { 9582 pw.println(" "); 9583 pw.println(" Active serialized broadcasts:"); 9584 } 9585 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) { 9586 pw.println(" Serialized Broadcast #" + i + ":"); 9587 mOrderedBroadcasts.get(i).dump(pw, " "); 9588 } 9589 pw.println(" "); 9590 pw.println(" Pending broadcast:"); 9591 if (mPendingBroadcast != null) { 9592 mPendingBroadcast.dump(pw, " "); 9593 } else { 9594 pw.println(" (null)"); 9595 } 9596 needSep = true; 9597 } 9598 9599 if (dumpAll) { 9600 pw.println(" "); 9601 pw.println(" Historical broadcasts:"); 9602 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) { 9603 BroadcastRecord r = mBroadcastHistory[i]; 9604 if (r == null) { 9605 break; 9606 } 9607 pw.println(" Historical Broadcast #" + i + ":"); 9608 r.dump(pw, " "); 9609 } 9610 needSep = true; 9611 } 9612 9613 if (mStickyBroadcasts != null) { 9614 pw.println(" "); 9615 pw.println(" Sticky broadcasts:"); 9616 StringBuilder sb = new StringBuilder(128); 9617 for (Map.Entry<String, ArrayList<Intent>> ent 9618 : mStickyBroadcasts.entrySet()) { 9619 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9620 pw.println(":"); 9621 ArrayList<Intent> intents = ent.getValue(); 9622 final int N = intents.size(); 9623 for (int i=0; i<N; i++) { 9624 sb.setLength(0); 9625 sb.append(" Intent: "); 9626 intents.get(i).toShortString(sb, true, false); 9627 pw.println(sb.toString()); 9628 Bundle bundle = intents.get(i).getExtras(); 9629 if (bundle != null) { 9630 pw.print(" "); 9631 pw.println(bundle.toString()); 9632 } 9633 } 9634 } 9635 needSep = true; 9636 } 9637 9638 if (dumpAll) { 9639 pw.println(" "); 9640 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled); 9641 pw.println(" mHandler:"); 9642 mHandler.dump(new PrintWriterPrinter(pw), " "); 9643 needSep = true; 9644 } 9645 9646 return needSep; 9647 } 9648 9649 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9650 int opti, boolean dumpAll) { 9651 boolean needSep = false; 9652 9653 if (dumpAll) { 9654 if (mServices.size() > 0) { 9655 pw.println(" Active services:"); 9656 Iterator<ServiceRecord> it = mServices.values().iterator(); 9657 while (it.hasNext()) { 9658 ServiceRecord r = it.next(); 9659 pw.print(" * "); pw.println(r); 9660 r.dump(pw, " "); 9661 } 9662 needSep = true; 9663 } 9664 } 9665 9666 if (mPendingServices.size() > 0) { 9667 if (needSep) pw.println(" "); 9668 pw.println(" Pending services:"); 9669 for (int i=0; i<mPendingServices.size(); i++) { 9670 ServiceRecord r = mPendingServices.get(i); 9671 pw.print(" * Pending "); pw.println(r); 9672 r.dump(pw, " "); 9673 } 9674 needSep = true; 9675 } 9676 9677 if (mRestartingServices.size() > 0) { 9678 if (needSep) pw.println(" "); 9679 pw.println(" Restarting services:"); 9680 for (int i=0; i<mRestartingServices.size(); i++) { 9681 ServiceRecord r = mRestartingServices.get(i); 9682 pw.print(" * Restarting "); pw.println(r); 9683 r.dump(pw, " "); 9684 } 9685 needSep = true; 9686 } 9687 9688 if (mStoppingServices.size() > 0) { 9689 if (needSep) pw.println(" "); 9690 pw.println(" Stopping services:"); 9691 for (int i=0; i<mStoppingServices.size(); i++) { 9692 ServiceRecord r = mStoppingServices.get(i); 9693 pw.print(" * Stopping "); pw.println(r); 9694 r.dump(pw, " "); 9695 } 9696 needSep = true; 9697 } 9698 9699 if (dumpAll) { 9700 if (mServiceConnections.size() > 0) { 9701 if (needSep) pw.println(" "); 9702 pw.println(" Connection bindings to services:"); 9703 Iterator<ConnectionRecord> it 9704 = mServiceConnections.values().iterator(); 9705 while (it.hasNext()) { 9706 ConnectionRecord r = it.next(); 9707 pw.print(" * "); pw.println(r); 9708 r.dump(pw, " "); 9709 } 9710 needSep = true; 9711 } 9712 } 9713 9714 return needSep; 9715 } 9716 9717 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9718 int opti, boolean dumpAll) { 9719 boolean needSep = false; 9720 9721 if (dumpAll) { 9722 if (mProvidersByClass.size() > 0) { 9723 if (needSep) pw.println(" "); 9724 pw.println(" Published content providers (by class):"); 9725 Iterator it = mProvidersByClass.entrySet().iterator(); 9726 while (it.hasNext()) { 9727 Map.Entry e = (Map.Entry)it.next(); 9728 ContentProviderRecord r = (ContentProviderRecord)e.getValue(); 9729 pw.print(" * "); pw.println(r); 9730 r.dump(pw, " "); 9731 } 9732 needSep = true; 9733 } 9734 9735 if (mProvidersByName.size() > 0) { 9736 pw.println(" "); 9737 pw.println(" Authority to provider mappings:"); 9738 Iterator it = mProvidersByName.entrySet().iterator(); 9739 while (it.hasNext()) { 9740 Map.Entry e = (Map.Entry)it.next(); 9741 ContentProviderRecord r = (ContentProviderRecord)e.getValue(); 9742 pw.print(" "); pw.print(e.getKey()); pw.print(": "); 9743 pw.println(r); 9744 } 9745 needSep = true; 9746 } 9747 } 9748 9749 if (mLaunchingProviders.size() > 0) { 9750 if (needSep) pw.println(" "); 9751 pw.println(" Launching content providers:"); 9752 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9753 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9754 pw.println(mLaunchingProviders.get(i)); 9755 } 9756 needSep = true; 9757 } 9758 9759 if (mGrantedUriPermissions.size() > 0) { 9760 pw.println(); 9761 pw.println("Granted Uri Permissions:"); 9762 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9763 int uid = mGrantedUriPermissions.keyAt(i); 9764 HashMap<Uri, UriPermission> perms 9765 = mGrantedUriPermissions.valueAt(i); 9766 pw.print(" * UID "); pw.print(uid); 9767 pw.println(" holds:"); 9768 for (UriPermission perm : perms.values()) { 9769 pw.print(" "); pw.println(perm); 9770 perm.dump(pw, " "); 9771 } 9772 } 9773 needSep = true; 9774 } 9775 9776 return needSep; 9777 } 9778 9779 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9780 int opti, boolean dumpAll) { 9781 boolean needSep = false; 9782 9783 if (dumpAll) { 9784 if (this.mIntentSenderRecords.size() > 0) { 9785 Iterator<WeakReference<PendingIntentRecord>> it 9786 = mIntentSenderRecords.values().iterator(); 9787 while (it.hasNext()) { 9788 WeakReference<PendingIntentRecord> ref = it.next(); 9789 PendingIntentRecord rec = ref != null ? ref.get(): null; 9790 needSep = true; 9791 if (rec != null) { 9792 pw.print(" * "); pw.println(rec); 9793 rec.dump(pw, " "); 9794 } else { 9795 pw.print(" * "); pw.print(ref); 9796 } 9797 } 9798 } 9799 } 9800 9801 return needSep; 9802 } 9803 9804 private static final void dumpHistoryList(PrintWriter pw, List list, 9805 String prefix, String label, boolean complete) { 9806 TaskRecord lastTask = null; 9807 for (int i=list.size()-1; i>=0; i--) { 9808 HistoryRecord r = (HistoryRecord)list.get(i); 9809 final boolean full = complete || !r.inHistory; 9810 if (lastTask != r.task) { 9811 lastTask = r.task; 9812 pw.print(prefix); 9813 pw.print(full ? "* " : " "); 9814 pw.println(lastTask); 9815 if (full) { 9816 lastTask.dump(pw, prefix + " "); 9817 } 9818 } 9819 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9820 pw.print(" #"); pw.print(i); pw.print(": "); 9821 pw.println(r); 9822 if (full) { 9823 r.dump(pw, prefix + " "); 9824 } 9825 } 9826 } 9827 9828 private static String buildOomTag(String prefix, String space, int val, int base) { 9829 if (val == base) { 9830 if (space == null) return prefix; 9831 return prefix + " "; 9832 } 9833 return prefix + "+" + Integer.toString(val-base); 9834 } 9835 9836 private static final int dumpProcessList(PrintWriter pw, 9837 ActivityManagerService service, List list, 9838 String prefix, String normalLabel, String persistentLabel, 9839 boolean inclOomAdj) { 9840 int numPers = 0; 9841 for (int i=list.size()-1; i>=0; i--) { 9842 ProcessRecord r = (ProcessRecord)list.get(i); 9843 if (false) { 9844 pw.println(prefix + (r.persistent ? persistentLabel : normalLabel) 9845 + " #" + i + ":"); 9846 r.dump(pw, prefix + " "); 9847 } else if (inclOomAdj) { 9848 String oomAdj; 9849 if (r.setAdj >= EMPTY_APP_ADJ) { 9850 oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ); 9851 } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) { 9852 oomAdj = buildOomTag("bak", " ", r.setAdj, HIDDEN_APP_MIN_ADJ); 9853 } else if (r.setAdj >= HOME_APP_ADJ) { 9854 oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ); 9855 } else if (r.setAdj >= SECONDARY_SERVER_ADJ) { 9856 oomAdj = buildOomTag("svc", " ", r.setAdj, SECONDARY_SERVER_ADJ); 9857 } else if (r.setAdj >= BACKUP_APP_ADJ) { 9858 oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ); 9859 } else if (r.setAdj >= VISIBLE_APP_ADJ) { 9860 oomAdj = buildOomTag("vis ", null, r.setAdj, VISIBLE_APP_ADJ); 9861 } else if (r.setAdj >= FOREGROUND_APP_ADJ) { 9862 oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ); 9863 } else if (r.setAdj >= CORE_SERVER_ADJ) { 9864 oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ); 9865 } else if (r.setAdj >= SYSTEM_ADJ) { 9866 oomAdj = buildOomTag("sys ", null, r.setAdj, SYSTEM_ADJ); 9867 } else { 9868 oomAdj = Integer.toString(r.setAdj); 9869 } 9870 String schedGroup; 9871 switch (r.setSchedGroup) { 9872 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9873 schedGroup = "B"; 9874 break; 9875 case Process.THREAD_GROUP_DEFAULT: 9876 schedGroup = "F"; 9877 break; 9878 default: 9879 schedGroup = Integer.toString(r.setSchedGroup); 9880 break; 9881 } 9882 pw.println(String.format("%s%s #%2d: adj=%s/%s %s (%s)", 9883 prefix, (r.persistent ? persistentLabel : normalLabel), 9884 i, oomAdj, schedGroup, r.toShortString(), r.adjType)); 9885 if (r.adjSource != null || r.adjTarget != null) { 9886 pw.println(prefix + " " + r.adjTarget 9887 + "<=" + r.adjSource); 9888 } 9889 } else { 9890 pw.println(String.format("%s%s #%2d: %s", 9891 prefix, (r.persistent ? persistentLabel : normalLabel), 9892 i, r.toString())); 9893 } 9894 if (r.persistent) { 9895 numPers++; 9896 } 9897 } 9898 return numPers; 9899 } 9900 9901 private static final void dumpApplicationMemoryUsage(FileDescriptor fd, 9902 PrintWriter pw, List list, String prefix, String[] args) { 9903 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 9904 long uptime = SystemClock.uptimeMillis(); 9905 long realtime = SystemClock.elapsedRealtime(); 9906 9907 if (isCheckinRequest) { 9908 // short checkin version 9909 pw.println(uptime + "," + realtime); 9910 pw.flush(); 9911 } else { 9912 pw.println("Applications Memory Usage (kB):"); 9913 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9914 } 9915 for (int i = list.size() - 1 ; i >= 0 ; i--) { 9916 ProcessRecord r = (ProcessRecord)list.get(i); 9917 if (r.thread != null) { 9918 if (!isCheckinRequest) { 9919 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 9920 pw.flush(); 9921 } 9922 try { 9923 r.thread.asBinder().dump(fd, args); 9924 } catch (RemoteException e) { 9925 if (!isCheckinRequest) { 9926 pw.println("Got RemoteException!"); 9927 pw.flush(); 9928 } 9929 } 9930 } 9931 } 9932 } 9933 9934 /** 9935 * Searches array of arguments for the specified string 9936 * @param args array of argument strings 9937 * @param value value to search for 9938 * @return true if the value is contained in the array 9939 */ 9940 private static boolean scanArgs(String[] args, String value) { 9941 if (args != null) { 9942 for (String arg : args) { 9943 if (value.equals(arg)) { 9944 return true; 9945 } 9946 } 9947 } 9948 return false; 9949 } 9950 9951 private final int indexOfTokenLocked(IBinder token) { 9952 int count = mHistory.size(); 9953 9954 // convert the token to an entry in the history. 9955 HistoryRecord r = null; 9956 int index = -1; 9957 for (int i=count-1; i>=0; i--) { 9958 Object o = mHistory.get(i); 9959 if (o == token) { 9960 r = (HistoryRecord)o; 9961 index = i; 9962 break; 9963 } 9964 } 9965 9966 return index; 9967 } 9968 9969 private final void killServicesLocked(ProcessRecord app, 9970 boolean allowRestart) { 9971 // Report disconnected services. 9972 if (false) { 9973 // XXX we are letting the client link to the service for 9974 // death notifications. 9975 if (app.services.size() > 0) { 9976 Iterator it = app.services.iterator(); 9977 while (it.hasNext()) { 9978 ServiceRecord r = (ServiceRecord)it.next(); 9979 if (r.connections.size() > 0) { 9980 Iterator<ConnectionRecord> jt 9981 = r.connections.values().iterator(); 9982 while (jt.hasNext()) { 9983 ConnectionRecord c = jt.next(); 9984 if (c.binding.client != app) { 9985 try { 9986 //c.conn.connected(r.className, null); 9987 } catch (Exception e) { 9988 // todo: this should be asynchronous! 9989 Log.w(TAG, "Exception thrown disconnected servce " 9990 + r.shortName 9991 + " from app " + app.processName, e); 9992 } 9993 } 9994 } 9995 } 9996 } 9997 } 9998 } 9999 10000 // Clean up any connections this application has to other services. 10001 if (app.connections.size() > 0) { 10002 Iterator<ConnectionRecord> it = app.connections.iterator(); 10003 while (it.hasNext()) { 10004 ConnectionRecord r = it.next(); 10005 removeConnectionLocked(r, app, null); 10006 } 10007 } 10008 app.connections.clear(); 10009 10010 if (app.services.size() != 0) { 10011 // Any services running in the application need to be placed 10012 // back in the pending list. 10013 Iterator it = app.services.iterator(); 10014 while (it.hasNext()) { 10015 ServiceRecord sr = (ServiceRecord)it.next(); 10016 synchronized (sr.stats.getBatteryStats()) { 10017 sr.stats.stopLaunchedLocked(); 10018 } 10019 sr.app = null; 10020 sr.executeNesting = 0; 10021 mStoppingServices.remove(sr); 10022 10023 boolean hasClients = sr.bindings.size() > 0; 10024 if (hasClients) { 10025 Iterator<IntentBindRecord> bindings 10026 = sr.bindings.values().iterator(); 10027 while (bindings.hasNext()) { 10028 IntentBindRecord b = bindings.next(); 10029 if (DEBUG_SERVICE) Log.v(TAG, "Killing binding " + b 10030 + ": shouldUnbind=" + b.hasBound); 10031 b.binder = null; 10032 b.requested = b.received = b.hasBound = false; 10033 } 10034 } 10035 10036 if (sr.crashCount >= 2) { 10037 Log.w(TAG, "Service crashed " + sr.crashCount 10038 + " times, stopping: " + sr); 10039 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH, 10040 sr.crashCount, sr.shortName, app.pid); 10041 bringDownServiceLocked(sr, true); 10042 } else if (!allowRestart) { 10043 bringDownServiceLocked(sr, true); 10044 } else { 10045 boolean canceled = scheduleServiceRestartLocked(sr, true); 10046 10047 // Should the service remain running? Note that in the 10048 // extreme case of so many attempts to deliver a command 10049 // that it failed, that we also will stop it here. 10050 if (sr.startRequested && (sr.stopIfKilled || canceled)) { 10051 if (sr.pendingStarts.size() == 0) { 10052 sr.startRequested = false; 10053 if (!hasClients) { 10054 // Whoops, no reason to restart! 10055 bringDownServiceLocked(sr, true); 10056 } 10057 } 10058 } 10059 } 10060 } 10061 10062 if (!allowRestart) { 10063 app.services.clear(); 10064 } 10065 } 10066 10067 // Make sure we have no more records on the stopping list. 10068 int i = mStoppingServices.size(); 10069 while (i > 0) { 10070 i--; 10071 ServiceRecord sr = mStoppingServices.get(i); 10072 if (sr.app == app) { 10073 mStoppingServices.remove(i); 10074 } 10075 } 10076 10077 app.executingServices.clear(); 10078 } 10079 10080 private final void removeDyingProviderLocked(ProcessRecord proc, 10081 ContentProviderRecord cpr) { 10082 synchronized (cpr) { 10083 cpr.launchingApp = null; 10084 cpr.notifyAll(); 10085 } 10086 10087 mProvidersByClass.remove(cpr.info.name); 10088 String names[] = cpr.info.authority.split(";"); 10089 for (int j = 0; j < names.length; j++) { 10090 mProvidersByName.remove(names[j]); 10091 } 10092 10093 Iterator<ProcessRecord> cit = cpr.clients.iterator(); 10094 while (cit.hasNext()) { 10095 ProcessRecord capp = cit.next(); 10096 if (!capp.persistent && capp.thread != null 10097 && capp.pid != 0 10098 && capp.pid != MY_PID) { 10099 Log.i(TAG, "Killing app " + capp.processName 10100 + " (pid " + capp.pid 10101 + ") because provider " + cpr.info.name 10102 + " is in dying process " + proc.processName); 10103 Process.killProcess(capp.pid); 10104 } 10105 } 10106 10107 mLaunchingProviders.remove(cpr); 10108 } 10109 10110 /** 10111 * Main code for cleaning up a process when it has gone away. This is 10112 * called both as a result of the process dying, or directly when stopping 10113 * a process when running in single process mode. 10114 */ 10115 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10116 boolean restarting, int index) { 10117 if (index >= 0) { 10118 mLruProcesses.remove(index); 10119 } 10120 10121 mProcessesToGc.remove(app); 10122 10123 // Dismiss any open dialogs. 10124 if (app.crashDialog != null) { 10125 app.crashDialog.dismiss(); 10126 app.crashDialog = null; 10127 } 10128 if (app.anrDialog != null) { 10129 app.anrDialog.dismiss(); 10130 app.anrDialog = null; 10131 } 10132 if (app.waitDialog != null) { 10133 app.waitDialog.dismiss(); 10134 app.waitDialog = null; 10135 } 10136 10137 app.crashing = false; 10138 app.notResponding = false; 10139 10140 app.resetPackageList(); 10141 app.thread = null; 10142 app.forcingToForeground = null; 10143 app.foregroundServices = false; 10144 10145 killServicesLocked(app, true); 10146 10147 boolean restart = false; 10148 10149 int NL = mLaunchingProviders.size(); 10150 10151 // Remove published content providers. 10152 if (!app.pubProviders.isEmpty()) { 10153 Iterator it = app.pubProviders.values().iterator(); 10154 while (it.hasNext()) { 10155 ContentProviderRecord cpr = (ContentProviderRecord)it.next(); 10156 cpr.provider = null; 10157 cpr.app = null; 10158 10159 // See if someone is waiting for this provider... in which 10160 // case we don't remove it, but just let it restart. 10161 int i = 0; 10162 if (!app.bad) { 10163 for (; i<NL; i++) { 10164 if (mLaunchingProviders.get(i) == cpr) { 10165 restart = true; 10166 break; 10167 } 10168 } 10169 } else { 10170 i = NL; 10171 } 10172 10173 if (i >= NL) { 10174 removeDyingProviderLocked(app, cpr); 10175 NL = mLaunchingProviders.size(); 10176 } 10177 } 10178 app.pubProviders.clear(); 10179 } 10180 10181 // Take care of any launching providers waiting for this process. 10182 if (checkAppInLaunchingProvidersLocked(app, false)) { 10183 restart = true; 10184 } 10185 10186 // Unregister from connected content providers. 10187 if (!app.conProviders.isEmpty()) { 10188 Iterator it = app.conProviders.keySet().iterator(); 10189 while (it.hasNext()) { 10190 ContentProviderRecord cpr = (ContentProviderRecord)it.next(); 10191 cpr.clients.remove(app); 10192 } 10193 app.conProviders.clear(); 10194 } 10195 10196 // At this point there may be remaining entries in mLaunchingProviders 10197 // where we were the only one waiting, so they are no longer of use. 10198 // Look for these and clean up if found. 10199 // XXX Commented out for now. Trying to figure out a way to reproduce 10200 // the actual situation to identify what is actually going on. 10201 if (false) { 10202 for (int i=0; i<NL; i++) { 10203 ContentProviderRecord cpr = (ContentProviderRecord) 10204 mLaunchingProviders.get(i); 10205 if (cpr.clients.size() <= 0 && cpr.externals <= 0) { 10206 synchronized (cpr) { 10207 cpr.launchingApp = null; 10208 cpr.notifyAll(); 10209 } 10210 } 10211 } 10212 } 10213 10214 skipCurrentReceiverLocked(app); 10215 10216 // Unregister any receivers. 10217 if (app.receivers.size() > 0) { 10218 Iterator<ReceiverList> it = app.receivers.iterator(); 10219 while (it.hasNext()) { 10220 removeReceiverLocked(it.next()); 10221 } 10222 app.receivers.clear(); 10223 } 10224 10225 // If the app is undergoing backup, tell the backup manager about it 10226 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10227 if (DEBUG_BACKUP) Log.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10228 try { 10229 IBackupManager bm = IBackupManager.Stub.asInterface( 10230 ServiceManager.getService(Context.BACKUP_SERVICE)); 10231 bm.agentDisconnected(app.info.packageName); 10232 } catch (RemoteException e) { 10233 // can't happen; backup manager is local 10234 } 10235 } 10236 10237 // If the caller is restarting this app, then leave it in its 10238 // current lists and let the caller take care of it. 10239 if (restarting) { 10240 return; 10241 } 10242 10243 if (!app.persistent) { 10244 if (DEBUG_PROCESSES) Log.v(TAG, 10245 "Removing non-persistent process during cleanup: " + app); 10246 mProcessNames.remove(app.processName, app.info.uid); 10247 } else if (!app.removed) { 10248 // This app is persistent, so we need to keep its record around. 10249 // If it is not already on the pending app list, add it there 10250 // and start a new process for it. 10251 app.thread = null; 10252 app.forcingToForeground = null; 10253 app.foregroundServices = false; 10254 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10255 mPersistentStartingProcesses.add(app); 10256 restart = true; 10257 } 10258 } 10259 mProcessesOnHold.remove(app); 10260 10261 if (app == mHomeProcess) { 10262 mHomeProcess = null; 10263 } 10264 10265 if (restart) { 10266 // We have components that still need to be running in the 10267 // process, so re-launch it. 10268 mProcessNames.put(app.processName, app.info.uid, app); 10269 startProcessLocked(app, "restart", app.processName); 10270 } else if (app.pid > 0 && app.pid != MY_PID) { 10271 // Goodbye! 10272 synchronized (mPidsSelfLocked) { 10273 mPidsSelfLocked.remove(app.pid); 10274 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10275 } 10276 app.setPid(0); 10277 } 10278 } 10279 10280 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10281 // Look through the content providers we are waiting to have launched, 10282 // and if any run in this process then either schedule a restart of 10283 // the process or kill the client waiting for it if this process has 10284 // gone bad. 10285 int NL = mLaunchingProviders.size(); 10286 boolean restart = false; 10287 for (int i=0; i<NL; i++) { 10288 ContentProviderRecord cpr = (ContentProviderRecord) 10289 mLaunchingProviders.get(i); 10290 if (cpr.launchingApp == app) { 10291 if (!alwaysBad && !app.bad) { 10292 restart = true; 10293 } else { 10294 removeDyingProviderLocked(app, cpr); 10295 NL = mLaunchingProviders.size(); 10296 } 10297 } 10298 } 10299 return restart; 10300 } 10301 10302 // ========================================================= 10303 // SERVICES 10304 // ========================================================= 10305 10306 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) { 10307 ActivityManager.RunningServiceInfo info = 10308 new ActivityManager.RunningServiceInfo(); 10309 info.service = r.name; 10310 if (r.app != null) { 10311 info.pid = r.app.pid; 10312 } 10313 info.uid = r.appInfo.uid; 10314 info.process = r.processName; 10315 info.foreground = r.isForeground; 10316 info.activeSince = r.createTime; 10317 info.started = r.startRequested; 10318 info.clientCount = r.connections.size(); 10319 info.crashCount = r.crashCount; 10320 info.lastActivityTime = r.lastActivity; 10321 if (r.isForeground) { 10322 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND; 10323 } 10324 if (r.startRequested) { 10325 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED; 10326 } 10327 if (r.app != null && r.app.pid == MY_PID) { 10328 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS; 10329 } 10330 if (r.app != null && r.app.persistent) { 10331 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS; 10332 } 10333 for (ConnectionRecord conn : r.connections.values()) { 10334 if (conn.clientLabel != 0) { 10335 info.clientPackage = conn.binding.client.info.packageName; 10336 info.clientLabel = conn.clientLabel; 10337 break; 10338 } 10339 } 10340 return info; 10341 } 10342 10343 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10344 int flags) { 10345 synchronized (this) { 10346 ArrayList<ActivityManager.RunningServiceInfo> res 10347 = new ArrayList<ActivityManager.RunningServiceInfo>(); 10348 10349 if (mServices.size() > 0) { 10350 Iterator<ServiceRecord> it = mServices.values().iterator(); 10351 while (it.hasNext() && res.size() < maxNum) { 10352 res.add(makeRunningServiceInfoLocked(it.next())); 10353 } 10354 } 10355 10356 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) { 10357 ServiceRecord r = mRestartingServices.get(i); 10358 ActivityManager.RunningServiceInfo info = 10359 makeRunningServiceInfoLocked(r); 10360 info.restarting = r.nextRestartTime; 10361 res.add(info); 10362 } 10363 10364 return res; 10365 } 10366 } 10367 10368 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10369 synchronized (this) { 10370 ServiceRecord r = mServices.get(name); 10371 if (r != null) { 10372 for (ConnectionRecord conn : r.connections.values()) { 10373 if (conn.clientIntent != null) { 10374 return conn.clientIntent; 10375 } 10376 } 10377 } 10378 } 10379 return null; 10380 } 10381 10382 private final ServiceRecord findServiceLocked(ComponentName name, 10383 IBinder token) { 10384 ServiceRecord r = mServices.get(name); 10385 return r == token ? r : null; 10386 } 10387 10388 private final class ServiceLookupResult { 10389 final ServiceRecord record; 10390 final String permission; 10391 10392 ServiceLookupResult(ServiceRecord _record, String _permission) { 10393 record = _record; 10394 permission = _permission; 10395 } 10396 }; 10397 10398 private ServiceLookupResult findServiceLocked(Intent service, 10399 String resolvedType) { 10400 ServiceRecord r = null; 10401 if (service.getComponent() != null) { 10402 r = mServices.get(service.getComponent()); 10403 } 10404 if (r == null) { 10405 Intent.FilterComparison filter = new Intent.FilterComparison(service); 10406 r = mServicesByIntent.get(filter); 10407 } 10408 10409 if (r == null) { 10410 try { 10411 ResolveInfo rInfo = 10412 ActivityThread.getPackageManager().resolveService( 10413 service, resolvedType, 0); 10414 ServiceInfo sInfo = 10415 rInfo != null ? rInfo.serviceInfo : null; 10416 if (sInfo == null) { 10417 return null; 10418 } 10419 10420 ComponentName name = new ComponentName( 10421 sInfo.applicationInfo.packageName, sInfo.name); 10422 r = mServices.get(name); 10423 } catch (RemoteException ex) { 10424 // pm is in same process, this will never happen. 10425 } 10426 } 10427 if (r != null) { 10428 int callingPid = Binder.getCallingPid(); 10429 int callingUid = Binder.getCallingUid(); 10430 if (checkComponentPermission(r.permission, 10431 callingPid, callingUid, r.exported ? -1 : r.appInfo.uid) 10432 != PackageManager.PERMISSION_GRANTED) { 10433 Log.w(TAG, "Permission Denial: Accessing service " + r.name 10434 + " from pid=" + callingPid 10435 + ", uid=" + callingUid 10436 + " requires " + r.permission); 10437 return new ServiceLookupResult(null, r.permission); 10438 } 10439 return new ServiceLookupResult(r, null); 10440 } 10441 return null; 10442 } 10443 10444 private class ServiceRestarter implements Runnable { 10445 private ServiceRecord mService; 10446 10447 void setService(ServiceRecord service) { 10448 mService = service; 10449 } 10450 10451 public void run() { 10452 synchronized(ActivityManagerService.this) { 10453 performServiceRestartLocked(mService); 10454 } 10455 } 10456 } 10457 10458 private ServiceLookupResult retrieveServiceLocked(Intent service, 10459 String resolvedType, int callingPid, int callingUid) { 10460 ServiceRecord r = null; 10461 if (service.getComponent() != null) { 10462 r = mServices.get(service.getComponent()); 10463 } 10464 Intent.FilterComparison filter = new Intent.FilterComparison(service); 10465 r = mServicesByIntent.get(filter); 10466 if (r == null) { 10467 try { 10468 ResolveInfo rInfo = 10469 ActivityThread.getPackageManager().resolveService( 10470 service, resolvedType, STOCK_PM_FLAGS); 10471 ServiceInfo sInfo = 10472 rInfo != null ? rInfo.serviceInfo : null; 10473 if (sInfo == null) { 10474 Log.w(TAG, "Unable to start service " + service + 10475 ": not found"); 10476 return null; 10477 } 10478 10479 ComponentName name = new ComponentName( 10480 sInfo.applicationInfo.packageName, sInfo.name); 10481 r = mServices.get(name); 10482 if (r == null) { 10483 filter = new Intent.FilterComparison(service.cloneFilter()); 10484 ServiceRestarter res = new ServiceRestarter(); 10485 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10486 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10487 synchronized (stats) { 10488 ss = stats.getServiceStatsLocked( 10489 sInfo.applicationInfo.uid, sInfo.packageName, 10490 sInfo.name); 10491 } 10492 r = new ServiceRecord(this, ss, name, filter, sInfo, res); 10493 res.setService(r); 10494 mServices.put(name, r); 10495 mServicesByIntent.put(filter, r); 10496 10497 // Make sure this component isn't in the pending list. 10498 int N = mPendingServices.size(); 10499 for (int i=0; i<N; i++) { 10500 ServiceRecord pr = mPendingServices.get(i); 10501 if (pr.name.equals(name)) { 10502 mPendingServices.remove(i); 10503 i--; 10504 N--; 10505 } 10506 } 10507 } 10508 } catch (RemoteException ex) { 10509 // pm is in same process, this will never happen. 10510 } 10511 } 10512 if (r != null) { 10513 if (checkComponentPermission(r.permission, 10514 callingPid, callingUid, r.exported ? -1 : r.appInfo.uid) 10515 != PackageManager.PERMISSION_GRANTED) { 10516 Log.w(TAG, "Permission Denial: Accessing service " + r.name 10517 + " from pid=" + Binder.getCallingPid() 10518 + ", uid=" + Binder.getCallingUid() 10519 + " requires " + r.permission); 10520 return new ServiceLookupResult(null, r.permission); 10521 } 10522 return new ServiceLookupResult(r, null); 10523 } 10524 return null; 10525 } 10526 10527 private final void bumpServiceExecutingLocked(ServiceRecord r) { 10528 long now = SystemClock.uptimeMillis(); 10529 if (r.executeNesting == 0 && r.app != null) { 10530 if (r.app.executingServices.size() == 0) { 10531 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 10532 msg.obj = r.app; 10533 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT); 10534 } 10535 r.app.executingServices.add(r); 10536 } 10537 r.executeNesting++; 10538 r.executingStart = now; 10539 } 10540 10541 private final void sendServiceArgsLocked(ServiceRecord r, 10542 boolean oomAdjusted) { 10543 final int N = r.pendingStarts.size(); 10544 if (N == 0) { 10545 return; 10546 } 10547 10548 int i = 0; 10549 while (i < N) { 10550 try { 10551 ServiceRecord.StartItem si = r.pendingStarts.get(i); 10552 if (DEBUG_SERVICE) Log.v(TAG, "Sending arguments to service: " 10553 + r.name + " " + r.intent + " args=" + si.intent); 10554 if (si.intent == null && N > 1) { 10555 // If somehow we got a dummy start at the front, then 10556 // just drop it here. 10557 i++; 10558 continue; 10559 } 10560 bumpServiceExecutingLocked(r); 10561 if (!oomAdjusted) { 10562 oomAdjusted = true; 10563 updateOomAdjLocked(r.app); 10564 } 10565 int flags = 0; 10566 if (si.deliveryCount > 0) { 10567 flags |= Service.START_FLAG_RETRY; 10568 } 10569 if (si.doneExecutingCount > 0) { 10570 flags |= Service.START_FLAG_REDELIVERY; 10571 } 10572 r.app.thread.scheduleServiceArgs(r, si.id, flags, si.intent); 10573 si.deliveredTime = SystemClock.uptimeMillis(); 10574 r.deliveredStarts.add(si); 10575 si.deliveryCount++; 10576 i++; 10577 } catch (RemoteException e) { 10578 // Remote process gone... we'll let the normal cleanup take 10579 // care of this. 10580 break; 10581 } catch (Exception e) { 10582 Log.w(TAG, "Unexpected exception", e); 10583 break; 10584 } 10585 } 10586 if (i == N) { 10587 r.pendingStarts.clear(); 10588 } else { 10589 while (i > 0) { 10590 i--; 10591 r.pendingStarts.remove(i); 10592 } 10593 } 10594 } 10595 10596 private final boolean requestServiceBindingLocked(ServiceRecord r, 10597 IntentBindRecord i, boolean rebind) { 10598 if (r.app == null || r.app.thread == null) { 10599 // If service is not currently running, can't yet bind. 10600 return false; 10601 } 10602 if ((!i.requested || rebind) && i.apps.size() > 0) { 10603 try { 10604 bumpServiceExecutingLocked(r); 10605 if (DEBUG_SERVICE) Log.v(TAG, "Connecting binding " + i 10606 + ": shouldUnbind=" + i.hasBound); 10607 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind); 10608 if (!rebind) { 10609 i.requested = true; 10610 } 10611 i.hasBound = true; 10612 i.doRebind = false; 10613 } catch (RemoteException e) { 10614 return false; 10615 } 10616 } 10617 return true; 10618 } 10619 10620 private final void requestServiceBindingsLocked(ServiceRecord r) { 10621 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator(); 10622 while (bindings.hasNext()) { 10623 IntentBindRecord i = bindings.next(); 10624 if (!requestServiceBindingLocked(r, i, false)) { 10625 break; 10626 } 10627 } 10628 } 10629 10630 private final void realStartServiceLocked(ServiceRecord r, 10631 ProcessRecord app) throws RemoteException { 10632 if (app.thread == null) { 10633 throw new RemoteException(); 10634 } 10635 10636 r.app = app; 10637 r.restartTime = r.lastActivity = SystemClock.uptimeMillis(); 10638 10639 app.services.add(r); 10640 bumpServiceExecutingLocked(r); 10641 updateLruProcessLocked(app, true, true); 10642 10643 boolean created = false; 10644 try { 10645 if (DEBUG_SERVICE) Log.v(TAG, "Scheduling start service: " 10646 + r.name + " " + r.intent); 10647 mStringBuilder.setLength(0); 10648 r.intent.getIntent().toShortString(mStringBuilder, false, true); 10649 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE, 10650 System.identityHashCode(r), r.shortName, 10651 mStringBuilder.toString(), r.app.pid); 10652 synchronized (r.stats.getBatteryStats()) { 10653 r.stats.startLaunchedLocked(); 10654 } 10655 ensurePackageDexOpt(r.serviceInfo.packageName); 10656 app.thread.scheduleCreateService(r, r.serviceInfo); 10657 r.postNotification(); 10658 created = true; 10659 } finally { 10660 if (!created) { 10661 app.services.remove(r); 10662 scheduleServiceRestartLocked(r, false); 10663 } 10664 } 10665 10666 requestServiceBindingsLocked(r); 10667 10668 // If the service is in the started state, and there are no 10669 // pending arguments, then fake up one so its onStartCommand() will 10670 // be called. 10671 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) { 10672 r.lastStartId++; 10673 if (r.lastStartId < 1) { 10674 r.lastStartId = 1; 10675 } 10676 r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, null)); 10677 } 10678 10679 sendServiceArgsLocked(r, true); 10680 } 10681 10682 private final boolean scheduleServiceRestartLocked(ServiceRecord r, 10683 boolean allowCancel) { 10684 boolean canceled = false; 10685 10686 final long now = SystemClock.uptimeMillis(); 10687 long minDuration = SERVICE_RESTART_DURATION; 10688 long resetTime = SERVICE_RESET_RUN_DURATION; 10689 10690 // Any delivered but not yet finished starts should be put back 10691 // on the pending list. 10692 final int N = r.deliveredStarts.size(); 10693 if (N > 0) { 10694 for (int i=N-1; i>=0; i--) { 10695 ServiceRecord.StartItem si = r.deliveredStarts.get(i); 10696 if (si.intent == null) { 10697 // We'll generate this again if needed. 10698 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT 10699 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) { 10700 r.pendingStarts.add(0, si); 10701 long dur = SystemClock.uptimeMillis() - si.deliveredTime; 10702 dur *= 2; 10703 if (minDuration < dur) minDuration = dur; 10704 if (resetTime < dur) resetTime = dur; 10705 } else { 10706 Log.w(TAG, "Canceling start item " + si.intent + " in service " 10707 + r.name); 10708 canceled = true; 10709 } 10710 } 10711 r.deliveredStarts.clear(); 10712 } 10713 10714 r.totalRestartCount++; 10715 if (r.restartDelay == 0) { 10716 r.restartCount++; 10717 r.restartDelay = minDuration; 10718 } else { 10719 // If it has been a "reasonably long time" since the service 10720 // was started, then reset our restart duration back to 10721 // the beginning, so we don't infinitely increase the duration 10722 // on a service that just occasionally gets killed (which is 10723 // a normal case, due to process being killed to reclaim memory). 10724 if (now > (r.restartTime+resetTime)) { 10725 r.restartCount = 1; 10726 r.restartDelay = minDuration; 10727 } else { 10728 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR; 10729 if (r.restartDelay < minDuration) { 10730 r.restartDelay = minDuration; 10731 } 10732 } 10733 } 10734 10735 r.nextRestartTime = now + r.restartDelay; 10736 10737 // Make sure that we don't end up restarting a bunch of services 10738 // all at the same time. 10739 boolean repeat; 10740 do { 10741 repeat = false; 10742 for (int i=mRestartingServices.size()-1; i>=0; i--) { 10743 ServiceRecord r2 = mRestartingServices.get(i); 10744 if (r2 != r && r.nextRestartTime 10745 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN) 10746 && r.nextRestartTime 10747 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) { 10748 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN; 10749 r.restartDelay = r.nextRestartTime - now; 10750 repeat = true; 10751 break; 10752 } 10753 } 10754 } while (repeat); 10755 10756 if (!mRestartingServices.contains(r)) { 10757 mRestartingServices.add(r); 10758 } 10759 10760 r.cancelNotification(); 10761 10762 mHandler.removeCallbacks(r.restarter); 10763 mHandler.postAtTime(r.restarter, r.nextRestartTime); 10764 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay; 10765 Log.w(TAG, "Scheduling restart of crashed service " 10766 + r.shortName + " in " + r.restartDelay + "ms"); 10767 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART, 10768 r.shortName, r.restartDelay); 10769 10770 Message msg = Message.obtain(); 10771 msg.what = SERVICE_ERROR_MSG; 10772 msg.obj = r; 10773 mHandler.sendMessage(msg); 10774 10775 return canceled; 10776 } 10777 10778 final void performServiceRestartLocked(ServiceRecord r) { 10779 if (!mRestartingServices.contains(r)) { 10780 return; 10781 } 10782 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true); 10783 } 10784 10785 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) { 10786 if (r.restartDelay == 0) { 10787 return false; 10788 } 10789 r.resetRestartCounter(); 10790 mRestartingServices.remove(r); 10791 mHandler.removeCallbacks(r.restarter); 10792 return true; 10793 } 10794 10795 private final boolean bringUpServiceLocked(ServiceRecord r, 10796 int intentFlags, boolean whileRestarting) { 10797 //Log.i(TAG, "Bring up service:"); 10798 //r.dump(" "); 10799 10800 if (r.app != null && r.app.thread != null) { 10801 sendServiceArgsLocked(r, false); 10802 return true; 10803 } 10804 10805 if (!whileRestarting && r.restartDelay > 0) { 10806 // If waiting for a restart, then do nothing. 10807 return true; 10808 } 10809 10810 if (DEBUG_SERVICE) Log.v(TAG, "Bringing up service " + r.name 10811 + " " + r.intent); 10812 10813 // We are now bringing the service up, so no longer in the 10814 // restarting state. 10815 mRestartingServices.remove(r); 10816 10817 final String appName = r.processName; 10818 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid); 10819 if (app != null && app.thread != null) { 10820 try { 10821 realStartServiceLocked(r, app); 10822 return true; 10823 } catch (RemoteException e) { 10824 Log.w(TAG, "Exception when starting service " + r.shortName, e); 10825 } 10826 10827 // If a dead object exception was thrown -- fall through to 10828 // restart the application. 10829 } 10830 10831 // Not running -- get it started, and enqueue this service record 10832 // to be executed when the app comes up. 10833 if (startProcessLocked(appName, r.appInfo, true, intentFlags, 10834 "service", r.name, false) == null) { 10835 Log.w(TAG, "Unable to launch app " 10836 + r.appInfo.packageName + "/" 10837 + r.appInfo.uid + " for service " 10838 + r.intent.getIntent() + ": process is bad"); 10839 bringDownServiceLocked(r, true); 10840 return false; 10841 } 10842 10843 if (!mPendingServices.contains(r)) { 10844 mPendingServices.add(r); 10845 } 10846 10847 return true; 10848 } 10849 10850 private final void bringDownServiceLocked(ServiceRecord r, boolean force) { 10851 //Log.i(TAG, "Bring down service:"); 10852 //r.dump(" "); 10853 10854 // Does it still need to run? 10855 if (!force && r.startRequested) { 10856 return; 10857 } 10858 if (r.connections.size() > 0) { 10859 if (!force) { 10860 // XXX should probably keep a count of the number of auto-create 10861 // connections directly in the service. 10862 Iterator<ConnectionRecord> it = r.connections.values().iterator(); 10863 while (it.hasNext()) { 10864 ConnectionRecord cr = it.next(); 10865 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) { 10866 return; 10867 } 10868 } 10869 } 10870 10871 // Report to all of the connections that the service is no longer 10872 // available. 10873 Iterator<ConnectionRecord> it = r.connections.values().iterator(); 10874 while (it.hasNext()) { 10875 ConnectionRecord c = it.next(); 10876 try { 10877 // todo: shouldn't be a synchronous call! 10878 c.conn.connected(r.name, null); 10879 } catch (Exception e) { 10880 Log.w(TAG, "Failure disconnecting service " + r.name + 10881 " to connection " + c.conn.asBinder() + 10882 " (in " + c.binding.client.processName + ")", e); 10883 } 10884 } 10885 } 10886 10887 // Tell the service that it has been unbound. 10888 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) { 10889 Iterator<IntentBindRecord> it = r.bindings.values().iterator(); 10890 while (it.hasNext()) { 10891 IntentBindRecord ibr = it.next(); 10892 if (DEBUG_SERVICE) Log.v(TAG, "Bringing down binding " + ibr 10893 + ": hasBound=" + ibr.hasBound); 10894 if (r.app != null && r.app.thread != null && ibr.hasBound) { 10895 try { 10896 bumpServiceExecutingLocked(r); 10897 updateOomAdjLocked(r.app); 10898 ibr.hasBound = false; 10899 r.app.thread.scheduleUnbindService(r, 10900 ibr.intent.getIntent()); 10901 } catch (Exception e) { 10902 Log.w(TAG, "Exception when unbinding service " 10903 + r.shortName, e); 10904 serviceDoneExecutingLocked(r, true); 10905 } 10906 } 10907 } 10908 } 10909 10910 if (DEBUG_SERVICE) Log.v(TAG, "Bringing down service " + r.name 10911 + " " + r.intent); 10912 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE, 10913 System.identityHashCode(r), r.shortName, 10914 (r.app != null) ? r.app.pid : -1); 10915 10916 mServices.remove(r.name); 10917 mServicesByIntent.remove(r.intent); 10918 if (localLOGV) Log.v(TAG, "BRING DOWN SERVICE: " + r.shortName); 10919 r.totalRestartCount = 0; 10920 unscheduleServiceRestartLocked(r); 10921 10922 // Also make sure it is not on the pending list. 10923 int N = mPendingServices.size(); 10924 for (int i=0; i<N; i++) { 10925 if (mPendingServices.get(i) == r) { 10926 mPendingServices.remove(i); 10927 if (DEBUG_SERVICE) Log.v( 10928 TAG, "Removed pending service: " + r.shortName); 10929 i--; 10930 N--; 10931 } 10932 } 10933 10934 r.cancelNotification(); 10935 r.isForeground = false; 10936 r.foregroundId = 0; 10937 r.foregroundNoti = null; 10938 10939 // Clear start entries. 10940 r.deliveredStarts.clear(); 10941 r.pendingStarts.clear(); 10942 10943 if (r.app != null) { 10944 synchronized (r.stats.getBatteryStats()) { 10945 r.stats.stopLaunchedLocked(); 10946 } 10947 r.app.services.remove(r); 10948 if (r.app.thread != null) { 10949 try { 10950 if (DEBUG_SERVICE) Log.v(TAG, 10951 "Stopping service: " + r.shortName); 10952 bumpServiceExecutingLocked(r); 10953 mStoppingServices.add(r); 10954 updateOomAdjLocked(r.app); 10955 r.app.thread.scheduleStopService(r); 10956 } catch (Exception e) { 10957 Log.w(TAG, "Exception when stopping service " 10958 + r.shortName, e); 10959 serviceDoneExecutingLocked(r, true); 10960 } 10961 updateServiceForegroundLocked(r.app, false); 10962 } else { 10963 if (DEBUG_SERVICE) Log.v( 10964 TAG, "Removed service that has no process: " + r.shortName); 10965 } 10966 } else { 10967 if (DEBUG_SERVICE) Log.v( 10968 TAG, "Removed service that is not running: " + r.shortName); 10969 } 10970 } 10971 10972 ComponentName startServiceLocked(IApplicationThread caller, 10973 Intent service, String resolvedType, 10974 int callingPid, int callingUid) { 10975 synchronized(this) { 10976 if (DEBUG_SERVICE) Log.v(TAG, "startService: " + service 10977 + " type=" + resolvedType + " args=" + service.getExtras()); 10978 10979 if (caller != null) { 10980 final ProcessRecord callerApp = getRecordForAppLocked(caller); 10981 if (callerApp == null) { 10982 throw new SecurityException( 10983 "Unable to find app for caller " + caller 10984 + " (pid=" + Binder.getCallingPid() 10985 + ") when starting service " + service); 10986 } 10987 } 10988 10989 ServiceLookupResult res = 10990 retrieveServiceLocked(service, resolvedType, 10991 callingPid, callingUid); 10992 if (res == null) { 10993 return null; 10994 } 10995 if (res.record == null) { 10996 return new ComponentName("!", res.permission != null 10997 ? res.permission : "private to package"); 10998 } 10999 ServiceRecord r = res.record; 11000 if (unscheduleServiceRestartLocked(r)) { 11001 if (DEBUG_SERVICE) Log.v(TAG, "START SERVICE WHILE RESTART PENDING: " 11002 + r.shortName); 11003 } 11004 r.startRequested = true; 11005 r.callStart = false; 11006 r.lastStartId++; 11007 if (r.lastStartId < 1) { 11008 r.lastStartId = 1; 11009 } 11010 r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, service)); 11011 r.lastActivity = SystemClock.uptimeMillis(); 11012 synchronized (r.stats.getBatteryStats()) { 11013 r.stats.startRunningLocked(); 11014 } 11015 if (!bringUpServiceLocked(r, service.getFlags(), false)) { 11016 return new ComponentName("!", "Service process is bad"); 11017 } 11018 return r.name; 11019 } 11020 } 11021 11022 public ComponentName startService(IApplicationThread caller, Intent service, 11023 String resolvedType) { 11024 // Refuse possible leaked file descriptors 11025 if (service != null && service.hasFileDescriptors() == true) { 11026 throw new IllegalArgumentException("File descriptors passed in Intent"); 11027 } 11028 11029 synchronized(this) { 11030 final int callingPid = Binder.getCallingPid(); 11031 final int callingUid = Binder.getCallingUid(); 11032 final long origId = Binder.clearCallingIdentity(); 11033 ComponentName res = startServiceLocked(caller, service, 11034 resolvedType, callingPid, callingUid); 11035 Binder.restoreCallingIdentity(origId); 11036 return res; 11037 } 11038 } 11039 11040 ComponentName startServiceInPackage(int uid, 11041 Intent service, String resolvedType) { 11042 synchronized(this) { 11043 final long origId = Binder.clearCallingIdentity(); 11044 ComponentName res = startServiceLocked(null, service, 11045 resolvedType, -1, uid); 11046 Binder.restoreCallingIdentity(origId); 11047 return res; 11048 } 11049 } 11050 11051 public int stopService(IApplicationThread caller, Intent service, 11052 String resolvedType) { 11053 // Refuse possible leaked file descriptors 11054 if (service != null && service.hasFileDescriptors() == true) { 11055 throw new IllegalArgumentException("File descriptors passed in Intent"); 11056 } 11057 11058 synchronized(this) { 11059 if (DEBUG_SERVICE) Log.v(TAG, "stopService: " + service 11060 + " type=" + resolvedType); 11061 11062 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11063 if (caller != null && callerApp == null) { 11064 throw new SecurityException( 11065 "Unable to find app for caller " + caller 11066 + " (pid=" + Binder.getCallingPid() 11067 + ") when stopping service " + service); 11068 } 11069 11070 // If this service is active, make sure it is stopped. 11071 ServiceLookupResult r = findServiceLocked(service, resolvedType); 11072 if (r != null) { 11073 if (r.record != null) { 11074 synchronized (r.record.stats.getBatteryStats()) { 11075 r.record.stats.stopRunningLocked(); 11076 } 11077 r.record.startRequested = false; 11078 r.record.callStart = false; 11079 final long origId = Binder.clearCallingIdentity(); 11080 bringDownServiceLocked(r.record, false); 11081 Binder.restoreCallingIdentity(origId); 11082 return 1; 11083 } 11084 return -1; 11085 } 11086 } 11087 11088 return 0; 11089 } 11090 11091 public IBinder peekService(Intent service, String resolvedType) { 11092 // Refuse possible leaked file descriptors 11093 if (service != null && service.hasFileDescriptors() == true) { 11094 throw new IllegalArgumentException("File descriptors passed in Intent"); 11095 } 11096 11097 IBinder ret = null; 11098 11099 synchronized(this) { 11100 ServiceLookupResult r = findServiceLocked(service, resolvedType); 11101 11102 if (r != null) { 11103 // r.record is null if findServiceLocked() failed the caller permission check 11104 if (r.record == null) { 11105 throw new SecurityException( 11106 "Permission Denial: Accessing service " + r.record.name 11107 + " from pid=" + Binder.getCallingPid() 11108 + ", uid=" + Binder.getCallingUid() 11109 + " requires " + r.permission); 11110 } 11111 IntentBindRecord ib = r.record.bindings.get(r.record.intent); 11112 if (ib != null) { 11113 ret = ib.binder; 11114 } 11115 } 11116 } 11117 11118 return ret; 11119 } 11120 11121 public boolean stopServiceToken(ComponentName className, IBinder token, 11122 int startId) { 11123 synchronized(this) { 11124 if (DEBUG_SERVICE) Log.v(TAG, "stopServiceToken: " + className 11125 + " " + token + " startId=" + startId); 11126 ServiceRecord r = findServiceLocked(className, token); 11127 if (r != null) { 11128 if (startId >= 0) { 11129 // Asked to only stop if done with all work. Note that 11130 // to avoid leaks, we will take this as dropping all 11131 // start items up to and including this one. 11132 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 11133 if (si != null) { 11134 while (r.deliveredStarts.size() > 0) { 11135 if (r.deliveredStarts.remove(0) == si) { 11136 break; 11137 } 11138 } 11139 } 11140 11141 if (r.lastStartId != startId) { 11142 return false; 11143 } 11144 11145 if (r.deliveredStarts.size() > 0) { 11146 Log.w(TAG, "stopServiceToken startId " + startId 11147 + " is last, but have " + r.deliveredStarts.size() 11148 + " remaining args"); 11149 } 11150 } 11151 11152 synchronized (r.stats.getBatteryStats()) { 11153 r.stats.stopRunningLocked(); 11154 r.startRequested = false; 11155 r.callStart = false; 11156 } 11157 final long origId = Binder.clearCallingIdentity(); 11158 bringDownServiceLocked(r, false); 11159 Binder.restoreCallingIdentity(origId); 11160 return true; 11161 } 11162 } 11163 return false; 11164 } 11165 11166 public void setServiceForeground(ComponentName className, IBinder token, 11167 int id, Notification notification, boolean removeNotification) { 11168 final long origId = Binder.clearCallingIdentity(); 11169 try { 11170 synchronized(this) { 11171 ServiceRecord r = findServiceLocked(className, token); 11172 if (r != null) { 11173 if (id != 0) { 11174 if (notification == null) { 11175 throw new IllegalArgumentException("null notification"); 11176 } 11177 if (r.foregroundId != id) { 11178 r.cancelNotification(); 11179 r.foregroundId = id; 11180 } 11181 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE; 11182 r.foregroundNoti = notification; 11183 r.isForeground = true; 11184 r.postNotification(); 11185 if (r.app != null) { 11186 updateServiceForegroundLocked(r.app, true); 11187 } 11188 } else { 11189 if (r.isForeground) { 11190 r.isForeground = false; 11191 if (r.app != null) { 11192 updateServiceForegroundLocked(r.app, true); 11193 } 11194 } 11195 if (removeNotification) { 11196 r.cancelNotification(); 11197 r.foregroundId = 0; 11198 r.foregroundNoti = null; 11199 } 11200 } 11201 } 11202 } 11203 } finally { 11204 Binder.restoreCallingIdentity(origId); 11205 } 11206 } 11207 11208 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) { 11209 boolean anyForeground = false; 11210 for (ServiceRecord sr : (HashSet<ServiceRecord>)proc.services) { 11211 if (sr.isForeground) { 11212 anyForeground = true; 11213 break; 11214 } 11215 } 11216 if (anyForeground != proc.foregroundServices) { 11217 proc.foregroundServices = anyForeground; 11218 if (oomAdj) { 11219 updateOomAdjLocked(); 11220 } 11221 } 11222 } 11223 11224 public int bindService(IApplicationThread caller, IBinder token, 11225 Intent service, String resolvedType, 11226 IServiceConnection connection, int flags) { 11227 // Refuse possible leaked file descriptors 11228 if (service != null && service.hasFileDescriptors() == true) { 11229 throw new IllegalArgumentException("File descriptors passed in Intent"); 11230 } 11231 11232 synchronized(this) { 11233 if (DEBUG_SERVICE) Log.v(TAG, "bindService: " + service 11234 + " type=" + resolvedType + " conn=" + connection.asBinder() 11235 + " flags=0x" + Integer.toHexString(flags)); 11236 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11237 if (callerApp == null) { 11238 throw new SecurityException( 11239 "Unable to find app for caller " + caller 11240 + " (pid=" + Binder.getCallingPid() 11241 + ") when binding service " + service); 11242 } 11243 11244 HistoryRecord activity = null; 11245 if (token != null) { 11246 int aindex = indexOfTokenLocked(token); 11247 if (aindex < 0) { 11248 Log.w(TAG, "Binding with unknown activity: " + token); 11249 return 0; 11250 } 11251 activity = (HistoryRecord)mHistory.get(aindex); 11252 } 11253 11254 int clientLabel = 0; 11255 PendingIntent clientIntent = null; 11256 11257 if (callerApp.info.uid == Process.SYSTEM_UID) { 11258 // Hacky kind of thing -- allow system stuff to tell us 11259 // what they are, so we can report this elsewhere for 11260 // others to know why certain services are running. 11261 try { 11262 clientIntent = (PendingIntent)service.getParcelableExtra( 11263 Intent.EXTRA_CLIENT_INTENT); 11264 } catch (RuntimeException e) { 11265 } 11266 if (clientIntent != null) { 11267 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0); 11268 if (clientLabel != 0) { 11269 // There are no useful extras in the intent, trash them. 11270 // System code calling with this stuff just needs to know 11271 // this will happen. 11272 service = service.cloneFilter(); 11273 } 11274 } 11275 } 11276 11277 ServiceLookupResult res = 11278 retrieveServiceLocked(service, resolvedType, 11279 Binder.getCallingPid(), Binder.getCallingUid()); 11280 if (res == null) { 11281 return 0; 11282 } 11283 if (res.record == null) { 11284 return -1; 11285 } 11286 ServiceRecord s = res.record; 11287 11288 final long origId = Binder.clearCallingIdentity(); 11289 11290 if (unscheduleServiceRestartLocked(s)) { 11291 if (DEBUG_SERVICE) Log.v(TAG, "BIND SERVICE WHILE RESTART PENDING: " 11292 + s.shortName); 11293 } 11294 11295 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp); 11296 ConnectionRecord c = new ConnectionRecord(b, activity, 11297 connection, flags, clientLabel, clientIntent); 11298 11299 IBinder binder = connection.asBinder(); 11300 s.connections.put(binder, c); 11301 b.connections.add(c); 11302 if (activity != null) { 11303 if (activity.connections == null) { 11304 activity.connections = new HashSet<ConnectionRecord>(); 11305 } 11306 activity.connections.add(c); 11307 } 11308 b.client.connections.add(c); 11309 mServiceConnections.put(binder, c); 11310 11311 if ((flags&Context.BIND_AUTO_CREATE) != 0) { 11312 s.lastActivity = SystemClock.uptimeMillis(); 11313 if (!bringUpServiceLocked(s, service.getFlags(), false)) { 11314 return 0; 11315 } 11316 } 11317 11318 if (s.app != null) { 11319 // This could have made the service more important. 11320 updateOomAdjLocked(s.app); 11321 } 11322 11323 if (DEBUG_SERVICE) Log.v(TAG, "Bind " + s + " with " + b 11324 + ": received=" + b.intent.received 11325 + " apps=" + b.intent.apps.size() 11326 + " doRebind=" + b.intent.doRebind); 11327 11328 if (s.app != null && b.intent.received) { 11329 // Service is already running, so we can immediately 11330 // publish the connection. 11331 try { 11332 c.conn.connected(s.name, b.intent.binder); 11333 } catch (Exception e) { 11334 Log.w(TAG, "Failure sending service " + s.shortName 11335 + " to connection " + c.conn.asBinder() 11336 + " (in " + c.binding.client.processName + ")", e); 11337 } 11338 11339 // If this is the first app connected back to this binding, 11340 // and the service had previously asked to be told when 11341 // rebound, then do so. 11342 if (b.intent.apps.size() == 1 && b.intent.doRebind) { 11343 requestServiceBindingLocked(s, b.intent, true); 11344 } 11345 } else if (!b.intent.requested) { 11346 requestServiceBindingLocked(s, b.intent, false); 11347 } 11348 11349 Binder.restoreCallingIdentity(origId); 11350 } 11351 11352 return 1; 11353 } 11354 11355 private void removeConnectionLocked( 11356 ConnectionRecord c, ProcessRecord skipApp, HistoryRecord skipAct) { 11357 IBinder binder = c.conn.asBinder(); 11358 AppBindRecord b = c.binding; 11359 ServiceRecord s = b.service; 11360 s.connections.remove(binder); 11361 b.connections.remove(c); 11362 if (c.activity != null && c.activity != skipAct) { 11363 if (c.activity.connections != null) { 11364 c.activity.connections.remove(c); 11365 } 11366 } 11367 if (b.client != skipApp) { 11368 b.client.connections.remove(c); 11369 } 11370 mServiceConnections.remove(binder); 11371 11372 if (b.connections.size() == 0) { 11373 b.intent.apps.remove(b.client); 11374 } 11375 11376 if (DEBUG_SERVICE) Log.v(TAG, "Disconnecting binding " + b.intent 11377 + ": shouldUnbind=" + b.intent.hasBound); 11378 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0 11379 && b.intent.hasBound) { 11380 try { 11381 bumpServiceExecutingLocked(s); 11382 updateOomAdjLocked(s.app); 11383 b.intent.hasBound = false; 11384 // Assume the client doesn't want to know about a rebind; 11385 // we will deal with that later if it asks for one. 11386 b.intent.doRebind = false; 11387 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent()); 11388 } catch (Exception e) { 11389 Log.w(TAG, "Exception when unbinding service " + s.shortName, e); 11390 serviceDoneExecutingLocked(s, true); 11391 } 11392 } 11393 11394 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) { 11395 bringDownServiceLocked(s, false); 11396 } 11397 } 11398 11399 public boolean unbindService(IServiceConnection connection) { 11400 synchronized (this) { 11401 IBinder binder = connection.asBinder(); 11402 if (DEBUG_SERVICE) Log.v(TAG, "unbindService: conn=" + binder); 11403 ConnectionRecord r = mServiceConnections.get(binder); 11404 if (r == null) { 11405 Log.w(TAG, "Unbind failed: could not find connection for " 11406 + connection.asBinder()); 11407 return false; 11408 } 11409 11410 final long origId = Binder.clearCallingIdentity(); 11411 11412 removeConnectionLocked(r, null, null); 11413 11414 if (r.binding.service.app != null) { 11415 // This could have made the service less important. 11416 updateOomAdjLocked(r.binding.service.app); 11417 } 11418 11419 Binder.restoreCallingIdentity(origId); 11420 } 11421 11422 return true; 11423 } 11424 11425 public void publishService(IBinder token, Intent intent, IBinder service) { 11426 // Refuse possible leaked file descriptors 11427 if (intent != null && intent.hasFileDescriptors() == true) { 11428 throw new IllegalArgumentException("File descriptors passed in Intent"); 11429 } 11430 11431 synchronized(this) { 11432 if (!(token instanceof ServiceRecord)) { 11433 throw new IllegalArgumentException("Invalid service token"); 11434 } 11435 ServiceRecord r = (ServiceRecord)token; 11436 11437 final long origId = Binder.clearCallingIdentity(); 11438 11439 if (DEBUG_SERVICE) Log.v(TAG, "PUBLISHING SERVICE " + r.name 11440 + " " + intent + ": " + service); 11441 if (r != null) { 11442 Intent.FilterComparison filter 11443 = new Intent.FilterComparison(intent); 11444 IntentBindRecord b = r.bindings.get(filter); 11445 if (b != null && !b.received) { 11446 b.binder = service; 11447 b.requested = true; 11448 b.received = true; 11449 if (r.connections.size() > 0) { 11450 Iterator<ConnectionRecord> it 11451 = r.connections.values().iterator(); 11452 while (it.hasNext()) { 11453 ConnectionRecord c = it.next(); 11454 if (!filter.equals(c.binding.intent.intent)) { 11455 if (DEBUG_SERVICE) Log.v( 11456 TAG, "Not publishing to: " + c); 11457 if (DEBUG_SERVICE) Log.v( 11458 TAG, "Bound intent: " + c.binding.intent.intent); 11459 if (DEBUG_SERVICE) Log.v( 11460 TAG, "Published intent: " + intent); 11461 continue; 11462 } 11463 if (DEBUG_SERVICE) Log.v(TAG, "Publishing to: " + c); 11464 try { 11465 c.conn.connected(r.name, service); 11466 } catch (Exception e) { 11467 Log.w(TAG, "Failure sending service " + r.name + 11468 " to connection " + c.conn.asBinder() + 11469 " (in " + c.binding.client.processName + ")", e); 11470 } 11471 } 11472 } 11473 } 11474 11475 serviceDoneExecutingLocked(r, mStoppingServices.contains(r)); 11476 11477 Binder.restoreCallingIdentity(origId); 11478 } 11479 } 11480 } 11481 11482 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 11483 // Refuse possible leaked file descriptors 11484 if (intent != null && intent.hasFileDescriptors() == true) { 11485 throw new IllegalArgumentException("File descriptors passed in Intent"); 11486 } 11487 11488 synchronized(this) { 11489 if (!(token instanceof ServiceRecord)) { 11490 throw new IllegalArgumentException("Invalid service token"); 11491 } 11492 ServiceRecord r = (ServiceRecord)token; 11493 11494 final long origId = Binder.clearCallingIdentity(); 11495 11496 if (r != null) { 11497 Intent.FilterComparison filter 11498 = new Intent.FilterComparison(intent); 11499 IntentBindRecord b = r.bindings.get(filter); 11500 if (DEBUG_SERVICE) Log.v(TAG, "unbindFinished in " + r 11501 + " at " + b + ": apps=" 11502 + (b != null ? b.apps.size() : 0)); 11503 if (b != null) { 11504 if (b.apps.size() > 0) { 11505 // Applications have already bound since the last 11506 // unbind, so just rebind right here. 11507 requestServiceBindingLocked(r, b, true); 11508 } else { 11509 // Note to tell the service the next time there is 11510 // a new client. 11511 b.doRebind = true; 11512 } 11513 } 11514 11515 serviceDoneExecutingLocked(r, mStoppingServices.contains(r)); 11516 11517 Binder.restoreCallingIdentity(origId); 11518 } 11519 } 11520 } 11521 11522 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 11523 synchronized(this) { 11524 if (!(token instanceof ServiceRecord)) { 11525 throw new IllegalArgumentException("Invalid service token"); 11526 } 11527 ServiceRecord r = (ServiceRecord)token; 11528 boolean inStopping = mStoppingServices.contains(token); 11529 if (r != null) { 11530 if (DEBUG_SERVICE) Log.v(TAG, "DONE EXECUTING SERVICE " + r.name 11531 + ": nesting=" + r.executeNesting 11532 + ", inStopping=" + inStopping); 11533 if (r != token) { 11534 Log.w(TAG, "Done executing service " + r.name 11535 + " with incorrect token: given " + token 11536 + ", expected " + r); 11537 return; 11538 } 11539 11540 if (type == 1) { 11541 // This is a call from a service start... take care of 11542 // book-keeping. 11543 r.callStart = true; 11544 switch (res) { 11545 case Service.START_STICKY_COMPATIBILITY: 11546 case Service.START_STICKY: { 11547 // We are done with the associated start arguments. 11548 r.findDeliveredStart(startId, true); 11549 // Don't stop if killed. 11550 r.stopIfKilled = false; 11551 break; 11552 } 11553 case Service.START_NOT_STICKY: { 11554 // We are done with the associated start arguments. 11555 r.findDeliveredStart(startId, true); 11556 if (r.lastStartId == startId) { 11557 // There is no more work, and this service 11558 // doesn't want to hang around if killed. 11559 r.stopIfKilled = true; 11560 } 11561 break; 11562 } 11563 case Service.START_REDELIVER_INTENT: { 11564 // We'll keep this item until they explicitly 11565 // call stop for it, but keep track of the fact 11566 // that it was delivered. 11567 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 11568 if (si != null) { 11569 si.deliveryCount = 0; 11570 si.doneExecutingCount++; 11571 // Don't stop if killed. 11572 r.stopIfKilled = true; 11573 } 11574 break; 11575 } 11576 default: 11577 throw new IllegalArgumentException( 11578 "Unknown service start result: " + res); 11579 } 11580 if (res == Service.START_STICKY_COMPATIBILITY) { 11581 r.callStart = false; 11582 } 11583 } 11584 11585 final long origId = Binder.clearCallingIdentity(); 11586 serviceDoneExecutingLocked(r, inStopping); 11587 Binder.restoreCallingIdentity(origId); 11588 } else { 11589 Log.w(TAG, "Done executing unknown service " + r.name 11590 + " with token " + token); 11591 } 11592 } 11593 } 11594 11595 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) { 11596 r.executeNesting--; 11597 if (r.executeNesting <= 0 && r.app != null) { 11598 r.app.executingServices.remove(r); 11599 if (r.app.executingServices.size() == 0) { 11600 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app); 11601 } 11602 if (inStopping) { 11603 mStoppingServices.remove(r); 11604 } 11605 updateOomAdjLocked(r.app); 11606 } 11607 } 11608 11609 void serviceTimeout(ProcessRecord proc) { 11610 synchronized(this) { 11611 if (proc.executingServices.size() == 0 || proc.thread == null) { 11612 return; 11613 } 11614 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT; 11615 Iterator<ServiceRecord> it = proc.executingServices.iterator(); 11616 ServiceRecord timeout = null; 11617 long nextTime = 0; 11618 while (it.hasNext()) { 11619 ServiceRecord sr = it.next(); 11620 if (sr.executingStart < maxTime) { 11621 timeout = sr; 11622 break; 11623 } 11624 if (sr.executingStart > nextTime) { 11625 nextTime = sr.executingStart; 11626 } 11627 } 11628 if (timeout != null && mLruProcesses.contains(proc)) { 11629 Log.w(TAG, "Timeout executing service: " + timeout); 11630 appNotRespondingLocked(proc, null, null, "Executing service " + timeout.shortName); 11631 } else { 11632 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 11633 msg.obj = proc; 11634 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT); 11635 } 11636 } 11637 } 11638 11639 // ========================================================= 11640 // BACKUP AND RESTORE 11641 // ========================================================= 11642 11643 // Cause the target app to be launched if necessary and its backup agent 11644 // instantiated. The backup agent will invoke backupAgentCreated() on the 11645 // activity manager to announce its creation. 11646 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 11647 if (DEBUG_BACKUP) Log.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 11648 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 11649 11650 synchronized(this) { 11651 // !!! TODO: currently no check here that we're already bound 11652 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 11653 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 11654 synchronized (stats) { 11655 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 11656 } 11657 11658 BackupRecord r = new BackupRecord(ss, app, backupMode); 11659 ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName); 11660 // startProcessLocked() returns existing proc's record if it's already running 11661 ProcessRecord proc = startProcessLocked(app.processName, app, 11662 false, 0, "backup", hostingName, false); 11663 if (proc == null) { 11664 Log.e(TAG, "Unable to start backup agent process " + r); 11665 return false; 11666 } 11667 11668 r.app = proc; 11669 mBackupTarget = r; 11670 mBackupAppName = app.packageName; 11671 11672 // Try not to kill the process during backup 11673 updateOomAdjLocked(proc); 11674 11675 // If the process is already attached, schedule the creation of the backup agent now. 11676 // If it is not yet live, this will be done when it attaches to the framework. 11677 if (proc.thread != null) { 11678 if (DEBUG_BACKUP) Log.v(TAG, "Agent proc already running: " + proc); 11679 try { 11680 proc.thread.scheduleCreateBackupAgent(app, backupMode); 11681 } catch (RemoteException e) { 11682 // Will time out on the backup manager side 11683 } 11684 } else { 11685 if (DEBUG_BACKUP) Log.v(TAG, "Agent proc not running, waiting for attach"); 11686 } 11687 // Invariants: at this point, the target app process exists and the application 11688 // is either already running or in the process of coming up. mBackupTarget and 11689 // mBackupAppName describe the app, so that when it binds back to the AM we 11690 // know that it's scheduled for a backup-agent operation. 11691 } 11692 11693 return true; 11694 } 11695 11696 // A backup agent has just come up 11697 public void backupAgentCreated(String agentPackageName, IBinder agent) { 11698 if (DEBUG_BACKUP) Log.v(TAG, "backupAgentCreated: " + agentPackageName 11699 + " = " + agent); 11700 11701 synchronized(this) { 11702 if (!agentPackageName.equals(mBackupAppName)) { 11703 Log.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 11704 return; 11705 } 11706 11707 long oldIdent = Binder.clearCallingIdentity(); 11708 try { 11709 IBackupManager bm = IBackupManager.Stub.asInterface( 11710 ServiceManager.getService(Context.BACKUP_SERVICE)); 11711 bm.agentConnected(agentPackageName, agent); 11712 } catch (RemoteException e) { 11713 // can't happen; the backup manager service is local 11714 } catch (Exception e) { 11715 Log.w(TAG, "Exception trying to deliver BackupAgent binding: "); 11716 e.printStackTrace(); 11717 } finally { 11718 Binder.restoreCallingIdentity(oldIdent); 11719 } 11720 } 11721 } 11722 11723 // done with this agent 11724 public void unbindBackupAgent(ApplicationInfo appInfo) { 11725 if (DEBUG_BACKUP) Log.v(TAG, "unbindBackupAgent: " + appInfo); 11726 if (appInfo == null) { 11727 Log.w(TAG, "unbind backup agent for null app"); 11728 return; 11729 } 11730 11731 synchronized(this) { 11732 if (mBackupAppName == null) { 11733 Log.w(TAG, "Unbinding backup agent with no active backup"); 11734 return; 11735 } 11736 11737 if (!mBackupAppName.equals(appInfo.packageName)) { 11738 Log.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 11739 return; 11740 } 11741 11742 ProcessRecord proc = mBackupTarget.app; 11743 mBackupTarget = null; 11744 mBackupAppName = null; 11745 11746 // Not backing this app up any more; reset its OOM adjustment 11747 updateOomAdjLocked(proc); 11748 11749 // If the app crashed during backup, 'thread' will be null here 11750 if (proc.thread != null) { 11751 try { 11752 proc.thread.scheduleDestroyBackupAgent(appInfo); 11753 } catch (Exception e) { 11754 Log.e(TAG, "Exception when unbinding backup agent:"); 11755 e.printStackTrace(); 11756 } 11757 } 11758 } 11759 } 11760 // ========================================================= 11761 // BROADCASTS 11762 // ========================================================= 11763 11764 private final List getStickies(String action, IntentFilter filter, 11765 List cur) { 11766 final ContentResolver resolver = mContext.getContentResolver(); 11767 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 11768 if (list == null) { 11769 return cur; 11770 } 11771 int N = list.size(); 11772 for (int i=0; i<N; i++) { 11773 Intent intent = list.get(i); 11774 if (filter.match(resolver, intent, true, TAG) >= 0) { 11775 if (cur == null) { 11776 cur = new ArrayList<Intent>(); 11777 } 11778 cur.add(intent); 11779 } 11780 } 11781 return cur; 11782 } 11783 11784 private final void scheduleBroadcastsLocked() { 11785 if (DEBUG_BROADCAST) Log.v(TAG, "Schedule broadcasts: current=" 11786 + mBroadcastsScheduled); 11787 11788 if (mBroadcastsScheduled) { 11789 return; 11790 } 11791 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG); 11792 mBroadcastsScheduled = true; 11793 } 11794 11795 public Intent registerReceiver(IApplicationThread caller, 11796 IIntentReceiver receiver, IntentFilter filter, String permission) { 11797 synchronized(this) { 11798 ProcessRecord callerApp = null; 11799 if (caller != null) { 11800 callerApp = getRecordForAppLocked(caller); 11801 if (callerApp == null) { 11802 throw new SecurityException( 11803 "Unable to find app for caller " + caller 11804 + " (pid=" + Binder.getCallingPid() 11805 + ") when registering receiver " + receiver); 11806 } 11807 } 11808 11809 List allSticky = null; 11810 11811 // Look for any matching sticky broadcasts... 11812 Iterator actions = filter.actionsIterator(); 11813 if (actions != null) { 11814 while (actions.hasNext()) { 11815 String action = (String)actions.next(); 11816 allSticky = getStickies(action, filter, allSticky); 11817 } 11818 } else { 11819 allSticky = getStickies(null, filter, allSticky); 11820 } 11821 11822 // The first sticky in the list is returned directly back to 11823 // the client. 11824 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11825 11826 if (DEBUG_BROADCAST) Log.v(TAG, "Register receiver " + filter 11827 + ": " + sticky); 11828 11829 if (receiver == null) { 11830 return sticky; 11831 } 11832 11833 ReceiverList rl 11834 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11835 if (rl == null) { 11836 rl = new ReceiverList(this, callerApp, 11837 Binder.getCallingPid(), 11838 Binder.getCallingUid(), receiver); 11839 if (rl.app != null) { 11840 rl.app.receivers.add(rl); 11841 } else { 11842 try { 11843 receiver.asBinder().linkToDeath(rl, 0); 11844 } catch (RemoteException e) { 11845 return sticky; 11846 } 11847 rl.linkedToDeath = true; 11848 } 11849 mRegisteredReceivers.put(receiver.asBinder(), rl); 11850 } 11851 BroadcastFilter bf = new BroadcastFilter(filter, rl, permission); 11852 rl.add(bf); 11853 if (!bf.debugCheck()) { 11854 Log.w(TAG, "==> For Dynamic broadast"); 11855 } 11856 mReceiverResolver.addFilter(bf); 11857 11858 // Enqueue broadcasts for all existing stickies that match 11859 // this filter. 11860 if (allSticky != null) { 11861 ArrayList receivers = new ArrayList(); 11862 receivers.add(bf); 11863 11864 int N = allSticky.size(); 11865 for (int i=0; i<N; i++) { 11866 Intent intent = (Intent)allSticky.get(i); 11867 BroadcastRecord r = new BroadcastRecord(intent, null, 11868 null, -1, -1, null, receivers, null, 0, null, null, 11869 false, true, true); 11870 if (mParallelBroadcasts.size() == 0) { 11871 scheduleBroadcastsLocked(); 11872 } 11873 mParallelBroadcasts.add(r); 11874 } 11875 } 11876 11877 return sticky; 11878 } 11879 } 11880 11881 public void unregisterReceiver(IIntentReceiver receiver) { 11882 if (DEBUG_BROADCAST) Log.v(TAG, "Unregister receiver: " + receiver); 11883 11884 boolean doNext = false; 11885 11886 synchronized(this) { 11887 ReceiverList rl 11888 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11889 if (rl != null) { 11890 if (rl.curBroadcast != null) { 11891 BroadcastRecord r = rl.curBroadcast; 11892 doNext = finishReceiverLocked( 11893 receiver.asBinder(), r.resultCode, r.resultData, 11894 r.resultExtras, r.resultAbort, true); 11895 } 11896 11897 if (rl.app != null) { 11898 rl.app.receivers.remove(rl); 11899 } 11900 removeReceiverLocked(rl); 11901 if (rl.linkedToDeath) { 11902 rl.linkedToDeath = false; 11903 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11904 } 11905 } 11906 } 11907 11908 if (!doNext) { 11909 return; 11910 } 11911 11912 final long origId = Binder.clearCallingIdentity(); 11913 processNextBroadcast(false); 11914 trimApplications(); 11915 Binder.restoreCallingIdentity(origId); 11916 } 11917 11918 void removeReceiverLocked(ReceiverList rl) { 11919 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11920 int N = rl.size(); 11921 for (int i=0; i<N; i++) { 11922 mReceiverResolver.removeFilter(rl.get(i)); 11923 } 11924 } 11925 11926 private final int broadcastIntentLocked(ProcessRecord callerApp, 11927 String callerPackage, Intent intent, String resolvedType, 11928 IIntentReceiver resultTo, int resultCode, String resultData, 11929 Bundle map, String requiredPermission, 11930 boolean ordered, boolean sticky, int callingPid, int callingUid) { 11931 intent = new Intent(intent); 11932 11933 if (DEBUG_BROADCAST_LIGHT) Log.v( 11934 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11935 + " ordered=" + ordered); 11936 if ((resultTo != null) && !ordered) { 11937 Log.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11938 } 11939 11940 // Handle special intents: if this broadcast is from the package 11941 // manager about a package being removed, we need to remove all of 11942 // its activities from the history stack. 11943 final boolean uidRemoved = intent.ACTION_UID_REMOVED.equals( 11944 intent.getAction()); 11945 if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11946 || intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11947 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 11948 || uidRemoved) { 11949 if (checkComponentPermission( 11950 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11951 callingPid, callingUid, -1) 11952 == PackageManager.PERMISSION_GRANTED) { 11953 if (uidRemoved) { 11954 final Bundle intentExtras = intent.getExtras(); 11955 final int uid = intentExtras != null 11956 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11957 if (uid >= 0) { 11958 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11959 synchronized (bs) { 11960 bs.removeUidStatsLocked(uid); 11961 } 11962 } 11963 } else { 11964 // If resources are unvailble just force stop all 11965 // those packages and flush the attribute cache as well. 11966 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 11967 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 11968 if (list != null && (list.length > 0)) { 11969 for (String pkg : list) { 11970 forceStopPackageLocked(pkg, -1, false, true); 11971 } 11972 } 11973 } else { 11974 Uri data = intent.getData(); 11975 String ssp; 11976 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11977 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11978 forceStopPackageLocked(ssp, 11979 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true); 11980 } 11981 } 11982 } 11983 } 11984 } else { 11985 String msg = "Permission Denial: " + intent.getAction() 11986 + " broadcast from " + callerPackage + " (pid=" + callingPid 11987 + ", uid=" + callingUid + ")" 11988 + " requires " 11989 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11990 Log.w(TAG, msg); 11991 throw new SecurityException(msg); 11992 } 11993 } 11994 11995 /* 11996 * If this is the time zone changed action, queue up a message that will reset the timezone 11997 * of all currently running processes. This message will get queued up before the broadcast 11998 * happens. 11999 */ 12000 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 12001 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 12002 } 12003 12004 /* 12005 * Prevent non-system code (defined here to be non-persistent 12006 * processes) from sending protected broadcasts. 12007 */ 12008 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 12009 || callingUid == Process.SHELL_UID || callingUid == 0) { 12010 // Always okay. 12011 } else if (callerApp == null || !callerApp.persistent) { 12012 try { 12013 if (ActivityThread.getPackageManager().isProtectedBroadcast( 12014 intent.getAction())) { 12015 String msg = "Permission Denial: not allowed to send broadcast " 12016 + intent.getAction() + " from pid=" 12017 + callingPid + ", uid=" + callingUid; 12018 Log.w(TAG, msg); 12019 throw new SecurityException(msg); 12020 } 12021 } catch (RemoteException e) { 12022 Log.w(TAG, "Remote exception", e); 12023 return BROADCAST_SUCCESS; 12024 } 12025 } 12026 12027 // Add to the sticky list if requested. 12028 if (sticky) { 12029 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 12030 callingPid, callingUid) 12031 != PackageManager.PERMISSION_GRANTED) { 12032 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 12033 + callingPid + ", uid=" + callingUid 12034 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 12035 Log.w(TAG, msg); 12036 throw new SecurityException(msg); 12037 } 12038 if (requiredPermission != null) { 12039 Log.w(TAG, "Can't broadcast sticky intent " + intent 12040 + " and enforce permission " + requiredPermission); 12041 return BROADCAST_STICKY_CANT_HAVE_PERMISSION; 12042 } 12043 if (intent.getComponent() != null) { 12044 throw new SecurityException( 12045 "Sticky broadcasts can't target a specific component"); 12046 } 12047 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 12048 if (list == null) { 12049 list = new ArrayList<Intent>(); 12050 mStickyBroadcasts.put(intent.getAction(), list); 12051 } 12052 int N = list.size(); 12053 int i; 12054 for (i=0; i<N; i++) { 12055 if (intent.filterEquals(list.get(i))) { 12056 // This sticky already exists, replace it. 12057 list.set(i, new Intent(intent)); 12058 break; 12059 } 12060 } 12061 if (i >= N) { 12062 list.add(new Intent(intent)); 12063 } 12064 } 12065 12066 // Figure out who all will receive this broadcast. 12067 List receivers = null; 12068 List<BroadcastFilter> registeredReceivers = null; 12069 try { 12070 if (intent.getComponent() != null) { 12071 // Broadcast is going to one specific receiver class... 12072 ActivityInfo ai = ActivityThread.getPackageManager(). 12073 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS); 12074 if (ai != null) { 12075 receivers = new ArrayList(); 12076 ResolveInfo ri = new ResolveInfo(); 12077 ri.activityInfo = ai; 12078 receivers.add(ri); 12079 } 12080 } else { 12081 // Need to resolve the intent to interested receivers... 12082 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 12083 == 0) { 12084 receivers = 12085 ActivityThread.getPackageManager().queryIntentReceivers( 12086 intent, resolvedType, STOCK_PM_FLAGS); 12087 } 12088 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false); 12089 } 12090 } catch (RemoteException ex) { 12091 // pm is in same process, this will never happen. 12092 } 12093 12094 final boolean replacePending = 12095 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 12096 12097 if (DEBUG_BROADCAST) Log.v(TAG, "Enqueing broadcast: " + intent.getAction() 12098 + " replacePending=" + replacePending); 12099 12100 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 12101 if (!ordered && NR > 0) { 12102 // If we are not serializing this broadcast, then send the 12103 // registered receivers separately so they don't wait for the 12104 // components to be launched. 12105 BroadcastRecord r = new BroadcastRecord(intent, callerApp, 12106 callerPackage, callingPid, callingUid, requiredPermission, 12107 registeredReceivers, resultTo, resultCode, resultData, map, 12108 ordered, sticky, false); 12109 if (DEBUG_BROADCAST) Log.v( 12110 TAG, "Enqueueing parallel broadcast " + r 12111 + ": prev had " + mParallelBroadcasts.size()); 12112 boolean replaced = false; 12113 if (replacePending) { 12114 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) { 12115 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) { 12116 if (DEBUG_BROADCAST) Log.v(TAG, 12117 "***** DROPPING PARALLEL: " + intent); 12118 mParallelBroadcasts.set(i, r); 12119 replaced = true; 12120 break; 12121 } 12122 } 12123 } 12124 if (!replaced) { 12125 mParallelBroadcasts.add(r); 12126 scheduleBroadcastsLocked(); 12127 } 12128 registeredReceivers = null; 12129 NR = 0; 12130 } 12131 12132 // Merge into one list. 12133 int ir = 0; 12134 if (receivers != null) { 12135 // A special case for PACKAGE_ADDED: do not allow the package 12136 // being added to see this broadcast. This prevents them from 12137 // using this as a back door to get run as soon as they are 12138 // installed. Maybe in the future we want to have a special install 12139 // broadcast or such for apps, but we'd like to deliberately make 12140 // this decision. 12141 String skipPackages[] = null; 12142 if (intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 12143 || intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 12144 || intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 12145 Uri data = intent.getData(); 12146 if (data != null) { 12147 String pkgName = data.getSchemeSpecificPart(); 12148 if (pkgName != null) { 12149 skipPackages = new String[] { pkgName }; 12150 } 12151 } 12152 } else if (intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 12153 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 12154 } 12155 if (skipPackages != null && (skipPackages.length > 0)) { 12156 for (String skipPackage : skipPackages) { 12157 if (skipPackage != null) { 12158 int NT = receivers.size(); 12159 for (int it=0; it<NT; it++) { 12160 ResolveInfo curt = (ResolveInfo)receivers.get(it); 12161 if (curt.activityInfo.packageName.equals(skipPackage)) { 12162 receivers.remove(it); 12163 it--; 12164 NT--; 12165 } 12166 } 12167 } 12168 } 12169 } 12170 12171 int NT = receivers != null ? receivers.size() : 0; 12172 int it = 0; 12173 ResolveInfo curt = null; 12174 BroadcastFilter curr = null; 12175 while (it < NT && ir < NR) { 12176 if (curt == null) { 12177 curt = (ResolveInfo)receivers.get(it); 12178 } 12179 if (curr == null) { 12180 curr = registeredReceivers.get(ir); 12181 } 12182 if (curr.getPriority() >= curt.priority) { 12183 // Insert this broadcast record into the final list. 12184 receivers.add(it, curr); 12185 ir++; 12186 curr = null; 12187 it++; 12188 NT++; 12189 } else { 12190 // Skip to the next ResolveInfo in the final list. 12191 it++; 12192 curt = null; 12193 } 12194 } 12195 } 12196 while (ir < NR) { 12197 if (receivers == null) { 12198 receivers = new ArrayList(); 12199 } 12200 receivers.add(registeredReceivers.get(ir)); 12201 ir++; 12202 } 12203 12204 if ((receivers != null && receivers.size() > 0) 12205 || resultTo != null) { 12206 BroadcastRecord r = new BroadcastRecord(intent, callerApp, 12207 callerPackage, callingPid, callingUid, requiredPermission, 12208 receivers, resultTo, resultCode, resultData, map, ordered, 12209 sticky, false); 12210 if (DEBUG_BROADCAST) Log.v( 12211 TAG, "Enqueueing ordered broadcast " + r 12212 + ": prev had " + mOrderedBroadcasts.size()); 12213 if (DEBUG_BROADCAST) { 12214 int seq = r.intent.getIntExtra("seq", -1); 12215 Log.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 12216 } 12217 boolean replaced = false; 12218 if (replacePending) { 12219 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) { 12220 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) { 12221 if (DEBUG_BROADCAST) Log.v(TAG, 12222 "***** DROPPING ORDERED: " + intent); 12223 mOrderedBroadcasts.set(i, r); 12224 replaced = true; 12225 break; 12226 } 12227 } 12228 } 12229 if (!replaced) { 12230 mOrderedBroadcasts.add(r); 12231 scheduleBroadcastsLocked(); 12232 } 12233 } 12234 12235 return BROADCAST_SUCCESS; 12236 } 12237 12238 public final int broadcastIntent(IApplicationThread caller, 12239 Intent intent, String resolvedType, IIntentReceiver resultTo, 12240 int resultCode, String resultData, Bundle map, 12241 String requiredPermission, boolean serialized, boolean sticky) { 12242 // Refuse possible leaked file descriptors 12243 if (intent != null && intent.hasFileDescriptors() == true) { 12244 throw new IllegalArgumentException("File descriptors passed in Intent"); 12245 } 12246 12247 synchronized(this) { 12248 int flags = intent.getFlags(); 12249 12250 if (!mSystemReady) { 12251 // if the caller really truly claims to know what they're doing, go 12252 // ahead and allow the broadcast without launching any receivers 12253 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 12254 intent = new Intent(intent); 12255 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 12256 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0){ 12257 Log.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 12258 + " before boot completion"); 12259 throw new IllegalStateException("Cannot broadcast before boot completed"); 12260 } 12261 } 12262 12263 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 12264 throw new IllegalArgumentException( 12265 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 12266 } 12267 12268 final ProcessRecord callerApp = getRecordForAppLocked(caller); 12269 final int callingPid = Binder.getCallingPid(); 12270 final int callingUid = Binder.getCallingUid(); 12271 final long origId = Binder.clearCallingIdentity(); 12272 int res = broadcastIntentLocked(callerApp, 12273 callerApp != null ? callerApp.info.packageName : null, 12274 intent, resolvedType, resultTo, 12275 resultCode, resultData, map, requiredPermission, serialized, 12276 sticky, callingPid, callingUid); 12277 Binder.restoreCallingIdentity(origId); 12278 return res; 12279 } 12280 } 12281 12282 int broadcastIntentInPackage(String packageName, int uid, 12283 Intent intent, String resolvedType, IIntentReceiver resultTo, 12284 int resultCode, String resultData, Bundle map, 12285 String requiredPermission, boolean serialized, boolean sticky) { 12286 synchronized(this) { 12287 final long origId = Binder.clearCallingIdentity(); 12288 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 12289 resultTo, resultCode, resultData, map, requiredPermission, 12290 serialized, sticky, -1, uid); 12291 Binder.restoreCallingIdentity(origId); 12292 return res; 12293 } 12294 } 12295 12296 public final void unbroadcastIntent(IApplicationThread caller, 12297 Intent intent) { 12298 // Refuse possible leaked file descriptors 12299 if (intent != null && intent.hasFileDescriptors() == true) { 12300 throw new IllegalArgumentException("File descriptors passed in Intent"); 12301 } 12302 12303 synchronized(this) { 12304 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 12305 != PackageManager.PERMISSION_GRANTED) { 12306 String msg = "Permission Denial: unbroadcastIntent() from pid=" 12307 + Binder.getCallingPid() 12308 + ", uid=" + Binder.getCallingUid() 12309 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 12310 Log.w(TAG, msg); 12311 throw new SecurityException(msg); 12312 } 12313 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 12314 if (list != null) { 12315 int N = list.size(); 12316 int i; 12317 for (i=0; i<N; i++) { 12318 if (intent.filterEquals(list.get(i))) { 12319 list.remove(i); 12320 break; 12321 } 12322 } 12323 } 12324 } 12325 } 12326 12327 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 12328 String resultData, Bundle resultExtras, boolean resultAbort, 12329 boolean explicit) { 12330 if (mOrderedBroadcasts.size() == 0) { 12331 if (explicit) { 12332 Log.w(TAG, "finishReceiver called but no pending broadcasts"); 12333 } 12334 return false; 12335 } 12336 BroadcastRecord r = mOrderedBroadcasts.get(0); 12337 if (r.receiver == null) { 12338 if (explicit) { 12339 Log.w(TAG, "finishReceiver called but none active"); 12340 } 12341 return false; 12342 } 12343 if (r.receiver != receiver) { 12344 Log.w(TAG, "finishReceiver called but active receiver is different"); 12345 return false; 12346 } 12347 int state = r.state; 12348 r.state = r.IDLE; 12349 if (state == r.IDLE) { 12350 if (explicit) { 12351 Log.w(TAG, "finishReceiver called but state is IDLE"); 12352 } 12353 } 12354 r.receiver = null; 12355 r.intent.setComponent(null); 12356 if (r.curApp != null) { 12357 r.curApp.curReceiver = null; 12358 } 12359 if (r.curFilter != null) { 12360 r.curFilter.receiverList.curBroadcast = null; 12361 } 12362 r.curFilter = null; 12363 r.curApp = null; 12364 r.curComponent = null; 12365 r.curReceiver = null; 12366 mPendingBroadcast = null; 12367 12368 r.resultCode = resultCode; 12369 r.resultData = resultData; 12370 r.resultExtras = resultExtras; 12371 r.resultAbort = resultAbort; 12372 12373 // We will process the next receiver right now if this is finishing 12374 // an app receiver (which is always asynchronous) or after we have 12375 // come back from calling a receiver. 12376 return state == BroadcastRecord.APP_RECEIVE 12377 || state == BroadcastRecord.CALL_DONE_RECEIVE; 12378 } 12379 12380 public void finishReceiver(IBinder who, int resultCode, String resultData, 12381 Bundle resultExtras, boolean resultAbort) { 12382 if (DEBUG_BROADCAST) Log.v(TAG, "Finish receiver: " + who); 12383 12384 // Refuse possible leaked file descriptors 12385 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 12386 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12387 } 12388 12389 boolean doNext; 12390 12391 final long origId = Binder.clearCallingIdentity(); 12392 12393 synchronized(this) { 12394 doNext = finishReceiverLocked( 12395 who, resultCode, resultData, resultExtras, resultAbort, true); 12396 } 12397 12398 if (doNext) { 12399 processNextBroadcast(false); 12400 } 12401 trimApplications(); 12402 12403 Binder.restoreCallingIdentity(origId); 12404 } 12405 12406 private final void logBroadcastReceiverDiscard(BroadcastRecord r) { 12407 if (r.nextReceiver > 0) { 12408 Object curReceiver = r.receivers.get(r.nextReceiver-1); 12409 if (curReceiver instanceof BroadcastFilter) { 12410 BroadcastFilter bf = (BroadcastFilter) curReceiver; 12411 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER, 12412 System.identityHashCode(r), 12413 r.intent.getAction(), 12414 r.nextReceiver - 1, 12415 System.identityHashCode(bf)); 12416 } else { 12417 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP, 12418 System.identityHashCode(r), 12419 r.intent.getAction(), 12420 r.nextReceiver - 1, 12421 ((ResolveInfo)curReceiver).toString()); 12422 } 12423 } else { 12424 Log.w(TAG, "Discarding broadcast before first receiver is invoked: " 12425 + r); 12426 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP, 12427 System.identityHashCode(r), 12428 r.intent.getAction(), 12429 r.nextReceiver, 12430 "NONE"); 12431 } 12432 } 12433 12434 private final void broadcastTimeout() { 12435 synchronized (this) { 12436 if (mOrderedBroadcasts.size() == 0) { 12437 return; 12438 } 12439 long now = SystemClock.uptimeMillis(); 12440 BroadcastRecord r = mOrderedBroadcasts.get(0); 12441 if ((r.receiverTime+BROADCAST_TIMEOUT) > now) { 12442 if (DEBUG_BROADCAST) Log.v(TAG, 12443 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for " 12444 + (r.receiverTime + BROADCAST_TIMEOUT)); 12445 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG); 12446 mHandler.sendMessageAtTime(msg, r.receiverTime+BROADCAST_TIMEOUT); 12447 return; 12448 } 12449 12450 Log.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver); 12451 r.receiverTime = now; 12452 r.anrCount++; 12453 12454 // Current receiver has passed its expiration date. 12455 if (r.nextReceiver <= 0) { 12456 Log.w(TAG, "Timeout on receiver with nextReceiver <= 0"); 12457 return; 12458 } 12459 12460 ProcessRecord app = null; 12461 12462 Object curReceiver = r.receivers.get(r.nextReceiver-1); 12463 Log.w(TAG, "Receiver during timeout: " + curReceiver); 12464 logBroadcastReceiverDiscard(r); 12465 if (curReceiver instanceof BroadcastFilter) { 12466 BroadcastFilter bf = (BroadcastFilter)curReceiver; 12467 if (bf.receiverList.pid != 0 12468 && bf.receiverList.pid != MY_PID) { 12469 synchronized (this.mPidsSelfLocked) { 12470 app = this.mPidsSelfLocked.get( 12471 bf.receiverList.pid); 12472 } 12473 } 12474 } else { 12475 app = r.curApp; 12476 } 12477 12478 if (app != null) { 12479 appNotRespondingLocked(app, null, null, "Broadcast of " + r.intent.toString()); 12480 } 12481 12482 if (mPendingBroadcast == r) { 12483 mPendingBroadcast = null; 12484 } 12485 12486 // Move on to the next receiver. 12487 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 12488 r.resultExtras, r.resultAbort, true); 12489 scheduleBroadcastsLocked(); 12490 } 12491 } 12492 12493 private final void processCurBroadcastLocked(BroadcastRecord r, 12494 ProcessRecord app) throws RemoteException { 12495 if (app.thread == null) { 12496 throw new RemoteException(); 12497 } 12498 r.receiver = app.thread.asBinder(); 12499 r.curApp = app; 12500 app.curReceiver = r; 12501 updateLruProcessLocked(app, true, true); 12502 12503 // Tell the application to launch this receiver. 12504 r.intent.setComponent(r.curComponent); 12505 12506 boolean started = false; 12507 try { 12508 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, 12509 "Delivering to component " + r.curComponent 12510 + ": " + r); 12511 ensurePackageDexOpt(r.intent.getComponent().getPackageName()); 12512 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver, 12513 r.resultCode, r.resultData, r.resultExtras, r.ordered); 12514 started = true; 12515 } finally { 12516 if (!started) { 12517 r.receiver = null; 12518 r.curApp = null; 12519 app.curReceiver = null; 12520 } 12521 } 12522 12523 } 12524 12525 static void performReceive(ProcessRecord app, IIntentReceiver receiver, 12526 Intent intent, int resultCode, String data, Bundle extras, 12527 boolean ordered, boolean sticky) throws RemoteException { 12528 if (app != null && app.thread != null) { 12529 // If we have an app thread, do the call through that so it is 12530 // correctly ordered with other one-way calls. 12531 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode, 12532 data, extras, ordered, sticky); 12533 } else { 12534 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky); 12535 } 12536 } 12537 12538 private final void deliverToRegisteredReceiver(BroadcastRecord r, 12539 BroadcastFilter filter, boolean ordered) { 12540 boolean skip = false; 12541 if (filter.requiredPermission != null) { 12542 int perm = checkComponentPermission(filter.requiredPermission, 12543 r.callingPid, r.callingUid, -1); 12544 if (perm != PackageManager.PERMISSION_GRANTED) { 12545 Log.w(TAG, "Permission Denial: broadcasting " 12546 + r.intent.toString() 12547 + " from " + r.callerPackage + " (pid=" 12548 + r.callingPid + ", uid=" + r.callingUid + ")" 12549 + " requires " + filter.requiredPermission 12550 + " due to registered receiver " + filter); 12551 skip = true; 12552 } 12553 } 12554 if (r.requiredPermission != null) { 12555 int perm = checkComponentPermission(r.requiredPermission, 12556 filter.receiverList.pid, filter.receiverList.uid, -1); 12557 if (perm != PackageManager.PERMISSION_GRANTED) { 12558 Log.w(TAG, "Permission Denial: receiving " 12559 + r.intent.toString() 12560 + " to " + filter.receiverList.app 12561 + " (pid=" + filter.receiverList.pid 12562 + ", uid=" + filter.receiverList.uid + ")" 12563 + " requires " + r.requiredPermission 12564 + " due to sender " + r.callerPackage 12565 + " (uid " + r.callingUid + ")"); 12566 skip = true; 12567 } 12568 } 12569 12570 if (!skip) { 12571 // If this is not being sent as an ordered broadcast, then we 12572 // don't want to touch the fields that keep track of the current 12573 // state of ordered broadcasts. 12574 if (ordered) { 12575 r.receiver = filter.receiverList.receiver.asBinder(); 12576 r.curFilter = filter; 12577 filter.receiverList.curBroadcast = r; 12578 r.state = BroadcastRecord.CALL_IN_RECEIVE; 12579 if (filter.receiverList.app != null) { 12580 // Bump hosting application to no longer be in background 12581 // scheduling class. Note that we can't do that if there 12582 // isn't an app... but we can only be in that case for 12583 // things that directly call the IActivityManager API, which 12584 // are already core system stuff so don't matter for this. 12585 r.curApp = filter.receiverList.app; 12586 filter.receiverList.app.curReceiver = r; 12587 updateOomAdjLocked(); 12588 } 12589 } 12590 try { 12591 if (DEBUG_BROADCAST_LIGHT) { 12592 int seq = r.intent.getIntExtra("seq", -1); 12593 Log.i(TAG, "Delivering to " + filter.receiverList.app 12594 + " (seq=" + seq + "): " + r); 12595 } 12596 performReceive(filter.receiverList.app, filter.receiverList.receiver, 12597 new Intent(r.intent), r.resultCode, 12598 r.resultData, r.resultExtras, r.ordered, r.initialSticky); 12599 if (ordered) { 12600 r.state = BroadcastRecord.CALL_DONE_RECEIVE; 12601 } 12602 } catch (RemoteException e) { 12603 Log.w(TAG, "Failure sending broadcast " + r.intent, e); 12604 if (ordered) { 12605 r.receiver = null; 12606 r.curFilter = null; 12607 filter.receiverList.curBroadcast = null; 12608 if (filter.receiverList.app != null) { 12609 filter.receiverList.app.curReceiver = null; 12610 } 12611 } 12612 } 12613 } 12614 } 12615 12616 private final void addBroadcastToHistoryLocked(BroadcastRecord r) { 12617 if (r.callingUid < 0) { 12618 // This was from a registerReceiver() call; ignore it. 12619 return; 12620 } 12621 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1, 12622 MAX_BROADCAST_HISTORY-1); 12623 r.finishTime = SystemClock.uptimeMillis(); 12624 mBroadcastHistory[0] = r; 12625 } 12626 12627 private final void processNextBroadcast(boolean fromMsg) { 12628 synchronized(this) { 12629 BroadcastRecord r; 12630 12631 if (DEBUG_BROADCAST) Log.v(TAG, "processNextBroadcast: " 12632 + mParallelBroadcasts.size() + " broadcasts, " 12633 + mOrderedBroadcasts.size() + " serialized broadcasts"); 12634 12635 updateCpuStats(); 12636 12637 if (fromMsg) { 12638 mBroadcastsScheduled = false; 12639 } 12640 12641 // First, deliver any non-serialized broadcasts right away. 12642 while (mParallelBroadcasts.size() > 0) { 12643 r = mParallelBroadcasts.remove(0); 12644 r.dispatchTime = SystemClock.uptimeMillis(); 12645 final int N = r.receivers.size(); 12646 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Processing parallel broadcast " 12647 + r); 12648 for (int i=0; i<N; i++) { 12649 Object target = r.receivers.get(i); 12650 if (DEBUG_BROADCAST) Log.v(TAG, 12651 "Delivering non-serialized to registered " 12652 + target + ": " + r); 12653 deliverToRegisteredReceiver(r, (BroadcastFilter)target, false); 12654 } 12655 addBroadcastToHistoryLocked(r); 12656 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Done with parallel broadcast " 12657 + r); 12658 } 12659 12660 // Now take care of the next serialized one... 12661 12662 // If we are waiting for a process to come up to handle the next 12663 // broadcast, then do nothing at this point. Just in case, we 12664 // check that the process we're waiting for still exists. 12665 if (mPendingBroadcast != null) { 12666 if (DEBUG_BROADCAST_LIGHT) { 12667 Log.v(TAG, "processNextBroadcast: waiting for " 12668 + mPendingBroadcast.curApp); 12669 } 12670 12671 boolean isDead; 12672 synchronized (mPidsSelfLocked) { 12673 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null); 12674 } 12675 if (!isDead) { 12676 // It's still alive, so keep waiting 12677 return; 12678 } else { 12679 Log.w(TAG, "pending app " + mPendingBroadcast.curApp 12680 + " died before responding to broadcast"); 12681 mPendingBroadcast = null; 12682 } 12683 } 12684 12685 boolean looped = false; 12686 12687 do { 12688 if (mOrderedBroadcasts.size() == 0) { 12689 // No more broadcasts pending, so all done! 12690 scheduleAppGcsLocked(); 12691 if (looped) { 12692 // If we had finished the last ordered broadcast, then 12693 // make sure all processes have correct oom and sched 12694 // adjustments. 12695 updateOomAdjLocked(); 12696 } 12697 return; 12698 } 12699 r = mOrderedBroadcasts.get(0); 12700 boolean forceReceive = false; 12701 12702 // Ensure that even if something goes awry with the timeout 12703 // detection, we catch "hung" broadcasts here, discard them, 12704 // and continue to make progress. 12705 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0; 12706 long now = SystemClock.uptimeMillis(); 12707 if (r.dispatchTime > 0) { 12708 if ((numReceivers > 0) && 12709 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) { 12710 Log.w(TAG, "Hung broadcast discarded after timeout failure:" 12711 + " now=" + now 12712 + " dispatchTime=" + r.dispatchTime 12713 + " startTime=" + r.receiverTime 12714 + " intent=" + r.intent 12715 + " numReceivers=" + numReceivers 12716 + " nextReceiver=" + r.nextReceiver 12717 + " state=" + r.state); 12718 broadcastTimeout(); // forcibly finish this broadcast 12719 forceReceive = true; 12720 r.state = BroadcastRecord.IDLE; 12721 } 12722 } 12723 12724 if (r.state != BroadcastRecord.IDLE) { 12725 if (DEBUG_BROADCAST) Log.d(TAG, 12726 "processNextBroadcast() called when not idle (state=" 12727 + r.state + ")"); 12728 return; 12729 } 12730 12731 if (r.receivers == null || r.nextReceiver >= numReceivers 12732 || r.resultAbort || forceReceive) { 12733 // No more receivers for this broadcast! Send the final 12734 // result if requested... 12735 if (r.resultTo != null) { 12736 try { 12737 if (DEBUG_BROADCAST) { 12738 int seq = r.intent.getIntExtra("seq", -1); 12739 Log.i(TAG, "Finishing broadcast " + r.intent.getAction() 12740 + " seq=" + seq + " app=" + r.callerApp); 12741 } 12742 performReceive(r.callerApp, r.resultTo, 12743 new Intent(r.intent), r.resultCode, 12744 r.resultData, r.resultExtras, false, false); 12745 } catch (RemoteException e) { 12746 Log.w(TAG, "Failure sending broadcast result of " + r.intent, e); 12747 } 12748 } 12749 12750 if (DEBUG_BROADCAST) Log.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG"); 12751 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG); 12752 12753 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Finished with ordered broadcast " 12754 + r); 12755 12756 // ... and on to the next... 12757 addBroadcastToHistoryLocked(r); 12758 mOrderedBroadcasts.remove(0); 12759 r = null; 12760 looped = true; 12761 continue; 12762 } 12763 } while (r == null); 12764 12765 // Get the next receiver... 12766 int recIdx = r.nextReceiver++; 12767 12768 // Keep track of when this receiver started, and make sure there 12769 // is a timeout message pending to kill it if need be. 12770 r.receiverTime = SystemClock.uptimeMillis(); 12771 if (recIdx == 0) { 12772 r.dispatchTime = r.receiverTime; 12773 12774 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Processing ordered broadcast " 12775 + r); 12776 if (DEBUG_BROADCAST) Log.v(TAG, 12777 "Submitting BROADCAST_TIMEOUT_MSG for " 12778 + (r.receiverTime + BROADCAST_TIMEOUT)); 12779 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG); 12780 mHandler.sendMessageAtTime(msg, r.receiverTime+BROADCAST_TIMEOUT); 12781 } 12782 12783 Object nextReceiver = r.receivers.get(recIdx); 12784 if (nextReceiver instanceof BroadcastFilter) { 12785 // Simple case: this is a registered receiver who gets 12786 // a direct call. 12787 BroadcastFilter filter = (BroadcastFilter)nextReceiver; 12788 if (DEBUG_BROADCAST) Log.v(TAG, 12789 "Delivering serialized to registered " 12790 + filter + ": " + r); 12791 deliverToRegisteredReceiver(r, filter, r.ordered); 12792 if (r.receiver == null || !r.ordered) { 12793 // The receiver has already finished, so schedule to 12794 // process the next one. 12795 r.state = BroadcastRecord.IDLE; 12796 scheduleBroadcastsLocked(); 12797 } 12798 return; 12799 } 12800 12801 // Hard case: need to instantiate the receiver, possibly 12802 // starting its application process to host it. 12803 12804 ResolveInfo info = 12805 (ResolveInfo)nextReceiver; 12806 12807 boolean skip = false; 12808 int perm = checkComponentPermission(info.activityInfo.permission, 12809 r.callingPid, r.callingUid, 12810 info.activityInfo.exported 12811 ? -1 : info.activityInfo.applicationInfo.uid); 12812 if (perm != PackageManager.PERMISSION_GRANTED) { 12813 Log.w(TAG, "Permission Denial: broadcasting " 12814 + r.intent.toString() 12815 + " from " + r.callerPackage + " (pid=" + r.callingPid 12816 + ", uid=" + r.callingUid + ")" 12817 + " requires " + info.activityInfo.permission 12818 + " due to receiver " + info.activityInfo.packageName 12819 + "/" + info.activityInfo.name); 12820 skip = true; 12821 } 12822 if (r.callingUid != Process.SYSTEM_UID && 12823 r.requiredPermission != null) { 12824 try { 12825 perm = ActivityThread.getPackageManager(). 12826 checkPermission(r.requiredPermission, 12827 info.activityInfo.applicationInfo.packageName); 12828 } catch (RemoteException e) { 12829 perm = PackageManager.PERMISSION_DENIED; 12830 } 12831 if (perm != PackageManager.PERMISSION_GRANTED) { 12832 Log.w(TAG, "Permission Denial: receiving " 12833 + r.intent + " to " 12834 + info.activityInfo.applicationInfo.packageName 12835 + " requires " + r.requiredPermission 12836 + " due to sender " + r.callerPackage 12837 + " (uid " + r.callingUid + ")"); 12838 skip = true; 12839 } 12840 } 12841 if (r.curApp != null && r.curApp.crashing) { 12842 // If the target process is crashing, just skip it. 12843 skip = true; 12844 } 12845 12846 if (skip) { 12847 r.receiver = null; 12848 r.curFilter = null; 12849 r.state = BroadcastRecord.IDLE; 12850 scheduleBroadcastsLocked(); 12851 return; 12852 } 12853 12854 r.state = BroadcastRecord.APP_RECEIVE; 12855 String targetProcess = info.activityInfo.processName; 12856 r.curComponent = new ComponentName( 12857 info.activityInfo.applicationInfo.packageName, 12858 info.activityInfo.name); 12859 r.curReceiver = info.activityInfo; 12860 12861 // Is this receiver's application already running? 12862 ProcessRecord app = getProcessRecordLocked(targetProcess, 12863 info.activityInfo.applicationInfo.uid); 12864 if (app != null && app.thread != null) { 12865 try { 12866 processCurBroadcastLocked(r, app); 12867 return; 12868 } catch (RemoteException e) { 12869 Log.w(TAG, "Exception when sending broadcast to " 12870 + r.curComponent, e); 12871 } 12872 12873 // If a dead object exception was thrown -- fall through to 12874 // restart the application. 12875 } 12876 12877 // Not running -- get it started, to be executed when the app comes up. 12878 if ((r.curApp=startProcessLocked(targetProcess, 12879 info.activityInfo.applicationInfo, true, 12880 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND, 12881 "broadcast", r.curComponent, 12882 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0)) 12883 == null) { 12884 // Ah, this recipient is unavailable. Finish it if necessary, 12885 // and mark the broadcast record as ready for the next. 12886 Log.w(TAG, "Unable to launch app " 12887 + info.activityInfo.applicationInfo.packageName + "/" 12888 + info.activityInfo.applicationInfo.uid + " for broadcast " 12889 + r.intent + ": process is bad"); 12890 logBroadcastReceiverDiscard(r); 12891 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 12892 r.resultExtras, r.resultAbort, true); 12893 scheduleBroadcastsLocked(); 12894 r.state = BroadcastRecord.IDLE; 12895 return; 12896 } 12897 12898 mPendingBroadcast = r; 12899 } 12900 } 12901 12902 // ========================================================= 12903 // INSTRUMENTATION 12904 // ========================================================= 12905 12906 public boolean startInstrumentation(ComponentName className, 12907 String profileFile, int flags, Bundle arguments, 12908 IInstrumentationWatcher watcher) { 12909 // Refuse possible leaked file descriptors 12910 if (arguments != null && arguments.hasFileDescriptors()) { 12911 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12912 } 12913 12914 synchronized(this) { 12915 InstrumentationInfo ii = null; 12916 ApplicationInfo ai = null; 12917 try { 12918 ii = mContext.getPackageManager().getInstrumentationInfo( 12919 className, STOCK_PM_FLAGS); 12920 ai = mContext.getPackageManager().getApplicationInfo( 12921 ii.targetPackage, STOCK_PM_FLAGS); 12922 } catch (PackageManager.NameNotFoundException e) { 12923 } 12924 if (ii == null) { 12925 reportStartInstrumentationFailure(watcher, className, 12926 "Unable to find instrumentation info for: " + className); 12927 return false; 12928 } 12929 if (ai == null) { 12930 reportStartInstrumentationFailure(watcher, className, 12931 "Unable to find instrumentation target package: " + ii.targetPackage); 12932 return false; 12933 } 12934 12935 int match = mContext.getPackageManager().checkSignatures( 12936 ii.targetPackage, ii.packageName); 12937 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 12938 String msg = "Permission Denial: starting instrumentation " 12939 + className + " from pid=" 12940 + Binder.getCallingPid() 12941 + ", uid=" + Binder.getCallingPid() 12942 + " not allowed because package " + ii.packageName 12943 + " does not have a signature matching the target " 12944 + ii.targetPackage; 12945 reportStartInstrumentationFailure(watcher, className, msg); 12946 throw new SecurityException(msg); 12947 } 12948 12949 final long origId = Binder.clearCallingIdentity(); 12950 forceStopPackageLocked(ii.targetPackage, -1, true, false); 12951 ProcessRecord app = addAppLocked(ai); 12952 app.instrumentationClass = className; 12953 app.instrumentationInfo = ai; 12954 app.instrumentationProfileFile = profileFile; 12955 app.instrumentationArguments = arguments; 12956 app.instrumentationWatcher = watcher; 12957 app.instrumentationResultClass = className; 12958 Binder.restoreCallingIdentity(origId); 12959 } 12960 12961 return true; 12962 } 12963 12964 /** 12965 * Report errors that occur while attempting to start Instrumentation. Always writes the 12966 * error to the logs, but if somebody is watching, send the report there too. This enables 12967 * the "am" command to report errors with more information. 12968 * 12969 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 12970 * @param cn The component name of the instrumentation. 12971 * @param report The error report. 12972 */ 12973 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 12974 ComponentName cn, String report) { 12975 Log.w(TAG, report); 12976 try { 12977 if (watcher != null) { 12978 Bundle results = new Bundle(); 12979 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 12980 results.putString("Error", report); 12981 watcher.instrumentationStatus(cn, -1, results); 12982 } 12983 } catch (RemoteException e) { 12984 Log.w(TAG, e); 12985 } 12986 } 12987 12988 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 12989 if (app.instrumentationWatcher != null) { 12990 try { 12991 // NOTE: IInstrumentationWatcher *must* be oneway here 12992 app.instrumentationWatcher.instrumentationFinished( 12993 app.instrumentationClass, 12994 resultCode, 12995 results); 12996 } catch (RemoteException e) { 12997 } 12998 } 12999 app.instrumentationWatcher = null; 13000 app.instrumentationClass = null; 13001 app.instrumentationInfo = null; 13002 app.instrumentationProfileFile = null; 13003 app.instrumentationArguments = null; 13004 13005 forceStopPackageLocked(app.processName, -1, false, false); 13006 } 13007 13008 public void finishInstrumentation(IApplicationThread target, 13009 int resultCode, Bundle results) { 13010 // Refuse possible leaked file descriptors 13011 if (results != null && results.hasFileDescriptors()) { 13012 throw new IllegalArgumentException("File descriptors passed in Intent"); 13013 } 13014 13015 synchronized(this) { 13016 ProcessRecord app = getRecordForAppLocked(target); 13017 if (app == null) { 13018 Log.w(TAG, "finishInstrumentation: no app for " + target); 13019 return; 13020 } 13021 final long origId = Binder.clearCallingIdentity(); 13022 finishInstrumentationLocked(app, resultCode, results); 13023 Binder.restoreCallingIdentity(origId); 13024 } 13025 } 13026 13027 // ========================================================= 13028 // CONFIGURATION 13029 // ========================================================= 13030 13031 public ConfigurationInfo getDeviceConfigurationInfo() { 13032 ConfigurationInfo config = new ConfigurationInfo(); 13033 synchronized (this) { 13034 config.reqTouchScreen = mConfiguration.touchscreen; 13035 config.reqKeyboardType = mConfiguration.keyboard; 13036 config.reqNavigation = mConfiguration.navigation; 13037 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13038 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13039 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13040 } 13041 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13042 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13043 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13044 } 13045 config.reqGlEsVersion = GL_ES_VERSION; 13046 } 13047 return config; 13048 } 13049 13050 public Configuration getConfiguration() { 13051 Configuration ci; 13052 synchronized(this) { 13053 ci = new Configuration(mConfiguration); 13054 } 13055 return ci; 13056 } 13057 13058 public void updateConfiguration(Configuration values) { 13059 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13060 "updateConfiguration()"); 13061 13062 synchronized(this) { 13063 if (values == null && mWindowManager != null) { 13064 // sentinel: fetch the current configuration from the window manager 13065 values = mWindowManager.computeNewConfiguration(); 13066 } 13067 13068 final long origId = Binder.clearCallingIdentity(); 13069 updateConfigurationLocked(values, null); 13070 Binder.restoreCallingIdentity(origId); 13071 } 13072 } 13073 13074 /** 13075 * Do either or both things: (1) change the current configuration, and (2) 13076 * make sure the given activity is running with the (now) current 13077 * configuration. Returns true if the activity has been left running, or 13078 * false if <var>starting</var> is being destroyed to match the new 13079 * configuration. 13080 */ 13081 public boolean updateConfigurationLocked(Configuration values, 13082 HistoryRecord starting) { 13083 int changes = 0; 13084 13085 boolean kept = true; 13086 13087 if (values != null) { 13088 Configuration newConfig = new Configuration(mConfiguration); 13089 changes = newConfig.updateFrom(values); 13090 if (changes != 0) { 13091 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13092 Log.i(TAG, "Updating configuration to: " + values); 13093 } 13094 13095 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 13096 13097 if (values.locale != null) { 13098 saveLocaleLocked(values.locale, 13099 !values.locale.equals(mConfiguration.locale), 13100 values.userSetLocale); 13101 } 13102 13103 mConfiguration = newConfig; 13104 Log.i(TAG, "Config changed: " + newConfig); 13105 13106 AttributeCache ac = AttributeCache.instance(); 13107 if (ac != null) { 13108 ac.updateConfiguration(mConfiguration); 13109 } 13110 13111 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 13112 msg.obj = new Configuration(mConfiguration); 13113 mHandler.sendMessage(msg); 13114 13115 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13116 ProcessRecord app = mLruProcesses.get(i); 13117 try { 13118 if (app.thread != null) { 13119 if (DEBUG_CONFIGURATION) Log.v(TAG, "Sending to proc " 13120 + app.processName + " new config " + mConfiguration); 13121 app.thread.scheduleConfigurationChanged(mConfiguration); 13122 } 13123 } catch (Exception e) { 13124 } 13125 } 13126 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 13127 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 13128 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 13129 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 13130 null, false, false, MY_PID, Process.SYSTEM_UID); 13131 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 13132 broadcastIntentLocked(null, null, 13133 new Intent(Intent.ACTION_LOCALE_CHANGED), 13134 null, null, 0, null, null, 13135 null, false, false, MY_PID, Process.SYSTEM_UID); 13136 } 13137 } 13138 } 13139 13140 if (changes != 0 && starting == null) { 13141 // If the configuration changed, and the caller is not already 13142 // in the process of starting an activity, then find the top 13143 // activity to check if its configuration needs to change. 13144 starting = topRunningActivityLocked(null); 13145 } 13146 13147 if (starting != null) { 13148 kept = ensureActivityConfigurationLocked(starting, changes); 13149 if (kept) { 13150 // If this didn't result in the starting activity being 13151 // destroyed, then we need to make sure at this point that all 13152 // other activities are made visible. 13153 if (DEBUG_SWITCH) Log.i(TAG, "Config didn't destroy " + starting 13154 + ", ensuring others are correct."); 13155 ensureActivitiesVisibleLocked(starting, changes); 13156 } 13157 } 13158 13159 return kept; 13160 } 13161 13162 private final boolean relaunchActivityLocked(HistoryRecord r, 13163 int changes, boolean andResume) { 13164 List<ResultInfo> results = null; 13165 List<Intent> newIntents = null; 13166 if (andResume) { 13167 results = r.results; 13168 newIntents = r.newIntents; 13169 } 13170 if (DEBUG_SWITCH) Log.v(TAG, "Relaunching: " + r 13171 + " with results=" + results + " newIntents=" + newIntents 13172 + " andResume=" + andResume); 13173 EventLog.writeEvent(andResume ? EventLogTags.AM_RELAUNCH_RESUME_ACTIVITY 13174 : EventLogTags.AM_RELAUNCH_ACTIVITY, System.identityHashCode(r), 13175 r.task.taskId, r.shortComponentName); 13176 13177 r.startFreezingScreenLocked(r.app, 0); 13178 13179 try { 13180 if (DEBUG_SWITCH) Log.i(TAG, "Switch is restarting resumed " + r); 13181 r.app.thread.scheduleRelaunchActivity(r, results, newIntents, 13182 changes, !andResume, mConfiguration); 13183 // Note: don't need to call pauseIfSleepingLocked() here, because 13184 // the caller will only pass in 'andResume' if this activity is 13185 // currently resumed, which implies we aren't sleeping. 13186 } catch (RemoteException e) { 13187 return false; 13188 } 13189 13190 if (andResume) { 13191 r.results = null; 13192 r.newIntents = null; 13193 reportResumedActivityLocked(r); 13194 } 13195 13196 return true; 13197 } 13198 13199 /** 13200 * Make sure the given activity matches the current configuration. Returns 13201 * false if the activity had to be destroyed. Returns true if the 13202 * configuration is the same, or the activity will remain running as-is 13203 * for whatever reason. Ensures the HistoryRecord is updated with the 13204 * correct configuration and all other bookkeeping is handled. 13205 */ 13206 private final boolean ensureActivityConfigurationLocked(HistoryRecord r, 13207 int globalChanges) { 13208 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 13209 "Ensuring correct configuration: " + r); 13210 13211 // Short circuit: if the two configurations are the exact same 13212 // object (the common case), then there is nothing to do. 13213 Configuration newConfig = mConfiguration; 13214 if (r.configuration == newConfig) { 13215 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 13216 "Configuration unchanged in " + r); 13217 return true; 13218 } 13219 13220 // We don't worry about activities that are finishing. 13221 if (r.finishing) { 13222 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 13223 "Configuration doesn't matter in finishing " + r); 13224 r.stopFreezingScreenLocked(false); 13225 return true; 13226 } 13227 13228 // Okay we now are going to make this activity have the new config. 13229 // But then we need to figure out how it needs to deal with that. 13230 Configuration oldConfig = r.configuration; 13231 r.configuration = newConfig; 13232 13233 // If the activity isn't currently running, just leave the new 13234 // configuration and it will pick that up next time it starts. 13235 if (r.app == null || r.app.thread == null) { 13236 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 13237 "Configuration doesn't matter not running " + r); 13238 r.stopFreezingScreenLocked(false); 13239 return true; 13240 } 13241 13242 // If the activity isn't persistent, there is a chance we will 13243 // need to restart it. 13244 if (!r.persistent) { 13245 13246 // Figure out what has changed between the two configurations. 13247 int changes = oldConfig.diff(newConfig); 13248 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13249 Log.v(TAG, "Checking to restart " + r.info.name + ": changed=0x" 13250 + Integer.toHexString(changes) + ", handles=0x" 13251 + Integer.toHexString(r.info.configChanges) 13252 + ", newConfig=" + newConfig); 13253 } 13254 if ((changes&(~r.info.configChanges)) != 0) { 13255 // Aha, the activity isn't handling the change, so DIE DIE DIE. 13256 r.configChangeFlags |= changes; 13257 r.startFreezingScreenLocked(r.app, globalChanges); 13258 if (r.app == null || r.app.thread == null) { 13259 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 13260 "Switch is destroying non-running " + r); 13261 destroyActivityLocked(r, true); 13262 } else if (r.state == ActivityState.PAUSING) { 13263 // A little annoying: we are waiting for this activity to 13264 // finish pausing. Let's not do anything now, but just 13265 // flag that it needs to be restarted when done pausing. 13266 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 13267 "Switch is skipping already pausing " + r); 13268 r.configDestroy = true; 13269 return true; 13270 } else if (r.state == ActivityState.RESUMED) { 13271 // Try to optimize this case: the configuration is changing 13272 // and we need to restart the top, resumed activity. 13273 // Instead of doing the normal handshaking, just say 13274 // "restart!". 13275 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 13276 "Switch is restarting resumed " + r); 13277 relaunchActivityLocked(r, r.configChangeFlags, true); 13278 r.configChangeFlags = 0; 13279 } else { 13280 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 13281 "Switch is restarting non-resumed " + r); 13282 relaunchActivityLocked(r, r.configChangeFlags, false); 13283 r.configChangeFlags = 0; 13284 } 13285 13286 // All done... tell the caller we weren't able to keep this 13287 // activity around. 13288 return false; 13289 } 13290 } 13291 13292 // Default case: the activity can handle this new configuration, so 13293 // hand it over. Note that we don't need to give it the new 13294 // configuration, since we always send configuration changes to all 13295 // process when they happen so it can just use whatever configuration 13296 // it last got. 13297 if (r.app != null && r.app.thread != null) { 13298 try { 13299 if (DEBUG_CONFIGURATION) Log.v(TAG, "Sending new config to " + r); 13300 r.app.thread.scheduleActivityConfigurationChanged(r); 13301 } catch (RemoteException e) { 13302 // If process died, whatever. 13303 } 13304 } 13305 r.stopFreezingScreenLocked(false); 13306 13307 return true; 13308 } 13309 13310 /** 13311 * Save the locale. You must be inside a synchronized (this) block. 13312 */ 13313 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 13314 if(isDiff) { 13315 SystemProperties.set("user.language", l.getLanguage()); 13316 SystemProperties.set("user.region", l.getCountry()); 13317 } 13318 13319 if(isPersist) { 13320 SystemProperties.set("persist.sys.language", l.getLanguage()); 13321 SystemProperties.set("persist.sys.country", l.getCountry()); 13322 SystemProperties.set("persist.sys.localevar", l.getVariant()); 13323 } 13324 } 13325 13326 // ========================================================= 13327 // LIFETIME MANAGEMENT 13328 // ========================================================= 13329 13330 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 13331 ProcessRecord TOP_APP, boolean recursed) { 13332 if (mAdjSeq == app.adjSeq) { 13333 // This adjustment has already been computed. If we are calling 13334 // from the top, we may have already computed our adjustment with 13335 // an earlier hidden adjustment that isn't really for us... if 13336 // so, use the new hidden adjustment. 13337 if (!recursed && app.hidden) { 13338 app.curAdj = hiddenAdj; 13339 } 13340 return app.curAdj; 13341 } 13342 13343 if (app.thread == null) { 13344 app.adjSeq = mAdjSeq; 13345 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13346 return (app.curAdj=EMPTY_APP_ADJ); 13347 } 13348 13349 if (app.maxAdj <= FOREGROUND_APP_ADJ) { 13350 // The max adjustment doesn't allow this app to be anything 13351 // below foreground, so it is not worth doing work for it. 13352 app.adjType = "fixed"; 13353 app.adjSeq = mAdjSeq; 13354 app.curRawAdj = app.maxAdj; 13355 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 13356 return (app.curAdj=app.maxAdj); 13357 } 13358 13359 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 13360 app.adjSource = null; 13361 app.adjTarget = null; 13362 app.empty = false; 13363 app.hidden = false; 13364 13365 // Determine the importance of the process, starting with most 13366 // important to least, and assign an appropriate OOM adjustment. 13367 int adj; 13368 int schedGroup; 13369 int N; 13370 if (app == TOP_APP) { 13371 // The last app on the list is the foreground app. 13372 adj = FOREGROUND_APP_ADJ; 13373 schedGroup = Process.THREAD_GROUP_DEFAULT; 13374 app.adjType = "top-activity"; 13375 } else if (app.instrumentationClass != null) { 13376 // Don't want to kill running instrumentation. 13377 adj = FOREGROUND_APP_ADJ; 13378 schedGroup = Process.THREAD_GROUP_DEFAULT; 13379 app.adjType = "instrumentation"; 13380 } else if (app.persistentActivities > 0) { 13381 // Special persistent activities... shouldn't be used these days. 13382 adj = FOREGROUND_APP_ADJ; 13383 schedGroup = Process.THREAD_GROUP_DEFAULT; 13384 app.adjType = "persistent"; 13385 } else if (app.curReceiver != null || 13386 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) { 13387 // An app that is currently receiving a broadcast also 13388 // counts as being in the foreground. 13389 adj = FOREGROUND_APP_ADJ; 13390 schedGroup = Process.THREAD_GROUP_DEFAULT; 13391 app.adjType = "broadcast"; 13392 } else if (app.executingServices.size() > 0) { 13393 // An app that is currently executing a service callback also 13394 // counts as being in the foreground. 13395 adj = FOREGROUND_APP_ADJ; 13396 schedGroup = Process.THREAD_GROUP_DEFAULT; 13397 app.adjType = "exec-service"; 13398 } else if (app.foregroundServices) { 13399 // The user is aware of this app, so make it visible. 13400 adj = VISIBLE_APP_ADJ; 13401 schedGroup = Process.THREAD_GROUP_DEFAULT; 13402 app.adjType = "foreground-service"; 13403 } else if (app.forcingToForeground != null) { 13404 // The user is aware of this app, so make it visible. 13405 adj = VISIBLE_APP_ADJ; 13406 schedGroup = Process.THREAD_GROUP_DEFAULT; 13407 app.adjType = "force-foreground"; 13408 app.adjSource = app.forcingToForeground; 13409 } else if (app == mHomeProcess) { 13410 // This process is hosting what we currently consider to be the 13411 // home app, so we don't want to let it go into the background. 13412 adj = HOME_APP_ADJ; 13413 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13414 app.adjType = "home"; 13415 } else if ((N=app.activities.size()) != 0) { 13416 // This app is in the background with paused activities. 13417 app.hidden = true; 13418 adj = hiddenAdj; 13419 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13420 app.adjType = "bg-activities"; 13421 N = app.activities.size(); 13422 for (int j=0; j<N; j++) { 13423 if (((HistoryRecord)app.activities.get(j)).visible) { 13424 // This app has a visible activity! 13425 app.hidden = false; 13426 adj = VISIBLE_APP_ADJ; 13427 schedGroup = Process.THREAD_GROUP_DEFAULT; 13428 app.adjType = "visible"; 13429 break; 13430 } 13431 } 13432 } else { 13433 // A very not-needed process. If this is lower in the lru list, 13434 // we will push it in to the empty bucket. 13435 app.hidden = true; 13436 app.empty = true; 13437 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13438 adj = hiddenAdj; 13439 app.adjType = "bg-empty"; 13440 } 13441 13442 //Log.i(TAG, "OOM " + app + ": initial adj=" + adj); 13443 13444 // By default, we use the computed adjustment. It may be changed if 13445 // there are applications dependent on our services or providers, but 13446 // this gives us a baseline and makes sure we don't get into an 13447 // infinite recursion. 13448 app.adjSeq = mAdjSeq; 13449 app.curRawAdj = adj; 13450 13451 if (mBackupTarget != null && app == mBackupTarget.app) { 13452 // If possible we want to avoid killing apps while they're being backed up 13453 if (adj > BACKUP_APP_ADJ) { 13454 if (DEBUG_BACKUP) Log.v(TAG, "oom BACKUP_APP_ADJ for " + app); 13455 adj = BACKUP_APP_ADJ; 13456 app.adjType = "backup"; 13457 app.hidden = false; 13458 } 13459 } 13460 13461 if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ 13462 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13463 final long now = SystemClock.uptimeMillis(); 13464 // This process is more important if the top activity is 13465 // bound to the service. 13466 Iterator jt = app.services.iterator(); 13467 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) { 13468 ServiceRecord s = (ServiceRecord)jt.next(); 13469 if (s.startRequested) { 13470 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) { 13471 // This service has seen some activity within 13472 // recent memory, so we will keep its process ahead 13473 // of the background processes. 13474 if (adj > SECONDARY_SERVER_ADJ) { 13475 adj = SECONDARY_SERVER_ADJ; 13476 app.adjType = "started-services"; 13477 app.hidden = false; 13478 } 13479 } 13480 } 13481 if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ 13482 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13483 Iterator<ConnectionRecord> kt 13484 = s.connections.values().iterator(); 13485 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) { 13486 // XXX should compute this based on the max of 13487 // all connected clients. 13488 ConnectionRecord cr = kt.next(); 13489 if (cr.binding.client == app) { 13490 // Binding to ourself is not interesting. 13491 continue; 13492 } 13493 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) { 13494 ProcessRecord client = cr.binding.client; 13495 int myHiddenAdj = hiddenAdj; 13496 if (myHiddenAdj > client.hiddenAdj) { 13497 if (client.hiddenAdj > VISIBLE_APP_ADJ) { 13498 myHiddenAdj = client.hiddenAdj; 13499 } else { 13500 myHiddenAdj = VISIBLE_APP_ADJ; 13501 } 13502 } 13503 int clientAdj = computeOomAdjLocked( 13504 client, myHiddenAdj, TOP_APP, true); 13505 if (adj > clientAdj) { 13506 adj = clientAdj > VISIBLE_APP_ADJ 13507 ? clientAdj : VISIBLE_APP_ADJ; 13508 if (!client.hidden) { 13509 app.hidden = false; 13510 } 13511 app.adjType = "service"; 13512 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13513 .REASON_SERVICE_IN_USE; 13514 app.adjSource = cr.binding.client; 13515 app.adjTarget = s.serviceInfo.name; 13516 } 13517 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 13518 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 13519 schedGroup = Process.THREAD_GROUP_DEFAULT; 13520 } 13521 } 13522 } 13523 HistoryRecord a = cr.activity; 13524 //if (a != null) { 13525 // Log.i(TAG, "Connection to " + a ": state=" + a.state); 13526 //} 13527 if (a != null && adj > FOREGROUND_APP_ADJ && 13528 (a.state == ActivityState.RESUMED 13529 || a.state == ActivityState.PAUSING)) { 13530 adj = FOREGROUND_APP_ADJ; 13531 schedGroup = Process.THREAD_GROUP_DEFAULT; 13532 app.hidden = false; 13533 app.adjType = "service"; 13534 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13535 .REASON_SERVICE_IN_USE; 13536 app.adjSource = a; 13537 app.adjTarget = s.serviceInfo.name; 13538 } 13539 } 13540 } 13541 } 13542 13543 // Finally, f this process has active services running in it, we 13544 // would like to avoid killing it unless it would prevent the current 13545 // application from running. By default we put the process in 13546 // with the rest of the background processes; as we scan through 13547 // its services we may bump it up from there. 13548 if (adj > hiddenAdj) { 13549 adj = hiddenAdj; 13550 app.hidden = false; 13551 app.adjType = "bg-services"; 13552 } 13553 } 13554 13555 if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ 13556 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13557 Iterator jt = app.pubProviders.values().iterator(); 13558 while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ 13559 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13560 ContentProviderRecord cpr = (ContentProviderRecord)jt.next(); 13561 if (cpr.clients.size() != 0) { 13562 Iterator<ProcessRecord> kt = cpr.clients.iterator(); 13563 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) { 13564 ProcessRecord client = kt.next(); 13565 if (client == app) { 13566 // Being our own client is not interesting. 13567 continue; 13568 } 13569 int myHiddenAdj = hiddenAdj; 13570 if (myHiddenAdj > client.hiddenAdj) { 13571 if (client.hiddenAdj > FOREGROUND_APP_ADJ) { 13572 myHiddenAdj = client.hiddenAdj; 13573 } else { 13574 myHiddenAdj = FOREGROUND_APP_ADJ; 13575 } 13576 } 13577 int clientAdj = computeOomAdjLocked( 13578 client, myHiddenAdj, TOP_APP, true); 13579 if (adj > clientAdj) { 13580 adj = clientAdj > FOREGROUND_APP_ADJ 13581 ? clientAdj : FOREGROUND_APP_ADJ; 13582 if (!client.hidden) { 13583 app.hidden = false; 13584 } 13585 app.adjType = "provider"; 13586 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13587 .REASON_PROVIDER_IN_USE; 13588 app.adjSource = client; 13589 app.adjTarget = cpr.info.name; 13590 } 13591 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 13592 schedGroup = Process.THREAD_GROUP_DEFAULT; 13593 } 13594 } 13595 } 13596 // If the provider has external (non-framework) process 13597 // dependencies, ensure that its adjustment is at least 13598 // FOREGROUND_APP_ADJ. 13599 if (cpr.externals != 0) { 13600 if (adj > FOREGROUND_APP_ADJ) { 13601 adj = FOREGROUND_APP_ADJ; 13602 schedGroup = Process.THREAD_GROUP_DEFAULT; 13603 app.hidden = false; 13604 app.adjType = "provider"; 13605 app.adjTarget = cpr.info.name; 13606 } 13607 } 13608 } 13609 } 13610 13611 app.curRawAdj = adj; 13612 13613 //Log.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 13614 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 13615 if (adj > app.maxAdj) { 13616 adj = app.maxAdj; 13617 if (app.maxAdj <= VISIBLE_APP_ADJ) { 13618 schedGroup = Process.THREAD_GROUP_DEFAULT; 13619 } 13620 } 13621 13622 app.curAdj = adj; 13623 app.curSchedGroup = schedGroup; 13624 13625 return adj; 13626 } 13627 13628 /** 13629 * Ask a given process to GC right now. 13630 */ 13631 final void performAppGcLocked(ProcessRecord app) { 13632 try { 13633 app.lastRequestedGc = SystemClock.uptimeMillis(); 13634 if (app.thread != null) { 13635 if (app.reportLowMemory) { 13636 app.reportLowMemory = false; 13637 app.thread.scheduleLowMemory(); 13638 } else { 13639 app.thread.processInBackground(); 13640 } 13641 } 13642 } catch (Exception e) { 13643 // whatever. 13644 } 13645 } 13646 13647 /** 13648 * Returns true if things are idle enough to perform GCs. 13649 */ 13650 private final boolean canGcNow() { 13651 return mParallelBroadcasts.size() == 0 13652 && mOrderedBroadcasts.size() == 0 13653 && (mSleeping || (mResumedActivity != null && 13654 mResumedActivity.idle)); 13655 } 13656 13657 /** 13658 * Perform GCs on all processes that are waiting for it, but only 13659 * if things are idle. 13660 */ 13661 final void performAppGcsLocked() { 13662 final int N = mProcessesToGc.size(); 13663 if (N <= 0) { 13664 return; 13665 } 13666 if (canGcNow()) { 13667 while (mProcessesToGc.size() > 0) { 13668 ProcessRecord proc = mProcessesToGc.remove(0); 13669 if (proc.curRawAdj > VISIBLE_APP_ADJ || proc.reportLowMemory) { 13670 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 13671 <= SystemClock.uptimeMillis()) { 13672 // To avoid spamming the system, we will GC processes one 13673 // at a time, waiting a few seconds between each. 13674 performAppGcLocked(proc); 13675 scheduleAppGcsLocked(); 13676 return; 13677 } else { 13678 // It hasn't been long enough since we last GCed this 13679 // process... put it in the list to wait for its time. 13680 addProcessToGcListLocked(proc); 13681 break; 13682 } 13683 } 13684 } 13685 13686 scheduleAppGcsLocked(); 13687 } 13688 } 13689 13690 /** 13691 * If all looks good, perform GCs on all processes waiting for them. 13692 */ 13693 final void performAppGcsIfAppropriateLocked() { 13694 if (canGcNow()) { 13695 performAppGcsLocked(); 13696 return; 13697 } 13698 // Still not idle, wait some more. 13699 scheduleAppGcsLocked(); 13700 } 13701 13702 /** 13703 * Schedule the execution of all pending app GCs. 13704 */ 13705 final void scheduleAppGcsLocked() { 13706 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 13707 13708 if (mProcessesToGc.size() > 0) { 13709 // Schedule a GC for the time to the next process. 13710 ProcessRecord proc = mProcessesToGc.get(0); 13711 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 13712 13713 long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL; 13714 long now = SystemClock.uptimeMillis(); 13715 if (when < (now+GC_TIMEOUT)) { 13716 when = now + GC_TIMEOUT; 13717 } 13718 mHandler.sendMessageAtTime(msg, when); 13719 } 13720 } 13721 13722 /** 13723 * Add a process to the array of processes waiting to be GCed. Keeps the 13724 * list in sorted order by the last GC time. The process can't already be 13725 * on the list. 13726 */ 13727 final void addProcessToGcListLocked(ProcessRecord proc) { 13728 boolean added = false; 13729 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 13730 if (mProcessesToGc.get(i).lastRequestedGc < 13731 proc.lastRequestedGc) { 13732 added = true; 13733 mProcessesToGc.add(i+1, proc); 13734 break; 13735 } 13736 } 13737 if (!added) { 13738 mProcessesToGc.add(0, proc); 13739 } 13740 } 13741 13742 /** 13743 * Set up to ask a process to GC itself. This will either do it 13744 * immediately, or put it on the list of processes to gc the next 13745 * time things are idle. 13746 */ 13747 final void scheduleAppGcLocked(ProcessRecord app) { 13748 long now = SystemClock.uptimeMillis(); 13749 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 13750 return; 13751 } 13752 if (!mProcessesToGc.contains(app)) { 13753 addProcessToGcListLocked(app); 13754 scheduleAppGcsLocked(); 13755 } 13756 } 13757 13758 private final boolean updateOomAdjLocked( 13759 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) { 13760 app.hiddenAdj = hiddenAdj; 13761 13762 if (app.thread == null) { 13763 return true; 13764 } 13765 13766 int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false); 13767 13768 if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) { 13769 if (app.curRawAdj != app.setRawAdj) { 13770 if (app.curRawAdj > FOREGROUND_APP_ADJ 13771 && app.setRawAdj <= FOREGROUND_APP_ADJ) { 13772 // If this app is transitioning from foreground to 13773 // non-foreground, have it do a gc. 13774 scheduleAppGcLocked(app); 13775 } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ 13776 && app.setRawAdj < HIDDEN_APP_MIN_ADJ) { 13777 // Likewise do a gc when an app is moving in to the 13778 // background (such as a service stopping). 13779 scheduleAppGcLocked(app); 13780 } 13781 app.setRawAdj = app.curRawAdj; 13782 } 13783 if (adj != app.setAdj) { 13784 if (Process.setOomAdj(app.pid, adj)) { 13785 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v( 13786 TAG, "Set app " + app.processName + 13787 " oom adj to " + adj); 13788 app.setAdj = adj; 13789 } else { 13790 return false; 13791 } 13792 } 13793 if (app.setSchedGroup != app.curSchedGroup) { 13794 app.setSchedGroup = app.curSchedGroup; 13795 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v(TAG, 13796 "Setting process group of " + app.processName 13797 + " to " + app.curSchedGroup); 13798 if (true) { 13799 long oldId = Binder.clearCallingIdentity(); 13800 try { 13801 Process.setProcessGroup(app.pid, app.curSchedGroup); 13802 } catch (Exception e) { 13803 Log.w(TAG, "Failed setting process group of " + app.pid 13804 + " to " + app.curSchedGroup); 13805 e.printStackTrace(); 13806 } finally { 13807 Binder.restoreCallingIdentity(oldId); 13808 } 13809 } 13810 if (false) { 13811 if (app.thread != null) { 13812 try { 13813 app.thread.setSchedulingGroup(app.curSchedGroup); 13814 } catch (RemoteException e) { 13815 } 13816 } 13817 } 13818 } 13819 } 13820 13821 return true; 13822 } 13823 13824 private final HistoryRecord resumedAppLocked() { 13825 HistoryRecord resumedActivity = mResumedActivity; 13826 if (resumedActivity == null || resumedActivity.app == null) { 13827 resumedActivity = mPausingActivity; 13828 if (resumedActivity == null || resumedActivity.app == null) { 13829 resumedActivity = topRunningActivityLocked(null); 13830 } 13831 } 13832 return resumedActivity; 13833 } 13834 13835 private final boolean updateOomAdjLocked(ProcessRecord app) { 13836 final HistoryRecord TOP_ACT = resumedAppLocked(); 13837 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13838 int curAdj = app.curAdj; 13839 final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ 13840 && app.curAdj <= HIDDEN_APP_MAX_ADJ; 13841 13842 mAdjSeq++; 13843 13844 final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP); 13845 if (res) { 13846 final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ 13847 && app.curAdj <= HIDDEN_APP_MAX_ADJ; 13848 if (nowHidden != wasHidden) { 13849 // Changed to/from hidden state, so apps after it in the LRU 13850 // list may also be changed. 13851 updateOomAdjLocked(); 13852 } 13853 } 13854 return res; 13855 } 13856 13857 private final boolean updateOomAdjLocked() { 13858 boolean didOomAdj = true; 13859 final HistoryRecord TOP_ACT = resumedAppLocked(); 13860 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13861 13862 if (false) { 13863 RuntimeException e = new RuntimeException(); 13864 e.fillInStackTrace(); 13865 Log.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13866 } 13867 13868 mAdjSeq++; 13869 13870 // First try updating the OOM adjustment for each of the 13871 // application processes based on their current state. 13872 int i = mLruProcesses.size(); 13873 int curHiddenAdj = HIDDEN_APP_MIN_ADJ; 13874 while (i > 0) { 13875 i--; 13876 ProcessRecord app = mLruProcesses.get(i); 13877 //Log.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13878 if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) { 13879 if (curHiddenAdj < EMPTY_APP_ADJ 13880 && app.curAdj == curHiddenAdj) { 13881 curHiddenAdj++; 13882 } 13883 } else { 13884 didOomAdj = false; 13885 } 13886 } 13887 13888 // If we return false, we will fall back on killing processes to 13889 // have a fixed limit. Do this if a limit has been requested; else 13890 // only return false if one of the adjustments failed. 13891 return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj; 13892 } 13893 13894 private final void trimApplications() { 13895 synchronized (this) { 13896 int i; 13897 13898 // First remove any unused application processes whose package 13899 // has been removed. 13900 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13901 final ProcessRecord app = mRemovedProcesses.get(i); 13902 if (app.activities.size() == 0 13903 && app.curReceiver == null && app.services.size() == 0) { 13904 Log.i( 13905 TAG, "Exiting empty application process " 13906 + app.processName + " (" 13907 + (app.thread != null ? app.thread.asBinder() : null) 13908 + ")\n"); 13909 if (app.pid > 0 && app.pid != MY_PID) { 13910 Process.killProcess(app.pid); 13911 } else { 13912 try { 13913 app.thread.scheduleExit(); 13914 } catch (Exception e) { 13915 // Ignore exceptions. 13916 } 13917 } 13918 cleanUpApplicationRecordLocked(app, false, -1); 13919 mRemovedProcesses.remove(i); 13920 13921 if (app.persistent) { 13922 if (app.persistent) { 13923 addAppLocked(app.info); 13924 } 13925 } 13926 } 13927 } 13928 13929 // Now try updating the OOM adjustment for each of the 13930 // application processes based on their current state. 13931 // If the setOomAdj() API is not supported, then go with our 13932 // back-up plan... 13933 if (!updateOomAdjLocked()) { 13934 13935 // Count how many processes are running services. 13936 int numServiceProcs = 0; 13937 for (i=mLruProcesses.size()-1; i>=0; i--) { 13938 final ProcessRecord app = mLruProcesses.get(i); 13939 13940 if (app.persistent || app.services.size() != 0 13941 || app.curReceiver != null 13942 || app.persistentActivities > 0) { 13943 // Don't count processes holding services against our 13944 // maximum process count. 13945 if (localLOGV) Log.v( 13946 TAG, "Not trimming app " + app + " with services: " 13947 + app.services); 13948 numServiceProcs++; 13949 } 13950 } 13951 13952 int curMaxProcs = mProcessLimit; 13953 if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES; 13954 if (mAlwaysFinishActivities) { 13955 curMaxProcs = 1; 13956 } 13957 curMaxProcs += numServiceProcs; 13958 13959 // Quit as many processes as we can to get down to the desired 13960 // process count. First remove any processes that no longer 13961 // have activites running in them. 13962 for ( i=0; 13963 i<mLruProcesses.size() 13964 && mLruProcesses.size() > curMaxProcs; 13965 i++) { 13966 final ProcessRecord app = mLruProcesses.get(i); 13967 // Quit an application only if it is not currently 13968 // running any activities. 13969 if (!app.persistent && app.activities.size() == 0 13970 && app.curReceiver == null && app.services.size() == 0) { 13971 Log.i( 13972 TAG, "Exiting empty application process " 13973 + app.processName + " (" 13974 + (app.thread != null ? app.thread.asBinder() : null) 13975 + ")\n"); 13976 if (app.pid > 0 && app.pid != MY_PID) { 13977 Process.killProcess(app.pid); 13978 } else { 13979 try { 13980 app.thread.scheduleExit(); 13981 } catch (Exception e) { 13982 // Ignore exceptions. 13983 } 13984 } 13985 // todo: For now we assume the application is not buggy 13986 // or evil, and will quit as a result of our request. 13987 // Eventually we need to drive this off of the death 13988 // notification, and kill the process if it takes too long. 13989 cleanUpApplicationRecordLocked(app, false, i); 13990 i--; 13991 } 13992 } 13993 13994 // If we still have too many processes, now from the least 13995 // recently used process we start finishing activities. 13996 if (Config.LOGV) Log.v( 13997 TAG, "*** NOW HAVE " + mLruProcesses.size() + 13998 " of " + curMaxProcs + " processes"); 13999 for ( i=0; 14000 i<mLruProcesses.size() 14001 && mLruProcesses.size() > curMaxProcs; 14002 i++) { 14003 final ProcessRecord app = mLruProcesses.get(i); 14004 // Quit the application only if we have a state saved for 14005 // all of its activities. 14006 boolean canQuit = !app.persistent && app.curReceiver == null 14007 && app.services.size() == 0 14008 && app.persistentActivities == 0; 14009 int NUMA = app.activities.size(); 14010 int j; 14011 if (Config.LOGV) Log.v( 14012 TAG, "Looking to quit " + app.processName); 14013 for (j=0; j<NUMA && canQuit; j++) { 14014 HistoryRecord r = (HistoryRecord)app.activities.get(j); 14015 if (Config.LOGV) Log.v( 14016 TAG, " " + r.intent.getComponent().flattenToShortString() 14017 + ": frozen=" + r.haveState + ", visible=" + r.visible); 14018 canQuit = (r.haveState || !r.stateNotNeeded) 14019 && !r.visible && r.stopped; 14020 } 14021 if (canQuit) { 14022 // Finish all of the activities, and then the app itself. 14023 for (j=0; j<NUMA; j++) { 14024 HistoryRecord r = (HistoryRecord)app.activities.get(j); 14025 if (!r.finishing) { 14026 destroyActivityLocked(r, false); 14027 } 14028 r.resultTo = null; 14029 } 14030 Log.i(TAG, "Exiting application process " 14031 + app.processName + " (" 14032 + (app.thread != null ? app.thread.asBinder() : null) 14033 + ")\n"); 14034 if (app.pid > 0 && app.pid != MY_PID) { 14035 Process.killProcess(app.pid); 14036 } else { 14037 try { 14038 app.thread.scheduleExit(); 14039 } catch (Exception e) { 14040 // Ignore exceptions. 14041 } 14042 } 14043 // todo: For now we assume the application is not buggy 14044 // or evil, and will quit as a result of our request. 14045 // Eventually we need to drive this off of the death 14046 // notification, and kill the process if it takes too long. 14047 cleanUpApplicationRecordLocked(app, false, i); 14048 i--; 14049 //dump(); 14050 } 14051 } 14052 14053 } 14054 14055 int curMaxActivities = MAX_ACTIVITIES; 14056 if (mAlwaysFinishActivities) { 14057 curMaxActivities = 1; 14058 } 14059 14060 // Finally, if there are too many activities now running, try to 14061 // finish as many as we can to get back down to the limit. 14062 for ( i=0; 14063 i<mLRUActivities.size() 14064 && mLRUActivities.size() > curMaxActivities; 14065 i++) { 14066 final HistoryRecord r 14067 = (HistoryRecord)mLRUActivities.get(i); 14068 14069 // We can finish this one if we have its icicle saved and 14070 // it is not persistent. 14071 if ((r.haveState || !r.stateNotNeeded) && !r.visible 14072 && r.stopped && !r.persistent && !r.finishing) { 14073 final int origSize = mLRUActivities.size(); 14074 destroyActivityLocked(r, true); 14075 14076 // This will remove it from the LRU list, so keep 14077 // our index at the same value. Note that this check to 14078 // see if the size changes is just paranoia -- if 14079 // something unexpected happens, we don't want to end up 14080 // in an infinite loop. 14081 if (origSize > mLRUActivities.size()) { 14082 i--; 14083 } 14084 } 14085 } 14086 } 14087 } 14088 14089 /** This method sends the specified signal to each of the persistent apps */ 14090 public void signalPersistentProcesses(int sig) throws RemoteException { 14091 if (sig != Process.SIGNAL_USR1) { 14092 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 14093 } 14094 14095 synchronized (this) { 14096 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 14097 != PackageManager.PERMISSION_GRANTED) { 14098 throw new SecurityException("Requires permission " 14099 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 14100 } 14101 14102 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 14103 ProcessRecord r = mLruProcesses.get(i); 14104 if (r.thread != null && r.persistent) { 14105 Process.sendSignal(r.pid, sig); 14106 } 14107 } 14108 } 14109 } 14110 14111 public boolean profileControl(String process, boolean start, 14112 String path, ParcelFileDescriptor fd) throws RemoteException { 14113 14114 try { 14115 synchronized (this) { 14116 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 14117 // its own permission. 14118 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 14119 != PackageManager.PERMISSION_GRANTED) { 14120 throw new SecurityException("Requires permission " 14121 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 14122 } 14123 14124 if (start && fd == null) { 14125 throw new IllegalArgumentException("null fd"); 14126 } 14127 14128 ProcessRecord proc = null; 14129 try { 14130 int pid = Integer.parseInt(process); 14131 synchronized (mPidsSelfLocked) { 14132 proc = mPidsSelfLocked.get(pid); 14133 } 14134 } catch (NumberFormatException e) { 14135 } 14136 14137 if (proc == null) { 14138 HashMap<String, SparseArray<ProcessRecord>> all 14139 = mProcessNames.getMap(); 14140 SparseArray<ProcessRecord> procs = all.get(process); 14141 if (procs != null && procs.size() > 0) { 14142 proc = procs.valueAt(0); 14143 } 14144 } 14145 14146 if (proc == null || proc.thread == null) { 14147 throw new IllegalArgumentException("Unknown process: " + process); 14148 } 14149 14150 boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0")); 14151 if (isSecure) { 14152 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 14153 throw new SecurityException("Process not debuggable: " + proc); 14154 } 14155 } 14156 14157 proc.thread.profilerControl(start, path, fd); 14158 fd = null; 14159 return true; 14160 } 14161 } catch (RemoteException e) { 14162 throw new IllegalStateException("Process disappeared"); 14163 } finally { 14164 if (fd != null) { 14165 try { 14166 fd.close(); 14167 } catch (IOException e) { 14168 } 14169 } 14170 } 14171 } 14172 14173 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 14174 public void monitor() { 14175 synchronized (this) { } 14176 } 14177} 14178