ActivityManagerService.java revision c9568e3989f1491abaa7960eca986af12743cb05
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 android.app.Activity; 29import android.app.ActivityManager; 30import android.app.ActivityManagerNative; 31import android.app.ActivityThread; 32import android.app.AlertDialog; 33import android.app.ApplicationErrorReport; 34import android.app.Dialog; 35import android.app.IActivityController; 36import android.app.IActivityWatcher; 37import android.app.IApplicationThread; 38import android.app.IInstrumentationWatcher; 39import android.app.IServiceConnection; 40import android.app.IThumbnailReceiver; 41import android.app.Instrumentation; 42import android.app.Notification; 43import android.app.PendingIntent; 44import android.app.ResultInfo; 45import android.app.Service; 46import android.backup.IBackupManager; 47import android.content.ActivityNotFoundException; 48import android.content.ComponentName; 49import android.content.ContentResolver; 50import android.content.Context; 51import android.content.Intent; 52import android.content.IntentFilter; 53import android.content.IIntentReceiver; 54import android.content.IIntentSender; 55import android.content.IntentSender; 56import android.content.pm.ActivityInfo; 57import android.content.pm.ApplicationInfo; 58import android.content.pm.ConfigurationInfo; 59import android.content.pm.IPackageDataObserver; 60import android.content.pm.IPackageManager; 61import android.content.pm.InstrumentationInfo; 62import android.content.pm.PackageManager; 63import android.content.pm.PathPermission; 64import android.content.pm.ProviderInfo; 65import android.content.pm.ResolveInfo; 66import android.content.pm.ServiceInfo; 67import android.content.res.Configuration; 68import android.graphics.Bitmap; 69import android.net.Uri; 70import android.os.Binder; 71import android.os.Bundle; 72import android.os.Debug; 73import android.os.Environment; 74import android.os.FileUtils; 75import android.os.Handler; 76import android.os.IBinder; 77import android.os.IPermissionController; 78import android.os.Looper; 79import android.os.Message; 80import android.os.Parcel; 81import android.os.ParcelFileDescriptor; 82import android.os.PowerManager; 83import android.os.Process; 84import android.os.RemoteCallbackList; 85import android.os.RemoteException; 86import android.os.ServiceManager; 87import android.os.SystemClock; 88import android.os.SystemProperties; 89import android.provider.Checkin; 90import android.provider.Settings; 91import android.server.data.CrashData; 92import android.server.data.StackTraceElementData; 93import android.server.data.ThrowableData; 94import android.text.TextUtils; 95import android.util.Config; 96import android.util.EventLog; 97import android.util.Log; 98import android.util.PrintWriterPrinter; 99import android.util.SparseArray; 100import android.view.Gravity; 101import android.view.LayoutInflater; 102import android.view.View; 103import android.view.WindowManager; 104import android.view.WindowManagerPolicy; 105 106import dalvik.system.Zygote; 107 108import java.io.ByteArrayInputStream; 109import java.io.DataInputStream; 110import java.io.File; 111import java.io.FileDescriptor; 112import java.io.FileInputStream; 113import java.io.FileNotFoundException; 114import java.io.IOException; 115import java.io.PrintWriter; 116import java.lang.IllegalStateException; 117import java.lang.ref.WeakReference; 118import java.util.ArrayList; 119import java.util.HashMap; 120import java.util.HashSet; 121import java.util.Iterator; 122import java.util.List; 123import java.util.Locale; 124import java.util.Map; 125 126public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor { 127 static final String TAG = "ActivityManager"; 128 static final boolean DEBUG = false; 129 static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV; 130 static final boolean DEBUG_SWITCH = localLOGV || false; 131 static final boolean DEBUG_TASKS = localLOGV || false; 132 static final boolean DEBUG_PAUSE = localLOGV || false; 133 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 134 static final boolean DEBUG_TRANSITION = localLOGV || false; 135 static final boolean DEBUG_BROADCAST = localLOGV || false; 136 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 137 static final boolean DEBUG_SERVICE = localLOGV || false; 138 static final boolean DEBUG_VISBILITY = localLOGV || false; 139 static final boolean DEBUG_PROCESSES = localLOGV || false; 140 static final boolean DEBUG_PROVIDER = localLOGV || false; 141 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 142 static final boolean DEBUG_RESULTS = localLOGV || false; 143 static final boolean DEBUG_BACKUP = localLOGV || false; 144 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 145 static final boolean VALIDATE_TOKENS = false; 146 static final boolean SHOW_ACTIVITY_START_TIME = true; 147 148 // Control over CPU and battery monitoring. 149 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 150 static final boolean MONITOR_CPU_USAGE = true; 151 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 152 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 153 static final boolean MONITOR_THREAD_CPU_USAGE = false; 154 155 // Event log tags 156 static final int LOG_CONFIGURATION_CHANGED = 2719; 157 static final int LOG_CPU = 2721; 158 static final int LOG_AM_FINISH_ACTIVITY = 30001; 159 static final int LOG_TASK_TO_FRONT = 30002; 160 static final int LOG_AM_NEW_INTENT = 30003; 161 static final int LOG_AM_CREATE_TASK = 30004; 162 static final int LOG_AM_CREATE_ACTIVITY = 30005; 163 static final int LOG_AM_RESTART_ACTIVITY = 30006; 164 static final int LOG_AM_RESUME_ACTIVITY = 30007; 165 static final int LOG_ANR = 30008; 166 static final int LOG_ACTIVITY_LAUNCH_TIME = 30009; 167 static final int LOG_AM_PROCESS_BOUND = 30010; 168 static final int LOG_AM_PROCESS_DIED = 30011; 169 static final int LOG_AM_FAILED_TO_PAUSE_ACTIVITY = 30012; 170 static final int LOG_AM_PAUSE_ACTIVITY = 30013; 171 static final int LOG_AM_PROCESS_START = 30014; 172 static final int LOG_AM_PROCESS_BAD = 30015; 173 static final int LOG_AM_PROCESS_GOOD = 30016; 174 static final int LOG_AM_LOW_MEMORY = 30017; 175 static final int LOG_AM_DESTROY_ACTIVITY = 30018; 176 static final int LOG_AM_RELAUNCH_RESUME_ACTIVITY = 30019; 177 static final int LOG_AM_RELAUNCH_ACTIVITY = 30020; 178 static final int LOG_AM_KILL_FOR_MEMORY = 30023; 179 static final int LOG_AM_BROADCAST_DISCARD_FILTER = 30024; 180 static final int LOG_AM_BROADCAST_DISCARD_APP = 30025; 181 static final int LOG_AM_CREATE_SERVICE = 30030; 182 static final int LOG_AM_DESTROY_SERVICE = 30031; 183 static final int LOG_AM_PROCESS_CRASHED_TOO_MUCH = 30032; 184 static final int LOG_AM_DROP_PROCESS = 30033; 185 static final int LOG_AM_SERVICE_CRASHED_TOO_MUCH = 30034; 186 static final int LOG_AM_SCHEDULE_SERVICE_RESTART = 30035; 187 static final int LOG_AM_PROVIDER_LOST_PROCESS = 30036; 188 189 static final int LOG_BOOT_PROGRESS_AMS_READY = 3040; 190 static final int LOG_BOOT_PROGRESS_ENABLE_SCREEN = 3050; 191 192 // The flags that are set for all calls we make to the package manager. 193 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 194 195 private static final String SYSTEM_SECURE = "ro.secure"; 196 197 // This is the maximum number of application processes we would like 198 // to have running. Due to the asynchronous nature of things, we can 199 // temporarily go beyond this limit. 200 static final int MAX_PROCESSES = 2; 201 202 // Set to false to leave processes running indefinitely, relying on 203 // the kernel killing them as resources are required. 204 static final boolean ENFORCE_PROCESS_LIMIT = false; 205 206 // This is the maximum number of activities that we would like to have 207 // running at a given time. 208 static final int MAX_ACTIVITIES = 20; 209 210 // Maximum number of recent tasks that we can remember. 211 static final int MAX_RECENT_TASKS = 20; 212 213 // Amount of time after a call to stopAppSwitches() during which we will 214 // prevent further untrusted switches from happening. 215 static final long APP_SWITCH_DELAY_TIME = 5*1000; 216 217 // How long until we reset a task when the user returns to it. Currently 218 // 30 minutes. 219 static final long ACTIVITY_INACTIVE_RESET_TIME = 1000*60*30; 220 221 // Set to true to disable the icon that is shown while a new activity 222 // is being started. 223 static final boolean SHOW_APP_STARTING_ICON = true; 224 225 // How long we wait until giving up on the last activity to pause. This 226 // is short because it directly impacts the responsiveness of starting the 227 // next activity. 228 static final int PAUSE_TIMEOUT = 500; 229 230 /** 231 * How long we can hold the launch wake lock before giving up. 232 */ 233 static final int LAUNCH_TIMEOUT = 10*1000; 234 235 // How long we wait for a launched process to attach to the activity manager 236 // before we decide it's never going to come up for real. 237 static final int PROC_START_TIMEOUT = 10*1000; 238 239 // How long we wait until giving up on the last activity telling us it 240 // is idle. 241 static final int IDLE_TIMEOUT = 10*1000; 242 243 // How long to wait after going idle before forcing apps to GC. 244 static final int GC_TIMEOUT = 5*1000; 245 246 // The minimum amount of time between successive GC requests for a process. 247 static final int GC_MIN_INTERVAL = 60*1000; 248 249 // How long we wait until giving up on an activity telling us it has 250 // finished destroying itself. 251 static final int DESTROY_TIMEOUT = 10*1000; 252 253 // How long we allow a receiver to run before giving up on it. 254 static final int BROADCAST_TIMEOUT = 10*1000; 255 256 // How long we wait for a service to finish executing. 257 static final int SERVICE_TIMEOUT = 20*1000; 258 259 // How long a service needs to be running until restarting its process 260 // is no longer considered to be a relaunch of the service. 261 static final int SERVICE_RESTART_DURATION = 5*1000; 262 263 // How long a service needs to be running until it will start back at 264 // SERVICE_RESTART_DURATION after being killed. 265 static final int SERVICE_RESET_RUN_DURATION = 60*1000; 266 267 // Multiplying factor to increase restart duration time by, for each time 268 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION. 269 static final int SERVICE_RESTART_DURATION_FACTOR = 4; 270 271 // The minimum amount of time between restarting services that we allow. 272 // That is, when multiple services are restarting, we won't allow each 273 // to restart less than this amount of time from the last one. 274 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000; 275 276 // Maximum amount of time for there to be no activity on a service before 277 // we consider it non-essential and allow its process to go on the 278 // LRU background list. 279 static final int MAX_SERVICE_INACTIVITY = 30*60*1000; 280 281 // How long we wait until we timeout on key dispatching. 282 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 283 284 // The minimum time we allow between crashes, for us to consider this 285 // application to be bad and stop and its services and reject broadcasts. 286 static final int MIN_CRASH_INTERVAL = 60*1000; 287 288 // How long we wait until we timeout on key dispatching during instrumentation. 289 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 290 291 // OOM adjustments for processes in various states: 292 293 // This is a process without anything currently running in it. Definitely 294 // the first to go! Value set in system/rootdir/init.rc on startup. 295 // This value is initalized in the constructor, careful when refering to 296 // this static variable externally. 297 static int EMPTY_APP_ADJ; 298 299 // This is a process with a content provider that does not have any clients 300 // attached to it. If it did have any clients, its adjustment would be the 301 // one for the highest-priority of those processes. 302 static int CONTENT_PROVIDER_ADJ; 303 304 // This is a process only hosting activities that are not visible, 305 // so it can be killed without any disruption. Value set in 306 // system/rootdir/init.rc on startup. 307 final int HIDDEN_APP_MAX_ADJ; 308 static int HIDDEN_APP_MIN_ADJ; 309 310 // This is a process holding the home application -- we want to try 311 // avoiding killing it, even if it would normally be in the background, 312 // because the user interacts with it so much. 313 final int HOME_APP_ADJ; 314 315 // This is a process currently hosting a backup operation. Killing it 316 // is not entirely fatal but is generally a bad idea. 317 final int BACKUP_APP_ADJ; 318 319 // This is a process holding a secondary server -- killing it will not 320 // have much of an impact as far as the user is concerned. Value set in 321 // system/rootdir/init.rc on startup. 322 final int SECONDARY_SERVER_ADJ; 323 324 // This is a process only hosting activities that are visible to the 325 // user, so we'd prefer they don't disappear. Value set in 326 // system/rootdir/init.rc on startup. 327 final int VISIBLE_APP_ADJ; 328 329 // This is the process running the current foreground app. We'd really 330 // rather not kill it! Value set in system/rootdir/init.rc on startup. 331 final int FOREGROUND_APP_ADJ; 332 333 // This is a process running a core server, such as telephony. Definitely 334 // don't want to kill it, but doing so is not completely fatal. 335 static final int CORE_SERVER_ADJ = -12; 336 337 // The system process runs at the default adjustment. 338 static final int SYSTEM_ADJ = -16; 339 340 // Memory pages are 4K. 341 static final int PAGE_SIZE = 4*1024; 342 343 // System property defining error report receiver for system apps 344 static final String SYSTEM_APPS_ERROR_RECEIVER_PROPERTY = "ro.error.receiver.system.apps"; 345 346 // System property defining default error report receiver 347 static final String DEFAULT_ERROR_RECEIVER_PROPERTY = "ro.error.receiver.default"; 348 349 // Corresponding memory levels for above adjustments. 350 final int EMPTY_APP_MEM; 351 final int HIDDEN_APP_MEM; 352 final int HOME_APP_MEM; 353 final int BACKUP_APP_MEM; 354 final int SECONDARY_SERVER_MEM; 355 final int VISIBLE_APP_MEM; 356 final int FOREGROUND_APP_MEM; 357 358 final int MY_PID; 359 360 static final String[] EMPTY_STRING_ARRAY = new String[0]; 361 362 enum ActivityState { 363 INITIALIZING, 364 RESUMED, 365 PAUSING, 366 PAUSED, 367 STOPPING, 368 STOPPED, 369 FINISHING, 370 DESTROYING, 371 DESTROYED 372 } 373 374 /** 375 * The back history of all previous (and possibly still 376 * running) activities. It contains HistoryRecord objects. 377 */ 378 final ArrayList mHistory = new ArrayList(); 379 380 /** 381 * Description of a request to start a new activity, which has been held 382 * due to app switches being disabled. 383 */ 384 class PendingActivityLaunch { 385 HistoryRecord r; 386 HistoryRecord sourceRecord; 387 Uri[] grantedUriPermissions; 388 int grantedMode; 389 boolean onlyIfNeeded; 390 } 391 392 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 393 = new ArrayList<PendingActivityLaunch>(); 394 395 /** 396 * List of all active broadcasts that are to be executed immediately 397 * (without waiting for another broadcast to finish). Currently this only 398 * contains broadcasts to registered receivers, to avoid spinning up 399 * a bunch of processes to execute IntentReceiver components. 400 */ 401 final ArrayList<BroadcastRecord> mParallelBroadcasts 402 = new ArrayList<BroadcastRecord>(); 403 404 /** 405 * List of all active broadcasts that are to be executed one at a time. 406 * The object at the top of the list is the currently activity broadcasts; 407 * those after it are waiting for the top to finish.. 408 */ 409 final ArrayList<BroadcastRecord> mOrderedBroadcasts 410 = new ArrayList<BroadcastRecord>(); 411 412 /** 413 * Set when we current have a BROADCAST_INTENT_MSG in flight. 414 */ 415 boolean mBroadcastsScheduled = false; 416 417 /** 418 * Set to indicate whether to issue an onUserLeaving callback when a 419 * newly launched activity is being brought in front of us. 420 */ 421 boolean mUserLeaving = false; 422 423 /** 424 * When we are in the process of pausing an activity, before starting the 425 * next one, this variable holds the activity that is currently being paused. 426 */ 427 HistoryRecord mPausingActivity = null; 428 429 /** 430 * Current activity that is resumed, or null if there is none. 431 */ 432 HistoryRecord mResumedActivity = null; 433 434 /** 435 * Activity we have told the window manager to have key focus. 436 */ 437 HistoryRecord mFocusedActivity = null; 438 439 /** 440 * This is the last activity that we put into the paused state. This is 441 * used to determine if we need to do an activity transition while sleeping, 442 * when we normally hold the top activity paused. 443 */ 444 HistoryRecord mLastPausedActivity = null; 445 446 /** 447 * List of activities that are waiting for a new activity 448 * to become visible before completing whatever operation they are 449 * supposed to do. 450 */ 451 final ArrayList mWaitingVisibleActivities = new ArrayList(); 452 453 /** 454 * List of activities that are ready to be stopped, but waiting 455 * for the next activity to settle down before doing so. It contains 456 * HistoryRecord objects. 457 */ 458 final ArrayList<HistoryRecord> mStoppingActivities 459 = new ArrayList<HistoryRecord>(); 460 461 /** 462 * Animations that for the current transition have requested not to 463 * be considered for the transition animation. 464 */ 465 final ArrayList<HistoryRecord> mNoAnimActivities 466 = new ArrayList<HistoryRecord>(); 467 468 /** 469 * List of intents that were used to start the most recent tasks. 470 */ 471 final ArrayList<TaskRecord> mRecentTasks 472 = new ArrayList<TaskRecord>(); 473 474 /** 475 * List of activities that are ready to be finished, but waiting 476 * for the previous activity to settle down before doing so. It contains 477 * HistoryRecord objects. 478 */ 479 final ArrayList mFinishingActivities = new ArrayList(); 480 481 /** 482 * All of the applications we currently have running organized by name. 483 * The keys are strings of the application package name (as 484 * returned by the package manager), and the keys are ApplicationRecord 485 * objects. 486 */ 487 final ProcessMap<ProcessRecord> mProcessNames 488 = new ProcessMap<ProcessRecord>(); 489 490 /** 491 * The last time that various processes have crashed. 492 */ 493 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 494 495 /** 496 * Set of applications that we consider to be bad, and will reject 497 * incoming broadcasts from (which the user has no control over). 498 * Processes are added to this set when they have crashed twice within 499 * a minimum amount of time; they are removed from it when they are 500 * later restarted (hopefully due to some user action). The value is the 501 * time it was added to the list. 502 */ 503 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 504 505 /** 506 * All of the processes we currently have running organized by pid. 507 * The keys are the pid running the application. 508 * 509 * <p>NOTE: This object is protected by its own lock, NOT the global 510 * activity manager lock! 511 */ 512 final SparseArray<ProcessRecord> mPidsSelfLocked 513 = new SparseArray<ProcessRecord>(); 514 515 /** 516 * All of the processes that have been forced to be foreground. The key 517 * is the pid of the caller who requested it (we hold a death 518 * link on it). 519 */ 520 abstract class ForegroundToken implements IBinder.DeathRecipient { 521 int pid; 522 IBinder token; 523 } 524 final SparseArray<ForegroundToken> mForegroundProcesses 525 = new SparseArray<ForegroundToken>(); 526 527 /** 528 * List of records for processes that someone had tried to start before the 529 * system was ready. We don't start them at that point, but ensure they 530 * are started by the time booting is complete. 531 */ 532 final ArrayList<ProcessRecord> mProcessesOnHold 533 = new ArrayList<ProcessRecord>(); 534 535 /** 536 * List of records for processes that we have started and are waiting 537 * for them to call back. This is really only needed when running in 538 * single processes mode, in which case we do not have a unique pid for 539 * each process. 540 */ 541 final ArrayList<ProcessRecord> mStartingProcesses 542 = new ArrayList<ProcessRecord>(); 543 544 /** 545 * List of persistent applications that are in the process 546 * of being started. 547 */ 548 final ArrayList<ProcessRecord> mPersistentStartingProcesses 549 = new ArrayList<ProcessRecord>(); 550 551 /** 552 * Processes that are being forcibly torn down. 553 */ 554 final ArrayList<ProcessRecord> mRemovedProcesses 555 = new ArrayList<ProcessRecord>(); 556 557 /** 558 * List of running applications, sorted by recent usage. 559 * The first entry in the list is the least recently used. 560 * It contains ApplicationRecord objects. This list does NOT include 561 * any persistent application records (since we never want to exit them). 562 */ 563 final ArrayList<ProcessRecord> mLRUProcesses 564 = new ArrayList<ProcessRecord>(); 565 566 /** 567 * List of processes that should gc as soon as things are idle. 568 */ 569 final ArrayList<ProcessRecord> mProcessesToGc 570 = new ArrayList<ProcessRecord>(); 571 572 /** 573 * This is the process holding what we currently consider to be 574 * the "home" activity. 575 */ 576 private ProcessRecord mHomeProcess; 577 578 /** 579 * List of running activities, sorted by recent usage. 580 * The first entry in the list is the least recently used. 581 * It contains HistoryRecord objects. 582 */ 583 private final ArrayList mLRUActivities = new ArrayList(); 584 585 /** 586 * Set of PendingResultRecord objects that are currently active. 587 */ 588 final HashSet mPendingResultRecords = new HashSet(); 589 590 /** 591 * Set of IntentSenderRecord objects that are currently active. 592 */ 593 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 594 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 595 596 /** 597 * Intent broadcast that we have tried to start, but are 598 * waiting for its application's process to be created. We only 599 * need one (instead of a list) because we always process broadcasts 600 * one at a time, so no others can be started while waiting for this 601 * one. 602 */ 603 BroadcastRecord mPendingBroadcast = null; 604 605 /** 606 * Keeps track of all IIntentReceivers that have been registered for 607 * broadcasts. Hash keys are the receiver IBinder, hash value is 608 * a ReceiverList. 609 */ 610 final HashMap mRegisteredReceivers = new HashMap(); 611 612 /** 613 * Resolver for broadcast intents to registered receivers. 614 * Holds BroadcastFilter (subclass of IntentFilter). 615 */ 616 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 617 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 618 @Override 619 protected boolean allowFilterResult( 620 BroadcastFilter filter, List<BroadcastFilter> dest) { 621 IBinder target = filter.receiverList.receiver.asBinder(); 622 for (int i=dest.size()-1; i>=0; i--) { 623 if (dest.get(i).receiverList.receiver.asBinder() == target) { 624 return false; 625 } 626 } 627 return true; 628 } 629 }; 630 631 /** 632 * State of all active sticky broadcasts. Keys are the action of the 633 * sticky Intent, values are an ArrayList of all broadcasted intents with 634 * that action (which should usually be one). 635 */ 636 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts = 637 new HashMap<String, ArrayList<Intent>>(); 638 639 /** 640 * All currently running services. 641 */ 642 final HashMap<ComponentName, ServiceRecord> mServices = 643 new HashMap<ComponentName, ServiceRecord>(); 644 645 /** 646 * All currently running services indexed by the Intent used to start them. 647 */ 648 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent = 649 new HashMap<Intent.FilterComparison, ServiceRecord>(); 650 651 /** 652 * All currently bound service connections. Keys are the IBinder of 653 * the client's IServiceConnection. 654 */ 655 final HashMap<IBinder, ConnectionRecord> mServiceConnections 656 = new HashMap<IBinder, ConnectionRecord>(); 657 658 /** 659 * List of services that we have been asked to start, 660 * but haven't yet been able to. It is used to hold start requests 661 * while waiting for their corresponding application thread to get 662 * going. 663 */ 664 final ArrayList<ServiceRecord> mPendingServices 665 = new ArrayList<ServiceRecord>(); 666 667 /** 668 * List of services that are scheduled to restart following a crash. 669 */ 670 final ArrayList<ServiceRecord> mRestartingServices 671 = new ArrayList<ServiceRecord>(); 672 673 /** 674 * List of services that are in the process of being stopped. 675 */ 676 final ArrayList<ServiceRecord> mStoppingServices 677 = new ArrayList<ServiceRecord>(); 678 679 /** 680 * Backup/restore process management 681 */ 682 String mBackupAppName = null; 683 BackupRecord mBackupTarget = null; 684 685 /** 686 * List of PendingThumbnailsRecord objects of clients who are still 687 * waiting to receive all of the thumbnails for a task. 688 */ 689 final ArrayList mPendingThumbnails = new ArrayList(); 690 691 /** 692 * List of HistoryRecord objects that have been finished and must 693 * still report back to a pending thumbnail receiver. 694 */ 695 final ArrayList mCancelledThumbnails = new ArrayList(); 696 697 /** 698 * All of the currently running global content providers. Keys are a 699 * string containing the provider name and values are a 700 * ContentProviderRecord object containing the data about it. Note 701 * that a single provider may be published under multiple names, so 702 * there may be multiple entries here for a single one in mProvidersByClass. 703 */ 704 final HashMap mProvidersByName = new HashMap(); 705 706 /** 707 * All of the currently running global content providers. Keys are a 708 * string containing the provider's implementation class and values are a 709 * ContentProviderRecord object containing the data about it. 710 */ 711 final HashMap mProvidersByClass = new HashMap(); 712 713 /** 714 * List of content providers who have clients waiting for them. The 715 * application is currently being launched and the provider will be 716 * removed from this list once it is published. 717 */ 718 final ArrayList mLaunchingProviders = new ArrayList(); 719 720 /** 721 * Global set of specific Uri permissions that have been granted. 722 */ 723 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 724 = new SparseArray<HashMap<Uri, UriPermission>>(); 725 726 /** 727 * Thread-local storage used to carry caller permissions over through 728 * indirect content-provider access. 729 * @see #ActivityManagerService.openContentUri() 730 */ 731 private class Identity { 732 public int pid; 733 public int uid; 734 735 Identity(int _pid, int _uid) { 736 pid = _pid; 737 uid = _uid; 738 } 739 } 740 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 741 742 /** 743 * All information we have collected about the runtime performance of 744 * any user id that can impact battery performance. 745 */ 746 final BatteryStatsService mBatteryStatsService; 747 748 /** 749 * information about component usage 750 */ 751 final UsageStatsService mUsageStatsService; 752 753 /** 754 * Current configuration information. HistoryRecord objects are given 755 * a reference to this object to indicate which configuration they are 756 * currently running in, so this object must be kept immutable. 757 */ 758 Configuration mConfiguration = new Configuration(); 759 760 /** 761 * Hardware-reported OpenGLES version. 762 */ 763 final int GL_ES_VERSION; 764 765 /** 766 * List of initialization arguments to pass to all processes when binding applications to them. 767 * For example, references to the commonly used services. 768 */ 769 HashMap<String, IBinder> mAppBindArgs; 770 771 /** 772 * Temporary to avoid allocations. Protected by main lock. 773 */ 774 final StringBuilder mStringBuilder = new StringBuilder(256); 775 776 /** 777 * Used to control how we initialize the service. 778 */ 779 boolean mStartRunning = false; 780 ComponentName mTopComponent; 781 String mTopAction; 782 String mTopData; 783 boolean mSystemReady = false; 784 boolean mBooting = false; 785 boolean mWaitingUpdate = false; 786 boolean mDidUpdate = false; 787 788 Context mContext; 789 790 int mFactoryTest; 791 792 boolean mCheckedForSetup; 793 794 /** 795 * The time at which we will allow normal application switches again, 796 * after a call to {@link #stopAppSwitches()}. 797 */ 798 long mAppSwitchesAllowedTime; 799 800 /** 801 * This is set to true after the first switch after mAppSwitchesAllowedTime 802 * is set; any switches after that will clear the time. 803 */ 804 boolean mDidAppSwitch; 805 806 /** 807 * Set while we are wanting to sleep, to prevent any 808 * activities from being started/resumed. 809 */ 810 boolean mSleeping = false; 811 812 /** 813 * Set if we are shutting down the system, similar to sleeping. 814 */ 815 boolean mShuttingDown = false; 816 817 /** 818 * Set when the system is going to sleep, until we have 819 * successfully paused the current activity and released our wake lock. 820 * At that point the system is allowed to actually sleep. 821 */ 822 PowerManager.WakeLock mGoingToSleep; 823 824 /** 825 * We don't want to allow the device to go to sleep while in the process 826 * of launching an activity. This is primarily to allow alarm intent 827 * receivers to launch an activity and get that to run before the device 828 * goes back to sleep. 829 */ 830 PowerManager.WakeLock mLaunchingActivity; 831 832 /** 833 * Task identifier that activities are currently being started 834 * in. Incremented each time a new task is created. 835 * todo: Replace this with a TokenSpace class that generates non-repeating 836 * integers that won't wrap. 837 */ 838 int mCurTask = 1; 839 840 /** 841 * Current sequence id for oom_adj computation traversal. 842 */ 843 int mAdjSeq = 0; 844 845 /** 846 * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar 847 * is set, indicating the user wants processes started in such a way 848 * that they can use ANDROID_PROCESS_WRAPPER and know what will be 849 * running in each process (thus no pre-initialized process, etc). 850 */ 851 boolean mSimpleProcessManagement = false; 852 853 /** 854 * System monitoring: number of processes that died since the last 855 * N procs were started. 856 */ 857 int[] mProcDeaths = new int[20]; 858 859 /** 860 * This is set if we had to do a delayed dexopt of an app before launching 861 * it, to increasing the ANR timeouts in that case. 862 */ 863 boolean mDidDexOpt; 864 865 String mDebugApp = null; 866 boolean mWaitForDebugger = false; 867 boolean mDebugTransient = false; 868 String mOrigDebugApp = null; 869 boolean mOrigWaitForDebugger = false; 870 boolean mAlwaysFinishActivities = false; 871 IActivityController mController = null; 872 873 final RemoteCallbackList<IActivityWatcher> mWatchers 874 = new RemoteCallbackList<IActivityWatcher>(); 875 876 /** 877 * Callback of last caller to {@link #requestPss}. 878 */ 879 Runnable mRequestPssCallback; 880 881 /** 882 * Remaining processes for which we are waiting results from the last 883 * call to {@link #requestPss}. 884 */ 885 final ArrayList<ProcessRecord> mRequestPssList 886 = new ArrayList<ProcessRecord>(); 887 888 /** 889 * Runtime statistics collection thread. This object's lock is used to 890 * protect all related state. 891 */ 892 final Thread mProcessStatsThread; 893 894 /** 895 * Used to collect process stats when showing not responding dialog. 896 * Protected by mProcessStatsThread. 897 */ 898 final ProcessStats mProcessStats = new ProcessStats( 899 MONITOR_THREAD_CPU_USAGE); 900 long mLastCpuTime = 0; 901 long mLastWriteTime = 0; 902 903 long mInitialStartTime = 0; 904 905 /** 906 * Set to true after the system has finished booting. 907 */ 908 boolean mBooted = false; 909 910 int mProcessLimit = 0; 911 912 WindowManagerService mWindowManager; 913 914 static ActivityManagerService mSelf; 915 static ActivityThread mSystemThread; 916 917 private final class AppDeathRecipient implements IBinder.DeathRecipient { 918 final ProcessRecord mApp; 919 final int mPid; 920 final IApplicationThread mAppThread; 921 922 AppDeathRecipient(ProcessRecord app, int pid, 923 IApplicationThread thread) { 924 if (localLOGV) Log.v( 925 TAG, "New death recipient " + this 926 + " for thread " + thread.asBinder()); 927 mApp = app; 928 mPid = pid; 929 mAppThread = thread; 930 } 931 932 public void binderDied() { 933 if (localLOGV) Log.v( 934 TAG, "Death received in " + this 935 + " for thread " + mAppThread.asBinder()); 936 removeRequestedPss(mApp); 937 synchronized(ActivityManagerService.this) { 938 appDiedLocked(mApp, mPid, mAppThread); 939 } 940 } 941 } 942 943 static final int SHOW_ERROR_MSG = 1; 944 static final int SHOW_NOT_RESPONDING_MSG = 2; 945 static final int SHOW_FACTORY_ERROR_MSG = 3; 946 static final int UPDATE_CONFIGURATION_MSG = 4; 947 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 948 static final int WAIT_FOR_DEBUGGER_MSG = 6; 949 static final int BROADCAST_INTENT_MSG = 7; 950 static final int BROADCAST_TIMEOUT_MSG = 8; 951 static final int PAUSE_TIMEOUT_MSG = 9; 952 static final int IDLE_TIMEOUT_MSG = 10; 953 static final int IDLE_NOW_MSG = 11; 954 static final int SERVICE_TIMEOUT_MSG = 12; 955 static final int UPDATE_TIME_ZONE = 13; 956 static final int SHOW_UID_ERROR_MSG = 14; 957 static final int IM_FEELING_LUCKY_MSG = 15; 958 static final int LAUNCH_TIMEOUT_MSG = 16; 959 static final int DESTROY_TIMEOUT_MSG = 17; 960 static final int SERVICE_ERROR_MSG = 18; 961 static final int RESUME_TOP_ACTIVITY_MSG = 19; 962 static final int PROC_START_TIMEOUT_MSG = 20; 963 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 964 static final int KILL_APPLICATION_MSG = 22; 965 966 AlertDialog mUidAlert; 967 968 final Handler mHandler = new Handler() { 969 //public Handler() { 970 // if (localLOGV) Log.v(TAG, "Handler started!"); 971 //} 972 973 public void handleMessage(Message msg) { 974 switch (msg.what) { 975 case SHOW_ERROR_MSG: { 976 HashMap data = (HashMap) msg.obj; 977 byte[] crashData = (byte[])data.get("crashData"); 978 if (crashData != null) { 979 // This needs to be *un*synchronized to avoid deadlock. 980 ContentResolver resolver = mContext.getContentResolver(); 981 Checkin.reportCrash(resolver, crashData); 982 } 983 synchronized (ActivityManagerService.this) { 984 ProcessRecord proc = (ProcessRecord)data.get("app"); 985 if (proc != null && proc.crashDialog != null) { 986 Log.e(TAG, "App already has crash dialog: " + proc); 987 return; 988 } 989 AppErrorResult res = (AppErrorResult) data.get("result"); 990 if (!mSleeping && !mShuttingDown) { 991 Dialog d = new AppErrorDialog( 992 mContext, res, proc, 993 (Integer)data.get("flags"), 994 (String)data.get("shortMsg"), 995 (String)data.get("longMsg")); 996 d.show(); 997 proc.crashDialog = d; 998 } else { 999 // The device is asleep, so just pretend that the user 1000 // saw a crash dialog and hit "force quit". 1001 res.set(0); 1002 } 1003 } 1004 1005 ensureBootCompleted(); 1006 } break; 1007 case SHOW_NOT_RESPONDING_MSG: { 1008 synchronized (ActivityManagerService.this) { 1009 HashMap data = (HashMap) msg.obj; 1010 ProcessRecord proc = (ProcessRecord)data.get("app"); 1011 if (proc != null && proc.anrDialog != null) { 1012 Log.e(TAG, "App already has anr dialog: " + proc); 1013 return; 1014 } 1015 1016 broadcastIntentLocked(null, null, new Intent("android.intent.action.ANR"), 1017 null, null, 0, null, null, null, 1018 false, false, MY_PID, Process.SYSTEM_UID); 1019 1020 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1021 mContext, proc, (HistoryRecord)data.get("activity")); 1022 d.show(); 1023 proc.anrDialog = d; 1024 } 1025 1026 ensureBootCompleted(); 1027 } break; 1028 case SHOW_FACTORY_ERROR_MSG: { 1029 Dialog d = new FactoryErrorDialog( 1030 mContext, msg.getData().getCharSequence("msg")); 1031 d.show(); 1032 ensureBootCompleted(); 1033 } break; 1034 case UPDATE_CONFIGURATION_MSG: { 1035 final ContentResolver resolver = mContext.getContentResolver(); 1036 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1037 } break; 1038 case GC_BACKGROUND_PROCESSES_MSG: { 1039 synchronized (ActivityManagerService.this) { 1040 performAppGcsIfAppropriateLocked(); 1041 } 1042 } break; 1043 case WAIT_FOR_DEBUGGER_MSG: { 1044 synchronized (ActivityManagerService.this) { 1045 ProcessRecord app = (ProcessRecord)msg.obj; 1046 if (msg.arg1 != 0) { 1047 if (!app.waitedForDebugger) { 1048 Dialog d = new AppWaitingForDebuggerDialog( 1049 ActivityManagerService.this, 1050 mContext, app); 1051 app.waitDialog = d; 1052 app.waitedForDebugger = true; 1053 d.show(); 1054 } 1055 } else { 1056 if (app.waitDialog != null) { 1057 app.waitDialog.dismiss(); 1058 app.waitDialog = null; 1059 } 1060 } 1061 } 1062 } break; 1063 case BROADCAST_INTENT_MSG: { 1064 if (DEBUG_BROADCAST) Log.v( 1065 TAG, "Received BROADCAST_INTENT_MSG"); 1066 processNextBroadcast(true); 1067 } break; 1068 case BROADCAST_TIMEOUT_MSG: { 1069 if (mDidDexOpt) { 1070 mDidDexOpt = false; 1071 Message nmsg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG); 1072 mHandler.sendMessageDelayed(nmsg, BROADCAST_TIMEOUT); 1073 return; 1074 } 1075 broadcastTimeout(); 1076 } break; 1077 case PAUSE_TIMEOUT_MSG: { 1078 IBinder token = (IBinder)msg.obj; 1079 // We don't at this point know if the activity is fullscreen, 1080 // so we need to be conservative and assume it isn't. 1081 Log.w(TAG, "Activity pause timeout for " + token); 1082 activityPaused(token, null, true); 1083 } break; 1084 case IDLE_TIMEOUT_MSG: { 1085 if (mDidDexOpt) { 1086 mDidDexOpt = false; 1087 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 1088 nmsg.obj = msg.obj; 1089 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); 1090 return; 1091 } 1092 // We don't at this point know if the activity is fullscreen, 1093 // so we need to be conservative and assume it isn't. 1094 IBinder token = (IBinder)msg.obj; 1095 Log.w(TAG, "Activity idle timeout for " + token); 1096 activityIdleInternal(token, true, null); 1097 } break; 1098 case DESTROY_TIMEOUT_MSG: { 1099 IBinder token = (IBinder)msg.obj; 1100 // We don't at this point know if the activity is fullscreen, 1101 // so we need to be conservative and assume it isn't. 1102 Log.w(TAG, "Activity destroy timeout for " + token); 1103 activityDestroyed(token); 1104 } break; 1105 case IDLE_NOW_MSG: { 1106 IBinder token = (IBinder)msg.obj; 1107 activityIdle(token, null); 1108 } break; 1109 case SERVICE_TIMEOUT_MSG: { 1110 if (mDidDexOpt) { 1111 mDidDexOpt = false; 1112 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1113 nmsg.obj = msg.obj; 1114 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT); 1115 return; 1116 } 1117 serviceTimeout((ProcessRecord)msg.obj); 1118 } break; 1119 case UPDATE_TIME_ZONE: { 1120 synchronized (ActivityManagerService.this) { 1121 for (int i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) { 1122 ProcessRecord r = mLRUProcesses.get(i); 1123 if (r.thread != null) { 1124 try { 1125 r.thread.updateTimeZone(); 1126 } catch (RemoteException ex) { 1127 Log.w(TAG, "Failed to update time zone for: " + r.info.processName); 1128 } 1129 } 1130 } 1131 } 1132 } break; 1133 case SHOW_UID_ERROR_MSG: { 1134 // XXX This is a temporary dialog, no need to localize. 1135 AlertDialog d = new BaseErrorDialog(mContext); 1136 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1137 d.setCancelable(false); 1138 d.setTitle("System UIDs Inconsistent"); 1139 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable."); 1140 d.setButton("I'm Feeling Lucky", 1141 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1142 mUidAlert = d; 1143 d.show(); 1144 } break; 1145 case IM_FEELING_LUCKY_MSG: { 1146 if (mUidAlert != null) { 1147 mUidAlert.dismiss(); 1148 mUidAlert = null; 1149 } 1150 } break; 1151 case LAUNCH_TIMEOUT_MSG: { 1152 if (mDidDexOpt) { 1153 mDidDexOpt = false; 1154 Message nmsg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG); 1155 mHandler.sendMessageDelayed(nmsg, LAUNCH_TIMEOUT); 1156 return; 1157 } 1158 synchronized (ActivityManagerService.this) { 1159 if (mLaunchingActivity.isHeld()) { 1160 Log.w(TAG, "Launch timeout has expired, giving up wake lock!"); 1161 mLaunchingActivity.release(); 1162 } 1163 } 1164 } break; 1165 case SERVICE_ERROR_MSG: { 1166 ServiceRecord srv = (ServiceRecord)msg.obj; 1167 // This needs to be *un*synchronized to avoid deadlock. 1168 Checkin.logEvent(mContext.getContentResolver(), 1169 Checkin.Events.Tag.SYSTEM_SERVICE_LOOPING, 1170 srv.name.toShortString()); 1171 } break; 1172 case RESUME_TOP_ACTIVITY_MSG: { 1173 synchronized (ActivityManagerService.this) { 1174 resumeTopActivityLocked(null); 1175 } 1176 } break; 1177 case PROC_START_TIMEOUT_MSG: { 1178 if (mDidDexOpt) { 1179 mDidDexOpt = false; 1180 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1181 nmsg.obj = msg.obj; 1182 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1183 return; 1184 } 1185 ProcessRecord app = (ProcessRecord)msg.obj; 1186 synchronized (ActivityManagerService.this) { 1187 processStartTimedOutLocked(app); 1188 } 1189 } break; 1190 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1191 synchronized (ActivityManagerService.this) { 1192 doPendingActivityLaunchesLocked(true); 1193 } 1194 } break; 1195 case KILL_APPLICATION_MSG: { 1196 synchronized (ActivityManagerService.this) { 1197 int uid = msg.arg1; 1198 boolean restart = (msg.arg2 == 1); 1199 String pkg = (String) msg.obj; 1200 uninstallPackageLocked(pkg, uid, restart); 1201 } 1202 } break; 1203 } 1204 } 1205 }; 1206 1207 public static void setSystemProcess() { 1208 try { 1209 ActivityManagerService m = mSelf; 1210 1211 ServiceManager.addService("activity", m); 1212 ServiceManager.addService("meminfo", new MemBinder(m)); 1213 if (MONITOR_CPU_USAGE) { 1214 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1215 } 1216 ServiceManager.addService("activity.broadcasts", new BroadcastsBinder(m)); 1217 ServiceManager.addService("activity.services", new ServicesBinder(m)); 1218 ServiceManager.addService("activity.senders", new SendersBinder(m)); 1219 ServiceManager.addService("activity.providers", new ProvidersBinder(m)); 1220 ServiceManager.addService("permission", new PermissionController(m)); 1221 1222 ApplicationInfo info = 1223 mSelf.mContext.getPackageManager().getApplicationInfo( 1224 "android", STOCK_PM_FLAGS); 1225 mSystemThread.installSystemApplicationInfo(info); 1226 1227 synchronized (mSelf) { 1228 ProcessRecord app = mSelf.newProcessRecordLocked( 1229 mSystemThread.getApplicationThread(), info, 1230 info.processName); 1231 app.persistent = true; 1232 app.pid = Process.myPid(); 1233 app.maxAdj = SYSTEM_ADJ; 1234 mSelf.mProcessNames.put(app.processName, app.info.uid, app); 1235 synchronized (mSelf.mPidsSelfLocked) { 1236 mSelf.mPidsSelfLocked.put(app.pid, app); 1237 } 1238 mSelf.updateLRUListLocked(app, true); 1239 } 1240 } catch (PackageManager.NameNotFoundException e) { 1241 throw new RuntimeException( 1242 "Unable to find android system package", e); 1243 } 1244 } 1245 1246 public void setWindowManager(WindowManagerService wm) { 1247 mWindowManager = wm; 1248 } 1249 1250 public static final Context main(int factoryTest) { 1251 AThread thr = new AThread(); 1252 thr.start(); 1253 1254 synchronized (thr) { 1255 while (thr.mService == null) { 1256 try { 1257 thr.wait(); 1258 } catch (InterruptedException e) { 1259 } 1260 } 1261 } 1262 1263 ActivityManagerService m = thr.mService; 1264 mSelf = m; 1265 ActivityThread at = ActivityThread.systemMain(); 1266 mSystemThread = at; 1267 Context context = at.getSystemContext(); 1268 m.mContext = context; 1269 m.mFactoryTest = factoryTest; 1270 PowerManager pm = 1271 (PowerManager)context.getSystemService(Context.POWER_SERVICE); 1272 m.mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep"); 1273 m.mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch"); 1274 m.mLaunchingActivity.setReferenceCounted(false); 1275 1276 m.mBatteryStatsService.publish(context); 1277 m.mUsageStatsService.publish(context); 1278 1279 synchronized (thr) { 1280 thr.mReady = true; 1281 thr.notifyAll(); 1282 } 1283 1284 m.startRunning(null, null, null, null); 1285 1286 return context; 1287 } 1288 1289 public static ActivityManagerService self() { 1290 return mSelf; 1291 } 1292 1293 static class AThread extends Thread { 1294 ActivityManagerService mService; 1295 boolean mReady = false; 1296 1297 public AThread() { 1298 super("ActivityManager"); 1299 } 1300 1301 public void run() { 1302 Looper.prepare(); 1303 1304 android.os.Process.setThreadPriority( 1305 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1306 1307 ActivityManagerService m = new ActivityManagerService(); 1308 1309 synchronized (this) { 1310 mService = m; 1311 notifyAll(); 1312 } 1313 1314 synchronized (this) { 1315 while (!mReady) { 1316 try { 1317 wait(); 1318 } catch (InterruptedException e) { 1319 } 1320 } 1321 } 1322 1323 Looper.loop(); 1324 } 1325 } 1326 1327 static class BroadcastsBinder extends Binder { 1328 ActivityManagerService mActivityManagerService; 1329 BroadcastsBinder(ActivityManagerService activityManagerService) { 1330 mActivityManagerService = activityManagerService; 1331 } 1332 1333 @Override 1334 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1335 mActivityManagerService.dumpBroadcasts(pw); 1336 } 1337 } 1338 1339 static class ServicesBinder extends Binder { 1340 ActivityManagerService mActivityManagerService; 1341 ServicesBinder(ActivityManagerService activityManagerService) { 1342 mActivityManagerService = activityManagerService; 1343 } 1344 1345 @Override 1346 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1347 mActivityManagerService.dumpServices(pw); 1348 } 1349 } 1350 1351 static class SendersBinder extends Binder { 1352 ActivityManagerService mActivityManagerService; 1353 SendersBinder(ActivityManagerService activityManagerService) { 1354 mActivityManagerService = activityManagerService; 1355 } 1356 1357 @Override 1358 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1359 mActivityManagerService.dumpSenders(pw); 1360 } 1361 } 1362 1363 static class ProvidersBinder extends Binder { 1364 ActivityManagerService mActivityManagerService; 1365 ProvidersBinder(ActivityManagerService activityManagerService) { 1366 mActivityManagerService = activityManagerService; 1367 } 1368 1369 @Override 1370 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1371 mActivityManagerService.dumpProviders(pw); 1372 } 1373 } 1374 1375 static class MemBinder extends Binder { 1376 ActivityManagerService mActivityManagerService; 1377 MemBinder(ActivityManagerService activityManagerService) { 1378 mActivityManagerService = activityManagerService; 1379 } 1380 1381 @Override 1382 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1383 ActivityManagerService service = mActivityManagerService; 1384 ArrayList<ProcessRecord> procs; 1385 synchronized (mActivityManagerService) { 1386 if (args != null && args.length > 0 1387 && args[0].charAt(0) != '-') { 1388 procs = new ArrayList<ProcessRecord>(); 1389 int pid = -1; 1390 try { 1391 pid = Integer.parseInt(args[0]); 1392 } catch (NumberFormatException e) { 1393 1394 } 1395 for (int i=0; i<service.mLRUProcesses.size(); i++) { 1396 ProcessRecord proc = service.mLRUProcesses.get(i); 1397 if (proc.pid == pid) { 1398 procs.add(proc); 1399 } else if (proc.processName.equals(args[0])) { 1400 procs.add(proc); 1401 } 1402 } 1403 if (procs.size() <= 0) { 1404 pw.println("No process found for: " + args[0]); 1405 return; 1406 } 1407 } else { 1408 procs = service.mLRUProcesses; 1409 } 1410 } 1411 dumpApplicationMemoryUsage(fd, pw, procs, " ", args); 1412 } 1413 } 1414 1415 static class CpuBinder extends Binder { 1416 ActivityManagerService mActivityManagerService; 1417 CpuBinder(ActivityManagerService activityManagerService) { 1418 mActivityManagerService = activityManagerService; 1419 } 1420 1421 @Override 1422 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1423 synchronized (mActivityManagerService.mProcessStatsThread) { 1424 pw.print(mActivityManagerService.mProcessStats.printCurrentState()); 1425 } 1426 } 1427 } 1428 1429 private ActivityManagerService() { 1430 String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT"); 1431 if (v != null && Integer.getInteger(v) != 0) { 1432 mSimpleProcessManagement = true; 1433 } 1434 v = System.getenv("ANDROID_DEBUG_APP"); 1435 if (v != null) { 1436 mSimpleProcessManagement = true; 1437 } 1438 1439 Log.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1440 1441 MY_PID = Process.myPid(); 1442 1443 File dataDir = Environment.getDataDirectory(); 1444 File systemDir = new File(dataDir, "system"); 1445 systemDir.mkdirs(); 1446 mBatteryStatsService = new BatteryStatsService(new File( 1447 systemDir, "batterystats.bin").toString()); 1448 mBatteryStatsService.getActiveStatistics().readLocked(); 1449 mBatteryStatsService.getActiveStatistics().writeLocked(); 1450 1451 mUsageStatsService = new UsageStatsService( new File( 1452 systemDir, "usagestats").toString()); 1453 1454 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1455 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1456 1457 mConfiguration.makeDefault(); 1458 mProcessStats.init(); 1459 1460 // Add ourself to the Watchdog monitors. 1461 Watchdog.getInstance().addMonitor(this); 1462 1463 // These values are set in system/rootdir/init.rc on startup. 1464 FOREGROUND_APP_ADJ = 1465 Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_ADJ")); 1466 VISIBLE_APP_ADJ = 1467 Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_ADJ")); 1468 SECONDARY_SERVER_ADJ = 1469 Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_ADJ")); 1470 BACKUP_APP_ADJ = 1471 Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_ADJ")); 1472 HOME_APP_ADJ = 1473 Integer.valueOf(SystemProperties.get("ro.HOME_APP_ADJ")); 1474 HIDDEN_APP_MIN_ADJ = 1475 Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MIN_ADJ")); 1476 CONTENT_PROVIDER_ADJ = 1477 Integer.valueOf(SystemProperties.get("ro.CONTENT_PROVIDER_ADJ")); 1478 HIDDEN_APP_MAX_ADJ = CONTENT_PROVIDER_ADJ-1; 1479 EMPTY_APP_ADJ = 1480 Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_ADJ")); 1481 FOREGROUND_APP_MEM = 1482 Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_MEM"))*PAGE_SIZE; 1483 VISIBLE_APP_MEM = 1484 Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_MEM"))*PAGE_SIZE; 1485 SECONDARY_SERVER_MEM = 1486 Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_MEM"))*PAGE_SIZE; 1487 BACKUP_APP_MEM = 1488 Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_MEM"))*PAGE_SIZE; 1489 HOME_APP_MEM = 1490 Integer.valueOf(SystemProperties.get("ro.HOME_APP_MEM"))*PAGE_SIZE; 1491 HIDDEN_APP_MEM = 1492 Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MEM"))*PAGE_SIZE; 1493 EMPTY_APP_MEM = 1494 Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_MEM"))*PAGE_SIZE; 1495 1496 mProcessStatsThread = new Thread("ProcessStats") { 1497 public void run() { 1498 while (true) { 1499 try { 1500 try { 1501 synchronized(this) { 1502 final long now = SystemClock.uptimeMillis(); 1503 long nextCpuDelay = (mLastCpuTime+MONITOR_CPU_MAX_TIME)-now; 1504 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1505 //Log.i(TAG, "Cpu delay=" + nextCpuDelay 1506 // + ", write delay=" + nextWriteDelay); 1507 if (nextWriteDelay < nextCpuDelay) { 1508 nextCpuDelay = nextWriteDelay; 1509 } 1510 if (nextCpuDelay > 0) { 1511 this.wait(nextCpuDelay); 1512 } 1513 } 1514 } catch (InterruptedException e) { 1515 } 1516 1517 updateCpuStatsNow(); 1518 } catch (Exception e) { 1519 Log.e(TAG, "Unexpected exception collecting process stats", e); 1520 } 1521 } 1522 } 1523 }; 1524 mProcessStatsThread.start(); 1525 } 1526 1527 @Override 1528 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1529 throws RemoteException { 1530 try { 1531 return super.onTransact(code, data, reply, flags); 1532 } catch (RuntimeException e) { 1533 // The activity manager only throws security exceptions, so let's 1534 // log all others. 1535 if (!(e instanceof SecurityException)) { 1536 Log.e(TAG, "Activity Manager Crash", e); 1537 } 1538 throw e; 1539 } 1540 } 1541 1542 void updateCpuStats() { 1543 synchronized (mProcessStatsThread) { 1544 final long now = SystemClock.uptimeMillis(); 1545 if (mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) { 1546 mProcessStatsThread.notify(); 1547 } 1548 } 1549 } 1550 1551 void updateCpuStatsNow() { 1552 synchronized (mProcessStatsThread) { 1553 final long now = SystemClock.uptimeMillis(); 1554 boolean haveNewCpuStats = false; 1555 1556 if (MONITOR_CPU_USAGE && 1557 mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) { 1558 mLastCpuTime = now; 1559 haveNewCpuStats = true; 1560 mProcessStats.update(); 1561 //Log.i(TAG, mProcessStats.printCurrentState()); 1562 //Log.i(TAG, "Total CPU usage: " 1563 // + mProcessStats.getTotalCpuPercent() + "%"); 1564 1565 // Log the cpu usage if the property is set. 1566 if ("true".equals(SystemProperties.get("events.cpu"))) { 1567 int user = mProcessStats.getLastUserTime(); 1568 int system = mProcessStats.getLastSystemTime(); 1569 int iowait = mProcessStats.getLastIoWaitTime(); 1570 int irq = mProcessStats.getLastIrqTime(); 1571 int softIrq = mProcessStats.getLastSoftIrqTime(); 1572 int idle = mProcessStats.getLastIdleTime(); 1573 1574 int total = user + system + iowait + irq + softIrq + idle; 1575 if (total == 0) total = 1; 1576 1577 EventLog.writeEvent(LOG_CPU, 1578 ((user+system+iowait+irq+softIrq) * 100) / total, 1579 (user * 100) / total, 1580 (system * 100) / total, 1581 (iowait * 100) / total, 1582 (irq * 100) / total, 1583 (softIrq * 100) / total); 1584 } 1585 } 1586 1587 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1588 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1589 synchronized(bstats) { 1590 synchronized(mPidsSelfLocked) { 1591 if (haveNewCpuStats) { 1592 if (mBatteryStatsService.isOnBattery()) { 1593 final int N = mProcessStats.countWorkingStats(); 1594 for (int i=0; i<N; i++) { 1595 ProcessStats.Stats st 1596 = mProcessStats.getWorkingStats(i); 1597 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1598 if (pr != null) { 1599 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1600 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); 1601 ps.addSpeedStepTimes(cpuSpeedTimes); 1602 } else { 1603 BatteryStatsImpl.Uid.Proc ps = 1604 bstats.getProcessStatsLocked(st.name, st.pid); 1605 if (ps != null) { 1606 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); 1607 ps.addSpeedStepTimes(cpuSpeedTimes); 1608 } 1609 } 1610 } 1611 } 1612 } 1613 } 1614 1615 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1616 mLastWriteTime = now; 1617 mBatteryStatsService.getActiveStatistics().writeLocked(); 1618 } 1619 } 1620 } 1621 } 1622 1623 /** 1624 * Initialize the application bind args. These are passed to each 1625 * process when the bindApplication() IPC is sent to the process. They're 1626 * lazily setup to make sure the services are running when they're asked for. 1627 */ 1628 private HashMap<String, IBinder> getCommonServicesLocked() { 1629 if (mAppBindArgs == null) { 1630 mAppBindArgs = new HashMap<String, IBinder>(); 1631 1632 // Setup the application init args 1633 mAppBindArgs.put("package", ServiceManager.getService("package")); 1634 mAppBindArgs.put("window", ServiceManager.getService("window")); 1635 mAppBindArgs.put(Context.ALARM_SERVICE, 1636 ServiceManager.getService(Context.ALARM_SERVICE)); 1637 } 1638 return mAppBindArgs; 1639 } 1640 1641 private final void setFocusedActivityLocked(HistoryRecord r) { 1642 if (mFocusedActivity != r) { 1643 mFocusedActivity = r; 1644 mWindowManager.setFocusedApp(r, true); 1645 } 1646 } 1647 1648 private final void updateLRUListLocked(ProcessRecord app, 1649 boolean oomAdj) { 1650 // put it on the LRU to keep track of when it should be exited. 1651 int lrui = mLRUProcesses.indexOf(app); 1652 if (lrui >= 0) mLRUProcesses.remove(lrui); 1653 mLRUProcesses.add(app); 1654 //Log.i(TAG, "Putting proc to front: " + app.processName); 1655 if (oomAdj) { 1656 updateOomAdjLocked(); 1657 } 1658 } 1659 1660 private final boolean updateLRUListLocked(HistoryRecord r) { 1661 final boolean hadit = mLRUActivities.remove(r); 1662 mLRUActivities.add(r); 1663 return hadit; 1664 } 1665 1666 private final HistoryRecord topRunningActivityLocked(HistoryRecord notTop) { 1667 int i = mHistory.size()-1; 1668 while (i >= 0) { 1669 HistoryRecord r = (HistoryRecord)mHistory.get(i); 1670 if (!r.finishing && r != notTop) { 1671 return r; 1672 } 1673 i--; 1674 } 1675 return null; 1676 } 1677 1678 private final HistoryRecord topRunningNonDelayedActivityLocked(HistoryRecord notTop) { 1679 int i = mHistory.size()-1; 1680 while (i >= 0) { 1681 HistoryRecord r = (HistoryRecord)mHistory.get(i); 1682 if (!r.finishing && !r.delayedResume && r != notTop) { 1683 return r; 1684 } 1685 i--; 1686 } 1687 return null; 1688 } 1689 1690 /** 1691 * This is a simplified version of topRunningActivityLocked that provides a number of 1692 * optional skip-over modes. It is intended for use with the ActivityController hook only. 1693 * 1694 * @param token If non-null, any history records matching this token will be skipped. 1695 * @param taskId If non-zero, we'll attempt to skip over records with the same task ID. 1696 * 1697 * @return Returns the HistoryRecord of the next activity on the stack. 1698 */ 1699 private final HistoryRecord topRunningActivityLocked(IBinder token, int taskId) { 1700 int i = mHistory.size()-1; 1701 while (i >= 0) { 1702 HistoryRecord r = (HistoryRecord)mHistory.get(i); 1703 // Note: the taskId check depends on real taskId fields being non-zero 1704 if (!r.finishing && (token != r) && (taskId != r.task.taskId)) { 1705 return r; 1706 } 1707 i--; 1708 } 1709 return null; 1710 } 1711 1712 private final ProcessRecord getProcessRecordLocked( 1713 String processName, int uid) { 1714 if (uid == Process.SYSTEM_UID) { 1715 // The system gets to run in any process. If there are multiple 1716 // processes with the same uid, just pick the first (this 1717 // should never happen). 1718 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1719 processName); 1720 return procs != null ? procs.valueAt(0) : null; 1721 } 1722 ProcessRecord proc = mProcessNames.get(processName, uid); 1723 return proc; 1724 } 1725 1726 private void ensurePackageDexOpt(String packageName) { 1727 IPackageManager pm = ActivityThread.getPackageManager(); 1728 try { 1729 if (pm.performDexOpt(packageName)) { 1730 mDidDexOpt = true; 1731 } 1732 } catch (RemoteException e) { 1733 } 1734 } 1735 1736 private boolean isNextTransitionForward() { 1737 int transit = mWindowManager.getPendingAppTransition(); 1738 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1739 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1740 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1741 } 1742 1743 private final boolean realStartActivityLocked(HistoryRecord r, 1744 ProcessRecord app, boolean andResume, boolean checkConfig) 1745 throws RemoteException { 1746 1747 r.startFreezingScreenLocked(app, 0); 1748 mWindowManager.setAppVisibility(r, true); 1749 1750 // Have the window manager re-evaluate the orientation of 1751 // the screen based on the new activity order. Note that 1752 // as a result of this, it can call back into the activity 1753 // manager with a new orientation. We don't care about that, 1754 // because the activity is not currently running so we are 1755 // just restarting it anyway. 1756 if (checkConfig) { 1757 Configuration config = mWindowManager.updateOrientationFromAppTokens( 1758 mConfiguration, 1759 r.mayFreezeScreenLocked(app) ? r : null); 1760 updateConfigurationLocked(config, r); 1761 } 1762 1763 r.app = app; 1764 1765 if (localLOGV) Log.v(TAG, "Launching: " + r); 1766 1767 int idx = app.activities.indexOf(r); 1768 if (idx < 0) { 1769 app.activities.add(r); 1770 } 1771 updateLRUListLocked(app, true); 1772 1773 try { 1774 if (app.thread == null) { 1775 throw new RemoteException(); 1776 } 1777 List<ResultInfo> results = null; 1778 List<Intent> newIntents = null; 1779 if (andResume) { 1780 results = r.results; 1781 newIntents = r.newIntents; 1782 } 1783 if (DEBUG_SWITCH) Log.v(TAG, "Launching: " + r 1784 + " icicle=" + r.icicle 1785 + " with results=" + results + " newIntents=" + newIntents 1786 + " andResume=" + andResume); 1787 if (andResume) { 1788 EventLog.writeEvent(LOG_AM_RESTART_ACTIVITY, 1789 System.identityHashCode(r), 1790 r.task.taskId, r.shortComponentName); 1791 } 1792 if (r.isHomeActivity) { 1793 mHomeProcess = app; 1794 } 1795 ensurePackageDexOpt(r.intent.getComponent().getPackageName()); 1796 app.thread.scheduleLaunchActivity(new Intent(r.intent), r, 1797 System.identityHashCode(r), 1798 r.info, r.icicle, results, newIntents, !andResume, 1799 isNextTransitionForward()); 1800 } catch (RemoteException e) { 1801 if (r.launchFailed) { 1802 // This is the second time we failed -- finish activity 1803 // and give up. 1804 Log.e(TAG, "Second failure launching " 1805 + r.intent.getComponent().flattenToShortString() 1806 + ", giving up", e); 1807 appDiedLocked(app, app.pid, app.thread); 1808 requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null, 1809 "2nd-crash"); 1810 return false; 1811 } 1812 1813 // This is the first time we failed -- restart process and 1814 // retry. 1815 app.activities.remove(r); 1816 throw e; 1817 } 1818 1819 r.launchFailed = false; 1820 if (updateLRUListLocked(r)) { 1821 Log.w(TAG, "Activity " + r 1822 + " being launched, but already in LRU list"); 1823 } 1824 1825 if (andResume) { 1826 // As part of the process of launching, ActivityThread also performs 1827 // a resume. 1828 r.state = ActivityState.RESUMED; 1829 r.icicle = null; 1830 r.haveState = false; 1831 r.stopped = false; 1832 mResumedActivity = r; 1833 r.task.touchActiveTime(); 1834 completeResumeLocked(r); 1835 pauseIfSleepingLocked(); 1836 } else { 1837 // This activity is not starting in the resumed state... which 1838 // should look like we asked it to pause+stop (but remain visible), 1839 // and it has done so and reported back the current icicle and 1840 // other state. 1841 r.state = ActivityState.STOPPED; 1842 r.stopped = true; 1843 } 1844 1845 // Launch the new version setup screen if needed. We do this -after- 1846 // launching the initial activity (that is, home), so that it can have 1847 // a chance to initialize itself while in the background, making the 1848 // switch back to it faster and look better. 1849 startSetupActivityLocked(); 1850 1851 return true; 1852 } 1853 1854 private final void startSpecificActivityLocked(HistoryRecord r, 1855 boolean andResume, boolean checkConfig) { 1856 // Is this activity's application already running? 1857 ProcessRecord app = getProcessRecordLocked(r.processName, 1858 r.info.applicationInfo.uid); 1859 1860 if (r.startTime == 0) { 1861 r.startTime = SystemClock.uptimeMillis(); 1862 if (mInitialStartTime == 0) { 1863 mInitialStartTime = r.startTime; 1864 } 1865 } else if (mInitialStartTime == 0) { 1866 mInitialStartTime = SystemClock.uptimeMillis(); 1867 } 1868 1869 if (app != null && app.thread != null) { 1870 try { 1871 realStartActivityLocked(r, app, andResume, checkConfig); 1872 return; 1873 } catch (RemoteException e) { 1874 Log.w(TAG, "Exception when starting activity " 1875 + r.intent.getComponent().flattenToShortString(), e); 1876 } 1877 1878 // If a dead object exception was thrown -- fall through to 1879 // restart the application. 1880 } 1881 1882 startProcessLocked(r.processName, r.info.applicationInfo, true, 0, 1883 "activity", r.intent.getComponent(), false); 1884 } 1885 1886 private final ProcessRecord startProcessLocked(String processName, 1887 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1888 String hostingType, ComponentName hostingName, boolean allowWhileBooting) { 1889 ProcessRecord app = getProcessRecordLocked(processName, info.uid); 1890 // We don't have to do anything more if: 1891 // (1) There is an existing application record; and 1892 // (2) The caller doesn't think it is dead, OR there is no thread 1893 // object attached to it so we know it couldn't have crashed; and 1894 // (3) There is a pid assigned to it, so it is either starting or 1895 // already running. 1896 if (DEBUG_PROCESSES) Log.v(TAG, "startProcess: name=" + processName 1897 + " app=" + app + " knownToBeDead=" + knownToBeDead 1898 + " thread=" + (app != null ? app.thread : null) 1899 + " pid=" + (app != null ? app.pid : -1)); 1900 if (app != null && 1901 (!knownToBeDead || app.thread == null) && app.pid > 0) { 1902 return app; 1903 } 1904 1905 String hostingNameStr = hostingName != null 1906 ? hostingName.flattenToShortString() : null; 1907 1908 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1909 // If we are in the background, then check to see if this process 1910 // is bad. If so, we will just silently fail. 1911 if (mBadProcesses.get(info.processName, info.uid) != null) { 1912 return null; 1913 } 1914 } else { 1915 // When the user is explicitly starting a process, then clear its 1916 // crash count so that we won't make it bad until they see at 1917 // least one crash dialog again, and make the process good again 1918 // if it had been bad. 1919 mProcessCrashTimes.remove(info.processName, info.uid); 1920 if (mBadProcesses.get(info.processName, info.uid) != null) { 1921 EventLog.writeEvent(LOG_AM_PROCESS_GOOD, info.uid, 1922 info.processName); 1923 mBadProcesses.remove(info.processName, info.uid); 1924 if (app != null) { 1925 app.bad = false; 1926 } 1927 } 1928 } 1929 1930 if (app == null) { 1931 app = newProcessRecordLocked(null, info, processName); 1932 mProcessNames.put(processName, info.uid, app); 1933 } else { 1934 // If this is a new package in the process, add the package to the list 1935 app.addPackage(info.packageName); 1936 } 1937 1938 // If the system is not ready yet, then hold off on starting this 1939 // process until it is. 1940 if (!mSystemReady 1941 && !isAllowedWhileBooting(info) 1942 && !allowWhileBooting) { 1943 if (!mProcessesOnHold.contains(app)) { 1944 mProcessesOnHold.add(app); 1945 } 1946 return app; 1947 } 1948 1949 startProcessLocked(app, hostingType, hostingNameStr); 1950 return (app.pid != 0) ? app : null; 1951 } 1952 1953 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1954 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1955 } 1956 1957 private final void startProcessLocked(ProcessRecord app, 1958 String hostingType, String hostingNameStr) { 1959 if (app.pid > 0 && app.pid != MY_PID) { 1960 synchronized (mPidsSelfLocked) { 1961 mPidsSelfLocked.remove(app.pid); 1962 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1963 } 1964 app.pid = 0; 1965 } 1966 1967 mProcessesOnHold.remove(app); 1968 1969 updateCpuStats(); 1970 1971 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 1972 mProcDeaths[0] = 0; 1973 1974 try { 1975 int uid = app.info.uid; 1976 int[] gids = null; 1977 try { 1978 gids = mContext.getPackageManager().getPackageGids( 1979 app.info.packageName); 1980 } catch (PackageManager.NameNotFoundException e) { 1981 Log.w(TAG, "Unable to retrieve gids", e); 1982 } 1983 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 1984 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 1985 && mTopComponent != null 1986 && app.processName.equals(mTopComponent.getPackageName())) { 1987 uid = 0; 1988 } 1989 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 1990 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 1991 uid = 0; 1992 } 1993 } 1994 int debugFlags = 0; 1995 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 1996 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 1997 } 1998 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 1999 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2000 } 2001 if ("1".equals(SystemProperties.get("debug.assert"))) { 2002 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2003 } 2004 int pid = Process.start("android.app.ActivityThread", 2005 mSimpleProcessManagement ? app.processName : null, uid, uid, 2006 gids, debugFlags, null); 2007 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2008 synchronized (bs) { 2009 if (bs.isOnBattery()) { 2010 app.batteryStats.incStartsLocked(); 2011 } 2012 } 2013 2014 EventLog.writeEvent(LOG_AM_PROCESS_START, pid, uid, 2015 app.processName, hostingType, 2016 hostingNameStr != null ? hostingNameStr : ""); 2017 2018 if (app.persistent) { 2019 Watchdog.getInstance().processStarted(app, app.processName, pid); 2020 } 2021 2022 StringBuilder buf = mStringBuilder; 2023 buf.setLength(0); 2024 buf.append("Start proc "); 2025 buf.append(app.processName); 2026 buf.append(" for "); 2027 buf.append(hostingType); 2028 if (hostingNameStr != null) { 2029 buf.append(" "); 2030 buf.append(hostingNameStr); 2031 } 2032 buf.append(": pid="); 2033 buf.append(pid); 2034 buf.append(" uid="); 2035 buf.append(uid); 2036 buf.append(" gids={"); 2037 if (gids != null) { 2038 for (int gi=0; gi<gids.length; gi++) { 2039 if (gi != 0) buf.append(", "); 2040 buf.append(gids[gi]); 2041 2042 } 2043 } 2044 buf.append("}"); 2045 Log.i(TAG, buf.toString()); 2046 if (pid == 0 || pid == MY_PID) { 2047 // Processes are being emulated with threads. 2048 app.pid = MY_PID; 2049 app.removed = false; 2050 mStartingProcesses.add(app); 2051 } else if (pid > 0) { 2052 app.pid = pid; 2053 app.removed = false; 2054 synchronized (mPidsSelfLocked) { 2055 this.mPidsSelfLocked.put(pid, app); 2056 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2057 msg.obj = app; 2058 mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT); 2059 } 2060 } else { 2061 app.pid = 0; 2062 RuntimeException e = new RuntimeException( 2063 "Failure starting process " + app.processName 2064 + ": returned pid=" + pid); 2065 Log.e(TAG, e.getMessage(), e); 2066 } 2067 } catch (RuntimeException e) { 2068 // XXX do better error recovery. 2069 app.pid = 0; 2070 Log.e(TAG, "Failure starting process " + app.processName, e); 2071 } 2072 } 2073 2074 private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) { 2075 if (mPausingActivity != null) { 2076 RuntimeException e = new RuntimeException(); 2077 Log.e(TAG, "Trying to pause when pause is already pending for " 2078 + mPausingActivity, e); 2079 } 2080 HistoryRecord prev = mResumedActivity; 2081 if (prev == null) { 2082 RuntimeException e = new RuntimeException(); 2083 Log.e(TAG, "Trying to pause when nothing is resumed", e); 2084 resumeTopActivityLocked(null); 2085 return; 2086 } 2087 if (DEBUG_PAUSE) Log.v(TAG, "Start pausing: " + prev); 2088 mResumedActivity = null; 2089 mPausingActivity = prev; 2090 mLastPausedActivity = prev; 2091 prev.state = ActivityState.PAUSING; 2092 prev.task.touchActiveTime(); 2093 2094 updateCpuStats(); 2095 2096 if (prev.app != null && prev.app.thread != null) { 2097 if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending pause: " + prev); 2098 try { 2099 EventLog.writeEvent(LOG_AM_PAUSE_ACTIVITY, 2100 System.identityHashCode(prev), 2101 prev.shortComponentName); 2102 prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving, 2103 prev.configChangeFlags); 2104 updateUsageStats(prev, false); 2105 } catch (Exception e) { 2106 // Ignore exception, if process died other code will cleanup. 2107 Log.w(TAG, "Exception thrown during pause", e); 2108 mPausingActivity = null; 2109 mLastPausedActivity = null; 2110 } 2111 } else { 2112 mPausingActivity = null; 2113 mLastPausedActivity = null; 2114 } 2115 2116 // If we are not going to sleep, we want to ensure the device is 2117 // awake until the next activity is started. 2118 if (!mSleeping && !mShuttingDown) { 2119 mLaunchingActivity.acquire(); 2120 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) { 2121 // To be safe, don't allow the wake lock to be held for too long. 2122 Message msg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG); 2123 mHandler.sendMessageDelayed(msg, LAUNCH_TIMEOUT); 2124 } 2125 } 2126 2127 2128 if (mPausingActivity != null) { 2129 // Have the window manager pause its key dispatching until the new 2130 // activity has started. If we're pausing the activity just because 2131 // the screen is being turned off and the UI is sleeping, don't interrupt 2132 // key dispatch; the same activity will pick it up again on wakeup. 2133 if (!uiSleeping) { 2134 prev.pauseKeyDispatchingLocked(); 2135 } else { 2136 if (DEBUG_PAUSE) Log.v(TAG, "Key dispatch not paused for screen off"); 2137 } 2138 2139 // Schedule a pause timeout in case the app doesn't respond. 2140 // We don't give it much time because this directly impacts the 2141 // responsiveness seen by the user. 2142 Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG); 2143 msg.obj = prev; 2144 mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT); 2145 if (DEBUG_PAUSE) Log.v(TAG, "Waiting for pause to complete..."); 2146 } else { 2147 // This activity failed to schedule the 2148 // pause, so just treat it as being paused now. 2149 if (DEBUG_PAUSE) Log.v(TAG, "Activity not running, resuming next."); 2150 resumeTopActivityLocked(null); 2151 } 2152 } 2153 2154 private final void completePauseLocked() { 2155 HistoryRecord prev = mPausingActivity; 2156 if (DEBUG_PAUSE) Log.v(TAG, "Complete pause: " + prev); 2157 2158 if (prev != null) { 2159 if (prev.finishing) { 2160 if (DEBUG_PAUSE) Log.v(TAG, "Executing finish of activity: " + prev); 2161 prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE); 2162 } else if (prev.app != null) { 2163 if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending stop: " + prev); 2164 if (prev.waitingVisible) { 2165 prev.waitingVisible = false; 2166 mWaitingVisibleActivities.remove(prev); 2167 if (DEBUG_SWITCH || DEBUG_PAUSE) Log.v( 2168 TAG, "Complete pause, no longer waiting: " + prev); 2169 } 2170 if (prev.configDestroy) { 2171 // The previous is being paused because the configuration 2172 // is changing, which means it is actually stopping... 2173 // To juggle the fact that we are also starting a new 2174 // instance right now, we need to first completely stop 2175 // the current instance before starting the new one. 2176 if (DEBUG_PAUSE) Log.v(TAG, "Destroying after pause: " + prev); 2177 destroyActivityLocked(prev, true); 2178 } else { 2179 mStoppingActivities.add(prev); 2180 if (mStoppingActivities.size() > 3) { 2181 // If we already have a few activities waiting to stop, 2182 // then give up on things going idle and start clearing 2183 // them out. 2184 if (DEBUG_PAUSE) Log.v(TAG, "To many pending stops, forcing idle"); 2185 Message msg = Message.obtain(); 2186 msg.what = ActivityManagerService.IDLE_NOW_MSG; 2187 mHandler.sendMessage(msg); 2188 } 2189 } 2190 } else { 2191 if (DEBUG_PAUSE) Log.v(TAG, "App died during pause, not stopping: " + prev); 2192 prev = null; 2193 } 2194 mPausingActivity = null; 2195 } 2196 2197 if (!mSleeping && !mShuttingDown) { 2198 resumeTopActivityLocked(prev); 2199 } else { 2200 if (mGoingToSleep.isHeld()) { 2201 mGoingToSleep.release(); 2202 } 2203 if (mShuttingDown) { 2204 notifyAll(); 2205 } 2206 } 2207 2208 if (prev != null) { 2209 prev.resumeKeyDispatchingLocked(); 2210 } 2211 2212 if (prev.app != null && prev.cpuTimeAtResume > 0 && mBatteryStatsService.isOnBattery()) { 2213 long diff = 0; 2214 synchronized (mProcessStatsThread) { 2215 diff = mProcessStats.getCpuTimeForPid(prev.app.pid) - prev.cpuTimeAtResume; 2216 } 2217 if (diff > 0) { 2218 BatteryStatsImpl bsi = mBatteryStatsService.getActiveStatistics(); 2219 synchronized (bsi) { 2220 BatteryStatsImpl.Uid.Proc ps = 2221 bsi.getProcessStatsLocked(prev.info.applicationInfo.uid, 2222 prev.info.packageName); 2223 if (ps != null) { 2224 ps.addForegroundTimeLocked(diff); 2225 } 2226 } 2227 } 2228 } 2229 prev.cpuTimeAtResume = 0; // reset it 2230 } 2231 2232 /** 2233 * Once we know that we have asked an application to put an activity in 2234 * the resumed state (either by launching it or explicitly telling it), 2235 * this function updates the rest of our state to match that fact. 2236 */ 2237 private final void completeResumeLocked(HistoryRecord next) { 2238 next.idle = false; 2239 next.results = null; 2240 next.newIntents = null; 2241 2242 // schedule an idle timeout in case the app doesn't do it for us. 2243 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 2244 msg.obj = next; 2245 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 2246 2247 if (false) { 2248 // The activity was never told to pause, so just keep 2249 // things going as-is. To maintain our own state, 2250 // we need to emulate it coming back and saying it is 2251 // idle. 2252 msg = mHandler.obtainMessage(IDLE_NOW_MSG); 2253 msg.obj = next; 2254 mHandler.sendMessage(msg); 2255 } 2256 2257 reportResumedActivityLocked(next); 2258 2259 next.thumbnail = null; 2260 setFocusedActivityLocked(next); 2261 next.resumeKeyDispatchingLocked(); 2262 ensureActivitiesVisibleLocked(null, 0); 2263 mWindowManager.executeAppTransition(); 2264 mNoAnimActivities.clear(); 2265 2266 // Mark the point when the activity is resuming 2267 // TODO: To be more accurate, the mark should be before the onCreate, 2268 // not after the onResume. But for subsequent starts, onResume is fine. 2269 if (next.app != null) { 2270 synchronized (mProcessStatsThread) { 2271 next.cpuTimeAtResume = mProcessStats.getCpuTimeForPid(next.app.pid); 2272 } 2273 } else { 2274 next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process 2275 } 2276 } 2277 2278 /** 2279 * Make sure that all activities that need to be visible (that is, they 2280 * currently can be seen by the user) actually are. 2281 */ 2282 private final void ensureActivitiesVisibleLocked(HistoryRecord top, 2283 HistoryRecord starting, String onlyThisProcess, int configChanges) { 2284 if (DEBUG_VISBILITY) Log.v( 2285 TAG, "ensureActivitiesVisible behind " + top 2286 + " configChanges=0x" + Integer.toHexString(configChanges)); 2287 2288 // If the top activity is not fullscreen, then we need to 2289 // make sure any activities under it are now visible. 2290 final int count = mHistory.size(); 2291 int i = count-1; 2292 while (mHistory.get(i) != top) { 2293 i--; 2294 } 2295 HistoryRecord r; 2296 boolean behindFullscreen = false; 2297 for (; i>=0; i--) { 2298 r = (HistoryRecord)mHistory.get(i); 2299 if (DEBUG_VISBILITY) Log.v( 2300 TAG, "Make visible? " + r + " finishing=" + r.finishing 2301 + " state=" + r.state); 2302 if (r.finishing) { 2303 continue; 2304 } 2305 2306 final boolean doThisProcess = onlyThisProcess == null 2307 || onlyThisProcess.equals(r.processName); 2308 2309 // First: if this is not the current activity being started, make 2310 // sure it matches the current configuration. 2311 if (r != starting && doThisProcess) { 2312 ensureActivityConfigurationLocked(r, 0); 2313 } 2314 2315 if (r.app == null || r.app.thread == null) { 2316 if (onlyThisProcess == null 2317 || onlyThisProcess.equals(r.processName)) { 2318 // This activity needs to be visible, but isn't even 2319 // running... get it started, but don't resume it 2320 // at this point. 2321 if (DEBUG_VISBILITY) Log.v( 2322 TAG, "Start and freeze screen for " + r); 2323 if (r != starting) { 2324 r.startFreezingScreenLocked(r.app, configChanges); 2325 } 2326 if (!r.visible) { 2327 if (DEBUG_VISBILITY) Log.v( 2328 TAG, "Starting and making visible: " + r); 2329 mWindowManager.setAppVisibility(r, true); 2330 } 2331 if (r != starting) { 2332 startSpecificActivityLocked(r, false, false); 2333 } 2334 } 2335 2336 } else if (r.visible) { 2337 // If this activity is already visible, then there is nothing 2338 // else to do here. 2339 if (DEBUG_VISBILITY) Log.v( 2340 TAG, "Skipping: already visible at " + r); 2341 r.stopFreezingScreenLocked(false); 2342 2343 } else if (onlyThisProcess == null) { 2344 // This activity is not currently visible, but is running. 2345 // Tell it to become visible. 2346 r.visible = true; 2347 if (r.state != ActivityState.RESUMED && r != starting) { 2348 // If this activity is paused, tell it 2349 // to now show its window. 2350 if (DEBUG_VISBILITY) Log.v( 2351 TAG, "Making visible and scheduling visibility: " + r); 2352 try { 2353 mWindowManager.setAppVisibility(r, true); 2354 r.app.thread.scheduleWindowVisibility(r, true); 2355 r.stopFreezingScreenLocked(false); 2356 } catch (Exception e) { 2357 // Just skip on any failure; we'll make it 2358 // visible when it next restarts. 2359 Log.w(TAG, "Exception thrown making visibile: " 2360 + r.intent.getComponent(), e); 2361 } 2362 } 2363 } 2364 2365 // Aggregate current change flags. 2366 configChanges |= r.configChangeFlags; 2367 2368 if (r.fullscreen) { 2369 // At this point, nothing else needs to be shown 2370 if (DEBUG_VISBILITY) Log.v( 2371 TAG, "Stopping: fullscreen at " + r); 2372 behindFullscreen = true; 2373 i--; 2374 break; 2375 } 2376 } 2377 2378 // Now for any activities that aren't visible to the user, make 2379 // sure they no longer are keeping the screen frozen. 2380 while (i >= 0) { 2381 r = (HistoryRecord)mHistory.get(i); 2382 if (DEBUG_VISBILITY) Log.v( 2383 TAG, "Make invisible? " + r + " finishing=" + r.finishing 2384 + " state=" + r.state 2385 + " behindFullscreen=" + behindFullscreen); 2386 if (!r.finishing) { 2387 if (behindFullscreen) { 2388 if (r.visible) { 2389 if (DEBUG_VISBILITY) Log.v( 2390 TAG, "Making invisible: " + r); 2391 r.visible = false; 2392 try { 2393 mWindowManager.setAppVisibility(r, false); 2394 if ((r.state == ActivityState.STOPPING 2395 || r.state == ActivityState.STOPPED) 2396 && r.app != null && r.app.thread != null) { 2397 if (DEBUG_VISBILITY) Log.v( 2398 TAG, "Scheduling invisibility: " + r); 2399 r.app.thread.scheduleWindowVisibility(r, false); 2400 } 2401 } catch (Exception e) { 2402 // Just skip on any failure; we'll make it 2403 // visible when it next restarts. 2404 Log.w(TAG, "Exception thrown making hidden: " 2405 + r.intent.getComponent(), e); 2406 } 2407 } else { 2408 if (DEBUG_VISBILITY) Log.v( 2409 TAG, "Already invisible: " + r); 2410 } 2411 } else if (r.fullscreen) { 2412 if (DEBUG_VISBILITY) Log.v( 2413 TAG, "Now behindFullscreen: " + r); 2414 behindFullscreen = true; 2415 } 2416 } 2417 i--; 2418 } 2419 } 2420 2421 /** 2422 * Version of ensureActivitiesVisible that can easily be called anywhere. 2423 */ 2424 private final void ensureActivitiesVisibleLocked(HistoryRecord starting, 2425 int configChanges) { 2426 HistoryRecord r = topRunningActivityLocked(null); 2427 if (r != null) { 2428 ensureActivitiesVisibleLocked(r, starting, null, configChanges); 2429 } 2430 } 2431 2432 private void updateUsageStats(HistoryRecord resumedComponent, boolean resumed) { 2433 if (resumed) { 2434 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2435 } else { 2436 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2437 } 2438 } 2439 2440 private boolean startHomeActivityLocked() { 2441 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2442 && mTopAction == null) { 2443 // We are running in factory test mode, but unable to find 2444 // the factory test app, so just sit around displaying the 2445 // error message and don't try to start anything. 2446 return false; 2447 } 2448 Intent intent = new Intent( 2449 mTopAction, 2450 mTopData != null ? Uri.parse(mTopData) : null); 2451 intent.setComponent(mTopComponent); 2452 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2453 intent.addCategory(Intent.CATEGORY_HOME); 2454 } 2455 ActivityInfo aInfo = 2456 intent.resolveActivityInfo(mContext.getPackageManager(), 2457 STOCK_PM_FLAGS); 2458 if (aInfo != null) { 2459 intent.setComponent(new ComponentName( 2460 aInfo.applicationInfo.packageName, aInfo.name)); 2461 // Don't do this if the home app is currently being 2462 // instrumented. 2463 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2464 aInfo.applicationInfo.uid); 2465 if (app == null || app.instrumentationClass == null) { 2466 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2467 startActivityLocked(null, intent, null, null, 0, aInfo, 2468 null, null, 0, 0, 0, false, false); 2469 } 2470 } 2471 2472 2473 return true; 2474 } 2475 2476 /** 2477 * Starts the "new version setup screen" if appropriate. 2478 */ 2479 private void startSetupActivityLocked() { 2480 // Only do this once per boot. 2481 if (mCheckedForSetup) { 2482 return; 2483 } 2484 2485 // We will show this screen if the current one is a different 2486 // version than the last one shown, and we are not running in 2487 // low-level factory test mode. 2488 final ContentResolver resolver = mContext.getContentResolver(); 2489 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2490 Settings.Secure.getInt(resolver, 2491 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2492 mCheckedForSetup = true; 2493 2494 // See if we should be showing the platform update setup UI. 2495 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2496 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2497 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2498 2499 // We don't allow third party apps to replace this. 2500 ResolveInfo ri = null; 2501 for (int i=0; ris != null && i<ris.size(); i++) { 2502 if ((ris.get(i).activityInfo.applicationInfo.flags 2503 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2504 ri = ris.get(i); 2505 break; 2506 } 2507 } 2508 2509 if (ri != null) { 2510 String vers = ri.activityInfo.metaData != null 2511 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2512 : null; 2513 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2514 vers = ri.activityInfo.applicationInfo.metaData.getString( 2515 Intent.METADATA_SETUP_VERSION); 2516 } 2517 String lastVers = Settings.Secure.getString( 2518 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2519 if (vers != null && !vers.equals(lastVers)) { 2520 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2521 intent.setComponent(new ComponentName( 2522 ri.activityInfo.packageName, ri.activityInfo.name)); 2523 startActivityLocked(null, intent, null, null, 0, ri.activityInfo, 2524 null, null, 0, 0, 0, false, false); 2525 } 2526 } 2527 } 2528 } 2529 2530 private void reportResumedActivityLocked(HistoryRecord r) { 2531 //Log.i(TAG, "**** REPORT RESUME: " + r); 2532 2533 final int identHash = System.identityHashCode(r); 2534 updateUsageStats(r, true); 2535 2536 int i = mWatchers.beginBroadcast(); 2537 while (i > 0) { 2538 i--; 2539 IActivityWatcher w = mWatchers.getBroadcastItem(i); 2540 if (w != null) { 2541 try { 2542 w.activityResuming(identHash); 2543 } catch (RemoteException e) { 2544 } 2545 } 2546 } 2547 mWatchers.finishBroadcast(); 2548 } 2549 2550 /** 2551 * Ensure that the top activity in the stack is resumed. 2552 * 2553 * @param prev The previously resumed activity, for when in the process 2554 * of pausing; can be null to call from elsewhere. 2555 * 2556 * @return Returns true if something is being resumed, or false if 2557 * nothing happened. 2558 */ 2559 private final boolean resumeTopActivityLocked(HistoryRecord prev) { 2560 // Find the first activity that is not finishing. 2561 HistoryRecord next = topRunningActivityLocked(null); 2562 2563 // Remember how we'll process this pause/resume situation, and ensure 2564 // that the state is reset however we wind up proceeding. 2565 final boolean userLeaving = mUserLeaving; 2566 mUserLeaving = false; 2567 2568 if (next == null) { 2569 // There are no more activities! Let's just start up the 2570 // Launcher... 2571 return startHomeActivityLocked(); 2572 } 2573 2574 next.delayedResume = false; 2575 2576 // If the top activity is the resumed one, nothing to do. 2577 if (mResumedActivity == next && next.state == ActivityState.RESUMED) { 2578 // Make sure we have executed any pending transitions, since there 2579 // should be nothing left to do at this point. 2580 mWindowManager.executeAppTransition(); 2581 mNoAnimActivities.clear(); 2582 return false; 2583 } 2584 2585 // If we are sleeping, and there is no resumed activity, and the top 2586 // activity is paused, well that is the state we want. 2587 if ((mSleeping || mShuttingDown) 2588 && mLastPausedActivity == next && next.state == ActivityState.PAUSED) { 2589 // Make sure we have executed any pending transitions, since there 2590 // should be nothing left to do at this point. 2591 mWindowManager.executeAppTransition(); 2592 mNoAnimActivities.clear(); 2593 return false; 2594 } 2595 2596 // The activity may be waiting for stop, but that is no longer 2597 // appropriate for it. 2598 mStoppingActivities.remove(next); 2599 mWaitingVisibleActivities.remove(next); 2600 2601 if (DEBUG_SWITCH) Log.v(TAG, "Resuming " + next); 2602 2603 // If we are currently pausing an activity, then don't do anything 2604 // until that is done. 2605 if (mPausingActivity != null) { 2606 if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: pausing=" + mPausingActivity); 2607 return false; 2608 } 2609 2610 // We need to start pausing the current activity so the top one 2611 // can be resumed... 2612 if (mResumedActivity != null) { 2613 if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: need to start pausing"); 2614 startPausingLocked(userLeaving, false); 2615 return true; 2616 } 2617 2618 if (prev != null && prev != next) { 2619 if (!prev.waitingVisible && next != null && !next.nowVisible) { 2620 prev.waitingVisible = true; 2621 mWaitingVisibleActivities.add(prev); 2622 if (DEBUG_SWITCH) Log.v( 2623 TAG, "Resuming top, waiting visible to hide: " + prev); 2624 } else { 2625 // The next activity is already visible, so hide the previous 2626 // activity's windows right now so we can show the new one ASAP. 2627 // We only do this if the previous is finishing, which should mean 2628 // it is on top of the one being resumed so hiding it quickly 2629 // is good. Otherwise, we want to do the normal route of allowing 2630 // the resumed activity to be shown so we can decide if the 2631 // previous should actually be hidden depending on whether the 2632 // new one is found to be full-screen or not. 2633 if (prev.finishing) { 2634 mWindowManager.setAppVisibility(prev, false); 2635 if (DEBUG_SWITCH) Log.v(TAG, "Not waiting for visible to hide: " 2636 + prev + ", waitingVisible=" 2637 + (prev != null ? prev.waitingVisible : null) 2638 + ", nowVisible=" + next.nowVisible); 2639 } else { 2640 if (DEBUG_SWITCH) Log.v(TAG, "Previous already visible but still waiting to hide: " 2641 + prev + ", waitingVisible=" 2642 + (prev != null ? prev.waitingVisible : null) 2643 + ", nowVisible=" + next.nowVisible); 2644 } 2645 } 2646 } 2647 2648 // We are starting up the next activity, so tell the window manager 2649 // that the previous one will be hidden soon. This way it can know 2650 // to ignore it when computing the desired screen orientation. 2651 if (prev != null) { 2652 if (prev.finishing) { 2653 if (DEBUG_TRANSITION) Log.v(TAG, 2654 "Prepare close transition: prev=" + prev); 2655 if (mNoAnimActivities.contains(prev)) { 2656 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 2657 } else { 2658 mWindowManager.prepareAppTransition(prev.task == next.task 2659 ? WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE 2660 : WindowManagerPolicy.TRANSIT_TASK_CLOSE); 2661 } 2662 mWindowManager.setAppWillBeHidden(prev); 2663 mWindowManager.setAppVisibility(prev, false); 2664 } else { 2665 if (DEBUG_TRANSITION) Log.v(TAG, 2666 "Prepare open transition: prev=" + prev); 2667 if (mNoAnimActivities.contains(next)) { 2668 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 2669 } else { 2670 mWindowManager.prepareAppTransition(prev.task == next.task 2671 ? WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 2672 : WindowManagerPolicy.TRANSIT_TASK_OPEN); 2673 } 2674 } 2675 if (false) { 2676 mWindowManager.setAppWillBeHidden(prev); 2677 mWindowManager.setAppVisibility(prev, false); 2678 } 2679 } else if (mHistory.size() > 1) { 2680 if (DEBUG_TRANSITION) Log.v(TAG, 2681 "Prepare open transition: no previous"); 2682 if (mNoAnimActivities.contains(next)) { 2683 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 2684 } else { 2685 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN); 2686 } 2687 } 2688 2689 if (next.app != null && next.app.thread != null) { 2690 if (DEBUG_SWITCH) Log.v(TAG, "Resume running: " + next); 2691 2692 // This activity is now becoming visible. 2693 mWindowManager.setAppVisibility(next, true); 2694 2695 HistoryRecord lastResumedActivity = mResumedActivity; 2696 ActivityState lastState = next.state; 2697 2698 updateCpuStats(); 2699 2700 next.state = ActivityState.RESUMED; 2701 mResumedActivity = next; 2702 next.task.touchActiveTime(); 2703 updateLRUListLocked(next.app, true); 2704 updateLRUListLocked(next); 2705 2706 // Have the window manager re-evaluate the orientation of 2707 // the screen based on the new activity order. 2708 boolean updated; 2709 synchronized (this) { 2710 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2711 mConfiguration, 2712 next.mayFreezeScreenLocked(next.app) ? next : null); 2713 if (config != null) { 2714 /* 2715 * Explicitly restore the locale to the one from the 2716 * old configuration, since the one that comes back from 2717 * the window manager has the default (boot) locale. 2718 * 2719 * It looks like previously the locale picker only worked 2720 * by coincidence: usually it would do its setting of 2721 * the locale after the activity transition, so it didn't 2722 * matter that this lost it. With the synchronized 2723 * block now keeping them from happening at the same time, 2724 * this one always would happen second and undo what the 2725 * locale picker had just done. 2726 */ 2727 config.locale = mConfiguration.locale; 2728 next.frozenBeforeDestroy = true; 2729 } 2730 updated = updateConfigurationLocked(config, next); 2731 } 2732 if (!updated) { 2733 // The configuration update wasn't able to keep the existing 2734 // instance of the activity, and instead started a new one. 2735 // We should be all done, but let's just make sure our activity 2736 // is still at the top and schedule another run if something 2737 // weird happened. 2738 HistoryRecord nextNext = topRunningActivityLocked(null); 2739 if (DEBUG_SWITCH) Log.i(TAG, 2740 "Activity config changed during resume: " + next 2741 + ", new next: " + nextNext); 2742 if (nextNext != next) { 2743 // Do over! 2744 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 2745 } 2746 setFocusedActivityLocked(next); 2747 ensureActivitiesVisibleLocked(null, 0); 2748 mWindowManager.executeAppTransition(); 2749 mNoAnimActivities.clear(); 2750 return true; 2751 } 2752 2753 try { 2754 // Deliver all pending results. 2755 ArrayList a = next.results; 2756 if (a != null) { 2757 final int N = a.size(); 2758 if (!next.finishing && N > 0) { 2759 if (DEBUG_RESULTS) Log.v( 2760 TAG, "Delivering results to " + next 2761 + ": " + a); 2762 next.app.thread.scheduleSendResult(next, a); 2763 } 2764 } 2765 2766 if (next.newIntents != null) { 2767 next.app.thread.scheduleNewIntent(next.newIntents, next); 2768 } 2769 2770 EventLog.writeEvent(LOG_AM_RESUME_ACTIVITY, 2771 System.identityHashCode(next), 2772 next.task.taskId, next.shortComponentName); 2773 2774 next.app.thread.scheduleResumeActivity(next, 2775 isNextTransitionForward()); 2776 2777 pauseIfSleepingLocked(); 2778 2779 } catch (Exception e) { 2780 // Whoops, need to restart this activity! 2781 next.state = lastState; 2782 mResumedActivity = lastResumedActivity; 2783 if (Config.LOGD) Log.d(TAG, 2784 "Restarting because process died: " + next); 2785 if (!next.hasBeenLaunched) { 2786 next.hasBeenLaunched = true; 2787 } else { 2788 if (SHOW_APP_STARTING_ICON) { 2789 mWindowManager.setAppStartingWindow( 2790 next, next.packageName, next.theme, 2791 next.nonLocalizedLabel, 2792 next.labelRes, next.icon, null, true); 2793 } 2794 } 2795 startSpecificActivityLocked(next, true, false); 2796 return true; 2797 } 2798 2799 // From this point on, if something goes wrong there is no way 2800 // to recover the activity. 2801 try { 2802 next.visible = true; 2803 completeResumeLocked(next); 2804 } catch (Exception e) { 2805 // If any exception gets thrown, toss away this 2806 // activity and try the next one. 2807 Log.w(TAG, "Exception thrown during resume of " + next, e); 2808 requestFinishActivityLocked(next, Activity.RESULT_CANCELED, null, 2809 "resume-exception"); 2810 return true; 2811 } 2812 2813 // Didn't need to use the icicle, and it is now out of date. 2814 next.icicle = null; 2815 next.haveState = false; 2816 next.stopped = false; 2817 2818 } else { 2819 // Whoops, need to restart this activity! 2820 if (!next.hasBeenLaunched) { 2821 next.hasBeenLaunched = true; 2822 } else { 2823 if (SHOW_APP_STARTING_ICON) { 2824 mWindowManager.setAppStartingWindow( 2825 next, next.packageName, next.theme, 2826 next.nonLocalizedLabel, 2827 next.labelRes, next.icon, null, true); 2828 } 2829 if (DEBUG_SWITCH) Log.v(TAG, "Restarting: " + next); 2830 } 2831 startSpecificActivityLocked(next, true, true); 2832 } 2833 2834 return true; 2835 } 2836 2837 private final void startActivityLocked(HistoryRecord r, boolean newTask, 2838 boolean doResume) { 2839 final int NH = mHistory.size(); 2840 2841 int addPos = -1; 2842 2843 if (!newTask) { 2844 // If starting in an existing task, find where that is... 2845 HistoryRecord next = null; 2846 boolean startIt = true; 2847 for (int i = NH-1; i >= 0; i--) { 2848 HistoryRecord p = (HistoryRecord)mHistory.get(i); 2849 if (p.finishing) { 2850 continue; 2851 } 2852 if (p.task == r.task) { 2853 // Here it is! Now, if this is not yet visible to the 2854 // user, then just add it without starting; it will 2855 // get started when the user navigates back to it. 2856 addPos = i+1; 2857 if (!startIt) { 2858 mHistory.add(addPos, r); 2859 r.inHistory = true; 2860 r.task.numActivities++; 2861 mWindowManager.addAppToken(addPos, r, r.task.taskId, 2862 r.info.screenOrientation, r.fullscreen); 2863 if (VALIDATE_TOKENS) { 2864 mWindowManager.validateAppTokens(mHistory); 2865 } 2866 return; 2867 } 2868 break; 2869 } 2870 if (p.fullscreen) { 2871 startIt = false; 2872 } 2873 next = p; 2874 } 2875 } 2876 2877 // Place a new activity at top of stack, so it is next to interact 2878 // with the user. 2879 if (addPos < 0) { 2880 addPos = mHistory.size(); 2881 } 2882 2883 // If we are not placing the new activity frontmost, we do not want 2884 // to deliver the onUserLeaving callback to the actual frontmost 2885 // activity 2886 if (addPos < NH) { 2887 mUserLeaving = false; 2888 if (DEBUG_USER_LEAVING) Log.v(TAG, "startActivity() behind front, mUserLeaving=false"); 2889 } 2890 2891 // Slot the activity into the history stack and proceed 2892 mHistory.add(addPos, r); 2893 r.inHistory = true; 2894 r.frontOfTask = newTask; 2895 r.task.numActivities++; 2896 if (NH > 0) { 2897 // We want to show the starting preview window if we are 2898 // switching to a new task, or the next activity's process is 2899 // not currently running. 2900 boolean showStartingIcon = newTask; 2901 ProcessRecord proc = r.app; 2902 if (proc == null) { 2903 proc = mProcessNames.get(r.processName, r.info.applicationInfo.uid); 2904 } 2905 if (proc == null || proc.thread == null) { 2906 showStartingIcon = true; 2907 } 2908 if (DEBUG_TRANSITION) Log.v(TAG, 2909 "Prepare open transition: starting " + r); 2910 if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { 2911 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 2912 mNoAnimActivities.add(r); 2913 } else if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) { 2914 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_OPEN); 2915 mNoAnimActivities.remove(r); 2916 } else { 2917 mWindowManager.prepareAppTransition(newTask 2918 ? WindowManagerPolicy.TRANSIT_TASK_OPEN 2919 : WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN); 2920 mNoAnimActivities.remove(r); 2921 } 2922 mWindowManager.addAppToken( 2923 addPos, r, r.task.taskId, r.info.screenOrientation, r.fullscreen); 2924 boolean doShow = true; 2925 if (newTask) { 2926 // Even though this activity is starting fresh, we still need 2927 // to reset it to make sure we apply affinities to move any 2928 // existing activities from other tasks in to it. 2929 // If the caller has requested that the target task be 2930 // reset, then do so. 2931 if ((r.intent.getFlags() 2932 &Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 2933 resetTaskIfNeededLocked(r, r); 2934 doShow = topRunningNonDelayedActivityLocked(null) == r; 2935 } 2936 } 2937 if (SHOW_APP_STARTING_ICON && doShow) { 2938 // Figure out if we are transitioning from another activity that is 2939 // "has the same starting icon" as the next one. This allows the 2940 // window manager to keep the previous window it had previously 2941 // created, if it still had one. 2942 HistoryRecord prev = mResumedActivity; 2943 if (prev != null) { 2944 // We don't want to reuse the previous starting preview if: 2945 // (1) The current activity is in a different task. 2946 if (prev.task != r.task) prev = null; 2947 // (2) The current activity is already displayed. 2948 else if (prev.nowVisible) prev = null; 2949 } 2950 mWindowManager.setAppStartingWindow( 2951 r, r.packageName, r.theme, r.nonLocalizedLabel, 2952 r.labelRes, r.icon, prev, showStartingIcon); 2953 } 2954 } else { 2955 // If this is the first activity, don't do any fancy animations, 2956 // because there is nothing for it to animate on top of. 2957 mWindowManager.addAppToken(addPos, r, r.task.taskId, 2958 r.info.screenOrientation, r.fullscreen); 2959 } 2960 if (VALIDATE_TOKENS) { 2961 mWindowManager.validateAppTokens(mHistory); 2962 } 2963 2964 if (doResume) { 2965 resumeTopActivityLocked(null); 2966 } 2967 } 2968 2969 /** 2970 * Perform clear operation as requested by 2971 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the 2972 * stack to the given task, then look for 2973 * an instance of that activity in the stack and, if found, finish all 2974 * activities on top of it and return the instance. 2975 * 2976 * @param newR Description of the new activity being started. 2977 * @return Returns the old activity that should be continue to be used, 2978 * or null if none was found. 2979 */ 2980 private final HistoryRecord performClearTaskLocked(int taskId, 2981 HistoryRecord newR, int launchFlags, boolean doClear) { 2982 int i = mHistory.size(); 2983 2984 // First find the requested task. 2985 while (i > 0) { 2986 i--; 2987 HistoryRecord r = (HistoryRecord)mHistory.get(i); 2988 if (r.task.taskId == taskId) { 2989 i++; 2990 break; 2991 } 2992 } 2993 2994 // Now clear it. 2995 while (i > 0) { 2996 i--; 2997 HistoryRecord r = (HistoryRecord)mHistory.get(i); 2998 if (r.finishing) { 2999 continue; 3000 } 3001 if (r.task.taskId != taskId) { 3002 return null; 3003 } 3004 if (r.realActivity.equals(newR.realActivity)) { 3005 // Here it is! Now finish everything in front... 3006 HistoryRecord ret = r; 3007 if (doClear) { 3008 while (i < (mHistory.size()-1)) { 3009 i++; 3010 r = (HistoryRecord)mHistory.get(i); 3011 if (r.finishing) { 3012 continue; 3013 } 3014 if (finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3015 null, "clear")) { 3016 i--; 3017 } 3018 } 3019 } 3020 3021 // Finally, if this is a normal launch mode (that is, not 3022 // expecting onNewIntent()), then we will finish the current 3023 // instance of the activity so a new fresh one can be started. 3024 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE 3025 && (launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) { 3026 if (!ret.finishing) { 3027 int index = indexOfTokenLocked(ret); 3028 if (index >= 0) { 3029 finishActivityLocked(ret, 0, Activity.RESULT_CANCELED, 3030 null, "clear"); 3031 } 3032 return null; 3033 } 3034 } 3035 3036 return ret; 3037 } 3038 } 3039 3040 return null; 3041 } 3042 3043 /** 3044 * Find the activity in the history stack within the given task. Returns 3045 * the index within the history at which it's found, or < 0 if not found. 3046 */ 3047 private final int findActivityInHistoryLocked(HistoryRecord r, int task) { 3048 int i = mHistory.size(); 3049 while (i > 0) { 3050 i--; 3051 HistoryRecord candidate = (HistoryRecord)mHistory.get(i); 3052 if (candidate.task.taskId != task) { 3053 break; 3054 } 3055 if (candidate.realActivity.equals(r.realActivity)) { 3056 return i; 3057 } 3058 } 3059 3060 return -1; 3061 } 3062 3063 /** 3064 * Reorder the history stack so that the activity at the given index is 3065 * brought to the front. 3066 */ 3067 private final HistoryRecord moveActivityToFrontLocked(int where) { 3068 HistoryRecord newTop = (HistoryRecord)mHistory.remove(where); 3069 int top = mHistory.size(); 3070 HistoryRecord oldTop = (HistoryRecord)mHistory.get(top-1); 3071 mHistory.add(top, newTop); 3072 oldTop.frontOfTask = false; 3073 newTop.frontOfTask = true; 3074 return newTop; 3075 } 3076 3077 /** 3078 * Deliver a new Intent to an existing activity, so that its onNewIntent() 3079 * method will be called at the proper time. 3080 */ 3081 private final void deliverNewIntentLocked(HistoryRecord r, Intent intent) { 3082 boolean sent = false; 3083 if (r.state == ActivityState.RESUMED 3084 && r.app != null && r.app.thread != null) { 3085 try { 3086 ArrayList<Intent> ar = new ArrayList<Intent>(); 3087 ar.add(new Intent(intent)); 3088 r.app.thread.scheduleNewIntent(ar, r); 3089 sent = true; 3090 } catch (Exception e) { 3091 Log.w(TAG, "Exception thrown sending new intent to " + r, e); 3092 } 3093 } 3094 if (!sent) { 3095 r.addNewIntentLocked(new Intent(intent)); 3096 } 3097 } 3098 3099 private final void logStartActivity(int tag, HistoryRecord r, 3100 TaskRecord task) { 3101 EventLog.writeEvent(tag, 3102 System.identityHashCode(r), task.taskId, 3103 r.shortComponentName, r.intent.getAction(), 3104 r.intent.getType(), r.intent.getDataString(), 3105 r.intent.getFlags()); 3106 } 3107 3108 private final int startActivityLocked(IApplicationThread caller, 3109 Intent intent, String resolvedType, 3110 Uri[] grantedUriPermissions, 3111 int grantedMode, ActivityInfo aInfo, IBinder resultTo, 3112 String resultWho, int requestCode, 3113 int callingPid, int callingUid, boolean onlyIfNeeded, 3114 boolean componentSpecified) { 3115 Log.i(TAG, "Starting activity: " + intent); 3116 3117 HistoryRecord sourceRecord = null; 3118 HistoryRecord resultRecord = null; 3119 if (resultTo != null) { 3120 int index = indexOfTokenLocked(resultTo); 3121 if (DEBUG_RESULTS) Log.v( 3122 TAG, "Sending result to " + resultTo + " (index " + index + ")"); 3123 if (index >= 0) { 3124 sourceRecord = (HistoryRecord)mHistory.get(index); 3125 if (requestCode >= 0 && !sourceRecord.finishing) { 3126 resultRecord = sourceRecord; 3127 } 3128 } 3129 } 3130 3131 int launchFlags = intent.getFlags(); 3132 3133 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 3134 && sourceRecord != null) { 3135 // Transfer the result target from the source activity to the new 3136 // one being started, including any failures. 3137 if (requestCode >= 0) { 3138 return START_FORWARD_AND_REQUEST_CONFLICT; 3139 } 3140 resultRecord = sourceRecord.resultTo; 3141 resultWho = sourceRecord.resultWho; 3142 requestCode = sourceRecord.requestCode; 3143 sourceRecord.resultTo = null; 3144 if (resultRecord != null) { 3145 resultRecord.removeResultsLocked( 3146 sourceRecord, resultWho, requestCode); 3147 } 3148 } 3149 3150 int err = START_SUCCESS; 3151 3152 if (intent.getComponent() == null) { 3153 // We couldn't find a class that can handle the given Intent. 3154 // That's the end of that! 3155 err = START_INTENT_NOT_RESOLVED; 3156 } 3157 3158 if (err == START_SUCCESS && aInfo == null) { 3159 // We couldn't find the specific class specified in the Intent. 3160 // Also the end of the line. 3161 err = START_CLASS_NOT_FOUND; 3162 } 3163 3164 ProcessRecord callerApp = null; 3165 if (err == START_SUCCESS && caller != null) { 3166 callerApp = getRecordForAppLocked(caller); 3167 if (callerApp != null) { 3168 callingPid = callerApp.pid; 3169 callingUid = callerApp.info.uid; 3170 } else { 3171 Log.w(TAG, "Unable to find app for caller " + caller 3172 + " (pid=" + callingPid + ") when starting: " 3173 + intent.toString()); 3174 err = START_PERMISSION_DENIED; 3175 } 3176 } 3177 3178 if (err != START_SUCCESS) { 3179 if (resultRecord != null) { 3180 sendActivityResultLocked(-1, 3181 resultRecord, resultWho, requestCode, 3182 Activity.RESULT_CANCELED, null); 3183 } 3184 return err; 3185 } 3186 3187 final int perm = checkComponentPermission(aInfo.permission, callingPid, 3188 callingUid, aInfo.exported ? -1 : aInfo.applicationInfo.uid); 3189 if (perm != PackageManager.PERMISSION_GRANTED) { 3190 if (resultRecord != null) { 3191 sendActivityResultLocked(-1, 3192 resultRecord, resultWho, requestCode, 3193 Activity.RESULT_CANCELED, null); 3194 } 3195 String msg = "Permission Denial: starting " + intent.toString() 3196 + " from " + callerApp + " (pid=" + callingPid 3197 + ", uid=" + callingUid + ")" 3198 + " requires " + aInfo.permission; 3199 Log.w(TAG, msg); 3200 throw new SecurityException(msg); 3201 } 3202 3203 if (mController != null) { 3204 boolean abort = false; 3205 try { 3206 // The Intent we give to the watcher has the extra data 3207 // stripped off, since it can contain private information. 3208 Intent watchIntent = intent.cloneFilter(); 3209 abort = !mController.activityStarting(watchIntent, 3210 aInfo.applicationInfo.packageName); 3211 } catch (RemoteException e) { 3212 mController = null; 3213 } 3214 3215 if (abort) { 3216 if (resultRecord != null) { 3217 sendActivityResultLocked(-1, 3218 resultRecord, resultWho, requestCode, 3219 Activity.RESULT_CANCELED, null); 3220 } 3221 // We pretend to the caller that it was really started, but 3222 // they will just get a cancel result. 3223 return START_SUCCESS; 3224 } 3225 } 3226 3227 HistoryRecord r = new HistoryRecord(this, callerApp, callingUid, 3228 intent, resolvedType, aInfo, mConfiguration, 3229 resultRecord, resultWho, requestCode, componentSpecified); 3230 3231 if (mResumedActivity == null 3232 || mResumedActivity.info.applicationInfo.uid != callingUid) { 3233 if (!checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) { 3234 PendingActivityLaunch pal = new PendingActivityLaunch(); 3235 pal.r = r; 3236 pal.sourceRecord = sourceRecord; 3237 pal.grantedUriPermissions = grantedUriPermissions; 3238 pal.grantedMode = grantedMode; 3239 pal.onlyIfNeeded = onlyIfNeeded; 3240 mPendingActivityLaunches.add(pal); 3241 return START_SWITCHES_CANCELED; 3242 } 3243 } 3244 3245 if (mDidAppSwitch) { 3246 // This is the second allowed switch since we stopped switches, 3247 // so now just generally allow switches. Use case: user presses 3248 // home (switches disabled, switch to home, mDidAppSwitch now true); 3249 // user taps a home icon (coming from home so allowed, we hit here 3250 // and now allow anyone to switch again). 3251 mAppSwitchesAllowedTime = 0; 3252 } else { 3253 mDidAppSwitch = true; 3254 } 3255 3256 doPendingActivityLaunchesLocked(false); 3257 3258 return startActivityUncheckedLocked(r, sourceRecord, 3259 grantedUriPermissions, grantedMode, onlyIfNeeded, true); 3260 } 3261 3262 private final void doPendingActivityLaunchesLocked(boolean doResume) { 3263 final int N = mPendingActivityLaunches.size(); 3264 if (N <= 0) { 3265 return; 3266 } 3267 for (int i=0; i<N; i++) { 3268 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3269 startActivityUncheckedLocked(pal.r, pal.sourceRecord, 3270 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded, 3271 doResume && i == (N-1)); 3272 } 3273 mPendingActivityLaunches.clear(); 3274 } 3275 3276 private final int startActivityUncheckedLocked(HistoryRecord r, 3277 HistoryRecord sourceRecord, Uri[] grantedUriPermissions, 3278 int grantedMode, boolean onlyIfNeeded, boolean doResume) { 3279 final Intent intent = r.intent; 3280 final int callingUid = r.launchedFromUid; 3281 3282 int launchFlags = intent.getFlags(); 3283 3284 // We'll invoke onUserLeaving before onPause only if the launching 3285 // activity did not explicitly state that this is an automated launch. 3286 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0; 3287 if (DEBUG_USER_LEAVING) Log.v(TAG, 3288 "startActivity() => mUserLeaving=" + mUserLeaving); 3289 3290 // If the caller has asked not to resume at this point, we make note 3291 // of this in the record so that we can skip it when trying to find 3292 // the top running activity. 3293 if (!doResume) { 3294 r.delayedResume = true; 3295 } 3296 3297 HistoryRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) 3298 != 0 ? r : null; 3299 3300 // If the onlyIfNeeded flag is set, then we can do this if the activity 3301 // being launched is the same as the one making the call... or, as 3302 // a special case, if we do not know the caller then we count the 3303 // current top activity as the caller. 3304 if (onlyIfNeeded) { 3305 HistoryRecord checkedCaller = sourceRecord; 3306 if (checkedCaller == null) { 3307 checkedCaller = topRunningNonDelayedActivityLocked(notTop); 3308 } 3309 if (!checkedCaller.realActivity.equals(r.realActivity)) { 3310 // Caller is not the same as launcher, so always needed. 3311 onlyIfNeeded = false; 3312 } 3313 } 3314 3315 if (grantedUriPermissions != null && callingUid > 0) { 3316 for (int i=0; i<grantedUriPermissions.length; i++) { 3317 grantUriPermissionLocked(callingUid, r.packageName, 3318 grantedUriPermissions[i], grantedMode, r); 3319 } 3320 } 3321 3322 grantUriPermissionFromIntentLocked(callingUid, r.packageName, 3323 intent, r); 3324 3325 if (sourceRecord == null) { 3326 // This activity is not being started from another... in this 3327 // case we -always- start a new task. 3328 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 3329 Log.w(TAG, "startActivity called from non-Activity context; forcing Intent.FLAG_ACTIVITY_NEW_TASK for: " 3330 + intent); 3331 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 3332 } 3333 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 3334 // The original activity who is starting us is running as a single 3335 // instance... this new activity it is starting must go on its 3336 // own task. 3337 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 3338 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE 3339 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 3340 // The activity being started is a single instance... it always 3341 // gets launched into its own task. 3342 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 3343 } 3344 3345 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 3346 // For whatever reason this activity is being launched into a new 3347 // task... yet the caller has requested a result back. Well, that 3348 // is pretty messed up, so instead immediately send back a cancel 3349 // and let the new task continue launched as normal without a 3350 // dependency on its originator. 3351 Log.w(TAG, "Activity is launching as a new task, so cancelling activity result."); 3352 sendActivityResultLocked(-1, 3353 r.resultTo, r.resultWho, r.requestCode, 3354 Activity.RESULT_CANCELED, null); 3355 r.resultTo = null; 3356 } 3357 3358 boolean addingToTask = false; 3359 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && 3360 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) 3361 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 3362 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 3363 // If bring to front is requested, and no result is requested, and 3364 // we can find a task that was started with this same 3365 // component, then instead of launching bring that one to the front. 3366 if (r.resultTo == null) { 3367 // See if there is a task to bring to the front. If this is 3368 // a SINGLE_INSTANCE activity, there can be one and only one 3369 // instance of it in the history, and it is always in its own 3370 // unique task, so we do a special search. 3371 HistoryRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE 3372 ? findTaskLocked(intent, r.info) 3373 : findActivityLocked(intent, r.info); 3374 if (taskTop != null) { 3375 if (taskTop.task.intent == null) { 3376 // This task was started because of movement of 3377 // the activity based on affinity... now that we 3378 // are actually launching it, we can assign the 3379 // base intent. 3380 taskTop.task.setIntent(intent, r.info); 3381 } 3382 // If the target task is not in the front, then we need 3383 // to bring it to the front... except... well, with 3384 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like 3385 // to have the same behavior as if a new instance was 3386 // being started, which means not bringing it to the front 3387 // if the caller is not itself in the front. 3388 HistoryRecord curTop = topRunningNonDelayedActivityLocked(notTop); 3389 if (curTop.task != taskTop.task) { 3390 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); 3391 boolean callerAtFront = sourceRecord == null 3392 || curTop.task == sourceRecord.task; 3393 if (callerAtFront) { 3394 // We really do want to push this one into the 3395 // user's face, right now. 3396 moveTaskToFrontLocked(taskTop.task, r); 3397 } 3398 } 3399 // If the caller has requested that the target task be 3400 // reset, then do so. 3401 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 3402 taskTop = resetTaskIfNeededLocked(taskTop, r); 3403 } 3404 if (onlyIfNeeded) { 3405 // We don't need to start a new activity, and 3406 // the client said not to do anything if that 3407 // is the case, so this is it! And for paranoia, make 3408 // sure we have correctly resumed the top activity. 3409 if (doResume) { 3410 resumeTopActivityLocked(null); 3411 } 3412 return START_RETURN_INTENT_TO_CALLER; 3413 } 3414 if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0 3415 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 3416 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 3417 // In this situation we want to remove all activities 3418 // from the task up to the one being started. In most 3419 // cases this means we are resetting the task to its 3420 // initial state. 3421 HistoryRecord top = performClearTaskLocked( 3422 taskTop.task.taskId, r, launchFlags, true); 3423 if (top != null) { 3424 if (top.frontOfTask) { 3425 // Activity aliases may mean we use different 3426 // intents for the top activity, so make sure 3427 // the task now has the identity of the new 3428 // intent. 3429 top.task.setIntent(r.intent, r.info); 3430 } 3431 logStartActivity(LOG_AM_NEW_INTENT, r, top.task); 3432 deliverNewIntentLocked(top, r.intent); 3433 } else { 3434 // A special case: we need to 3435 // start the activity because it is not currently 3436 // running, and the caller has asked to clear the 3437 // current task to have this activity at the top. 3438 addingToTask = true; 3439 // Now pretend like this activity is being started 3440 // by the top of its task, so it is put in the 3441 // right place. 3442 sourceRecord = taskTop; 3443 } 3444 } else if (r.realActivity.equals(taskTop.task.realActivity)) { 3445 // In this case the top activity on the task is the 3446 // same as the one being launched, so we take that 3447 // as a request to bring the task to the foreground. 3448 // If the top activity in the task is the root 3449 // activity, deliver this new intent to it if it 3450 // desires. 3451 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 3452 && taskTop.realActivity.equals(r.realActivity)) { 3453 logStartActivity(LOG_AM_NEW_INTENT, r, taskTop.task); 3454 if (taskTop.frontOfTask) { 3455 taskTop.task.setIntent(r.intent, r.info); 3456 } 3457 deliverNewIntentLocked(taskTop, r.intent); 3458 } else if (!r.intent.filterEquals(taskTop.task.intent)) { 3459 // In this case we are launching the root activity 3460 // of the task, but with a different intent. We 3461 // should start a new instance on top. 3462 addingToTask = true; 3463 sourceRecord = taskTop; 3464 } 3465 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) { 3466 // In this case an activity is being launched in to an 3467 // existing task, without resetting that task. This 3468 // is typically the situation of launching an activity 3469 // from a notification or shortcut. We want to place 3470 // the new activity on top of the current task. 3471 addingToTask = true; 3472 sourceRecord = taskTop; 3473 } else if (!taskTop.task.rootWasReset) { 3474 // In this case we are launching in to an existing task 3475 // that has not yet been started from its front door. 3476 // The current task has been brought to the front. 3477 // Ideally, we'd probably like to place this new task 3478 // at the bottom of its stack, but that's a little hard 3479 // to do with the current organization of the code so 3480 // for now we'll just drop it. 3481 taskTop.task.setIntent(r.intent, r.info); 3482 } 3483 if (!addingToTask) { 3484 // We didn't do anything... but it was needed (a.k.a., client 3485 // don't use that intent!) And for paranoia, make 3486 // sure we have correctly resumed the top activity. 3487 if (doResume) { 3488 resumeTopActivityLocked(null); 3489 } 3490 return START_TASK_TO_FRONT; 3491 } 3492 } 3493 } 3494 } 3495 3496 //String uri = r.intent.toURI(); 3497 //Intent intent2 = new Intent(uri); 3498 //Log.i(TAG, "Given intent: " + r.intent); 3499 //Log.i(TAG, "URI is: " + uri); 3500 //Log.i(TAG, "To intent: " + intent2); 3501 3502 if (r.packageName != null) { 3503 // If the activity being launched is the same as the one currently 3504 // at the top, then we need to check if it should only be launched 3505 // once. 3506 HistoryRecord top = topRunningNonDelayedActivityLocked(notTop); 3507 if (top != null && r.resultTo == null) { 3508 if (top.realActivity.equals(r.realActivity)) { 3509 if (top.app != null && top.app.thread != null) { 3510 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 3511 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP 3512 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 3513 logStartActivity(LOG_AM_NEW_INTENT, top, top.task); 3514 // For paranoia, make sure we have correctly 3515 // resumed the top activity. 3516 if (doResume) { 3517 resumeTopActivityLocked(null); 3518 } 3519 if (onlyIfNeeded) { 3520 // We don't need to start a new activity, and 3521 // the client said not to do anything if that 3522 // is the case, so this is it! 3523 return START_RETURN_INTENT_TO_CALLER; 3524 } 3525 deliverNewIntentLocked(top, r.intent); 3526 return START_DELIVERED_TO_TOP; 3527 } 3528 } 3529 } 3530 } 3531 3532 } else { 3533 if (r.resultTo != null) { 3534 sendActivityResultLocked(-1, 3535 r.resultTo, r.resultWho, r.requestCode, 3536 Activity.RESULT_CANCELED, null); 3537 } 3538 return START_CLASS_NOT_FOUND; 3539 } 3540 3541 boolean newTask = false; 3542 3543 // Should this be considered a new task? 3544 if (r.resultTo == null && !addingToTask 3545 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 3546 // todo: should do better management of integers. 3547 mCurTask++; 3548 if (mCurTask <= 0) { 3549 mCurTask = 1; 3550 } 3551 r.task = new TaskRecord(mCurTask, r.info, intent, 3552 (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0); 3553 if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r 3554 + " in new task " + r.task); 3555 newTask = true; 3556 addRecentTask(r.task); 3557 3558 } else if (sourceRecord != null) { 3559 if (!addingToTask && 3560 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 3561 // In this case, we are adding the activity to an existing 3562 // task, but the caller has asked to clear that task if the 3563 // activity is already running. 3564 HistoryRecord top = performClearTaskLocked( 3565 sourceRecord.task.taskId, r, launchFlags, true); 3566 if (top != null) { 3567 logStartActivity(LOG_AM_NEW_INTENT, r, top.task); 3568 deliverNewIntentLocked(top, r.intent); 3569 // For paranoia, make sure we have correctly 3570 // resumed the top activity. 3571 if (doResume) { 3572 resumeTopActivityLocked(null); 3573 } 3574 return START_DELIVERED_TO_TOP; 3575 } 3576 } else if (!addingToTask && 3577 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { 3578 // In this case, we are launching an activity in our own task 3579 // that may already be running somewhere in the history, and 3580 // we want to shuffle it to the front of the stack if so. 3581 int where = findActivityInHistoryLocked(r, sourceRecord.task.taskId); 3582 if (where >= 0) { 3583 HistoryRecord top = moveActivityToFrontLocked(where); 3584 logStartActivity(LOG_AM_NEW_INTENT, r, top.task); 3585 deliverNewIntentLocked(top, r.intent); 3586 if (doResume) { 3587 resumeTopActivityLocked(null); 3588 } 3589 return START_DELIVERED_TO_TOP; 3590 } 3591 } 3592 // An existing activity is starting this new activity, so we want 3593 // to keep the new one in the same task as the one that is starting 3594 // it. 3595 r.task = sourceRecord.task; 3596 if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r 3597 + " in existing task " + r.task); 3598 3599 } else { 3600 // This not being started from an existing activity, and not part 3601 // of a new task... just put it in the top task, though these days 3602 // this case should never happen. 3603 final int N = mHistory.size(); 3604 HistoryRecord prev = 3605 N > 0 ? (HistoryRecord)mHistory.get(N-1) : null; 3606 r.task = prev != null 3607 ? prev.task 3608 : new TaskRecord(mCurTask, r.info, intent, 3609 (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0); 3610 if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r 3611 + " in new guessed " + r.task); 3612 } 3613 if (newTask) { 3614 EventLog.writeEvent(LOG_AM_CREATE_TASK, r.task.taskId); 3615 } 3616 logStartActivity(LOG_AM_CREATE_ACTIVITY, r, r.task); 3617 startActivityLocked(r, newTask, doResume); 3618 return START_SUCCESS; 3619 } 3620 3621 public final int startActivity(IApplicationThread caller, 3622 Intent intent, String resolvedType, Uri[] grantedUriPermissions, 3623 int grantedMode, IBinder resultTo, 3624 String resultWho, int requestCode, boolean onlyIfNeeded, 3625 boolean debug) { 3626 // Refuse possible leaked file descriptors 3627 if (intent != null && intent.hasFileDescriptors()) { 3628 throw new IllegalArgumentException("File descriptors passed in Intent"); 3629 } 3630 3631 final boolean componentSpecified = intent.getComponent() != null; 3632 3633 // Don't modify the client's object! 3634 intent = new Intent(intent); 3635 3636 // Collect information about the target of the Intent. 3637 ActivityInfo aInfo; 3638 try { 3639 ResolveInfo rInfo = 3640 ActivityThread.getPackageManager().resolveIntent( 3641 intent, resolvedType, 3642 PackageManager.MATCH_DEFAULT_ONLY 3643 | STOCK_PM_FLAGS); 3644 aInfo = rInfo != null ? rInfo.activityInfo : null; 3645 } catch (RemoteException e) { 3646 aInfo = null; 3647 } 3648 3649 if (aInfo != null) { 3650 // Store the found target back into the intent, because now that 3651 // we have it we never want to do this again. For example, if the 3652 // user navigates back to this point in the history, we should 3653 // always restart the exact same activity. 3654 intent.setComponent(new ComponentName( 3655 aInfo.applicationInfo.packageName, aInfo.name)); 3656 3657 // Don't debug things in the system process 3658 if (debug) { 3659 if (!aInfo.processName.equals("system")) { 3660 setDebugApp(aInfo.processName, true, false); 3661 } 3662 } 3663 } 3664 3665 synchronized(this) { 3666 final long origId = Binder.clearCallingIdentity(); 3667 int res = startActivityLocked(caller, intent, resolvedType, 3668 grantedUriPermissions, grantedMode, aInfo, 3669 resultTo, resultWho, requestCode, -1, -1, 3670 onlyIfNeeded, componentSpecified); 3671 Binder.restoreCallingIdentity(origId); 3672 return res; 3673 } 3674 } 3675 3676 public int startActivityIntentSender(IApplicationThread caller, 3677 IntentSender intent, Intent fillInIntent, String resolvedType, 3678 IBinder resultTo, String resultWho, int requestCode, 3679 int flagsMask, int flagsValues) { 3680 // Refuse possible leaked file descriptors 3681 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3682 throw new IllegalArgumentException("File descriptors passed in Intent"); 3683 } 3684 3685 IIntentSender sender = intent.getTarget(); 3686 if (!(sender instanceof PendingIntentRecord)) { 3687 throw new IllegalArgumentException("Bad PendingIntent object"); 3688 } 3689 3690 PendingIntentRecord pir = (PendingIntentRecord)sender; 3691 3692 synchronized (this) { 3693 // If this is coming from the currently resumed activity, it is 3694 // effectively saying that app switches are allowed at this point. 3695 if (mResumedActivity != null 3696 && mResumedActivity.info.applicationInfo.uid == 3697 Binder.getCallingUid()) { 3698 mAppSwitchesAllowedTime = 0; 3699 } 3700 } 3701 3702 return pir.sendInner(0, fillInIntent, resolvedType, 3703 null, resultTo, resultWho, requestCode, flagsMask, flagsValues); 3704 } 3705 3706 public boolean startNextMatchingActivity(IBinder callingActivity, 3707 Intent intent) { 3708 // Refuse possible leaked file descriptors 3709 if (intent != null && intent.hasFileDescriptors() == true) { 3710 throw new IllegalArgumentException("File descriptors passed in Intent"); 3711 } 3712 3713 synchronized (this) { 3714 int index = indexOfTokenLocked(callingActivity); 3715 if (index < 0) { 3716 return false; 3717 } 3718 HistoryRecord r = (HistoryRecord)mHistory.get(index); 3719 if (r.app == null || r.app.thread == null) { 3720 // The caller is not running... d'oh! 3721 return false; 3722 } 3723 intent = new Intent(intent); 3724 // The caller is not allowed to change the data. 3725 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3726 // And we are resetting to find the next component... 3727 intent.setComponent(null); 3728 3729 ActivityInfo aInfo = null; 3730 try { 3731 List<ResolveInfo> resolves = 3732 ActivityThread.getPackageManager().queryIntentActivities( 3733 intent, r.resolvedType, 3734 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS); 3735 3736 // Look for the original activity in the list... 3737 final int N = resolves != null ? resolves.size() : 0; 3738 for (int i=0; i<N; i++) { 3739 ResolveInfo rInfo = resolves.get(i); 3740 if (rInfo.activityInfo.packageName.equals(r.packageName) 3741 && rInfo.activityInfo.name.equals(r.info.name)) { 3742 // We found the current one... the next matching is 3743 // after it. 3744 i++; 3745 if (i<N) { 3746 aInfo = resolves.get(i).activityInfo; 3747 } 3748 break; 3749 } 3750 } 3751 } catch (RemoteException e) { 3752 } 3753 3754 if (aInfo == null) { 3755 // Nobody who is next! 3756 return false; 3757 } 3758 3759 intent.setComponent(new ComponentName( 3760 aInfo.applicationInfo.packageName, aInfo.name)); 3761 intent.setFlags(intent.getFlags()&~( 3762 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3763 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3764 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3765 Intent.FLAG_ACTIVITY_NEW_TASK)); 3766 3767 // Okay now we need to start the new activity, replacing the 3768 // currently running activity. This is a little tricky because 3769 // we want to start the new one as if the current one is finished, 3770 // but not finish the current one first so that there is no flicker. 3771 // And thus... 3772 final boolean wasFinishing = r.finishing; 3773 r.finishing = true; 3774 3775 // Propagate reply information over to the new activity. 3776 final HistoryRecord resultTo = r.resultTo; 3777 final String resultWho = r.resultWho; 3778 final int requestCode = r.requestCode; 3779 r.resultTo = null; 3780 if (resultTo != null) { 3781 resultTo.removeResultsLocked(r, resultWho, requestCode); 3782 } 3783 3784 final long origId = Binder.clearCallingIdentity(); 3785 // XXX we are not dealing with propagating grantedUriPermissions... 3786 // those are not yet exposed to user code, so there is no need. 3787 int res = startActivityLocked(r.app.thread, intent, 3788 r.resolvedType, null, 0, aInfo, resultTo, resultWho, 3789 requestCode, -1, r.launchedFromUid, false, false); 3790 Binder.restoreCallingIdentity(origId); 3791 3792 r.finishing = wasFinishing; 3793 if (res != START_SUCCESS) { 3794 return false; 3795 } 3796 return true; 3797 } 3798 } 3799 3800 public final int startActivityInPackage(int uid, 3801 Intent intent, String resolvedType, IBinder resultTo, 3802 String resultWho, int requestCode, boolean onlyIfNeeded) { 3803 3804 // This is so super not safe, that only the system (or okay root) 3805 // can do it. 3806 final int callingUid = Binder.getCallingUid(); 3807 if (callingUid != 0 && callingUid != Process.myUid()) { 3808 throw new SecurityException( 3809 "startActivityInPackage only available to the system"); 3810 } 3811 3812 final boolean componentSpecified = intent.getComponent() != null; 3813 3814 // Don't modify the client's object! 3815 intent = new Intent(intent); 3816 3817 // Collect information about the target of the Intent. 3818 ActivityInfo aInfo; 3819 try { 3820 ResolveInfo rInfo = 3821 ActivityThread.getPackageManager().resolveIntent( 3822 intent, resolvedType, 3823 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS); 3824 aInfo = rInfo != null ? rInfo.activityInfo : null; 3825 } catch (RemoteException e) { 3826 aInfo = null; 3827 } 3828 3829 if (aInfo != null) { 3830 // Store the found target back into the intent, because now that 3831 // we have it we never want to do this again. For example, if the 3832 // user navigates back to this point in the history, we should 3833 // always restart the exact same activity. 3834 intent.setComponent(new ComponentName( 3835 aInfo.applicationInfo.packageName, aInfo.name)); 3836 } 3837 3838 synchronized(this) { 3839 return startActivityLocked(null, intent, resolvedType, 3840 null, 0, aInfo, resultTo, resultWho, requestCode, -1, uid, 3841 onlyIfNeeded, componentSpecified); 3842 } 3843 } 3844 3845 private final void addRecentTask(TaskRecord task) { 3846 // Remove any existing entries that are the same kind of task. 3847 int N = mRecentTasks.size(); 3848 for (int i=0; i<N; i++) { 3849 TaskRecord tr = mRecentTasks.get(i); 3850 if ((task.affinity != null && task.affinity.equals(tr.affinity)) 3851 || (task.intent != null && task.intent.filterEquals(tr.intent))) { 3852 mRecentTasks.remove(i); 3853 i--; 3854 N--; 3855 if (task.intent == null) { 3856 // If the new recent task we are adding is not fully 3857 // specified, then replace it with the existing recent task. 3858 task = tr; 3859 } 3860 } 3861 } 3862 if (N >= MAX_RECENT_TASKS) { 3863 mRecentTasks.remove(N-1); 3864 } 3865 mRecentTasks.add(0, task); 3866 } 3867 3868 public void setRequestedOrientation(IBinder token, 3869 int requestedOrientation) { 3870 synchronized (this) { 3871 int index = indexOfTokenLocked(token); 3872 if (index < 0) { 3873 return; 3874 } 3875 HistoryRecord r = (HistoryRecord)mHistory.get(index); 3876 final long origId = Binder.clearCallingIdentity(); 3877 mWindowManager.setAppOrientation(r, requestedOrientation); 3878 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3879 mConfiguration, 3880 r.mayFreezeScreenLocked(r.app) ? r : null); 3881 if (config != null) { 3882 r.frozenBeforeDestroy = true; 3883 if (!updateConfigurationLocked(config, r)) { 3884 resumeTopActivityLocked(null); 3885 } 3886 } 3887 Binder.restoreCallingIdentity(origId); 3888 } 3889 } 3890 3891 public int getRequestedOrientation(IBinder token) { 3892 synchronized (this) { 3893 int index = indexOfTokenLocked(token); 3894 if (index < 0) { 3895 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3896 } 3897 HistoryRecord r = (HistoryRecord)mHistory.get(index); 3898 return mWindowManager.getAppOrientation(r); 3899 } 3900 } 3901 3902 private final void stopActivityLocked(HistoryRecord r) { 3903 if (DEBUG_SWITCH) Log.d(TAG, "Stopping: " + r); 3904 if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0 3905 || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) { 3906 if (!r.finishing) { 3907 requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null, 3908 "no-history"); 3909 } 3910 } else if (r.app != null && r.app.thread != null) { 3911 if (mFocusedActivity == r) { 3912 setFocusedActivityLocked(topRunningActivityLocked(null)); 3913 } 3914 r.resumeKeyDispatchingLocked(); 3915 try { 3916 r.stopped = false; 3917 r.state = ActivityState.STOPPING; 3918 if (DEBUG_VISBILITY) Log.v( 3919 TAG, "Stopping visible=" + r.visible + " for " + r); 3920 if (!r.visible) { 3921 mWindowManager.setAppVisibility(r, false); 3922 } 3923 r.app.thread.scheduleStopActivity(r, r.visible, r.configChangeFlags); 3924 } catch (Exception e) { 3925 // Maybe just ignore exceptions here... if the process 3926 // has crashed, our death notification will clean things 3927 // up. 3928 Log.w(TAG, "Exception thrown during pause", e); 3929 // Just in case, assume it to be stopped. 3930 r.stopped = true; 3931 r.state = ActivityState.STOPPED; 3932 if (r.configDestroy) { 3933 destroyActivityLocked(r, true); 3934 } 3935 } 3936 } 3937 } 3938 3939 /** 3940 * @return Returns true if the activity is being finished, false if for 3941 * some reason it is being left as-is. 3942 */ 3943 private final boolean requestFinishActivityLocked(IBinder token, int resultCode, 3944 Intent resultData, String reason) { 3945 if (DEBUG_RESULTS) Log.v( 3946 TAG, "Finishing activity: token=" + token 3947 + ", result=" + resultCode + ", data=" + resultData); 3948 3949 int index = indexOfTokenLocked(token); 3950 if (index < 0) { 3951 return false; 3952 } 3953 HistoryRecord r = (HistoryRecord)mHistory.get(index); 3954 3955 // Is this the last activity left? 3956 boolean lastActivity = true; 3957 for (int i=mHistory.size()-1; i>=0; i--) { 3958 HistoryRecord p = (HistoryRecord)mHistory.get(i); 3959 if (!p.finishing && p != r) { 3960 lastActivity = false; 3961 break; 3962 } 3963 } 3964 3965 // If this is the last activity, but it is the home activity, then 3966 // just don't finish it. 3967 if (lastActivity) { 3968 if (r.intent.hasCategory(Intent.CATEGORY_HOME)) { 3969 return false; 3970 } 3971 } 3972 3973 finishActivityLocked(r, index, resultCode, resultData, reason); 3974 return true; 3975 } 3976 3977 /** 3978 * @return Returns true if this activity has been removed from the history 3979 * list, or false if it is still in the list and will be removed later. 3980 */ 3981 private final boolean finishActivityLocked(HistoryRecord r, int index, 3982 int resultCode, Intent resultData, String reason) { 3983 if (r.finishing) { 3984 Log.w(TAG, "Duplicate finish request for " + r); 3985 return false; 3986 } 3987 3988 r.finishing = true; 3989 EventLog.writeEvent(LOG_AM_FINISH_ACTIVITY, 3990 System.identityHashCode(r), 3991 r.task.taskId, r.shortComponentName, reason); 3992 r.task.numActivities--; 3993 if (r.frontOfTask && index < (mHistory.size()-1)) { 3994 HistoryRecord next = (HistoryRecord)mHistory.get(index+1); 3995 if (next.task == r.task) { 3996 next.frontOfTask = true; 3997 } 3998 } 3999 4000 r.pauseKeyDispatchingLocked(); 4001 if (mFocusedActivity == r) { 4002 setFocusedActivityLocked(topRunningActivityLocked(null)); 4003 } 4004 4005 // send the result 4006 HistoryRecord resultTo = r.resultTo; 4007 if (resultTo != null) { 4008 if (DEBUG_RESULTS) Log.v(TAG, "Adding result to " + resultTo 4009 + " who=" + r.resultWho + " req=" + r.requestCode 4010 + " res=" + resultCode + " data=" + resultData); 4011 if (r.info.applicationInfo.uid > 0) { 4012 grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid, 4013 r.packageName, resultData, r); 4014 } 4015 resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode, 4016 resultData); 4017 r.resultTo = null; 4018 } 4019 else if (DEBUG_RESULTS) Log.v(TAG, "No result destination from " + r); 4020 4021 // Make sure this HistoryRecord is not holding on to other resources, 4022 // because clients have remote IPC references to this object so we 4023 // can't assume that will go away and want to avoid circular IPC refs. 4024 r.results = null; 4025 r.pendingResults = null; 4026 r.newIntents = null; 4027 r.icicle = null; 4028 4029 if (mPendingThumbnails.size() > 0) { 4030 // There are clients waiting to receive thumbnails so, in case 4031 // this is an activity that someone is waiting for, add it 4032 // to the pending list so we can correctly update the clients. 4033 mCancelledThumbnails.add(r); 4034 } 4035 4036 if (mResumedActivity == r) { 4037 boolean endTask = index <= 0 4038 || ((HistoryRecord)mHistory.get(index-1)).task != r.task; 4039 if (DEBUG_TRANSITION) Log.v(TAG, 4040 "Prepare close transition: finishing " + r); 4041 mWindowManager.prepareAppTransition(endTask 4042 ? WindowManagerPolicy.TRANSIT_TASK_CLOSE 4043 : WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE); 4044 4045 // Tell window manager to prepare for this one to be removed. 4046 mWindowManager.setAppVisibility(r, false); 4047 4048 if (mPausingActivity == null) { 4049 if (DEBUG_PAUSE) Log.v(TAG, "Finish needs to pause: " + r); 4050 if (DEBUG_USER_LEAVING) Log.v(TAG, "finish() => pause with userLeaving=false"); 4051 startPausingLocked(false, false); 4052 } 4053 4054 } else if (r.state != ActivityState.PAUSING) { 4055 // If the activity is PAUSING, we will complete the finish once 4056 // it is done pausing; else we can just directly finish it here. 4057 if (DEBUG_PAUSE) Log.v(TAG, "Finish not pausing: " + r); 4058 return finishCurrentActivityLocked(r, index, 4059 FINISH_AFTER_PAUSE) == null; 4060 } else { 4061 if (DEBUG_PAUSE) Log.v(TAG, "Finish waiting for pause of: " + r); 4062 } 4063 4064 return false; 4065 } 4066 4067 private static final int FINISH_IMMEDIATELY = 0; 4068 private static final int FINISH_AFTER_PAUSE = 1; 4069 private static final int FINISH_AFTER_VISIBLE = 2; 4070 4071 private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r, 4072 int mode) { 4073 final int index = indexOfTokenLocked(r); 4074 if (index < 0) { 4075 return null; 4076 } 4077 4078 return finishCurrentActivityLocked(r, index, mode); 4079 } 4080 4081 private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r, 4082 int index, int mode) { 4083 // First things first: if this activity is currently visible, 4084 // and the resumed activity is not yet visible, then hold off on 4085 // finishing until the resumed one becomes visible. 4086 if (mode == FINISH_AFTER_VISIBLE && r.nowVisible) { 4087 if (!mStoppingActivities.contains(r)) { 4088 mStoppingActivities.add(r); 4089 if (mStoppingActivities.size() > 3) { 4090 // If we already have a few activities waiting to stop, 4091 // then give up on things going idle and start clearing 4092 // them out. 4093 Message msg = Message.obtain(); 4094 msg.what = ActivityManagerService.IDLE_NOW_MSG; 4095 mHandler.sendMessage(msg); 4096 } 4097 } 4098 r.state = ActivityState.STOPPING; 4099 updateOomAdjLocked(); 4100 return r; 4101 } 4102 4103 // make sure the record is cleaned out of other places. 4104 mStoppingActivities.remove(r); 4105 mWaitingVisibleActivities.remove(r); 4106 if (mResumedActivity == r) { 4107 mResumedActivity = null; 4108 } 4109 final ActivityState prevState = r.state; 4110 r.state = ActivityState.FINISHING; 4111 4112 if (mode == FINISH_IMMEDIATELY 4113 || prevState == ActivityState.STOPPED 4114 || prevState == ActivityState.INITIALIZING) { 4115 // If this activity is already stopped, we can just finish 4116 // it right now. 4117 return destroyActivityLocked(r, true) ? null : r; 4118 } else { 4119 // Need to go through the full pause cycle to get this 4120 // activity into the stopped state and then finish it. 4121 if (localLOGV) Log.v(TAG, "Enqueueing pending finish: " + r); 4122 mFinishingActivities.add(r); 4123 resumeTopActivityLocked(null); 4124 } 4125 return r; 4126 } 4127 4128 /** 4129 * This is the internal entry point for handling Activity.finish(). 4130 * 4131 * @param token The Binder token referencing the Activity we want to finish. 4132 * @param resultCode Result code, if any, from this Activity. 4133 * @param resultData Result data (Intent), if any, from this Activity. 4134 * 4135 * @result Returns true if the activity successfully finished, or false if it is still running. 4136 */ 4137 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 4138 // Refuse possible leaked file descriptors 4139 if (resultData != null && resultData.hasFileDescriptors() == true) { 4140 throw new IllegalArgumentException("File descriptors passed in Intent"); 4141 } 4142 4143 synchronized(this) { 4144 if (mController != null) { 4145 // Find the first activity that is not finishing. 4146 HistoryRecord next = topRunningActivityLocked(token, 0); 4147 if (next != null) { 4148 // ask watcher if this is allowed 4149 boolean resumeOK = true; 4150 try { 4151 resumeOK = mController.activityResuming(next.packageName); 4152 } catch (RemoteException e) { 4153 mController = null; 4154 } 4155 4156 if (!resumeOK) { 4157 return false; 4158 } 4159 } 4160 } 4161 final long origId = Binder.clearCallingIdentity(); 4162 boolean res = requestFinishActivityLocked(token, resultCode, 4163 resultData, "app-request"); 4164 Binder.restoreCallingIdentity(origId); 4165 return res; 4166 } 4167 } 4168 4169 void sendActivityResultLocked(int callingUid, HistoryRecord r, 4170 String resultWho, int requestCode, int resultCode, Intent data) { 4171 4172 if (callingUid > 0) { 4173 grantUriPermissionFromIntentLocked(callingUid, r.packageName, 4174 data, r); 4175 } 4176 4177 if (DEBUG_RESULTS) Log.v(TAG, "Send activity result to " + r 4178 + " : who=" + resultWho + " req=" + requestCode 4179 + " res=" + resultCode + " data=" + data); 4180 if (mResumedActivity == r && r.app != null && r.app.thread != null) { 4181 try { 4182 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>(); 4183 list.add(new ResultInfo(resultWho, requestCode, 4184 resultCode, data)); 4185 r.app.thread.scheduleSendResult(r, list); 4186 return; 4187 } catch (Exception e) { 4188 Log.w(TAG, "Exception thrown sending result to " + r, e); 4189 } 4190 } 4191 4192 r.addResultLocked(null, resultWho, requestCode, resultCode, data); 4193 } 4194 4195 public final void finishSubActivity(IBinder token, String resultWho, 4196 int requestCode) { 4197 synchronized(this) { 4198 int index = indexOfTokenLocked(token); 4199 if (index < 0) { 4200 return; 4201 } 4202 HistoryRecord self = (HistoryRecord)mHistory.get(index); 4203 4204 final long origId = Binder.clearCallingIdentity(); 4205 4206 int i; 4207 for (i=mHistory.size()-1; i>=0; i--) { 4208 HistoryRecord r = (HistoryRecord)mHistory.get(i); 4209 if (r.resultTo == self && r.requestCode == requestCode) { 4210 if ((r.resultWho == null && resultWho == null) || 4211 (r.resultWho != null && r.resultWho.equals(resultWho))) { 4212 finishActivityLocked(r, i, 4213 Activity.RESULT_CANCELED, null, "request-sub"); 4214 } 4215 } 4216 } 4217 4218 Binder.restoreCallingIdentity(origId); 4219 } 4220 } 4221 4222 public void overridePendingTransition(IBinder token, String packageName, 4223 int enterAnim, int exitAnim) { 4224 synchronized(this) { 4225 int index = indexOfTokenLocked(token); 4226 if (index < 0) { 4227 return; 4228 } 4229 HistoryRecord self = (HistoryRecord)mHistory.get(index); 4230 4231 final long origId = Binder.clearCallingIdentity(); 4232 4233 if (self.state == ActivityState.RESUMED 4234 || self.state == ActivityState.PAUSING) { 4235 mWindowManager.overridePendingAppTransition(packageName, 4236 enterAnim, exitAnim); 4237 } 4238 4239 Binder.restoreCallingIdentity(origId); 4240 } 4241 } 4242 4243 /** 4244 * Perform clean-up of service connections in an activity record. 4245 */ 4246 private final void cleanUpActivityServicesLocked(HistoryRecord r) { 4247 // Throw away any services that have been bound by this activity. 4248 if (r.connections != null) { 4249 Iterator<ConnectionRecord> it = r.connections.iterator(); 4250 while (it.hasNext()) { 4251 ConnectionRecord c = it.next(); 4252 removeConnectionLocked(c, null, r); 4253 } 4254 r.connections = null; 4255 } 4256 } 4257 4258 /** 4259 * Perform the common clean-up of an activity record. This is called both 4260 * as part of destroyActivityLocked() (when destroying the client-side 4261 * representation) and cleaning things up as a result of its hosting 4262 * processing going away, in which case there is no remaining client-side 4263 * state to destroy so only the cleanup here is needed. 4264 */ 4265 private final void cleanUpActivityLocked(HistoryRecord r, boolean cleanServices) { 4266 if (mResumedActivity == r) { 4267 mResumedActivity = null; 4268 } 4269 if (mFocusedActivity == r) { 4270 mFocusedActivity = null; 4271 } 4272 4273 r.configDestroy = false; 4274 r.frozenBeforeDestroy = false; 4275 4276 // Make sure this record is no longer in the pending finishes list. 4277 // This could happen, for example, if we are trimming activities 4278 // down to the max limit while they are still waiting to finish. 4279 mFinishingActivities.remove(r); 4280 mWaitingVisibleActivities.remove(r); 4281 4282 // Remove any pending results. 4283 if (r.finishing && r.pendingResults != null) { 4284 for (WeakReference<PendingIntentRecord> apr : r.pendingResults) { 4285 PendingIntentRecord rec = apr.get(); 4286 if (rec != null) { 4287 cancelIntentSenderLocked(rec, false); 4288 } 4289 } 4290 r.pendingResults = null; 4291 } 4292 4293 if (cleanServices) { 4294 cleanUpActivityServicesLocked(r); 4295 } 4296 4297 if (mPendingThumbnails.size() > 0) { 4298 // There are clients waiting to receive thumbnails so, in case 4299 // this is an activity that someone is waiting for, add it 4300 // to the pending list so we can correctly update the clients. 4301 mCancelledThumbnails.add(r); 4302 } 4303 4304 // Get rid of any pending idle timeouts. 4305 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); 4306 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 4307 } 4308 4309 private final void removeActivityFromHistoryLocked(HistoryRecord r) { 4310 if (r.state != ActivityState.DESTROYED) { 4311 mHistory.remove(r); 4312 r.inHistory = false; 4313 r.state = ActivityState.DESTROYED; 4314 mWindowManager.removeAppToken(r); 4315 if (VALIDATE_TOKENS) { 4316 mWindowManager.validateAppTokens(mHistory); 4317 } 4318 cleanUpActivityServicesLocked(r); 4319 removeActivityUriPermissionsLocked(r); 4320 } 4321 } 4322 4323 /** 4324 * Destroy the current CLIENT SIDE instance of an activity. This may be 4325 * called both when actually finishing an activity, or when performing 4326 * a configuration switch where we destroy the current client-side object 4327 * but then create a new client-side object for this same HistoryRecord. 4328 */ 4329 private final boolean destroyActivityLocked(HistoryRecord r, 4330 boolean removeFromApp) { 4331 if (DEBUG_SWITCH) Log.v( 4332 TAG, "Removing activity: token=" + r 4333 + ", app=" + (r.app != null ? r.app.processName : "(null)")); 4334 EventLog.writeEvent(LOG_AM_DESTROY_ACTIVITY, 4335 System.identityHashCode(r), 4336 r.task.taskId, r.shortComponentName); 4337 4338 boolean removedFromHistory = false; 4339 4340 cleanUpActivityLocked(r, false); 4341 4342 if (r.app != null) { 4343 if (removeFromApp) { 4344 int idx = r.app.activities.indexOf(r); 4345 if (idx >= 0) { 4346 r.app.activities.remove(idx); 4347 } 4348 if (r.persistent) { 4349 decPersistentCountLocked(r.app); 4350 } 4351 } 4352 4353 boolean skipDestroy = false; 4354 4355 try { 4356 if (DEBUG_SWITCH) Log.i(TAG, "Destroying: " + r); 4357 r.app.thread.scheduleDestroyActivity(r, r.finishing, 4358 r.configChangeFlags); 4359 } catch (Exception e) { 4360 // We can just ignore exceptions here... if the process 4361 // has crashed, our death notification will clean things 4362 // up. 4363 //Log.w(TAG, "Exception thrown during finish", e); 4364 if (r.finishing) { 4365 removeActivityFromHistoryLocked(r); 4366 removedFromHistory = true; 4367 skipDestroy = true; 4368 } 4369 } 4370 4371 r.app = null; 4372 r.nowVisible = false; 4373 4374 if (r.finishing && !skipDestroy) { 4375 r.state = ActivityState.DESTROYING; 4376 Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG); 4377 msg.obj = r; 4378 mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT); 4379 } else { 4380 r.state = ActivityState.DESTROYED; 4381 } 4382 } else { 4383 // remove this record from the history. 4384 if (r.finishing) { 4385 removeActivityFromHistoryLocked(r); 4386 removedFromHistory = true; 4387 } else { 4388 r.state = ActivityState.DESTROYED; 4389 } 4390 } 4391 4392 r.configChangeFlags = 0; 4393 4394 if (!mLRUActivities.remove(r)) { 4395 Log.w(TAG, "Activity " + r + " being finished, but not in LRU list"); 4396 } 4397 4398 return removedFromHistory; 4399 } 4400 4401 private static void removeHistoryRecordsForAppLocked(ArrayList list, 4402 ProcessRecord app) 4403 { 4404 int i = list.size(); 4405 if (localLOGV) Log.v( 4406 TAG, "Removing app " + app + " from list " + list 4407 + " with " + i + " entries"); 4408 while (i > 0) { 4409 i--; 4410 HistoryRecord r = (HistoryRecord)list.get(i); 4411 if (localLOGV) Log.v( 4412 TAG, "Record #" + i + " " + r + ": app=" + r.app); 4413 if (r.app == app) { 4414 if (localLOGV) Log.v(TAG, "Removing this entry!"); 4415 list.remove(i); 4416 } 4417 } 4418 } 4419 4420 /** 4421 * Main function for removing an existing process from the activity manager 4422 * as a result of that process going away. Clears out all connections 4423 * to the process. 4424 */ 4425 private final void handleAppDiedLocked(ProcessRecord app, 4426 boolean restarting) { 4427 cleanUpApplicationRecordLocked(app, restarting, -1); 4428 if (!restarting) { 4429 mLRUProcesses.remove(app); 4430 } 4431 4432 // Just in case... 4433 if (mPausingActivity != null && mPausingActivity.app == app) { 4434 if (DEBUG_PAUSE) Log.v(TAG, "App died while pausing: " + mPausingActivity); 4435 mPausingActivity = null; 4436 } 4437 if (mLastPausedActivity != null && mLastPausedActivity.app == app) { 4438 mLastPausedActivity = null; 4439 } 4440 4441 // Remove this application's activities from active lists. 4442 removeHistoryRecordsForAppLocked(mLRUActivities, app); 4443 removeHistoryRecordsForAppLocked(mStoppingActivities, app); 4444 removeHistoryRecordsForAppLocked(mWaitingVisibleActivities, app); 4445 removeHistoryRecordsForAppLocked(mFinishingActivities, app); 4446 4447 boolean atTop = true; 4448 boolean hasVisibleActivities = false; 4449 4450 // Clean out the history list. 4451 int i = mHistory.size(); 4452 if (localLOGV) Log.v( 4453 TAG, "Removing app " + app + " from history with " + i + " entries"); 4454 while (i > 0) { 4455 i--; 4456 HistoryRecord r = (HistoryRecord)mHistory.get(i); 4457 if (localLOGV) Log.v( 4458 TAG, "Record #" + i + " " + r + ": app=" + r.app); 4459 if (r.app == app) { 4460 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 4461 if (localLOGV) Log.v( 4462 TAG, "Removing this entry! frozen=" + r.haveState 4463 + " finishing=" + r.finishing); 4464 mHistory.remove(i); 4465 4466 r.inHistory = false; 4467 mWindowManager.removeAppToken(r); 4468 if (VALIDATE_TOKENS) { 4469 mWindowManager.validateAppTokens(mHistory); 4470 } 4471 removeActivityUriPermissionsLocked(r); 4472 4473 } else { 4474 // We have the current state for this activity, so 4475 // it can be restarted later when needed. 4476 if (localLOGV) Log.v( 4477 TAG, "Keeping entry, setting app to null"); 4478 if (r.visible) { 4479 hasVisibleActivities = true; 4480 } 4481 r.app = null; 4482 r.nowVisible = false; 4483 if (!r.haveState) { 4484 r.icicle = null; 4485 } 4486 } 4487 4488 cleanUpActivityLocked(r, true); 4489 r.state = ActivityState.STOPPED; 4490 } 4491 atTop = false; 4492 } 4493 4494 app.activities.clear(); 4495 4496 if (app.instrumentationClass != null) { 4497 Log.w(TAG, "Crash of app " + app.processName 4498 + " running instrumentation " + app.instrumentationClass); 4499 Bundle info = new Bundle(); 4500 info.putString("shortMsg", "Process crashed."); 4501 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4502 } 4503 4504 if (!restarting) { 4505 if (!resumeTopActivityLocked(null)) { 4506 // If there was nothing to resume, and we are not already 4507 // restarting this process, but there is a visible activity that 4508 // is hosted by the process... then make sure all visible 4509 // activities are running, taking care of restarting this 4510 // process. 4511 if (hasVisibleActivities) { 4512 ensureActivitiesVisibleLocked(null, 0); 4513 } 4514 } 4515 } 4516 } 4517 4518 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4519 IBinder threadBinder = thread.asBinder(); 4520 4521 // Find the application record. 4522 int count = mLRUProcesses.size(); 4523 int i; 4524 for (i=0; i<count; i++) { 4525 ProcessRecord rec = mLRUProcesses.get(i); 4526 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4527 return i; 4528 } 4529 } 4530 return -1; 4531 } 4532 4533 private final ProcessRecord getRecordForAppLocked( 4534 IApplicationThread thread) { 4535 if (thread == null) { 4536 return null; 4537 } 4538 4539 int appIndex = getLRURecordIndexForAppLocked(thread); 4540 return appIndex >= 0 ? mLRUProcesses.get(appIndex) : null; 4541 } 4542 4543 private final void appDiedLocked(ProcessRecord app, int pid, 4544 IApplicationThread thread) { 4545 4546 mProcDeaths[0]++; 4547 4548 if (app.thread != null && app.thread.asBinder() == thread.asBinder()) { 4549 Log.i(TAG, "Process " + app.processName + " (pid " + pid 4550 + ") has died."); 4551 EventLog.writeEvent(LOG_AM_PROCESS_DIED, app.pid, app.processName); 4552 if (localLOGV) Log.v( 4553 TAG, "Dying app: " + app + ", pid: " + pid 4554 + ", thread: " + thread.asBinder()); 4555 boolean doLowMem = app.instrumentationClass == null; 4556 handleAppDiedLocked(app, false); 4557 4558 if (doLowMem) { 4559 // If there are no longer any background processes running, 4560 // and the app that died was not running instrumentation, 4561 // then tell everyone we are now low on memory. 4562 boolean haveBg = false; 4563 int count = mLRUProcesses.size(); 4564 int i; 4565 for (i=0; i<count; i++) { 4566 ProcessRecord rec = mLRUProcesses.get(i); 4567 if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) { 4568 haveBg = true; 4569 break; 4570 } 4571 } 4572 4573 if (!haveBg) { 4574 Log.i(TAG, "Low Memory: No more background processes."); 4575 EventLog.writeEvent(LOG_AM_LOW_MEMORY, mLRUProcesses.size()); 4576 long now = SystemClock.uptimeMillis(); 4577 for (i=0; i<count; i++) { 4578 ProcessRecord rec = mLRUProcesses.get(i); 4579 if (rec != app && rec.thread != null && 4580 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4581 // The low memory report is overriding any current 4582 // state for a GC request. Make sure to do 4583 // visible/foreground processes first. 4584 if (rec.setAdj <= VISIBLE_APP_ADJ) { 4585 rec.lastRequestedGc = 0; 4586 } else { 4587 rec.lastRequestedGc = rec.lastLowMemory; 4588 } 4589 rec.reportLowMemory = true; 4590 rec.lastLowMemory = now; 4591 mProcessesToGc.remove(rec); 4592 addProcessToGcListLocked(rec); 4593 } 4594 } 4595 scheduleAppGcsLocked(); 4596 } 4597 } 4598 } else if (Config.LOGD) { 4599 Log.d(TAG, "Received spurious death notification for thread " 4600 + thread.asBinder()); 4601 } 4602 } 4603 4604 final String readFile(String filename) { 4605 try { 4606 FileInputStream fs = new FileInputStream(filename); 4607 byte[] inp = new byte[8192]; 4608 int size = fs.read(inp); 4609 fs.close(); 4610 return new String(inp, 0, 0, size); 4611 } catch (java.io.IOException e) { 4612 } 4613 return ""; 4614 } 4615 4616 final void appNotRespondingLocked(ProcessRecord app, HistoryRecord activity, 4617 HistoryRecord reportedActivity, final String annotation) { 4618 if (app.notResponding || app.crashing) { 4619 return; 4620 } 4621 4622 // Log the ANR to the event log. 4623 EventLog.writeEvent(LOG_ANR, app.pid, app.processName, annotation); 4624 4625 // If we are on a secure build and the application is not interesting to the user (it is 4626 // not visible or in the background), just kill it instead of displaying a dialog. 4627 boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0")); 4628 if (isSecure && !app.isInterestingToUserLocked() && Process.myPid() != app.pid) { 4629 Process.killProcess(app.pid); 4630 return; 4631 } 4632 4633 // DeviceMonitor.start(); 4634 4635 String processInfo = null; 4636 if (MONITOR_CPU_USAGE) { 4637 updateCpuStatsNow(); 4638 synchronized (mProcessStatsThread) { 4639 processInfo = mProcessStats.printCurrentState(); 4640 } 4641 } 4642 4643 StringBuilder info = mStringBuilder; 4644 info.setLength(0); 4645 info.append("ANR in process: "); 4646 info.append(app.processName); 4647 if (reportedActivity != null && reportedActivity.app != null) { 4648 info.append(" (last in "); 4649 info.append(reportedActivity.app.processName); 4650 info.append(")"); 4651 } 4652 if (annotation != null) { 4653 info.append("\nAnnotation: "); 4654 info.append(annotation); 4655 } 4656 if (MONITOR_CPU_USAGE) { 4657 info.append("\nCPU usage:\n"); 4658 info.append(processInfo); 4659 } 4660 Log.i(TAG, info.toString()); 4661 4662 // The application is not responding. Dump as many thread traces as we can. 4663 boolean fileDump = prepareTraceFile(true); 4664 if (!fileDump) { 4665 // Dumping traces to the log, just dump the process that isn't responding so 4666 // we don't overflow the log 4667 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4668 } else { 4669 // Dumping traces to a file so dump all active processes we know about 4670 synchronized (this) { 4671 // First, these are the most important processes. 4672 final int[] imppids = new int[3]; 4673 int i=0; 4674 imppids[0] = app.pid; 4675 i++; 4676 if (reportedActivity != null && reportedActivity.app != null 4677 && reportedActivity.app.thread != null 4678 && reportedActivity.app.pid != app.pid) { 4679 imppids[i] = reportedActivity.app.pid; 4680 i++; 4681 } 4682 imppids[i] = Process.myPid(); 4683 for (i=0; i<imppids.length && imppids[i] != 0; i++) { 4684 Process.sendSignal(imppids[i], Process.SIGNAL_QUIT); 4685 synchronized (this) { 4686 try { 4687 wait(200); 4688 } catch (InterruptedException e) { 4689 } 4690 } 4691 } 4692 for (i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) { 4693 ProcessRecord r = mLRUProcesses.get(i); 4694 boolean done = false; 4695 for (int j=0; j<imppids.length && imppids[j] != 0; j++) { 4696 if (imppids[j] == r.pid) { 4697 done = true; 4698 break; 4699 } 4700 } 4701 if (!done && r.thread != null) { 4702 Process.sendSignal(r.pid, Process.SIGNAL_QUIT); 4703 synchronized (this) { 4704 try { 4705 wait(200); 4706 } catch (InterruptedException e) { 4707 } 4708 } 4709 } 4710 } 4711 } 4712 } 4713 4714 if (mController != null) { 4715 try { 4716 int res = mController.appNotResponding(app.processName, 4717 app.pid, info.toString()); 4718 if (res != 0) { 4719 if (res < 0) { 4720 // wait until the SIGQUIT has had a chance to process before killing the 4721 // process. 4722 try { 4723 wait(2000); 4724 } catch (InterruptedException e) { 4725 } 4726 4727 Process.killProcess(app.pid); 4728 return; 4729 } 4730 } 4731 } catch (RemoteException e) { 4732 mController = null; 4733 } 4734 } 4735 4736 makeAppNotRespondingLocked(app, 4737 activity != null ? activity.shortComponentName : null, 4738 annotation != null ? "ANR " + annotation : "ANR", 4739 info.toString(), null); 4740 Message msg = Message.obtain(); 4741 HashMap map = new HashMap(); 4742 msg.what = SHOW_NOT_RESPONDING_MSG; 4743 msg.obj = map; 4744 map.put("app", app); 4745 if (activity != null) { 4746 map.put("activity", activity); 4747 } 4748 4749 mHandler.sendMessage(msg); 4750 return; 4751 } 4752 4753 /** 4754 * If a stack trace file has been configured, prepare the filesystem 4755 * by creating the directory if it doesn't exist and optionally 4756 * removing the old trace file. 4757 * 4758 * @param removeExisting If set, the existing trace file will be removed. 4759 * @return Returns true if the trace file preparations succeeded 4760 */ 4761 public static boolean prepareTraceFile(boolean removeExisting) { 4762 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4763 boolean fileReady = false; 4764 if (!TextUtils.isEmpty(tracesPath)) { 4765 File f = new File(tracesPath); 4766 if (!f.exists()) { 4767 // Ensure the enclosing directory exists 4768 File dir = f.getParentFile(); 4769 if (!dir.exists()) { 4770 fileReady = dir.mkdirs(); 4771 FileUtils.setPermissions(dir.getAbsolutePath(), 4772 FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IXOTH, -1, -1); 4773 } else if (dir.isDirectory()) { 4774 fileReady = true; 4775 } 4776 } else if (removeExisting) { 4777 // Remove the previous traces file, so we don't fill the disk. 4778 // The VM will recreate it 4779 Log.i(TAG, "Removing old ANR trace file from " + tracesPath); 4780 fileReady = f.delete(); 4781 } 4782 4783 if (removeExisting) { 4784 try { 4785 f.createNewFile(); 4786 FileUtils.setPermissions(f.getAbsolutePath(), 4787 FileUtils.S_IRWXU | FileUtils.S_IRWXG 4788 | FileUtils.S_IWOTH | FileUtils.S_IROTH, -1, -1); 4789 fileReady = true; 4790 } catch (IOException e) { 4791 Log.w(TAG, "Unable to make ANR traces file", e); 4792 } 4793 } 4794 } 4795 4796 return fileReady; 4797 } 4798 4799 4800 private final void decPersistentCountLocked(ProcessRecord app) 4801 { 4802 app.persistentActivities--; 4803 if (app.persistentActivities > 0) { 4804 // Still more of 'em... 4805 return; 4806 } 4807 if (app.persistent) { 4808 // Ah, but the application itself is persistent. Whatever! 4809 return; 4810 } 4811 4812 // App is no longer persistent... make sure it and the ones 4813 // following it in the LRU list have the correc oom_adj. 4814 updateOomAdjLocked(); 4815 } 4816 4817 public void setPersistent(IBinder token, boolean isPersistent) { 4818 if (checkCallingPermission(android.Manifest.permission.PERSISTENT_ACTIVITY) 4819 != PackageManager.PERMISSION_GRANTED) { 4820 String msg = "Permission Denial: setPersistent() from pid=" 4821 + Binder.getCallingPid() 4822 + ", uid=" + Binder.getCallingUid() 4823 + " requires " + android.Manifest.permission.PERSISTENT_ACTIVITY; 4824 Log.w(TAG, msg); 4825 throw new SecurityException(msg); 4826 } 4827 4828 synchronized(this) { 4829 int index = indexOfTokenLocked(token); 4830 if (index < 0) { 4831 return; 4832 } 4833 HistoryRecord r = (HistoryRecord)mHistory.get(index); 4834 ProcessRecord app = r.app; 4835 4836 if (localLOGV) Log.v( 4837 TAG, "Setting persistence " + isPersistent + ": " + r); 4838 4839 if (isPersistent) { 4840 if (r.persistent) { 4841 // Okay okay, I heard you already! 4842 if (localLOGV) Log.v(TAG, "Already persistent!"); 4843 return; 4844 } 4845 r.persistent = true; 4846 app.persistentActivities++; 4847 if (localLOGV) Log.v(TAG, "Num persistent now: " + app.persistentActivities); 4848 if (app.persistentActivities > 1) { 4849 // We aren't the first... 4850 if (localLOGV) Log.v(TAG, "Not the first!"); 4851 return; 4852 } 4853 if (app.persistent) { 4854 // This would be redundant. 4855 if (localLOGV) Log.v(TAG, "App is persistent!"); 4856 return; 4857 } 4858 4859 // App is now persistent... make sure it and the ones 4860 // following it now have the correct oom_adj. 4861 final long origId = Binder.clearCallingIdentity(); 4862 updateOomAdjLocked(); 4863 Binder.restoreCallingIdentity(origId); 4864 4865 } else { 4866 if (!r.persistent) { 4867 // Okay okay, I heard you already! 4868 return; 4869 } 4870 r.persistent = false; 4871 final long origId = Binder.clearCallingIdentity(); 4872 decPersistentCountLocked(app); 4873 Binder.restoreCallingIdentity(origId); 4874 4875 } 4876 } 4877 } 4878 4879 public boolean clearApplicationUserData(final String packageName, 4880 final IPackageDataObserver observer) { 4881 int uid = Binder.getCallingUid(); 4882 int pid = Binder.getCallingPid(); 4883 long callingId = Binder.clearCallingIdentity(); 4884 try { 4885 IPackageManager pm = ActivityThread.getPackageManager(); 4886 int pkgUid = -1; 4887 synchronized(this) { 4888 try { 4889 pkgUid = pm.getPackageUid(packageName); 4890 } catch (RemoteException e) { 4891 } 4892 if (pkgUid == -1) { 4893 Log.w(TAG, "Invalid packageName:" + packageName); 4894 return false; 4895 } 4896 if (uid == pkgUid || checkComponentPermission( 4897 android.Manifest.permission.CLEAR_APP_USER_DATA, 4898 pid, uid, -1) 4899 == PackageManager.PERMISSION_GRANTED) { 4900 restartPackageLocked(packageName, pkgUid); 4901 } else { 4902 throw new SecurityException(pid+" does not have permission:"+ 4903 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 4904 "for process:"+packageName); 4905 } 4906 } 4907 4908 try { 4909 //clear application user data 4910 pm.clearApplicationUserData(packageName, observer); 4911 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4912 Uri.fromParts("package", packageName, null)); 4913 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4914 broadcastIntentLocked(null, null, intent, 4915 null, null, 0, null, null, null, 4916 false, false, MY_PID, Process.SYSTEM_UID); 4917 } catch (RemoteException e) { 4918 } 4919 } finally { 4920 Binder.restoreCallingIdentity(callingId); 4921 } 4922 return true; 4923 } 4924 4925 public void restartPackage(final String packageName) { 4926 if (checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4927 != PackageManager.PERMISSION_GRANTED) { 4928 String msg = "Permission Denial: restartPackage() from pid=" 4929 + Binder.getCallingPid() 4930 + ", uid=" + Binder.getCallingUid() 4931 + " requires " + android.Manifest.permission.RESTART_PACKAGES; 4932 Log.w(TAG, msg); 4933 throw new SecurityException(msg); 4934 } 4935 4936 long callingId = Binder.clearCallingIdentity(); 4937 try { 4938 IPackageManager pm = ActivityThread.getPackageManager(); 4939 int pkgUid = -1; 4940 synchronized(this) { 4941 try { 4942 pkgUid = pm.getPackageUid(packageName); 4943 } catch (RemoteException e) { 4944 } 4945 if (pkgUid == -1) { 4946 Log.w(TAG, "Invalid packageName: " + packageName); 4947 return; 4948 } 4949 restartPackageLocked(packageName, pkgUid); 4950 } 4951 } finally { 4952 Binder.restoreCallingIdentity(callingId); 4953 } 4954 } 4955 4956 /* 4957 * The pkg name and uid have to be specified. 4958 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 4959 */ 4960 public void killApplicationWithUid(String pkg, int uid) { 4961 if (pkg == null) { 4962 return; 4963 } 4964 // Make sure the uid is valid. 4965 if (uid < 0) { 4966 Log.w(TAG, "Invalid uid specified for pkg : " + pkg); 4967 return; 4968 } 4969 int callerUid = Binder.getCallingUid(); 4970 // Only the system server can kill an application 4971 if (callerUid == Process.SYSTEM_UID) { 4972 // Post an aysnc message to kill the application 4973 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4974 msg.arg1 = uid; 4975 msg.arg2 = 0; 4976 msg.obj = pkg; 4977 mHandler.sendMessage(msg); 4978 } else { 4979 throw new SecurityException(callerUid + " cannot kill pkg: " + 4980 pkg); 4981 } 4982 } 4983 4984 public void closeSystemDialogs(String reason) { 4985 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4986 if (reason != null) { 4987 intent.putExtra("reason", reason); 4988 } 4989 4990 final int uid = Binder.getCallingUid(); 4991 final long origId = Binder.clearCallingIdentity(); 4992 synchronized (this) { 4993 int i = mWatchers.beginBroadcast(); 4994 while (i > 0) { 4995 i--; 4996 IActivityWatcher w = mWatchers.getBroadcastItem(i); 4997 if (w != null) { 4998 try { 4999 w.closingSystemDialogs(reason); 5000 } catch (RemoteException e) { 5001 } 5002 } 5003 } 5004 mWatchers.finishBroadcast(); 5005 5006 mWindowManager.closeSystemDialogs(reason); 5007 5008 for (i=mHistory.size()-1; i>=0; i--) { 5009 HistoryRecord r = (HistoryRecord)mHistory.get(i); 5010 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 5011 finishActivityLocked(r, i, 5012 Activity.RESULT_CANCELED, null, "close-sys"); 5013 } 5014 } 5015 5016 broadcastIntentLocked(null, null, intent, null, 5017 null, 0, null, null, null, false, false, -1, uid); 5018 } 5019 Binder.restoreCallingIdentity(origId); 5020 } 5021 5022 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 5023 throws RemoteException { 5024 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5025 for (int i=pids.length-1; i>=0; i--) { 5026 infos[i] = new Debug.MemoryInfo(); 5027 Debug.getMemoryInfo(pids[i], infos[i]); 5028 } 5029 return infos; 5030 } 5031 5032 public void killApplicationProcess(String processName, int uid) { 5033 if (processName == null) { 5034 return; 5035 } 5036 5037 int callerUid = Binder.getCallingUid(); 5038 // Only the system server can kill an application 5039 if (callerUid == Process.SYSTEM_UID) { 5040 synchronized (this) { 5041 ProcessRecord app = getProcessRecordLocked(processName, uid); 5042 if (app != null) { 5043 try { 5044 app.thread.scheduleSuicide(); 5045 } catch (RemoteException e) { 5046 // If the other end already died, then our work here is done. 5047 } 5048 } else { 5049 Log.w(TAG, "Process/uid not found attempting kill of " 5050 + processName + " / " + uid); 5051 } 5052 } 5053 } else { 5054 throw new SecurityException(callerUid + " cannot kill app process: " + 5055 processName); 5056 } 5057 } 5058 5059 private void restartPackageLocked(final String packageName, int uid) { 5060 uninstallPackageLocked(packageName, uid, false); 5061 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5062 Uri.fromParts("package", packageName, null)); 5063 intent.putExtra(Intent.EXTRA_UID, uid); 5064 broadcastIntentLocked(null, null, intent, 5065 null, null, 0, null, null, null, 5066 false, false, MY_PID, Process.SYSTEM_UID); 5067 } 5068 5069 private final void uninstallPackageLocked(String name, int uid, 5070 boolean callerWillRestart) { 5071 if (Config.LOGD) Log.d(TAG, "Uninstalling process " + name); 5072 5073 int i, N; 5074 5075 final String procNamePrefix = name + ":"; 5076 if (uid < 0) { 5077 try { 5078 uid = ActivityThread.getPackageManager().getPackageUid(name); 5079 } catch (RemoteException e) { 5080 } 5081 } 5082 5083 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 5084 while (badApps.hasNext()) { 5085 SparseArray<Long> ba = badApps.next(); 5086 if (ba.get(uid) != null) { 5087 badApps.remove(); 5088 } 5089 } 5090 5091 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5092 5093 // Remove all processes this package may have touched: all with the 5094 // same UID (except for the system or root user), and all whose name 5095 // matches the package name. 5096 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 5097 final int NA = apps.size(); 5098 for (int ia=0; ia<NA; ia++) { 5099 ProcessRecord app = apps.valueAt(ia); 5100 if (app.removed) { 5101 procs.add(app); 5102 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 5103 || app.processName.equals(name) 5104 || app.processName.startsWith(procNamePrefix)) { 5105 app.removed = true; 5106 procs.add(app); 5107 } 5108 } 5109 } 5110 5111 N = procs.size(); 5112 for (i=0; i<N; i++) { 5113 removeProcessLocked(procs.get(i), callerWillRestart); 5114 } 5115 5116 for (i=mHistory.size()-1; i>=0; i--) { 5117 HistoryRecord r = (HistoryRecord)mHistory.get(i); 5118 if (r.packageName.equals(name)) { 5119 if (Config.LOGD) Log.d( 5120 TAG, " Force finishing activity " 5121 + r.intent.getComponent().flattenToShortString()); 5122 if (r.app != null) { 5123 r.app.removed = true; 5124 } 5125 r.app = null; 5126 finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall"); 5127 } 5128 } 5129 5130 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 5131 for (ServiceRecord service : mServices.values()) { 5132 if (service.packageName.equals(name)) { 5133 if (service.app != null) { 5134 service.app.removed = true; 5135 } 5136 service.app = null; 5137 services.add(service); 5138 } 5139 } 5140 5141 N = services.size(); 5142 for (i=0; i<N; i++) { 5143 bringDownServiceLocked(services.get(i), true); 5144 } 5145 5146 resumeTopActivityLocked(null); 5147 } 5148 5149 private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) { 5150 final String name = app.processName; 5151 final int uid = app.info.uid; 5152 if (Config.LOGD) Log.d( 5153 TAG, "Force removing process " + app + " (" + name 5154 + "/" + uid + ")"); 5155 5156 mProcessNames.remove(name, uid); 5157 boolean needRestart = false; 5158 if (app.pid > 0 && app.pid != MY_PID) { 5159 int pid = app.pid; 5160 synchronized (mPidsSelfLocked) { 5161 mPidsSelfLocked.remove(pid); 5162 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5163 } 5164 handleAppDiedLocked(app, true); 5165 mLRUProcesses.remove(app); 5166 Process.killProcess(pid); 5167 5168 if (app.persistent) { 5169 if (!callerWillRestart) { 5170 addAppLocked(app.info); 5171 } else { 5172 needRestart = true; 5173 } 5174 } 5175 } else { 5176 mRemovedProcesses.add(app); 5177 } 5178 5179 return needRestart; 5180 } 5181 5182 private final void processStartTimedOutLocked(ProcessRecord app) { 5183 final int pid = app.pid; 5184 boolean gone = false; 5185 synchronized (mPidsSelfLocked) { 5186 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5187 if (knownApp != null && knownApp.thread == null) { 5188 mPidsSelfLocked.remove(pid); 5189 gone = true; 5190 } 5191 } 5192 5193 if (gone) { 5194 Log.w(TAG, "Process " + app + " failed to attach"); 5195 mProcessNames.remove(app.processName, app.info.uid); 5196 Process.killProcess(pid); 5197 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) { 5198 Log.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5199 mPendingBroadcast = null; 5200 scheduleBroadcastsLocked(); 5201 } 5202 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5203 Log.w(TAG, "Unattached app died before backup, skipping"); 5204 try { 5205 IBackupManager bm = IBackupManager.Stub.asInterface( 5206 ServiceManager.getService(Context.BACKUP_SERVICE)); 5207 bm.agentDisconnected(app.info.packageName); 5208 } catch (RemoteException e) { 5209 // Can't happen; the backup manager is local 5210 } 5211 } 5212 } else { 5213 Log.w(TAG, "Spurious process start timeout - pid not known for " + app); 5214 } 5215 } 5216 5217 private final boolean attachApplicationLocked(IApplicationThread thread, 5218 int pid) { 5219 5220 // Find the application record that is being attached... either via 5221 // the pid if we are running in multiple processes, or just pull the 5222 // next app record if we are emulating process with anonymous threads. 5223 ProcessRecord app; 5224 if (pid != MY_PID && pid >= 0) { 5225 synchronized (mPidsSelfLocked) { 5226 app = mPidsSelfLocked.get(pid); 5227 } 5228 } else if (mStartingProcesses.size() > 0) { 5229 app = mStartingProcesses.remove(0); 5230 app.setPid(pid); 5231 } else { 5232 app = null; 5233 } 5234 5235 if (app == null) { 5236 Log.w(TAG, "No pending application record for pid " + pid 5237 + " (IApplicationThread " + thread + "); dropping process"); 5238 EventLog.writeEvent(LOG_AM_DROP_PROCESS, pid); 5239 if (pid > 0 && pid != MY_PID) { 5240 Process.killProcess(pid); 5241 } else { 5242 try { 5243 thread.scheduleExit(); 5244 } catch (Exception e) { 5245 // Ignore exceptions. 5246 } 5247 } 5248 return false; 5249 } 5250 5251 // If this application record is still attached to a previous 5252 // process, clean it up now. 5253 if (app.thread != null) { 5254 handleAppDiedLocked(app, true); 5255 } 5256 5257 // Tell the process all about itself. 5258 5259 if (localLOGV) Log.v( 5260 TAG, "Binding process pid " + pid + " to record " + app); 5261 5262 String processName = app.processName; 5263 try { 5264 thread.asBinder().linkToDeath(new AppDeathRecipient( 5265 app, pid, thread), 0); 5266 } catch (RemoteException e) { 5267 app.resetPackageList(); 5268 startProcessLocked(app, "link fail", processName); 5269 return false; 5270 } 5271 5272 EventLog.writeEvent(LOG_AM_PROCESS_BOUND, app.pid, app.processName); 5273 5274 app.thread = thread; 5275 app.curAdj = app.setAdj = -100; 5276 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5277 app.forcingToForeground = null; 5278 app.foregroundServices = false; 5279 app.debugging = false; 5280 5281 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5282 5283 boolean normalMode = mSystemReady || isAllowedWhileBooting(app.info); 5284 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5285 5286 if (!normalMode) { 5287 Log.i(TAG, "Launching preboot mode app: " + app); 5288 } 5289 5290 if (localLOGV) Log.v( 5291 TAG, "New app record " + app 5292 + " thread=" + thread.asBinder() + " pid=" + pid); 5293 try { 5294 int testMode = IApplicationThread.DEBUG_OFF; 5295 if (mDebugApp != null && mDebugApp.equals(processName)) { 5296 testMode = mWaitForDebugger 5297 ? IApplicationThread.DEBUG_WAIT 5298 : IApplicationThread.DEBUG_ON; 5299 app.debugging = true; 5300 if (mDebugTransient) { 5301 mDebugApp = mOrigDebugApp; 5302 mWaitForDebugger = mOrigWaitForDebugger; 5303 } 5304 } 5305 5306 // If the app is being launched for restore or full backup, set it up specially 5307 boolean isRestrictedBackupMode = false; 5308 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5309 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5310 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5311 } 5312 5313 ensurePackageDexOpt(app.instrumentationInfo != null 5314 ? app.instrumentationInfo.packageName 5315 : app.info.packageName); 5316 if (app.instrumentationClass != null) { 5317 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5318 } 5319 if (DEBUG_CONFIGURATION) Log.v(TAG, "Binding proc " 5320 + processName + " with config " + mConfiguration); 5321 thread.bindApplication(processName, app.instrumentationInfo != null 5322 ? app.instrumentationInfo : app.info, providers, 5323 app.instrumentationClass, app.instrumentationProfileFile, 5324 app.instrumentationArguments, app.instrumentationWatcher, testMode, 5325 isRestrictedBackupMode || !normalMode, 5326 mConfiguration, getCommonServicesLocked()); 5327 updateLRUListLocked(app, false); 5328 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5329 } catch (Exception e) { 5330 // todo: Yikes! What should we do? For now we will try to 5331 // start another process, but that could easily get us in 5332 // an infinite loop of restarting processes... 5333 Log.w(TAG, "Exception thrown during bind!", e); 5334 5335 app.resetPackageList(); 5336 startProcessLocked(app, "bind fail", processName); 5337 return false; 5338 } 5339 5340 // Remove this record from the list of starting applications. 5341 mPersistentStartingProcesses.remove(app); 5342 mProcessesOnHold.remove(app); 5343 5344 boolean badApp = false; 5345 boolean didSomething = false; 5346 5347 // See if the top visible activity is waiting to run in this process... 5348 HistoryRecord hr = topRunningActivityLocked(null); 5349 if (hr != null) { 5350 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid 5351 && processName.equals(hr.processName)) { 5352 try { 5353 if (realStartActivityLocked(hr, app, true, true)) { 5354 didSomething = true; 5355 } 5356 } catch (Exception e) { 5357 Log.w(TAG, "Exception in new application when starting activity " 5358 + hr.intent.getComponent().flattenToShortString(), e); 5359 badApp = true; 5360 } 5361 } else { 5362 ensureActivitiesVisibleLocked(hr, null, processName, 0); 5363 } 5364 } 5365 5366 // Find any services that should be running in this process... 5367 if (!badApp && mPendingServices.size() > 0) { 5368 ServiceRecord sr = null; 5369 try { 5370 for (int i=0; i<mPendingServices.size(); i++) { 5371 sr = mPendingServices.get(i); 5372 if (app.info.uid != sr.appInfo.uid 5373 || !processName.equals(sr.processName)) { 5374 continue; 5375 } 5376 5377 mPendingServices.remove(i); 5378 i--; 5379 realStartServiceLocked(sr, app); 5380 didSomething = true; 5381 } 5382 } catch (Exception e) { 5383 Log.w(TAG, "Exception in new application when starting service " 5384 + sr.shortName, e); 5385 badApp = true; 5386 } 5387 } 5388 5389 // Check if the next broadcast receiver is in this process... 5390 BroadcastRecord br = mPendingBroadcast; 5391 if (!badApp && br != null && br.curApp == app) { 5392 try { 5393 mPendingBroadcast = null; 5394 processCurBroadcastLocked(br, app); 5395 didSomething = true; 5396 } catch (Exception e) { 5397 Log.w(TAG, "Exception in new application when starting receiver " 5398 + br.curComponent.flattenToShortString(), e); 5399 badApp = true; 5400 logBroadcastReceiverDiscard(br); 5401 finishReceiverLocked(br.receiver, br.resultCode, br.resultData, 5402 br.resultExtras, br.resultAbort, true); 5403 scheduleBroadcastsLocked(); 5404 } 5405 } 5406 5407 // Check whether the next backup agent is in this process... 5408 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) { 5409 if (DEBUG_BACKUP) Log.v(TAG, "New app is backup target, launching agent for " + app); 5410 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5411 try { 5412 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, mBackupTarget.backupMode); 5413 } catch (Exception e) { 5414 Log.w(TAG, "Exception scheduling backup agent creation: "); 5415 e.printStackTrace(); 5416 } 5417 } 5418 5419 if (badApp) { 5420 // todo: Also need to kill application to deal with all 5421 // kinds of exceptions. 5422 handleAppDiedLocked(app, false); 5423 return false; 5424 } 5425 5426 if (!didSomething) { 5427 updateOomAdjLocked(); 5428 } 5429 5430 return true; 5431 } 5432 5433 public final void attachApplication(IApplicationThread thread) { 5434 synchronized (this) { 5435 int callingPid = Binder.getCallingPid(); 5436 final long origId = Binder.clearCallingIdentity(); 5437 attachApplicationLocked(thread, callingPid); 5438 Binder.restoreCallingIdentity(origId); 5439 } 5440 } 5441 5442 public final void activityIdle(IBinder token, Configuration config) { 5443 final long origId = Binder.clearCallingIdentity(); 5444 activityIdleInternal(token, false, config); 5445 Binder.restoreCallingIdentity(origId); 5446 } 5447 5448 final ArrayList<HistoryRecord> processStoppingActivitiesLocked( 5449 boolean remove) { 5450 int N = mStoppingActivities.size(); 5451 if (N <= 0) return null; 5452 5453 ArrayList<HistoryRecord> stops = null; 5454 5455 final boolean nowVisible = mResumedActivity != null 5456 && mResumedActivity.nowVisible 5457 && !mResumedActivity.waitingVisible; 5458 for (int i=0; i<N; i++) { 5459 HistoryRecord s = mStoppingActivities.get(i); 5460 if (localLOGV) Log.v(TAG, "Stopping " + s + ": nowVisible=" 5461 + nowVisible + " waitingVisible=" + s.waitingVisible 5462 + " finishing=" + s.finishing); 5463 if (s.waitingVisible && nowVisible) { 5464 mWaitingVisibleActivities.remove(s); 5465 s.waitingVisible = false; 5466 if (s.finishing) { 5467 // If this activity is finishing, it is sitting on top of 5468 // everyone else but we now know it is no longer needed... 5469 // so get rid of it. Otherwise, we need to go through the 5470 // normal flow and hide it once we determine that it is 5471 // hidden by the activities in front of it. 5472 if (localLOGV) Log.v(TAG, "Before stopping, can hide: " + s); 5473 mWindowManager.setAppVisibility(s, false); 5474 } 5475 } 5476 if (!s.waitingVisible && remove) { 5477 if (localLOGV) Log.v(TAG, "Ready to stop: " + s); 5478 if (stops == null) { 5479 stops = new ArrayList<HistoryRecord>(); 5480 } 5481 stops.add(s); 5482 mStoppingActivities.remove(i); 5483 N--; 5484 i--; 5485 } 5486 } 5487 5488 return stops; 5489 } 5490 5491 void enableScreenAfterBoot() { 5492 EventLog.writeEvent(LOG_BOOT_PROGRESS_ENABLE_SCREEN, 5493 SystemClock.uptimeMillis()); 5494 mWindowManager.enableScreenAfterBoot(); 5495 } 5496 5497 final void activityIdleInternal(IBinder token, boolean fromTimeout, 5498 Configuration config) { 5499 if (localLOGV) Log.v(TAG, "Activity idle: " + token); 5500 5501 ArrayList<HistoryRecord> stops = null; 5502 ArrayList<HistoryRecord> finishes = null; 5503 ArrayList<HistoryRecord> thumbnails = null; 5504 int NS = 0; 5505 int NF = 0; 5506 int NT = 0; 5507 IApplicationThread sendThumbnail = null; 5508 boolean booting = false; 5509 boolean enableScreen = false; 5510 5511 synchronized (this) { 5512 if (token != null) { 5513 mHandler.removeMessages(IDLE_TIMEOUT_MSG, token); 5514 } 5515 5516 // Get the activity record. 5517 int index = indexOfTokenLocked(token); 5518 if (index >= 0) { 5519 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5520 5521 // This is a hack to semi-deal with a race condition 5522 // in the client where it can be constructed with a 5523 // newer configuration from when we asked it to launch. 5524 // We'll update with whatever configuration it now says 5525 // it used to launch. 5526 if (config != null) { 5527 r.configuration = config; 5528 } 5529 5530 // No longer need to keep the device awake. 5531 if (mResumedActivity == r && mLaunchingActivity.isHeld()) { 5532 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 5533 mLaunchingActivity.release(); 5534 } 5535 5536 // We are now idle. If someone is waiting for a thumbnail from 5537 // us, we can now deliver. 5538 r.idle = true; 5539 scheduleAppGcsLocked(); 5540 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) { 5541 sendThumbnail = r.app.thread; 5542 r.thumbnailNeeded = false; 5543 } 5544 5545 // If this activity is fullscreen, set up to hide those under it. 5546 5547 if (DEBUG_VISBILITY) Log.v(TAG, "Idle activity for " + r); 5548 ensureActivitiesVisibleLocked(null, 0); 5549 5550 //Log.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); 5551 if (!mBooted && !fromTimeout) { 5552 mBooted = true; 5553 enableScreen = true; 5554 } 5555 } 5556 5557 // Atomically retrieve all of the other things to do. 5558 stops = processStoppingActivitiesLocked(true); 5559 NS = stops != null ? stops.size() : 0; 5560 if ((NF=mFinishingActivities.size()) > 0) { 5561 finishes = new ArrayList<HistoryRecord>(mFinishingActivities); 5562 mFinishingActivities.clear(); 5563 } 5564 if ((NT=mCancelledThumbnails.size()) > 0) { 5565 thumbnails = new ArrayList<HistoryRecord>(mCancelledThumbnails); 5566 mCancelledThumbnails.clear(); 5567 } 5568 5569 booting = mBooting; 5570 mBooting = false; 5571 } 5572 5573 int i; 5574 5575 // Send thumbnail if requested. 5576 if (sendThumbnail != null) { 5577 try { 5578 sendThumbnail.requestThumbnail(token); 5579 } catch (Exception e) { 5580 Log.w(TAG, "Exception thrown when requesting thumbnail", e); 5581 sendPendingThumbnail(null, token, null, null, true); 5582 } 5583 } 5584 5585 // Stop any activities that are scheduled to do so but have been 5586 // waiting for the next one to start. 5587 for (i=0; i<NS; i++) { 5588 HistoryRecord r = (HistoryRecord)stops.get(i); 5589 synchronized (this) { 5590 if (r.finishing) { 5591 finishCurrentActivityLocked(r, FINISH_IMMEDIATELY); 5592 } else { 5593 stopActivityLocked(r); 5594 } 5595 } 5596 } 5597 5598 // Finish any activities that are scheduled to do so but have been 5599 // waiting for the next one to start. 5600 for (i=0; i<NF; i++) { 5601 HistoryRecord r = (HistoryRecord)finishes.get(i); 5602 synchronized (this) { 5603 destroyActivityLocked(r, true); 5604 } 5605 } 5606 5607 // Report back to any thumbnail receivers. 5608 for (i=0; i<NT; i++) { 5609 HistoryRecord r = (HistoryRecord)thumbnails.get(i); 5610 sendPendingThumbnail(r, null, null, null, true); 5611 } 5612 5613 if (booting) { 5614 finishBooting(); 5615 } 5616 5617 trimApplications(); 5618 //dump(); 5619 //mWindowManager.dump(); 5620 5621 if (enableScreen) { 5622 enableScreenAfterBoot(); 5623 } 5624 } 5625 5626 final void finishBooting() { 5627 // Ensure that any processes we had put on hold are now started 5628 // up. 5629 final int NP = mProcessesOnHold.size(); 5630 if (NP > 0) { 5631 ArrayList<ProcessRecord> procs = 5632 new ArrayList<ProcessRecord>(mProcessesOnHold); 5633 for (int ip=0; ip<NP; ip++) { 5634 this.startProcessLocked(procs.get(ip), "on-hold", null); 5635 } 5636 } 5637 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 5638 // Tell anyone interested that we are done booting! 5639 synchronized (this) { 5640 broadcastIntentLocked(null, null, 5641 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 5642 null, null, 0, null, null, 5643 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5644 false, false, MY_PID, Process.SYSTEM_UID); 5645 } 5646 } 5647 } 5648 5649 final void ensureBootCompleted() { 5650 boolean booting; 5651 boolean enableScreen; 5652 synchronized (this) { 5653 booting = mBooting; 5654 mBooting = false; 5655 enableScreen = !mBooted; 5656 mBooted = true; 5657 } 5658 5659 if (booting) { 5660 finishBooting(); 5661 } 5662 5663 if (enableScreen) { 5664 enableScreenAfterBoot(); 5665 } 5666 } 5667 5668 public final void activityPaused(IBinder token, Bundle icicle) { 5669 // Refuse possible leaked file descriptors 5670 if (icicle != null && icicle.hasFileDescriptors()) { 5671 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5672 } 5673 5674 final long origId = Binder.clearCallingIdentity(); 5675 activityPaused(token, icicle, false); 5676 Binder.restoreCallingIdentity(origId); 5677 } 5678 5679 final void activityPaused(IBinder token, Bundle icicle, boolean timeout) { 5680 if (DEBUG_PAUSE) Log.v( 5681 TAG, "Activity paused: token=" + token + ", icicle=" + icicle 5682 + ", timeout=" + timeout); 5683 5684 HistoryRecord r = null; 5685 5686 synchronized (this) { 5687 int index = indexOfTokenLocked(token); 5688 if (index >= 0) { 5689 r = (HistoryRecord)mHistory.get(index); 5690 if (!timeout) { 5691 r.icicle = icicle; 5692 r.haveState = true; 5693 } 5694 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); 5695 if (mPausingActivity == r) { 5696 r.state = ActivityState.PAUSED; 5697 completePauseLocked(); 5698 } else { 5699 EventLog.writeEvent(LOG_AM_FAILED_TO_PAUSE_ACTIVITY, 5700 System.identityHashCode(r), r.shortComponentName, 5701 mPausingActivity != null 5702 ? mPausingActivity.shortComponentName : "(none)"); 5703 } 5704 } 5705 } 5706 } 5707 5708 public final void activityStopped(IBinder token, Bitmap thumbnail, 5709 CharSequence description) { 5710 if (localLOGV) Log.v( 5711 TAG, "Activity stopped: token=" + token); 5712 5713 HistoryRecord r = null; 5714 5715 final long origId = Binder.clearCallingIdentity(); 5716 5717 synchronized (this) { 5718 int index = indexOfTokenLocked(token); 5719 if (index >= 0) { 5720 r = (HistoryRecord)mHistory.get(index); 5721 r.thumbnail = thumbnail; 5722 r.description = description; 5723 r.stopped = true; 5724 r.state = ActivityState.STOPPED; 5725 if (!r.finishing) { 5726 if (r.configDestroy) { 5727 destroyActivityLocked(r, true); 5728 resumeTopActivityLocked(null); 5729 } 5730 } 5731 } 5732 } 5733 5734 if (r != null) { 5735 sendPendingThumbnail(r, null, null, null, false); 5736 } 5737 5738 trimApplications(); 5739 5740 Binder.restoreCallingIdentity(origId); 5741 } 5742 5743 public final void activityDestroyed(IBinder token) { 5744 if (DEBUG_SWITCH) Log.v(TAG, "ACTIVITY DESTROYED: " + token); 5745 synchronized (this) { 5746 mHandler.removeMessages(DESTROY_TIMEOUT_MSG, token); 5747 5748 int index = indexOfTokenLocked(token); 5749 if (index >= 0) { 5750 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5751 if (r.state == ActivityState.DESTROYING) { 5752 final long origId = Binder.clearCallingIdentity(); 5753 removeActivityFromHistoryLocked(r); 5754 Binder.restoreCallingIdentity(origId); 5755 } 5756 } 5757 } 5758 } 5759 5760 public String getCallingPackage(IBinder token) { 5761 synchronized (this) { 5762 HistoryRecord r = getCallingRecordLocked(token); 5763 return r != null && r.app != null ? r.info.packageName : null; 5764 } 5765 } 5766 5767 public ComponentName getCallingActivity(IBinder token) { 5768 synchronized (this) { 5769 HistoryRecord r = getCallingRecordLocked(token); 5770 return r != null ? r.intent.getComponent() : null; 5771 } 5772 } 5773 5774 private HistoryRecord getCallingRecordLocked(IBinder token) { 5775 int index = indexOfTokenLocked(token); 5776 if (index >= 0) { 5777 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5778 if (r != null) { 5779 return r.resultTo; 5780 } 5781 } 5782 return null; 5783 } 5784 5785 public ComponentName getActivityClassForToken(IBinder token) { 5786 synchronized(this) { 5787 int index = indexOfTokenLocked(token); 5788 if (index >= 0) { 5789 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5790 return r.intent.getComponent(); 5791 } 5792 return null; 5793 } 5794 } 5795 5796 public String getPackageForToken(IBinder token) { 5797 synchronized(this) { 5798 int index = indexOfTokenLocked(token); 5799 if (index >= 0) { 5800 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5801 return r.packageName; 5802 } 5803 return null; 5804 } 5805 } 5806 5807 public IIntentSender getIntentSender(int type, 5808 String packageName, IBinder token, String resultWho, 5809 int requestCode, Intent intent, String resolvedType, int flags) { 5810 // Refuse possible leaked file descriptors 5811 if (intent != null && intent.hasFileDescriptors() == true) { 5812 throw new IllegalArgumentException("File descriptors passed in Intent"); 5813 } 5814 5815 if (type == INTENT_SENDER_BROADCAST) { 5816 if ((intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5817 throw new IllegalArgumentException( 5818 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5819 } 5820 } 5821 5822 synchronized(this) { 5823 int callingUid = Binder.getCallingUid(); 5824 try { 5825 if (callingUid != 0 && callingUid != Process.SYSTEM_UID && 5826 Process.supportsProcesses()) { 5827 int uid = ActivityThread.getPackageManager() 5828 .getPackageUid(packageName); 5829 if (uid != Binder.getCallingUid()) { 5830 String msg = "Permission Denial: getIntentSender() from pid=" 5831 + Binder.getCallingPid() 5832 + ", uid=" + Binder.getCallingUid() 5833 + ", (need uid=" + uid + ")" 5834 + " is not allowed to send as package " + packageName; 5835 Log.w(TAG, msg); 5836 throw new SecurityException(msg); 5837 } 5838 } 5839 } catch (RemoteException e) { 5840 throw new SecurityException(e); 5841 } 5842 HistoryRecord activity = null; 5843 if (type == INTENT_SENDER_ACTIVITY_RESULT) { 5844 int index = indexOfTokenLocked(token); 5845 if (index < 0) { 5846 return null; 5847 } 5848 activity = (HistoryRecord)mHistory.get(index); 5849 if (activity.finishing) { 5850 return null; 5851 } 5852 } 5853 5854 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5855 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5856 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5857 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5858 |PendingIntent.FLAG_UPDATE_CURRENT); 5859 5860 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5861 type, packageName, activity, resultWho, 5862 requestCode, intent, resolvedType, flags); 5863 WeakReference<PendingIntentRecord> ref; 5864 ref = mIntentSenderRecords.get(key); 5865 PendingIntentRecord rec = ref != null ? ref.get() : null; 5866 if (rec != null) { 5867 if (!cancelCurrent) { 5868 if (updateCurrent) { 5869 rec.key.requestIntent.replaceExtras(intent); 5870 } 5871 return rec; 5872 } 5873 rec.canceled = true; 5874 mIntentSenderRecords.remove(key); 5875 } 5876 if (noCreate) { 5877 return rec; 5878 } 5879 rec = new PendingIntentRecord(this, key, callingUid); 5880 mIntentSenderRecords.put(key, rec.ref); 5881 if (type == INTENT_SENDER_ACTIVITY_RESULT) { 5882 if (activity.pendingResults == null) { 5883 activity.pendingResults 5884 = new HashSet<WeakReference<PendingIntentRecord>>(); 5885 } 5886 activity.pendingResults.add(rec.ref); 5887 } 5888 return rec; 5889 } 5890 } 5891 5892 public void cancelIntentSender(IIntentSender sender) { 5893 if (!(sender instanceof PendingIntentRecord)) { 5894 return; 5895 } 5896 synchronized(this) { 5897 PendingIntentRecord rec = (PendingIntentRecord)sender; 5898 try { 5899 int uid = ActivityThread.getPackageManager() 5900 .getPackageUid(rec.key.packageName); 5901 if (uid != Binder.getCallingUid()) { 5902 String msg = "Permission Denial: cancelIntentSender() from pid=" 5903 + Binder.getCallingPid() 5904 + ", uid=" + Binder.getCallingUid() 5905 + " is not allowed to cancel packges " 5906 + rec.key.packageName; 5907 Log.w(TAG, msg); 5908 throw new SecurityException(msg); 5909 } 5910 } catch (RemoteException e) { 5911 throw new SecurityException(e); 5912 } 5913 cancelIntentSenderLocked(rec, true); 5914 } 5915 } 5916 5917 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5918 rec.canceled = true; 5919 mIntentSenderRecords.remove(rec.key); 5920 if (cleanActivity && rec.key.activity != null) { 5921 rec.key.activity.pendingResults.remove(rec.ref); 5922 } 5923 } 5924 5925 public String getPackageForIntentSender(IIntentSender pendingResult) { 5926 if (!(pendingResult instanceof PendingIntentRecord)) { 5927 return null; 5928 } 5929 synchronized(this) { 5930 try { 5931 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5932 return res.key.packageName; 5933 } catch (ClassCastException e) { 5934 } 5935 } 5936 return null; 5937 } 5938 5939 public void setProcessLimit(int max) { 5940 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5941 "setProcessLimit()"); 5942 mProcessLimit = max; 5943 } 5944 5945 public int getProcessLimit() { 5946 return mProcessLimit; 5947 } 5948 5949 void foregroundTokenDied(ForegroundToken token) { 5950 synchronized (ActivityManagerService.this) { 5951 synchronized (mPidsSelfLocked) { 5952 ForegroundToken cur 5953 = mForegroundProcesses.get(token.pid); 5954 if (cur != token) { 5955 return; 5956 } 5957 mForegroundProcesses.remove(token.pid); 5958 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5959 if (pr == null) { 5960 return; 5961 } 5962 pr.forcingToForeground = null; 5963 pr.foregroundServices = false; 5964 } 5965 updateOomAdjLocked(); 5966 } 5967 } 5968 5969 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5970 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5971 "setProcessForeground()"); 5972 synchronized(this) { 5973 boolean changed = false; 5974 5975 synchronized (mPidsSelfLocked) { 5976 ProcessRecord pr = mPidsSelfLocked.get(pid); 5977 if (pr == null) { 5978 Log.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5979 return; 5980 } 5981 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5982 if (oldToken != null) { 5983 oldToken.token.unlinkToDeath(oldToken, 0); 5984 mForegroundProcesses.remove(pid); 5985 pr.forcingToForeground = null; 5986 changed = true; 5987 } 5988 if (isForeground && token != null) { 5989 ForegroundToken newToken = new ForegroundToken() { 5990 public void binderDied() { 5991 foregroundTokenDied(this); 5992 } 5993 }; 5994 newToken.pid = pid; 5995 newToken.token = token; 5996 try { 5997 token.linkToDeath(newToken, 0); 5998 mForegroundProcesses.put(pid, newToken); 5999 pr.forcingToForeground = token; 6000 changed = true; 6001 } catch (RemoteException e) { 6002 // If the process died while doing this, we will later 6003 // do the cleanup with the process death link. 6004 } 6005 } 6006 } 6007 6008 if (changed) { 6009 updateOomAdjLocked(); 6010 } 6011 } 6012 } 6013 6014 // ========================================================= 6015 // PERMISSIONS 6016 // ========================================================= 6017 6018 static class PermissionController extends IPermissionController.Stub { 6019 ActivityManagerService mActivityManagerService; 6020 PermissionController(ActivityManagerService activityManagerService) { 6021 mActivityManagerService = activityManagerService; 6022 } 6023 6024 public boolean checkPermission(String permission, int pid, int uid) { 6025 return mActivityManagerService.checkPermission(permission, pid, 6026 uid) == PackageManager.PERMISSION_GRANTED; 6027 } 6028 } 6029 6030 /** 6031 * This can be called with or without the global lock held. 6032 */ 6033 int checkComponentPermission(String permission, int pid, int uid, 6034 int reqUid) { 6035 // We might be performing an operation on behalf of an indirect binder 6036 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6037 // client identity accordingly before proceeding. 6038 Identity tlsIdentity = sCallerIdentity.get(); 6039 if (tlsIdentity != null) { 6040 Log.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6041 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6042 uid = tlsIdentity.uid; 6043 pid = tlsIdentity.pid; 6044 } 6045 6046 // Root, system server and our own process get to do everything. 6047 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID || 6048 !Process.supportsProcesses()) { 6049 return PackageManager.PERMISSION_GRANTED; 6050 } 6051 // If the target requires a specific UID, always fail for others. 6052 if (reqUid >= 0 && uid != reqUid) { 6053 return PackageManager.PERMISSION_DENIED; 6054 } 6055 if (permission == null) { 6056 return PackageManager.PERMISSION_GRANTED; 6057 } 6058 try { 6059 return ActivityThread.getPackageManager() 6060 .checkUidPermission(permission, uid); 6061 } catch (RemoteException e) { 6062 // Should never happen, but if it does... deny! 6063 Log.e(TAG, "PackageManager is dead?!?", e); 6064 } 6065 return PackageManager.PERMISSION_DENIED; 6066 } 6067 6068 /** 6069 * As the only public entry point for permissions checking, this method 6070 * can enforce the semantic that requesting a check on a null global 6071 * permission is automatically denied. (Internally a null permission 6072 * string is used when calling {@link #checkComponentPermission} in cases 6073 * when only uid-based security is needed.) 6074 * 6075 * This can be called with or without the global lock held. 6076 */ 6077 public int checkPermission(String permission, int pid, int uid) { 6078 if (permission == null) { 6079 return PackageManager.PERMISSION_DENIED; 6080 } 6081 return checkComponentPermission(permission, pid, uid, -1); 6082 } 6083 6084 /** 6085 * Binder IPC calls go through the public entry point. 6086 * This can be called with or without the global lock held. 6087 */ 6088 int checkCallingPermission(String permission) { 6089 return checkPermission(permission, 6090 Binder.getCallingPid(), 6091 Binder.getCallingUid()); 6092 } 6093 6094 /** 6095 * This can be called with or without the global lock held. 6096 */ 6097 void enforceCallingPermission(String permission, String func) { 6098 if (checkCallingPermission(permission) 6099 == PackageManager.PERMISSION_GRANTED) { 6100 return; 6101 } 6102 6103 String msg = "Permission Denial: " + func + " from pid=" 6104 + Binder.getCallingPid() 6105 + ", uid=" + Binder.getCallingUid() 6106 + " requires " + permission; 6107 Log.w(TAG, msg); 6108 throw new SecurityException(msg); 6109 } 6110 6111 private final boolean checkHoldingPermissionsLocked(IPackageManager pm, 6112 ProviderInfo pi, int uid, int modeFlags) { 6113 try { 6114 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6115 if ((pi.readPermission != null) && 6116 (pm.checkUidPermission(pi.readPermission, uid) 6117 != PackageManager.PERMISSION_GRANTED)) { 6118 return false; 6119 } 6120 } 6121 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6122 if ((pi.writePermission != null) && 6123 (pm.checkUidPermission(pi.writePermission, uid) 6124 != PackageManager.PERMISSION_GRANTED)) { 6125 return false; 6126 } 6127 } 6128 return true; 6129 } catch (RemoteException e) { 6130 return false; 6131 } 6132 } 6133 6134 private final boolean checkUriPermissionLocked(Uri uri, int uid, 6135 int modeFlags) { 6136 // Root gets to do everything. 6137 if (uid == 0 || !Process.supportsProcesses()) { 6138 return true; 6139 } 6140 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6141 if (perms == null) return false; 6142 UriPermission perm = perms.get(uri); 6143 if (perm == null) return false; 6144 return (modeFlags&perm.modeFlags) == modeFlags; 6145 } 6146 6147 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 6148 // Another redirected-binder-call permissions check as in 6149 // {@link checkComponentPermission}. 6150 Identity tlsIdentity = sCallerIdentity.get(); 6151 if (tlsIdentity != null) { 6152 uid = tlsIdentity.uid; 6153 pid = tlsIdentity.pid; 6154 } 6155 6156 // Our own process gets to do everything. 6157 if (pid == MY_PID) { 6158 return PackageManager.PERMISSION_GRANTED; 6159 } 6160 synchronized(this) { 6161 return checkUriPermissionLocked(uri, uid, modeFlags) 6162 ? PackageManager.PERMISSION_GRANTED 6163 : PackageManager.PERMISSION_DENIED; 6164 } 6165 } 6166 6167 private void grantUriPermissionLocked(int callingUid, 6168 String targetPkg, Uri uri, int modeFlags, HistoryRecord activity) { 6169 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6170 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6171 if (modeFlags == 0) { 6172 return; 6173 } 6174 6175 final IPackageManager pm = ActivityThread.getPackageManager(); 6176 6177 // If this is not a content: uri, we can't do anything with it. 6178 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 6179 return; 6180 } 6181 6182 String name = uri.getAuthority(); 6183 ProviderInfo pi = null; 6184 ContentProviderRecord cpr 6185 = (ContentProviderRecord)mProvidersByName.get(name); 6186 if (cpr != null) { 6187 pi = cpr.info; 6188 } else { 6189 try { 6190 pi = pm.resolveContentProvider(name, 6191 PackageManager.GET_URI_PERMISSION_PATTERNS); 6192 } catch (RemoteException ex) { 6193 } 6194 } 6195 if (pi == null) { 6196 Log.w(TAG, "No content provider found for: " + name); 6197 return; 6198 } 6199 6200 int targetUid; 6201 try { 6202 targetUid = pm.getPackageUid(targetPkg); 6203 if (targetUid < 0) { 6204 return; 6205 } 6206 } catch (RemoteException ex) { 6207 return; 6208 } 6209 6210 // First... does the target actually need this permission? 6211 if (checkHoldingPermissionsLocked(pm, pi, targetUid, modeFlags)) { 6212 // No need to grant the target this permission. 6213 return; 6214 } 6215 6216 // Second... maybe someone else has already granted the 6217 // permission? 6218 if (checkUriPermissionLocked(uri, targetUid, modeFlags)) { 6219 // No need to grant the target this permission. 6220 return; 6221 } 6222 6223 // Third... is the provider allowing granting of URI permissions? 6224 if (!pi.grantUriPermissions) { 6225 throw new SecurityException("Provider " + pi.packageName 6226 + "/" + pi.name 6227 + " does not allow granting of Uri permissions (uri " 6228 + uri + ")"); 6229 } 6230 if (pi.uriPermissionPatterns != null) { 6231 final int N = pi.uriPermissionPatterns.length; 6232 boolean allowed = false; 6233 for (int i=0; i<N; i++) { 6234 if (pi.uriPermissionPatterns[i] != null 6235 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6236 allowed = true; 6237 break; 6238 } 6239 } 6240 if (!allowed) { 6241 throw new SecurityException("Provider " + pi.packageName 6242 + "/" + pi.name 6243 + " does not allow granting of permission to path of Uri " 6244 + uri); 6245 } 6246 } 6247 6248 // Fourth... does the caller itself have permission to access 6249 // this uri? 6250 if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) { 6251 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6252 throw new SecurityException("Uid " + callingUid 6253 + " does not have permission to uri " + uri); 6254 } 6255 } 6256 6257 // Okay! So here we are: the caller has the assumed permission 6258 // to the uri, and the target doesn't. Let's now give this to 6259 // the target. 6260 6261 HashMap<Uri, UriPermission> targetUris 6262 = mGrantedUriPermissions.get(targetUid); 6263 if (targetUris == null) { 6264 targetUris = new HashMap<Uri, UriPermission>(); 6265 mGrantedUriPermissions.put(targetUid, targetUris); 6266 } 6267 6268 UriPermission perm = targetUris.get(uri); 6269 if (perm == null) { 6270 perm = new UriPermission(targetUid, uri); 6271 targetUris.put(uri, perm); 6272 6273 } 6274 perm.modeFlags |= modeFlags; 6275 if (activity == null) { 6276 perm.globalModeFlags |= modeFlags; 6277 } else if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6278 perm.readActivities.add(activity); 6279 if (activity.readUriPermissions == null) { 6280 activity.readUriPermissions = new HashSet<UriPermission>(); 6281 } 6282 activity.readUriPermissions.add(perm); 6283 } else if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6284 perm.writeActivities.add(activity); 6285 if (activity.writeUriPermissions == null) { 6286 activity.writeUriPermissions = new HashSet<UriPermission>(); 6287 } 6288 activity.writeUriPermissions.add(perm); 6289 } 6290 } 6291 6292 private void grantUriPermissionFromIntentLocked(int callingUid, 6293 String targetPkg, Intent intent, HistoryRecord activity) { 6294 if (intent == null) { 6295 return; 6296 } 6297 Uri data = intent.getData(); 6298 if (data == null) { 6299 return; 6300 } 6301 grantUriPermissionLocked(callingUid, targetPkg, data, 6302 intent.getFlags(), activity); 6303 } 6304 6305 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6306 Uri uri, int modeFlags) { 6307 synchronized(this) { 6308 final ProcessRecord r = getRecordForAppLocked(caller); 6309 if (r == null) { 6310 throw new SecurityException("Unable to find app for caller " 6311 + caller 6312 + " when granting permission to uri " + uri); 6313 } 6314 if (targetPkg == null) { 6315 Log.w(TAG, "grantUriPermission: null target"); 6316 return; 6317 } 6318 if (uri == null) { 6319 Log.w(TAG, "grantUriPermission: null uri"); 6320 return; 6321 } 6322 6323 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags, 6324 null); 6325 } 6326 } 6327 6328 private void removeUriPermissionIfNeededLocked(UriPermission perm) { 6329 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6330 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6331 HashMap<Uri, UriPermission> perms 6332 = mGrantedUriPermissions.get(perm.uid); 6333 if (perms != null) { 6334 perms.remove(perm.uri); 6335 if (perms.size() == 0) { 6336 mGrantedUriPermissions.remove(perm.uid); 6337 } 6338 } 6339 } 6340 } 6341 6342 private void removeActivityUriPermissionsLocked(HistoryRecord activity) { 6343 if (activity.readUriPermissions != null) { 6344 for (UriPermission perm : activity.readUriPermissions) { 6345 perm.readActivities.remove(activity); 6346 if (perm.readActivities.size() == 0 && (perm.globalModeFlags 6347 &Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0) { 6348 perm.modeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION; 6349 removeUriPermissionIfNeededLocked(perm); 6350 } 6351 } 6352 } 6353 if (activity.writeUriPermissions != null) { 6354 for (UriPermission perm : activity.writeUriPermissions) { 6355 perm.writeActivities.remove(activity); 6356 if (perm.writeActivities.size() == 0 && (perm.globalModeFlags 6357 &Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0) { 6358 perm.modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION; 6359 removeUriPermissionIfNeededLocked(perm); 6360 } 6361 } 6362 } 6363 } 6364 6365 private void revokeUriPermissionLocked(int callingUid, Uri uri, 6366 int modeFlags) { 6367 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6368 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6369 if (modeFlags == 0) { 6370 return; 6371 } 6372 6373 final IPackageManager pm = ActivityThread.getPackageManager(); 6374 6375 final String authority = uri.getAuthority(); 6376 ProviderInfo pi = null; 6377 ContentProviderRecord cpr 6378 = (ContentProviderRecord)mProvidersByName.get(authority); 6379 if (cpr != null) { 6380 pi = cpr.info; 6381 } else { 6382 try { 6383 pi = pm.resolveContentProvider(authority, 6384 PackageManager.GET_URI_PERMISSION_PATTERNS); 6385 } catch (RemoteException ex) { 6386 } 6387 } 6388 if (pi == null) { 6389 Log.w(TAG, "No content provider found for: " + authority); 6390 return; 6391 } 6392 6393 // Does the caller have this permission on the URI? 6394 if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) { 6395 // Right now, if you are not the original owner of the permission, 6396 // you are not allowed to revoke it. 6397 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6398 throw new SecurityException("Uid " + callingUid 6399 + " does not have permission to uri " + uri); 6400 //} 6401 } 6402 6403 // Go through all of the permissions and remove any that match. 6404 final List<String> SEGMENTS = uri.getPathSegments(); 6405 if (SEGMENTS != null) { 6406 final int NS = SEGMENTS.size(); 6407 int N = mGrantedUriPermissions.size(); 6408 for (int i=0; i<N; i++) { 6409 HashMap<Uri, UriPermission> perms 6410 = mGrantedUriPermissions.valueAt(i); 6411 Iterator<UriPermission> it = perms.values().iterator(); 6412 toploop: 6413 while (it.hasNext()) { 6414 UriPermission perm = it.next(); 6415 Uri targetUri = perm.uri; 6416 if (!authority.equals(targetUri.getAuthority())) { 6417 continue; 6418 } 6419 List<String> targetSegments = targetUri.getPathSegments(); 6420 if (targetSegments == null) { 6421 continue; 6422 } 6423 if (targetSegments.size() < NS) { 6424 continue; 6425 } 6426 for (int j=0; j<NS; j++) { 6427 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6428 continue toploop; 6429 } 6430 } 6431 perm.clearModes(modeFlags); 6432 if (perm.modeFlags == 0) { 6433 it.remove(); 6434 } 6435 } 6436 if (perms.size() == 0) { 6437 mGrantedUriPermissions.remove( 6438 mGrantedUriPermissions.keyAt(i)); 6439 N--; 6440 i--; 6441 } 6442 } 6443 } 6444 } 6445 6446 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6447 int modeFlags) { 6448 synchronized(this) { 6449 final ProcessRecord r = getRecordForAppLocked(caller); 6450 if (r == null) { 6451 throw new SecurityException("Unable to find app for caller " 6452 + caller 6453 + " when revoking permission to uri " + uri); 6454 } 6455 if (uri == null) { 6456 Log.w(TAG, "revokeUriPermission: null uri"); 6457 return; 6458 } 6459 6460 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6461 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6462 if (modeFlags == 0) { 6463 return; 6464 } 6465 6466 final IPackageManager pm = ActivityThread.getPackageManager(); 6467 6468 final String authority = uri.getAuthority(); 6469 ProviderInfo pi = null; 6470 ContentProviderRecord cpr 6471 = (ContentProviderRecord)mProvidersByName.get(authority); 6472 if (cpr != null) { 6473 pi = cpr.info; 6474 } else { 6475 try { 6476 pi = pm.resolveContentProvider(authority, 6477 PackageManager.GET_URI_PERMISSION_PATTERNS); 6478 } catch (RemoteException ex) { 6479 } 6480 } 6481 if (pi == null) { 6482 Log.w(TAG, "No content provider found for: " + authority); 6483 return; 6484 } 6485 6486 revokeUriPermissionLocked(r.info.uid, uri, modeFlags); 6487 } 6488 } 6489 6490 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6491 synchronized (this) { 6492 ProcessRecord app = 6493 who != null ? getRecordForAppLocked(who) : null; 6494 if (app == null) return; 6495 6496 Message msg = Message.obtain(); 6497 msg.what = WAIT_FOR_DEBUGGER_MSG; 6498 msg.obj = app; 6499 msg.arg1 = waiting ? 1 : 0; 6500 mHandler.sendMessage(msg); 6501 } 6502 } 6503 6504 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6505 outInfo.availMem = Process.getFreeMemory(); 6506 outInfo.threshold = HOME_APP_MEM; 6507 outInfo.lowMemory = outInfo.availMem < 6508 (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2)); 6509 } 6510 6511 // ========================================================= 6512 // TASK MANAGEMENT 6513 // ========================================================= 6514 6515 public List getTasks(int maxNum, int flags, 6516 IThumbnailReceiver receiver) { 6517 ArrayList list = new ArrayList(); 6518 6519 PendingThumbnailsRecord pending = null; 6520 IApplicationThread topThumbnail = null; 6521 HistoryRecord topRecord = null; 6522 6523 synchronized(this) { 6524 if (localLOGV) Log.v( 6525 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6526 + ", receiver=" + receiver); 6527 6528 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6529 != PackageManager.PERMISSION_GRANTED) { 6530 if (receiver != null) { 6531 // If the caller wants to wait for pending thumbnails, 6532 // it ain't gonna get them. 6533 try { 6534 receiver.finished(); 6535 } catch (RemoteException ex) { 6536 } 6537 } 6538 String msg = "Permission Denial: getTasks() from pid=" 6539 + Binder.getCallingPid() 6540 + ", uid=" + Binder.getCallingUid() 6541 + " requires " + android.Manifest.permission.GET_TASKS; 6542 Log.w(TAG, msg); 6543 throw new SecurityException(msg); 6544 } 6545 6546 int pos = mHistory.size()-1; 6547 HistoryRecord next = 6548 pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null; 6549 HistoryRecord top = null; 6550 CharSequence topDescription = null; 6551 TaskRecord curTask = null; 6552 int numActivities = 0; 6553 int numRunning = 0; 6554 while (pos >= 0 && maxNum > 0) { 6555 final HistoryRecord r = next; 6556 pos--; 6557 next = pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null; 6558 6559 // Initialize state for next task if needed. 6560 if (top == null || 6561 (top.state == ActivityState.INITIALIZING 6562 && top.task == r.task)) { 6563 top = r; 6564 topDescription = r.description; 6565 curTask = r.task; 6566 numActivities = numRunning = 0; 6567 } 6568 6569 // Add 'r' into the current task. 6570 numActivities++; 6571 if (r.app != null && r.app.thread != null) { 6572 numRunning++; 6573 } 6574 if (topDescription == null) { 6575 topDescription = r.description; 6576 } 6577 6578 if (localLOGV) Log.v( 6579 TAG, r.intent.getComponent().flattenToShortString() 6580 + ": task=" + r.task); 6581 6582 // If the next one is a different task, generate a new 6583 // TaskInfo entry for what we have. 6584 if (next == null || next.task != curTask) { 6585 ActivityManager.RunningTaskInfo ci 6586 = new ActivityManager.RunningTaskInfo(); 6587 ci.id = curTask.taskId; 6588 ci.baseActivity = r.intent.getComponent(); 6589 ci.topActivity = top.intent.getComponent(); 6590 ci.thumbnail = top.thumbnail; 6591 ci.description = topDescription; 6592 ci.numActivities = numActivities; 6593 ci.numRunning = numRunning; 6594 //System.out.println( 6595 // "#" + maxNum + ": " + " descr=" + ci.description); 6596 if (ci.thumbnail == null && receiver != null) { 6597 if (localLOGV) Log.v( 6598 TAG, "State=" + top.state + "Idle=" + top.idle 6599 + " app=" + top.app 6600 + " thr=" + (top.app != null ? top.app.thread : null)); 6601 if (top.state == ActivityState.RESUMED 6602 || top.state == ActivityState.PAUSING) { 6603 if (top.idle && top.app != null 6604 && top.app.thread != null) { 6605 topRecord = top; 6606 topThumbnail = top.app.thread; 6607 } else { 6608 top.thumbnailNeeded = true; 6609 } 6610 } 6611 if (pending == null) { 6612 pending = new PendingThumbnailsRecord(receiver); 6613 } 6614 pending.pendingRecords.add(top); 6615 } 6616 list.add(ci); 6617 maxNum--; 6618 top = null; 6619 } 6620 } 6621 6622 if (pending != null) { 6623 mPendingThumbnails.add(pending); 6624 } 6625 } 6626 6627 if (localLOGV) Log.v(TAG, "We have pending thumbnails: " + pending); 6628 6629 if (topThumbnail != null) { 6630 if (localLOGV) Log.v(TAG, "Requesting top thumbnail"); 6631 try { 6632 topThumbnail.requestThumbnail(topRecord); 6633 } catch (Exception e) { 6634 Log.w(TAG, "Exception thrown when requesting thumbnail", e); 6635 sendPendingThumbnail(null, topRecord, null, null, true); 6636 } 6637 } 6638 6639 if (pending == null && receiver != null) { 6640 // In this case all thumbnails were available and the client 6641 // is being asked to be told when the remaining ones come in... 6642 // which is unusually, since the top-most currently running 6643 // activity should never have a canned thumbnail! Oh well. 6644 try { 6645 receiver.finished(); 6646 } catch (RemoteException ex) { 6647 } 6648 } 6649 6650 return list; 6651 } 6652 6653 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6654 int flags) { 6655 synchronized (this) { 6656 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6657 "getRecentTasks()"); 6658 6659 final int N = mRecentTasks.size(); 6660 ArrayList<ActivityManager.RecentTaskInfo> res 6661 = new ArrayList<ActivityManager.RecentTaskInfo>( 6662 maxNum < N ? maxNum : N); 6663 for (int i=0; i<N && maxNum > 0; i++) { 6664 TaskRecord tr = mRecentTasks.get(i); 6665 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6666 || (tr.intent == null) 6667 || ((tr.intent.getFlags() 6668 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6669 ActivityManager.RecentTaskInfo rti 6670 = new ActivityManager.RecentTaskInfo(); 6671 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6672 rti.baseIntent = new Intent( 6673 tr.intent != null ? tr.intent : tr.affinityIntent); 6674 rti.origActivity = tr.origActivity; 6675 res.add(rti); 6676 maxNum--; 6677 } 6678 } 6679 return res; 6680 } 6681 } 6682 6683 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 6684 int j; 6685 TaskRecord startTask = ((HistoryRecord)mHistory.get(startIndex)).task; 6686 TaskRecord jt = startTask; 6687 6688 // First look backwards 6689 for (j=startIndex-1; j>=0; j--) { 6690 HistoryRecord r = (HistoryRecord)mHistory.get(j); 6691 if (r.task != jt) { 6692 jt = r.task; 6693 if (affinity.equals(jt.affinity)) { 6694 return j; 6695 } 6696 } 6697 } 6698 6699 // Now look forwards 6700 final int N = mHistory.size(); 6701 jt = startTask; 6702 for (j=startIndex+1; j<N; j++) { 6703 HistoryRecord r = (HistoryRecord)mHistory.get(j); 6704 if (r.task != jt) { 6705 if (affinity.equals(jt.affinity)) { 6706 return j; 6707 } 6708 jt = r.task; 6709 } 6710 } 6711 6712 // Might it be at the top? 6713 if (affinity.equals(((HistoryRecord)mHistory.get(N-1)).task.affinity)) { 6714 return N-1; 6715 } 6716 6717 return -1; 6718 } 6719 6720 /** 6721 * Perform a reset of the given task, if needed as part of launching it. 6722 * Returns the new HistoryRecord at the top of the task. 6723 */ 6724 private final HistoryRecord resetTaskIfNeededLocked(HistoryRecord taskTop, 6725 HistoryRecord newActivity) { 6726 boolean forceReset = (newActivity.info.flags 6727 &ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0; 6728 if (taskTop.task.getInactiveDuration() > ACTIVITY_INACTIVE_RESET_TIME) { 6729 if ((newActivity.info.flags 6730 &ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE) == 0) { 6731 forceReset = true; 6732 } 6733 } 6734 6735 final TaskRecord task = taskTop.task; 6736 6737 // We are going to move through the history list so that we can look 6738 // at each activity 'target' with 'below' either the interesting 6739 // activity immediately below it in the stack or null. 6740 HistoryRecord target = null; 6741 int targetI = 0; 6742 int taskTopI = -1; 6743 int replyChainEnd = -1; 6744 int lastReparentPos = -1; 6745 for (int i=mHistory.size()-1; i>=-1; i--) { 6746 HistoryRecord below = i >= 0 ? (HistoryRecord)mHistory.get(i) : null; 6747 6748 if (below != null && below.finishing) { 6749 continue; 6750 } 6751 if (target == null) { 6752 target = below; 6753 targetI = i; 6754 // If we were in the middle of a reply chain before this 6755 // task, it doesn't appear like the root of the chain wants 6756 // anything interesting, so drop it. 6757 replyChainEnd = -1; 6758 continue; 6759 } 6760 6761 final int flags = target.info.flags; 6762 6763 final boolean finishOnTaskLaunch = 6764 (flags&ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0; 6765 final boolean allowTaskReparenting = 6766 (flags&ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0; 6767 6768 if (target.task == task) { 6769 // We are inside of the task being reset... we'll either 6770 // finish this activity, push it out for another task, 6771 // or leave it as-is. We only do this 6772 // for activities that are not the root of the task (since 6773 // if we finish the root, we may no longer have the task!). 6774 if (taskTopI < 0) { 6775 taskTopI = targetI; 6776 } 6777 if (below != null && below.task == task) { 6778 final boolean clearWhenTaskReset = 6779 (target.intent.getFlags() 6780 &Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0; 6781 if (!finishOnTaskLaunch && !clearWhenTaskReset && target.resultTo != null) { 6782 // If this activity is sending a reply to a previous 6783 // activity, we can't do anything with it now until 6784 // we reach the start of the reply chain. 6785 // XXX note that we are assuming the result is always 6786 // to the previous activity, which is almost always 6787 // the case but we really shouldn't count on. 6788 if (replyChainEnd < 0) { 6789 replyChainEnd = targetI; 6790 } 6791 } else if (!finishOnTaskLaunch && !clearWhenTaskReset && allowTaskReparenting 6792 && target.taskAffinity != null 6793 && !target.taskAffinity.equals(task.affinity)) { 6794 // If this activity has an affinity for another 6795 // task, then we need to move it out of here. We will 6796 // move it as far out of the way as possible, to the 6797 // bottom of the activity stack. This also keeps it 6798 // correctly ordered with any activities we previously 6799 // moved. 6800 HistoryRecord p = (HistoryRecord)mHistory.get(0); 6801 if (target.taskAffinity != null 6802 && target.taskAffinity.equals(p.task.affinity)) { 6803 // If the activity currently at the bottom has the 6804 // same task affinity as the one we are moving, 6805 // then merge it into the same task. 6806 target.task = p.task; 6807 if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target 6808 + " out to bottom task " + p.task); 6809 } else { 6810 mCurTask++; 6811 if (mCurTask <= 0) { 6812 mCurTask = 1; 6813 } 6814 target.task = new TaskRecord(mCurTask, target.info, null, 6815 (target.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0); 6816 target.task.affinityIntent = target.intent; 6817 if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target 6818 + " out to new task " + target.task); 6819 } 6820 mWindowManager.setAppGroupId(target, task.taskId); 6821 if (replyChainEnd < 0) { 6822 replyChainEnd = targetI; 6823 } 6824 int dstPos = 0; 6825 for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) { 6826 p = (HistoryRecord)mHistory.get(srcPos); 6827 if (p.finishing) { 6828 continue; 6829 } 6830 if (DEBUG_TASKS) Log.v(TAG, "Pushing next activity " + p 6831 + " out to target's task " + target.task); 6832 task.numActivities--; 6833 p.task = target.task; 6834 target.task.numActivities++; 6835 mHistory.remove(srcPos); 6836 mHistory.add(dstPos, p); 6837 mWindowManager.moveAppToken(dstPos, p); 6838 mWindowManager.setAppGroupId(p, p.task.taskId); 6839 dstPos++; 6840 if (VALIDATE_TOKENS) { 6841 mWindowManager.validateAppTokens(mHistory); 6842 } 6843 i++; 6844 } 6845 if (taskTop == p) { 6846 taskTop = below; 6847 } 6848 if (taskTopI == replyChainEnd) { 6849 taskTopI = -1; 6850 } 6851 replyChainEnd = -1; 6852 addRecentTask(target.task); 6853 } else if (forceReset || finishOnTaskLaunch 6854 || clearWhenTaskReset) { 6855 // If the activity should just be removed -- either 6856 // because it asks for it, or the task should be 6857 // cleared -- then finish it and anything that is 6858 // part of its reply chain. 6859 if (clearWhenTaskReset) { 6860 // In this case, we want to finish this activity 6861 // and everything above it, so be sneaky and pretend 6862 // like these are all in the reply chain. 6863 replyChainEnd = targetI+1; 6864 while (replyChainEnd < mHistory.size() && 6865 ((HistoryRecord)mHistory.get( 6866 replyChainEnd)).task == task) { 6867 replyChainEnd++; 6868 } 6869 replyChainEnd--; 6870 } else if (replyChainEnd < 0) { 6871 replyChainEnd = targetI; 6872 } 6873 HistoryRecord p = null; 6874 for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) { 6875 p = (HistoryRecord)mHistory.get(srcPos); 6876 if (p.finishing) { 6877 continue; 6878 } 6879 if (finishActivityLocked(p, srcPos, 6880 Activity.RESULT_CANCELED, null, "reset")) { 6881 replyChainEnd--; 6882 srcPos--; 6883 } 6884 } 6885 if (taskTop == p) { 6886 taskTop = below; 6887 } 6888 if (taskTopI == replyChainEnd) { 6889 taskTopI = -1; 6890 } 6891 replyChainEnd = -1; 6892 } else { 6893 // If we were in the middle of a chain, well the 6894 // activity that started it all doesn't want anything 6895 // special, so leave it all as-is. 6896 replyChainEnd = -1; 6897 } 6898 } else { 6899 // Reached the bottom of the task -- any reply chain 6900 // should be left as-is. 6901 replyChainEnd = -1; 6902 } 6903 6904 } else if (target.resultTo != null) { 6905 // If this activity is sending a reply to a previous 6906 // activity, we can't do anything with it now until 6907 // we reach the start of the reply chain. 6908 // XXX note that we are assuming the result is always 6909 // to the previous activity, which is almost always 6910 // the case but we really shouldn't count on. 6911 if (replyChainEnd < 0) { 6912 replyChainEnd = targetI; 6913 } 6914 6915 } else if (taskTopI >= 0 && allowTaskReparenting 6916 && task.affinity != null 6917 && task.affinity.equals(target.taskAffinity)) { 6918 // We are inside of another task... if this activity has 6919 // an affinity for our task, then either remove it if we are 6920 // clearing or move it over to our task. Note that 6921 // we currently punt on the case where we are resetting a 6922 // task that is not at the top but who has activities above 6923 // with an affinity to it... this is really not a normal 6924 // case, and we will need to later pull that task to the front 6925 // and usually at that point we will do the reset and pick 6926 // up those remaining activities. (This only happens if 6927 // someone starts an activity in a new task from an activity 6928 // in a task that is not currently on top.) 6929 if (forceReset || finishOnTaskLaunch) { 6930 if (replyChainEnd < 0) { 6931 replyChainEnd = targetI; 6932 } 6933 HistoryRecord p = null; 6934 for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) { 6935 p = (HistoryRecord)mHistory.get(srcPos); 6936 if (p.finishing) { 6937 continue; 6938 } 6939 if (finishActivityLocked(p, srcPos, 6940 Activity.RESULT_CANCELED, null, "reset")) { 6941 taskTopI--; 6942 lastReparentPos--; 6943 replyChainEnd--; 6944 srcPos--; 6945 } 6946 } 6947 replyChainEnd = -1; 6948 } else { 6949 if (replyChainEnd < 0) { 6950 replyChainEnd = targetI; 6951 } 6952 for (int srcPos=replyChainEnd; srcPos>=targetI; srcPos--) { 6953 HistoryRecord p = (HistoryRecord)mHistory.get(srcPos); 6954 if (p.finishing) { 6955 continue; 6956 } 6957 if (lastReparentPos < 0) { 6958 lastReparentPos = taskTopI; 6959 taskTop = p; 6960 } else { 6961 lastReparentPos--; 6962 } 6963 mHistory.remove(srcPos); 6964 p.task.numActivities--; 6965 p.task = task; 6966 mHistory.add(lastReparentPos, p); 6967 if (DEBUG_TASKS) Log.v(TAG, "Pulling activity " + p 6968 + " in to resetting task " + task); 6969 task.numActivities++; 6970 mWindowManager.moveAppToken(lastReparentPos, p); 6971 mWindowManager.setAppGroupId(p, p.task.taskId); 6972 if (VALIDATE_TOKENS) { 6973 mWindowManager.validateAppTokens(mHistory); 6974 } 6975 } 6976 replyChainEnd = -1; 6977 6978 // Now we've moved it in to place... but what if this is 6979 // a singleTop activity and we have put it on top of another 6980 // instance of the same activity? Then we drop the instance 6981 // below so it remains singleTop. 6982 if (target.info.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) { 6983 for (int j=lastReparentPos-1; j>=0; j--) { 6984 HistoryRecord p = (HistoryRecord)mHistory.get(j); 6985 if (p.finishing) { 6986 continue; 6987 } 6988 if (p.intent.getComponent().equals(target.intent.getComponent())) { 6989 if (finishActivityLocked(p, j, 6990 Activity.RESULT_CANCELED, null, "replace")) { 6991 taskTopI--; 6992 lastReparentPos--; 6993 } 6994 } 6995 } 6996 } 6997 } 6998 } 6999 7000 target = below; 7001 targetI = i; 7002 } 7003 7004 return taskTop; 7005 } 7006 7007 /** 7008 * TODO: Add mController hook 7009 */ 7010 public void moveTaskToFront(int task) { 7011 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7012 "moveTaskToFront()"); 7013 7014 synchronized(this) { 7015 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7016 Binder.getCallingUid(), "Task to front")) { 7017 return; 7018 } 7019 final long origId = Binder.clearCallingIdentity(); 7020 try { 7021 int N = mRecentTasks.size(); 7022 for (int i=0; i<N; i++) { 7023 TaskRecord tr = mRecentTasks.get(i); 7024 if (tr.taskId == task) { 7025 moveTaskToFrontLocked(tr, null); 7026 return; 7027 } 7028 } 7029 for (int i=mHistory.size()-1; i>=0; i--) { 7030 HistoryRecord hr = (HistoryRecord)mHistory.get(i); 7031 if (hr.task.taskId == task) { 7032 moveTaskToFrontLocked(hr.task, null); 7033 return; 7034 } 7035 } 7036 } finally { 7037 Binder.restoreCallingIdentity(origId); 7038 } 7039 } 7040 } 7041 7042 private final void moveTaskToFrontLocked(TaskRecord tr, HistoryRecord reason) { 7043 if (DEBUG_SWITCH) Log.v(TAG, "moveTaskToFront: " + tr); 7044 7045 final int task = tr.taskId; 7046 int top = mHistory.size()-1; 7047 7048 if (top < 0 || ((HistoryRecord)mHistory.get(top)).task.taskId == task) { 7049 // nothing to do! 7050 return; 7051 } 7052 7053 ArrayList moved = new ArrayList(); 7054 7055 // Applying the affinities may have removed entries from the history, 7056 // so get the size again. 7057 top = mHistory.size()-1; 7058 int pos = top; 7059 7060 // Shift all activities with this task up to the top 7061 // of the stack, keeping them in the same internal order. 7062 while (pos >= 0) { 7063 HistoryRecord r = (HistoryRecord)mHistory.get(pos); 7064 if (localLOGV) Log.v( 7065 TAG, "At " + pos + " ckp " + r.task + ": " + r); 7066 boolean first = true; 7067 if (r.task.taskId == task) { 7068 if (localLOGV) Log.v(TAG, "Removing and adding at " + top); 7069 mHistory.remove(pos); 7070 mHistory.add(top, r); 7071 moved.add(0, r); 7072 top--; 7073 if (first) { 7074 addRecentTask(r.task); 7075 first = false; 7076 } 7077 } 7078 pos--; 7079 } 7080 7081 if (DEBUG_TRANSITION) Log.v(TAG, 7082 "Prepare to front transition: task=" + tr); 7083 if (reason != null && 7084 (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { 7085 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 7086 HistoryRecord r = topRunningActivityLocked(null); 7087 if (r != null) { 7088 mNoAnimActivities.add(r); 7089 } 7090 } else { 7091 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT); 7092 } 7093 7094 mWindowManager.moveAppTokensToTop(moved); 7095 if (VALIDATE_TOKENS) { 7096 mWindowManager.validateAppTokens(mHistory); 7097 } 7098 7099 finishTaskMove(task); 7100 EventLog.writeEvent(LOG_TASK_TO_FRONT, task); 7101 } 7102 7103 private final void finishTaskMove(int task) { 7104 resumeTopActivityLocked(null); 7105 } 7106 7107 public void moveTaskToBack(int task) { 7108 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7109 "moveTaskToBack()"); 7110 7111 synchronized(this) { 7112 if (mResumedActivity != null && mResumedActivity.task.taskId == task) { 7113 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7114 Binder.getCallingUid(), "Task to back")) { 7115 return; 7116 } 7117 } 7118 final long origId = Binder.clearCallingIdentity(); 7119 moveTaskToBackLocked(task, null); 7120 Binder.restoreCallingIdentity(origId); 7121 } 7122 } 7123 7124 /** 7125 * Moves an activity, and all of the other activities within the same task, to the bottom 7126 * of the history stack. The activity's order within the task is unchanged. 7127 * 7128 * @param token A reference to the activity we wish to move 7129 * @param nonRoot If false then this only works if the activity is the root 7130 * of a task; if true it will work for any activity in a task. 7131 * @return Returns true if the move completed, false if not. 7132 */ 7133 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7134 synchronized(this) { 7135 final long origId = Binder.clearCallingIdentity(); 7136 int taskId = getTaskForActivityLocked(token, !nonRoot); 7137 if (taskId >= 0) { 7138 return moveTaskToBackLocked(taskId, null); 7139 } 7140 Binder.restoreCallingIdentity(origId); 7141 } 7142 return false; 7143 } 7144 7145 /** 7146 * Worker method for rearranging history stack. Implements the function of moving all 7147 * activities for a specific task (gathering them if disjoint) into a single group at the 7148 * bottom of the stack. 7149 * 7150 * If a watcher is installed, the action is preflighted and the watcher has an opportunity 7151 * to premeptively cancel the move. 7152 * 7153 * @param task The taskId to collect and move to the bottom. 7154 * @return Returns true if the move completed, false if not. 7155 */ 7156 private final boolean moveTaskToBackLocked(int task, HistoryRecord reason) { 7157 Log.i(TAG, "moveTaskToBack: " + task); 7158 7159 // If we have a watcher, preflight the move before committing to it. First check 7160 // for *other* available tasks, but if none are available, then try again allowing the 7161 // current task to be selected. 7162 if (mController != null) { 7163 HistoryRecord next = topRunningActivityLocked(null, task); 7164 if (next == null) { 7165 next = topRunningActivityLocked(null, 0); 7166 } 7167 if (next != null) { 7168 // ask watcher if this is allowed 7169 boolean moveOK = true; 7170 try { 7171 moveOK = mController.activityResuming(next.packageName); 7172 } catch (RemoteException e) { 7173 mController = null; 7174 } 7175 if (!moveOK) { 7176 return false; 7177 } 7178 } 7179 } 7180 7181 ArrayList moved = new ArrayList(); 7182 7183 if (DEBUG_TRANSITION) Log.v(TAG, 7184 "Prepare to back transition: task=" + task); 7185 7186 final int N = mHistory.size(); 7187 int bottom = 0; 7188 int pos = 0; 7189 7190 // Shift all activities with this task down to the bottom 7191 // of the stack, keeping them in the same internal order. 7192 while (pos < N) { 7193 HistoryRecord r = (HistoryRecord)mHistory.get(pos); 7194 if (localLOGV) Log.v( 7195 TAG, "At " + pos + " ckp " + r.task + ": " + r); 7196 if (r.task.taskId == task) { 7197 if (localLOGV) Log.v(TAG, "Removing and adding at " + (N-1)); 7198 mHistory.remove(pos); 7199 mHistory.add(bottom, r); 7200 moved.add(r); 7201 bottom++; 7202 } 7203 pos++; 7204 } 7205 7206 if (reason != null && 7207 (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { 7208 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 7209 HistoryRecord r = topRunningActivityLocked(null); 7210 if (r != null) { 7211 mNoAnimActivities.add(r); 7212 } 7213 } else { 7214 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_BACK); 7215 } 7216 mWindowManager.moveAppTokensToBottom(moved); 7217 if (VALIDATE_TOKENS) { 7218 mWindowManager.validateAppTokens(mHistory); 7219 } 7220 7221 finishTaskMove(task); 7222 return true; 7223 } 7224 7225 public void moveTaskBackwards(int task) { 7226 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7227 "moveTaskBackwards()"); 7228 7229 synchronized(this) { 7230 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7231 Binder.getCallingUid(), "Task backwards")) { 7232 return; 7233 } 7234 final long origId = Binder.clearCallingIdentity(); 7235 moveTaskBackwardsLocked(task); 7236 Binder.restoreCallingIdentity(origId); 7237 } 7238 } 7239 7240 private final void moveTaskBackwardsLocked(int task) { 7241 Log.e(TAG, "moveTaskBackwards not yet implemented!"); 7242 } 7243 7244 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7245 synchronized(this) { 7246 return getTaskForActivityLocked(token, onlyRoot); 7247 } 7248 } 7249 7250 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 7251 final int N = mHistory.size(); 7252 TaskRecord lastTask = null; 7253 for (int i=0; i<N; i++) { 7254 HistoryRecord r = (HistoryRecord)mHistory.get(i); 7255 if (r == token) { 7256 if (!onlyRoot || lastTask != r.task) { 7257 return r.task.taskId; 7258 } 7259 return -1; 7260 } 7261 lastTask = r.task; 7262 } 7263 7264 return -1; 7265 } 7266 7267 /** 7268 * Returns the top activity in any existing task matching the given 7269 * Intent. Returns null if no such task is found. 7270 */ 7271 private HistoryRecord findTaskLocked(Intent intent, ActivityInfo info) { 7272 ComponentName cls = intent.getComponent(); 7273 if (info.targetActivity != null) { 7274 cls = new ComponentName(info.packageName, info.targetActivity); 7275 } 7276 7277 TaskRecord cp = null; 7278 7279 final int N = mHistory.size(); 7280 for (int i=(N-1); i>=0; i--) { 7281 HistoryRecord r = (HistoryRecord)mHistory.get(i); 7282 if (!r.finishing && r.task != cp 7283 && r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 7284 cp = r.task; 7285 //Log.i(TAG, "Comparing existing cls=" + r.task.intent.getComponent().flattenToShortString() 7286 // + "/aff=" + r.task.affinity + " to new cls=" 7287 // + intent.getComponent().flattenToShortString() + "/aff=" + taskAffinity); 7288 if (r.task.affinity != null) { 7289 if (r.task.affinity.equals(info.taskAffinity)) { 7290 //Log.i(TAG, "Found matching affinity!"); 7291 return r; 7292 } 7293 } else if (r.task.intent != null 7294 && r.task.intent.getComponent().equals(cls)) { 7295 //Log.i(TAG, "Found matching class!"); 7296 //dump(); 7297 //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent); 7298 return r; 7299 } else if (r.task.affinityIntent != null 7300 && r.task.affinityIntent.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 /** 7313 * Returns the first activity (starting from the top of the stack) that 7314 * is the same as the given activity. Returns null if no such activity 7315 * is found. 7316 */ 7317 private HistoryRecord findActivityLocked(Intent intent, ActivityInfo info) { 7318 ComponentName cls = intent.getComponent(); 7319 if (info.targetActivity != null) { 7320 cls = new ComponentName(info.packageName, info.targetActivity); 7321 } 7322 7323 final int N = mHistory.size(); 7324 for (int i=(N-1); i>=0; i--) { 7325 HistoryRecord r = (HistoryRecord)mHistory.get(i); 7326 if (!r.finishing) { 7327 if (r.intent.getComponent().equals(cls)) { 7328 //Log.i(TAG, "Found matching class!"); 7329 //dump(); 7330 //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent); 7331 return r; 7332 } 7333 } 7334 } 7335 7336 return null; 7337 } 7338 7339 public void finishOtherInstances(IBinder token, ComponentName className) { 7340 synchronized(this) { 7341 final long origId = Binder.clearCallingIdentity(); 7342 7343 int N = mHistory.size(); 7344 TaskRecord lastTask = null; 7345 for (int i=0; i<N; i++) { 7346 HistoryRecord r = (HistoryRecord)mHistory.get(i); 7347 if (r.realActivity.equals(className) 7348 && r != token && lastTask != r.task) { 7349 if (finishActivityLocked(r, i, Activity.RESULT_CANCELED, 7350 null, "others")) { 7351 i--; 7352 N--; 7353 } 7354 } 7355 lastTask = r.task; 7356 } 7357 7358 Binder.restoreCallingIdentity(origId); 7359 } 7360 } 7361 7362 // ========================================================= 7363 // THUMBNAILS 7364 // ========================================================= 7365 7366 public void reportThumbnail(IBinder token, 7367 Bitmap thumbnail, CharSequence description) { 7368 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7369 final long origId = Binder.clearCallingIdentity(); 7370 sendPendingThumbnail(null, token, thumbnail, description, true); 7371 Binder.restoreCallingIdentity(origId); 7372 } 7373 7374 final void sendPendingThumbnail(HistoryRecord r, IBinder token, 7375 Bitmap thumbnail, CharSequence description, boolean always) { 7376 TaskRecord task = null; 7377 ArrayList receivers = null; 7378 7379 //System.out.println("Send pending thumbnail: " + r); 7380 7381 synchronized(this) { 7382 if (r == null) { 7383 int index = indexOfTokenLocked(token); 7384 if (index < 0) { 7385 return; 7386 } 7387 r = (HistoryRecord)mHistory.get(index); 7388 } 7389 if (thumbnail == null) { 7390 thumbnail = r.thumbnail; 7391 description = r.description; 7392 } 7393 if (thumbnail == null && !always) { 7394 // If there is no thumbnail, and this entry is not actually 7395 // going away, then abort for now and pick up the next 7396 // thumbnail we get. 7397 return; 7398 } 7399 task = r.task; 7400 7401 int N = mPendingThumbnails.size(); 7402 int i=0; 7403 while (i<N) { 7404 PendingThumbnailsRecord pr = 7405 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 7406 //System.out.println("Looking in " + pr.pendingRecords); 7407 if (pr.pendingRecords.remove(r)) { 7408 if (receivers == null) { 7409 receivers = new ArrayList(); 7410 } 7411 receivers.add(pr); 7412 if (pr.pendingRecords.size() == 0) { 7413 pr.finished = true; 7414 mPendingThumbnails.remove(i); 7415 N--; 7416 continue; 7417 } 7418 } 7419 i++; 7420 } 7421 } 7422 7423 if (receivers != null) { 7424 final int N = receivers.size(); 7425 for (int i=0; i<N; i++) { 7426 try { 7427 PendingThumbnailsRecord pr = 7428 (PendingThumbnailsRecord)receivers.get(i); 7429 pr.receiver.newThumbnail( 7430 task != null ? task.taskId : -1, thumbnail, description); 7431 if (pr.finished) { 7432 pr.receiver.finished(); 7433 } 7434 } catch (Exception e) { 7435 Log.w(TAG, "Exception thrown when sending thumbnail", e); 7436 } 7437 } 7438 } 7439 } 7440 7441 // ========================================================= 7442 // CONTENT PROVIDERS 7443 // ========================================================= 7444 7445 private final List generateApplicationProvidersLocked(ProcessRecord app) { 7446 List providers = null; 7447 try { 7448 providers = ActivityThread.getPackageManager(). 7449 queryContentProviders(app.processName, app.info.uid, 7450 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7451 } catch (RemoteException ex) { 7452 } 7453 if (providers != null) { 7454 final int N = providers.size(); 7455 for (int i=0; i<N; i++) { 7456 ProviderInfo cpi = 7457 (ProviderInfo)providers.get(i); 7458 ContentProviderRecord cpr = 7459 (ContentProviderRecord)mProvidersByClass.get(cpi.name); 7460 if (cpr == null) { 7461 cpr = new ContentProviderRecord(cpi, app.info); 7462 mProvidersByClass.put(cpi.name, cpr); 7463 } 7464 app.pubProviders.put(cpi.name, cpr); 7465 app.addPackage(cpi.applicationInfo.packageName); 7466 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7467 } 7468 } 7469 return providers; 7470 } 7471 7472 private final String checkContentProviderPermissionLocked( 7473 ProviderInfo cpi, ProcessRecord r, int mode) { 7474 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7475 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid(); 7476 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7477 cpi.exported ? -1 : cpi.applicationInfo.uid) 7478 == PackageManager.PERMISSION_GRANTED 7479 && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) { 7480 return null; 7481 } 7482 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7483 cpi.exported ? -1 : cpi.applicationInfo.uid) 7484 == PackageManager.PERMISSION_GRANTED) { 7485 return null; 7486 } 7487 7488 PathPermission[] pps = cpi.pathPermissions; 7489 if (pps != null) { 7490 int i = pps.length; 7491 while (i > 0) { 7492 i--; 7493 PathPermission pp = pps[i]; 7494 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7495 cpi.exported ? -1 : cpi.applicationInfo.uid) 7496 == PackageManager.PERMISSION_GRANTED 7497 && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) { 7498 return null; 7499 } 7500 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7501 cpi.exported ? -1 : cpi.applicationInfo.uid) 7502 == PackageManager.PERMISSION_GRANTED) { 7503 return null; 7504 } 7505 } 7506 } 7507 7508 String msg = "Permission Denial: opening provider " + cpi.name 7509 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7510 + ", uid=" + callingUid + ") requires " 7511 + cpi.readPermission + " or " + cpi.writePermission; 7512 Log.w(TAG, msg); 7513 return msg; 7514 } 7515 7516 private final ContentProviderHolder getContentProviderImpl( 7517 IApplicationThread caller, String name) { 7518 ContentProviderRecord cpr; 7519 ProviderInfo cpi = null; 7520 7521 synchronized(this) { 7522 ProcessRecord r = null; 7523 if (caller != null) { 7524 r = getRecordForAppLocked(caller); 7525 if (r == null) { 7526 throw new SecurityException( 7527 "Unable to find app for caller " + caller 7528 + " (pid=" + Binder.getCallingPid() 7529 + ") when getting content provider " + name); 7530 } 7531 } 7532 7533 // First check if this content provider has been published... 7534 cpr = (ContentProviderRecord)mProvidersByName.get(name); 7535 if (cpr != null) { 7536 cpi = cpr.info; 7537 if (checkContentProviderPermissionLocked(cpi, r, -1) != null) { 7538 return new ContentProviderHolder(cpi, 7539 cpi.readPermission != null 7540 ? cpi.readPermission : cpi.writePermission); 7541 } 7542 7543 if (r != null && cpr.canRunHere(r)) { 7544 // This provider has been published or is in the process 7545 // of being published... but it is also allowed to run 7546 // in the caller's process, so don't make a connection 7547 // and just let the caller instantiate its own instance. 7548 if (cpr.provider != null) { 7549 // don't give caller the provider object, it needs 7550 // to make its own. 7551 cpr = new ContentProviderRecord(cpr); 7552 } 7553 return cpr; 7554 } 7555 7556 final long origId = Binder.clearCallingIdentity(); 7557 7558 // In this case the provider instance already exists, so we can 7559 // return it right away. 7560 if (r != null) { 7561 if (DEBUG_PROVIDER) Log.v(TAG, 7562 "Adding provider requested by " 7563 + r.processName + " from process " 7564 + cpr.info.processName); 7565 Integer cnt = r.conProviders.get(cpr); 7566 if (cnt == null) { 7567 r.conProviders.put(cpr, new Integer(1)); 7568 } else { 7569 r.conProviders.put(cpr, new Integer(cnt.intValue()+1)); 7570 } 7571 cpr.clients.add(r); 7572 } else { 7573 cpr.externals++; 7574 } 7575 7576 if (cpr.app != null) { 7577 updateOomAdjLocked(cpr.app); 7578 } 7579 7580 Binder.restoreCallingIdentity(origId); 7581 7582 } else { 7583 try { 7584 cpi = ActivityThread.getPackageManager(). 7585 resolveContentProvider(name, 7586 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7587 } catch (RemoteException ex) { 7588 } 7589 if (cpi == null) { 7590 return null; 7591 } 7592 7593 if (checkContentProviderPermissionLocked(cpi, r, -1) != null) { 7594 return new ContentProviderHolder(cpi, 7595 cpi.readPermission != null 7596 ? cpi.readPermission : cpi.writePermission); 7597 } 7598 7599 cpr = (ContentProviderRecord)mProvidersByClass.get(cpi.name); 7600 final boolean firstClass = cpr == null; 7601 if (firstClass) { 7602 try { 7603 ApplicationInfo ai = 7604 ActivityThread.getPackageManager(). 7605 getApplicationInfo( 7606 cpi.applicationInfo.packageName, 7607 STOCK_PM_FLAGS); 7608 if (ai == null) { 7609 Log.w(TAG, "No package info for content provider " 7610 + cpi.name); 7611 return null; 7612 } 7613 cpr = new ContentProviderRecord(cpi, ai); 7614 } catch (RemoteException ex) { 7615 // pm is in same process, this will never happen. 7616 } 7617 } 7618 7619 if (r != null && cpr.canRunHere(r)) { 7620 // If this is a multiprocess provider, then just return its 7621 // info and allow the caller to instantiate it. Only do 7622 // this if the provider is the same user as the caller's 7623 // process, or can run as root (so can be in any process). 7624 return cpr; 7625 } 7626 7627 if (DEBUG_PROVIDER) { 7628 RuntimeException e = new RuntimeException("here"); 7629 Log.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid 7630 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7631 } 7632 7633 // This is single process, and our app is now connecting to it. 7634 // See if we are already in the process of launching this 7635 // provider. 7636 final int N = mLaunchingProviders.size(); 7637 int i; 7638 for (i=0; i<N; i++) { 7639 if (mLaunchingProviders.get(i) == cpr) { 7640 break; 7641 } 7642 } 7643 7644 // If the provider is not already being launched, then get it 7645 // started. 7646 if (i >= N) { 7647 final long origId = Binder.clearCallingIdentity(); 7648 ProcessRecord proc = startProcessLocked(cpi.processName, 7649 cpr.appInfo, false, 0, "content provider", 7650 new ComponentName(cpi.applicationInfo.packageName, 7651 cpi.name), false); 7652 if (proc == null) { 7653 Log.w(TAG, "Unable to launch app " 7654 + cpi.applicationInfo.packageName + "/" 7655 + cpi.applicationInfo.uid + " for provider " 7656 + name + ": process is bad"); 7657 return null; 7658 } 7659 cpr.launchingApp = proc; 7660 mLaunchingProviders.add(cpr); 7661 Binder.restoreCallingIdentity(origId); 7662 } 7663 7664 // Make sure the provider is published (the same provider class 7665 // may be published under multiple names). 7666 if (firstClass) { 7667 mProvidersByClass.put(cpi.name, cpr); 7668 } 7669 mProvidersByName.put(name, cpr); 7670 7671 if (r != null) { 7672 if (DEBUG_PROVIDER) Log.v(TAG, 7673 "Adding provider requested by " 7674 + r.processName + " from process " 7675 + cpr.info.processName); 7676 Integer cnt = r.conProviders.get(cpr); 7677 if (cnt == null) { 7678 r.conProviders.put(cpr, new Integer(1)); 7679 } else { 7680 r.conProviders.put(cpr, new Integer(cnt.intValue()+1)); 7681 } 7682 cpr.clients.add(r); 7683 } else { 7684 cpr.externals++; 7685 } 7686 } 7687 } 7688 7689 // Wait for the provider to be published... 7690 synchronized (cpr) { 7691 while (cpr.provider == null) { 7692 if (cpr.launchingApp == null) { 7693 Log.w(TAG, "Unable to launch app " 7694 + cpi.applicationInfo.packageName + "/" 7695 + cpi.applicationInfo.uid + " for provider " 7696 + name + ": launching app became null"); 7697 EventLog.writeEvent(LOG_AM_PROVIDER_LOST_PROCESS, 7698 cpi.applicationInfo.packageName, 7699 cpi.applicationInfo.uid, name); 7700 return null; 7701 } 7702 try { 7703 cpr.wait(); 7704 } catch (InterruptedException ex) { 7705 } 7706 } 7707 } 7708 return cpr; 7709 } 7710 7711 public final ContentProviderHolder getContentProvider( 7712 IApplicationThread caller, String name) { 7713 if (caller == null) { 7714 String msg = "null IApplicationThread when getting content provider " 7715 + name; 7716 Log.w(TAG, msg); 7717 throw new SecurityException(msg); 7718 } 7719 7720 return getContentProviderImpl(caller, name); 7721 } 7722 7723 private ContentProviderHolder getContentProviderExternal(String name) { 7724 return getContentProviderImpl(null, name); 7725 } 7726 7727 /** 7728 * Drop a content provider from a ProcessRecord's bookkeeping 7729 * @param cpr 7730 */ 7731 public void removeContentProvider(IApplicationThread caller, String name) { 7732 synchronized (this) { 7733 ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name); 7734 if(cpr == null) { 7735 // remove from mProvidersByClass 7736 if (DEBUG_PROVIDER) Log.v(TAG, name + 7737 " provider not found in providers list"); 7738 return; 7739 } 7740 final ProcessRecord r = getRecordForAppLocked(caller); 7741 if (r == null) { 7742 throw new SecurityException( 7743 "Unable to find app for caller " + caller + 7744 " when removing content provider " + name); 7745 } 7746 //update content provider record entry info 7747 ContentProviderRecord localCpr = (ContentProviderRecord) 7748 mProvidersByClass.get(cpr.info.name); 7749 if (DEBUG_PROVIDER) Log.v(TAG, "Removing provider requested by " 7750 + r.info.processName + " from process " 7751 + localCpr.appInfo.processName); 7752 if (localCpr.app == r) { 7753 //should not happen. taken care of as a local provider 7754 Log.w(TAG, "removeContentProvider called on local provider: " 7755 + cpr.info.name + " in process " + r.processName); 7756 return; 7757 } else { 7758 Integer cnt = r.conProviders.get(localCpr); 7759 if (cnt == null || cnt.intValue() <= 1) { 7760 localCpr.clients.remove(r); 7761 r.conProviders.remove(localCpr); 7762 } else { 7763 r.conProviders.put(localCpr, new Integer(cnt.intValue()-1)); 7764 } 7765 } 7766 updateOomAdjLocked(); 7767 } 7768 } 7769 7770 private void removeContentProviderExternal(String name) { 7771 synchronized (this) { 7772 ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name); 7773 if(cpr == null) { 7774 //remove from mProvidersByClass 7775 if(localLOGV) Log.v(TAG, name+" content provider not found in providers list"); 7776 return; 7777 } 7778 7779 //update content provider record entry info 7780 ContentProviderRecord localCpr = (ContentProviderRecord) mProvidersByClass.get(cpr.info.name); 7781 localCpr.externals--; 7782 if (localCpr.externals < 0) { 7783 Log.e(TAG, "Externals < 0 for content provider " + localCpr); 7784 } 7785 updateOomAdjLocked(); 7786 } 7787 } 7788 7789 public final void publishContentProviders(IApplicationThread caller, 7790 List<ContentProviderHolder> providers) { 7791 if (providers == null) { 7792 return; 7793 } 7794 7795 synchronized(this) { 7796 final ProcessRecord r = getRecordForAppLocked(caller); 7797 if (r == null) { 7798 throw new SecurityException( 7799 "Unable to find app for caller " + caller 7800 + " (pid=" + Binder.getCallingPid() 7801 + ") when publishing content providers"); 7802 } 7803 7804 final long origId = Binder.clearCallingIdentity(); 7805 7806 final int N = providers.size(); 7807 for (int i=0; i<N; i++) { 7808 ContentProviderHolder src = providers.get(i); 7809 if (src == null || src.info == null || src.provider == null) { 7810 continue; 7811 } 7812 ContentProviderRecord dst = 7813 (ContentProviderRecord)r.pubProviders.get(src.info.name); 7814 if (dst != null) { 7815 mProvidersByClass.put(dst.info.name, dst); 7816 String names[] = dst.info.authority.split(";"); 7817 for (int j = 0; j < names.length; j++) { 7818 mProvidersByName.put(names[j], dst); 7819 } 7820 7821 int NL = mLaunchingProviders.size(); 7822 int j; 7823 for (j=0; j<NL; j++) { 7824 if (mLaunchingProviders.get(j) == dst) { 7825 mLaunchingProviders.remove(j); 7826 j--; 7827 NL--; 7828 } 7829 } 7830 synchronized (dst) { 7831 dst.provider = src.provider; 7832 dst.app = r; 7833 dst.notifyAll(); 7834 } 7835 updateOomAdjLocked(r); 7836 } 7837 } 7838 7839 Binder.restoreCallingIdentity(origId); 7840 } 7841 } 7842 7843 public static final void installSystemProviders() { 7844 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 7845 List providers = mSelf.generateApplicationProvidersLocked(app); 7846 mSystemThread.installSystemProviders(providers); 7847 } 7848 7849 // ========================================================= 7850 // GLOBAL MANAGEMENT 7851 // ========================================================= 7852 7853 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 7854 ApplicationInfo info, String customProcess) { 7855 String proc = customProcess != null ? customProcess : info.processName; 7856 BatteryStatsImpl.Uid.Proc ps = null; 7857 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7858 synchronized (stats) { 7859 ps = stats.getProcessStatsLocked(info.uid, proc); 7860 } 7861 return new ProcessRecord(ps, thread, info, proc); 7862 } 7863 7864 final ProcessRecord addAppLocked(ApplicationInfo info) { 7865 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid); 7866 7867 if (app == null) { 7868 app = newProcessRecordLocked(null, info, null); 7869 mProcessNames.put(info.processName, info.uid, app); 7870 updateLRUListLocked(app, true); 7871 } 7872 7873 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 7874 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 7875 app.persistent = true; 7876 app.maxAdj = CORE_SERVER_ADJ; 7877 } 7878 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 7879 mPersistentStartingProcesses.add(app); 7880 startProcessLocked(app, "added application", app.processName); 7881 } 7882 7883 return app; 7884 } 7885 7886 public void unhandledBack() { 7887 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 7888 "unhandledBack()"); 7889 7890 synchronized(this) { 7891 int count = mHistory.size(); 7892 if (Config.LOGD) Log.d( 7893 TAG, "Performing unhandledBack(): stack size = " + count); 7894 if (count > 1) { 7895 final long origId = Binder.clearCallingIdentity(); 7896 finishActivityLocked((HistoryRecord)mHistory.get(count-1), 7897 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 7898 Binder.restoreCallingIdentity(origId); 7899 } 7900 } 7901 } 7902 7903 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 7904 String name = uri.getAuthority(); 7905 ContentProviderHolder cph = getContentProviderExternal(name); 7906 ParcelFileDescriptor pfd = null; 7907 if (cph != null) { 7908 // We record the binder invoker's uid in thread-local storage before 7909 // going to the content provider to open the file. Later, in the code 7910 // that handles all permissions checks, we look for this uid and use 7911 // that rather than the Activity Manager's own uid. The effect is that 7912 // we do the check against the caller's permissions even though it looks 7913 // to the content provider like the Activity Manager itself is making 7914 // the request. 7915 sCallerIdentity.set(new Identity( 7916 Binder.getCallingPid(), Binder.getCallingUid())); 7917 try { 7918 pfd = cph.provider.openFile(uri, "r"); 7919 } catch (FileNotFoundException e) { 7920 // do nothing; pfd will be returned null 7921 } finally { 7922 // Ensure that whatever happens, we clean up the identity state 7923 sCallerIdentity.remove(); 7924 } 7925 7926 // We've got the fd now, so we're done with the provider. 7927 removeContentProviderExternal(name); 7928 } else { 7929 Log.d(TAG, "Failed to get provider for authority '" + name + "'"); 7930 } 7931 return pfd; 7932 } 7933 7934 public void goingToSleep() { 7935 synchronized(this) { 7936 mSleeping = true; 7937 mWindowManager.setEventDispatching(false); 7938 7939 if (mResumedActivity != null) { 7940 pauseIfSleepingLocked(); 7941 } else { 7942 Log.w(TAG, "goingToSleep with no resumed activity!"); 7943 } 7944 } 7945 } 7946 7947 public boolean shutdown(int timeout) { 7948 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 7949 != PackageManager.PERMISSION_GRANTED) { 7950 throw new SecurityException("Requires permission " 7951 + android.Manifest.permission.SHUTDOWN); 7952 } 7953 7954 boolean timedout = false; 7955 7956 synchronized(this) { 7957 mShuttingDown = true; 7958 mWindowManager.setEventDispatching(false); 7959 7960 if (mResumedActivity != null) { 7961 pauseIfSleepingLocked(); 7962 final long endTime = System.currentTimeMillis() + timeout; 7963 while (mResumedActivity != null || mPausingActivity != null) { 7964 long delay = endTime - System.currentTimeMillis(); 7965 if (delay <= 0) { 7966 Log.w(TAG, "Activity manager shutdown timed out"); 7967 timedout = true; 7968 break; 7969 } 7970 try { 7971 this.wait(); 7972 } catch (InterruptedException e) { 7973 } 7974 } 7975 } 7976 } 7977 7978 mUsageStatsService.shutdown(); 7979 mBatteryStatsService.shutdown(); 7980 7981 return timedout; 7982 } 7983 7984 void pauseIfSleepingLocked() { 7985 if (mSleeping || mShuttingDown) { 7986 if (!mGoingToSleep.isHeld()) { 7987 mGoingToSleep.acquire(); 7988 if (mLaunchingActivity.isHeld()) { 7989 mLaunchingActivity.release(); 7990 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 7991 } 7992 } 7993 7994 // If we are not currently pausing an activity, get the current 7995 // one to pause. If we are pausing one, we will just let that stuff 7996 // run and release the wake lock when all done. 7997 if (mPausingActivity == null) { 7998 if (DEBUG_PAUSE) Log.v(TAG, "Sleep needs to pause..."); 7999 if (DEBUG_USER_LEAVING) Log.v(TAG, "Sleep => pause with userLeaving=false"); 8000 startPausingLocked(false, true); 8001 } 8002 } 8003 } 8004 8005 public void wakingUp() { 8006 synchronized(this) { 8007 if (mGoingToSleep.isHeld()) { 8008 mGoingToSleep.release(); 8009 } 8010 mWindowManager.setEventDispatching(true); 8011 mSleeping = false; 8012 resumeTopActivityLocked(null); 8013 } 8014 } 8015 8016 public void stopAppSwitches() { 8017 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8018 != PackageManager.PERMISSION_GRANTED) { 8019 throw new SecurityException("Requires permission " 8020 + android.Manifest.permission.STOP_APP_SWITCHES); 8021 } 8022 8023 synchronized(this) { 8024 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8025 + APP_SWITCH_DELAY_TIME; 8026 mDidAppSwitch = false; 8027 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8028 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8029 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8030 } 8031 } 8032 8033 public void resumeAppSwitches() { 8034 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8035 != PackageManager.PERMISSION_GRANTED) { 8036 throw new SecurityException("Requires permission " 8037 + android.Manifest.permission.STOP_APP_SWITCHES); 8038 } 8039 8040 synchronized(this) { 8041 // Note that we don't execute any pending app switches... we will 8042 // let those wait until either the timeout, or the next start 8043 // activity request. 8044 mAppSwitchesAllowedTime = 0; 8045 } 8046 } 8047 8048 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8049 String name) { 8050 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8051 return true; 8052 } 8053 8054 final int perm = checkComponentPermission( 8055 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8056 callingUid, -1); 8057 if (perm == PackageManager.PERMISSION_GRANTED) { 8058 return true; 8059 } 8060 8061 Log.w(TAG, name + " request from " + callingUid + " stopped"); 8062 return false; 8063 } 8064 8065 public void setDebugApp(String packageName, boolean waitForDebugger, 8066 boolean persistent) { 8067 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8068 "setDebugApp()"); 8069 8070 // Note that this is not really thread safe if there are multiple 8071 // callers into it at the same time, but that's not a situation we 8072 // care about. 8073 if (persistent) { 8074 final ContentResolver resolver = mContext.getContentResolver(); 8075 Settings.System.putString( 8076 resolver, Settings.System.DEBUG_APP, 8077 packageName); 8078 Settings.System.putInt( 8079 resolver, Settings.System.WAIT_FOR_DEBUGGER, 8080 waitForDebugger ? 1 : 0); 8081 } 8082 8083 synchronized (this) { 8084 if (!persistent) { 8085 mOrigDebugApp = mDebugApp; 8086 mOrigWaitForDebugger = mWaitForDebugger; 8087 } 8088 mDebugApp = packageName; 8089 mWaitForDebugger = waitForDebugger; 8090 mDebugTransient = !persistent; 8091 if (packageName != null) { 8092 final long origId = Binder.clearCallingIdentity(); 8093 uninstallPackageLocked(packageName, -1, false); 8094 Binder.restoreCallingIdentity(origId); 8095 } 8096 } 8097 } 8098 8099 public void setAlwaysFinish(boolean enabled) { 8100 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8101 "setAlwaysFinish()"); 8102 8103 Settings.System.putInt( 8104 mContext.getContentResolver(), 8105 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8106 8107 synchronized (this) { 8108 mAlwaysFinishActivities = enabled; 8109 } 8110 } 8111 8112 public void setActivityController(IActivityController controller) { 8113 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8114 "setActivityController()"); 8115 synchronized (this) { 8116 mController = controller; 8117 } 8118 } 8119 8120 public void registerActivityWatcher(IActivityWatcher watcher) { 8121 mWatchers.register(watcher); 8122 } 8123 8124 public void unregisterActivityWatcher(IActivityWatcher watcher) { 8125 mWatchers.unregister(watcher); 8126 } 8127 8128 public final void enterSafeMode() { 8129 synchronized(this) { 8130 // It only makes sense to do this before the system is ready 8131 // and started launching other packages. 8132 if (!mSystemReady) { 8133 try { 8134 ActivityThread.getPackageManager().enterSafeMode(); 8135 } catch (RemoteException e) { 8136 } 8137 8138 View v = LayoutInflater.from(mContext).inflate( 8139 com.android.internal.R.layout.safe_mode, null); 8140 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8141 lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; 8142 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8143 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8144 lp.gravity = Gravity.BOTTOM | Gravity.LEFT; 8145 lp.format = v.getBackground().getOpacity(); 8146 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8147 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8148 ((WindowManager)mContext.getSystemService( 8149 Context.WINDOW_SERVICE)).addView(v, lp); 8150 } 8151 } 8152 } 8153 8154 public void noteWakeupAlarm(IIntentSender sender) { 8155 if (!(sender instanceof PendingIntentRecord)) { 8156 return; 8157 } 8158 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8159 synchronized (stats) { 8160 if (mBatteryStatsService.isOnBattery()) { 8161 mBatteryStatsService.enforceCallingPermission(); 8162 PendingIntentRecord rec = (PendingIntentRecord)sender; 8163 int MY_UID = Binder.getCallingUid(); 8164 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8165 BatteryStatsImpl.Uid.Pkg pkg = 8166 stats.getPackageStatsLocked(uid, rec.key.packageName); 8167 pkg.incWakeupsLocked(); 8168 } 8169 } 8170 } 8171 8172 public boolean killPidsForMemory(int[] pids) { 8173 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8174 throw new SecurityException("killPidsForMemory only available to the system"); 8175 } 8176 8177 // XXX Note: don't acquire main activity lock here, because the window 8178 // manager calls in with its locks held. 8179 8180 boolean killed = false; 8181 synchronized (mPidsSelfLocked) { 8182 int[] types = new int[pids.length]; 8183 int worstType = 0; 8184 for (int i=0; i<pids.length; i++) { 8185 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8186 if (proc != null) { 8187 int type = proc.setAdj; 8188 types[i] = type; 8189 if (type > worstType) { 8190 worstType = type; 8191 } 8192 } 8193 } 8194 8195 // If the worse oom_adj is somewhere in the hidden proc LRU range, 8196 // then constrain it so we will kill all hidden procs. 8197 if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) { 8198 worstType = HIDDEN_APP_MIN_ADJ; 8199 } 8200 Log.w(TAG, "Killing processes for memory at adjustment " + worstType); 8201 for (int i=0; i<pids.length; i++) { 8202 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8203 if (proc == null) { 8204 continue; 8205 } 8206 int adj = proc.setAdj; 8207 if (adj >= worstType) { 8208 Log.w(TAG, "Killing for memory: " + proc + " (adj " 8209 + adj + ")"); 8210 EventLog.writeEvent(LOG_AM_KILL_FOR_MEMORY, proc.pid, 8211 proc.processName, adj); 8212 killed = true; 8213 Process.killProcess(pids[i]); 8214 } 8215 } 8216 } 8217 return killed; 8218 } 8219 8220 public void reportPss(IApplicationThread caller, int pss) { 8221 Watchdog.PssRequestor req; 8222 String name; 8223 ProcessRecord callerApp; 8224 synchronized (this) { 8225 if (caller == null) { 8226 return; 8227 } 8228 callerApp = getRecordForAppLocked(caller); 8229 if (callerApp == null) { 8230 return; 8231 } 8232 callerApp.lastPss = pss; 8233 req = callerApp; 8234 name = callerApp.processName; 8235 } 8236 Watchdog.getInstance().reportPss(req, name, pss); 8237 if (!callerApp.persistent) { 8238 removeRequestedPss(callerApp); 8239 } 8240 } 8241 8242 public void requestPss(Runnable completeCallback) { 8243 ArrayList<ProcessRecord> procs; 8244 synchronized (this) { 8245 mRequestPssCallback = completeCallback; 8246 mRequestPssList.clear(); 8247 for (int i=mLRUProcesses.size()-1; i>=0; i--) { 8248 ProcessRecord proc = mLRUProcesses.get(i); 8249 if (!proc.persistent) { 8250 mRequestPssList.add(proc); 8251 } 8252 } 8253 procs = new ArrayList<ProcessRecord>(mRequestPssList); 8254 } 8255 8256 int oldPri = Process.getThreadPriority(Process.myTid()); 8257 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 8258 for (int i=procs.size()-1; i>=0; i--) { 8259 ProcessRecord proc = procs.get(i); 8260 proc.lastPss = 0; 8261 proc.requestPss(); 8262 } 8263 Process.setThreadPriority(oldPri); 8264 } 8265 8266 void removeRequestedPss(ProcessRecord proc) { 8267 Runnable callback = null; 8268 synchronized (this) { 8269 if (mRequestPssList.remove(proc)) { 8270 if (mRequestPssList.size() == 0) { 8271 callback = mRequestPssCallback; 8272 mRequestPssCallback = null; 8273 } 8274 } 8275 } 8276 8277 if (callback != null) { 8278 callback.run(); 8279 } 8280 } 8281 8282 public void collectPss(Watchdog.PssStats stats) { 8283 stats.mEmptyPss = 0; 8284 stats.mEmptyCount = 0; 8285 stats.mBackgroundPss = 0; 8286 stats.mBackgroundCount = 0; 8287 stats.mServicePss = 0; 8288 stats.mServiceCount = 0; 8289 stats.mVisiblePss = 0; 8290 stats.mVisibleCount = 0; 8291 stats.mForegroundPss = 0; 8292 stats.mForegroundCount = 0; 8293 stats.mNoPssCount = 0; 8294 synchronized (this) { 8295 int i; 8296 int NPD = mProcDeaths.length < stats.mProcDeaths.length 8297 ? mProcDeaths.length : stats.mProcDeaths.length; 8298 int aggr = 0; 8299 for (i=0; i<NPD; i++) { 8300 aggr += mProcDeaths[i]; 8301 stats.mProcDeaths[i] = aggr; 8302 } 8303 while (i<stats.mProcDeaths.length) { 8304 stats.mProcDeaths[i] = 0; 8305 i++; 8306 } 8307 8308 for (i=mLRUProcesses.size()-1; i>=0; i--) { 8309 ProcessRecord proc = mLRUProcesses.get(i); 8310 if (proc.persistent) { 8311 continue; 8312 } 8313 //Log.i(TAG, "Proc " + proc + ": pss=" + proc.lastPss); 8314 if (proc.lastPss == 0) { 8315 stats.mNoPssCount++; 8316 continue; 8317 } 8318 if (proc.setAdj == EMPTY_APP_ADJ) { 8319 stats.mEmptyPss += proc.lastPss; 8320 stats.mEmptyCount++; 8321 } else if (proc.setAdj == CONTENT_PROVIDER_ADJ) { 8322 stats.mEmptyPss += proc.lastPss; 8323 stats.mEmptyCount++; 8324 } else if (proc.setAdj >= HIDDEN_APP_MIN_ADJ) { 8325 stats.mBackgroundPss += proc.lastPss; 8326 stats.mBackgroundCount++; 8327 } else if (proc.setAdj >= VISIBLE_APP_ADJ) { 8328 stats.mVisiblePss += proc.lastPss; 8329 stats.mVisibleCount++; 8330 } else { 8331 stats.mForegroundPss += proc.lastPss; 8332 stats.mForegroundCount++; 8333 } 8334 } 8335 } 8336 } 8337 8338 public final void startRunning(String pkg, String cls, String action, 8339 String data) { 8340 synchronized(this) { 8341 if (mStartRunning) { 8342 return; 8343 } 8344 mStartRunning = true; 8345 mTopComponent = pkg != null && cls != null 8346 ? new ComponentName(pkg, cls) : null; 8347 mTopAction = action != null ? action : Intent.ACTION_MAIN; 8348 mTopData = data; 8349 if (!mSystemReady) { 8350 return; 8351 } 8352 } 8353 8354 systemReady(null); 8355 } 8356 8357 private void retrieveSettings() { 8358 final ContentResolver resolver = mContext.getContentResolver(); 8359 String debugApp = Settings.System.getString( 8360 resolver, Settings.System.DEBUG_APP); 8361 boolean waitForDebugger = Settings.System.getInt( 8362 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 8363 boolean alwaysFinishActivities = Settings.System.getInt( 8364 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 8365 8366 Configuration configuration = new Configuration(); 8367 Settings.System.getConfiguration(resolver, configuration); 8368 8369 synchronized (this) { 8370 mDebugApp = mOrigDebugApp = debugApp; 8371 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 8372 mAlwaysFinishActivities = alwaysFinishActivities; 8373 // This happens before any activities are started, so we can 8374 // change mConfiguration in-place. 8375 mConfiguration.updateFrom(configuration); 8376 if (DEBUG_CONFIGURATION) Log.v(TAG, "Initial config: " + mConfiguration); 8377 } 8378 } 8379 8380 public boolean testIsSystemReady() { 8381 // no need to synchronize(this) just to read & return the value 8382 return mSystemReady; 8383 } 8384 8385 public void systemReady(final Runnable goingCallback) { 8386 // In the simulator, startRunning will never have been called, which 8387 // normally sets a few crucial variables. Do it here instead. 8388 if (!Process.supportsProcesses()) { 8389 mStartRunning = true; 8390 mTopAction = Intent.ACTION_MAIN; 8391 } 8392 8393 synchronized(this) { 8394 if (mSystemReady) { 8395 if (goingCallback != null) goingCallback.run(); 8396 return; 8397 } 8398 8399 // Check to see if there are any update receivers to run. 8400 if (!mDidUpdate) { 8401 if (mWaitingUpdate) { 8402 return; 8403 } 8404 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 8405 List<ResolveInfo> ris = null; 8406 try { 8407 ris = ActivityThread.getPackageManager().queryIntentReceivers( 8408 intent, null, 0); 8409 } catch (RemoteException e) { 8410 } 8411 if (ris != null) { 8412 for (int i=ris.size()-1; i>=0; i--) { 8413 if ((ris.get(i).activityInfo.applicationInfo.flags 8414 &ApplicationInfo.FLAG_SYSTEM) == 0) { 8415 ris.remove(i); 8416 } 8417 } 8418 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 8419 for (int i=0; i<ris.size(); i++) { 8420 ActivityInfo ai = ris.get(i).activityInfo; 8421 intent.setComponent(new ComponentName(ai.packageName, ai.name)); 8422 IIntentReceiver finisher = null; 8423 if (i == 0) { 8424 finisher = new IIntentReceiver.Stub() { 8425 public void performReceive(Intent intent, int resultCode, 8426 String data, Bundle extras, boolean ordered, 8427 boolean sticky) 8428 throws RemoteException { 8429 synchronized (ActivityManagerService.this) { 8430 mDidUpdate = true; 8431 } 8432 systemReady(goingCallback); 8433 } 8434 }; 8435 } 8436 Log.i(TAG, "Sending system update to: " + intent.getComponent()); 8437 broadcastIntentLocked(null, null, intent, null, finisher, 8438 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID); 8439 if (i == 0) { 8440 mWaitingUpdate = true; 8441 } 8442 } 8443 } 8444 if (mWaitingUpdate) { 8445 return; 8446 } 8447 mDidUpdate = true; 8448 } 8449 8450 mSystemReady = true; 8451 if (!mStartRunning) { 8452 return; 8453 } 8454 } 8455 8456 ArrayList<ProcessRecord> procsToKill = null; 8457 synchronized(mPidsSelfLocked) { 8458 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 8459 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8460 if (!isAllowedWhileBooting(proc.info)){ 8461 if (procsToKill == null) { 8462 procsToKill = new ArrayList<ProcessRecord>(); 8463 } 8464 procsToKill.add(proc); 8465 } 8466 } 8467 } 8468 8469 if (procsToKill != null) { 8470 synchronized(this) { 8471 for (int i=procsToKill.size()-1; i>=0; i--) { 8472 ProcessRecord proc = procsToKill.get(i); 8473 Log.i(TAG, "Removing system update proc: " + proc); 8474 removeProcessLocked(proc, true); 8475 } 8476 } 8477 } 8478 8479 Log.i(TAG, "System now ready"); 8480 EventLog.writeEvent(LOG_BOOT_PROGRESS_AMS_READY, 8481 SystemClock.uptimeMillis()); 8482 8483 synchronized(this) { 8484 // Make sure we have no pre-ready processes sitting around. 8485 8486 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 8487 ResolveInfo ri = mContext.getPackageManager() 8488 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 8489 STOCK_PM_FLAGS); 8490 CharSequence errorMsg = null; 8491 if (ri != null) { 8492 ActivityInfo ai = ri.activityInfo; 8493 ApplicationInfo app = ai.applicationInfo; 8494 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 8495 mTopAction = Intent.ACTION_FACTORY_TEST; 8496 mTopData = null; 8497 mTopComponent = new ComponentName(app.packageName, 8498 ai.name); 8499 } else { 8500 errorMsg = mContext.getResources().getText( 8501 com.android.internal.R.string.factorytest_not_system); 8502 } 8503 } else { 8504 errorMsg = mContext.getResources().getText( 8505 com.android.internal.R.string.factorytest_no_action); 8506 } 8507 if (errorMsg != null) { 8508 mTopAction = null; 8509 mTopData = null; 8510 mTopComponent = null; 8511 Message msg = Message.obtain(); 8512 msg.what = SHOW_FACTORY_ERROR_MSG; 8513 msg.getData().putCharSequence("msg", errorMsg); 8514 mHandler.sendMessage(msg); 8515 } 8516 } 8517 } 8518 8519 retrieveSettings(); 8520 8521 if (goingCallback != null) goingCallback.run(); 8522 8523 synchronized (this) { 8524 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 8525 try { 8526 List apps = ActivityThread.getPackageManager(). 8527 getPersistentApplications(STOCK_PM_FLAGS); 8528 if (apps != null) { 8529 int N = apps.size(); 8530 int i; 8531 for (i=0; i<N; i++) { 8532 ApplicationInfo info 8533 = (ApplicationInfo)apps.get(i); 8534 if (info != null && 8535 !info.packageName.equals("android")) { 8536 addAppLocked(info); 8537 } 8538 } 8539 } 8540 } catch (RemoteException ex) { 8541 // pm is in same process, this will never happen. 8542 } 8543 } 8544 8545 // Start up initial activity. 8546 mBooting = true; 8547 8548 try { 8549 if (ActivityThread.getPackageManager().hasSystemUidErrors()) { 8550 Message msg = Message.obtain(); 8551 msg.what = SHOW_UID_ERROR_MSG; 8552 mHandler.sendMessage(msg); 8553 } 8554 } catch (RemoteException e) { 8555 } 8556 8557 resumeTopActivityLocked(null); 8558 } 8559 } 8560 8561 boolean makeAppCrashingLocked(ProcessRecord app, 8562 String tag, String shortMsg, String longMsg, byte[] crashData) { 8563 app.crashing = true; 8564 app.crashingReport = generateProcessError(app, 8565 ActivityManager.ProcessErrorStateInfo.CRASHED, tag, shortMsg, longMsg, crashData); 8566 startAppProblemLocked(app); 8567 app.stopFreezingAllLocked(); 8568 return handleAppCrashLocked(app); 8569 } 8570 8571 private ComponentName getErrorReportReceiver(ProcessRecord app) { 8572 // check if error reporting is enabled in Gservices 8573 int enabled = Settings.Gservices.getInt(mContext.getContentResolver(), 8574 Settings.Gservices.SEND_ACTION_APP_ERROR, 0); 8575 if (enabled == 0) { 8576 return null; 8577 } 8578 8579 IPackageManager pm = ActivityThread.getPackageManager(); 8580 8581 try { 8582 // look for receiver in the installer package 8583 String candidate = pm.getInstallerPackageName(app.info.packageName); 8584 ComponentName result = getErrorReportReceiver(pm, app.info.packageName, candidate); 8585 if (result != null) { 8586 return result; 8587 } 8588 8589 // if the error app is on the system image, look for system apps 8590 // error receiver 8591 if ((app.info.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 8592 candidate = SystemProperties.get(SYSTEM_APPS_ERROR_RECEIVER_PROPERTY); 8593 result = getErrorReportReceiver(pm, app.info.packageName, candidate); 8594 if (result != null) { 8595 return result; 8596 } 8597 } 8598 8599 // if there is a default receiver, try that 8600 candidate = SystemProperties.get(DEFAULT_ERROR_RECEIVER_PROPERTY); 8601 return getErrorReportReceiver(pm, app.info.packageName, candidate); 8602 } catch (RemoteException e) { 8603 // should not happen 8604 Log.e(TAG, "error talking to PackageManager", e); 8605 return null; 8606 } 8607 } 8608 8609 /** 8610 * Return activity in receiverPackage that handles ACTION_APP_ERROR. 8611 * 8612 * @param pm PackageManager isntance 8613 * @param errorPackage package which caused the error 8614 * @param receiverPackage candidate package to receive the error 8615 * @return activity component within receiverPackage which handles 8616 * ACTION_APP_ERROR, or null if not found 8617 */ 8618 private ComponentName getErrorReportReceiver(IPackageManager pm, String errorPackage, 8619 String receiverPackage) throws RemoteException { 8620 if (receiverPackage == null || receiverPackage.length() == 0) { 8621 return null; 8622 } 8623 8624 // break the loop if it's the error report receiver package that crashed 8625 if (receiverPackage.equals(errorPackage)) { 8626 return null; 8627 } 8628 8629 Intent intent = new Intent(Intent.ACTION_APP_ERROR); 8630 intent.setPackage(receiverPackage); 8631 ResolveInfo info = pm.resolveIntent(intent, null, 0); 8632 if (info == null || info.activityInfo == null) { 8633 return null; 8634 } 8635 return new ComponentName(receiverPackage, info.activityInfo.name); 8636 } 8637 8638 void makeAppNotRespondingLocked(ProcessRecord app, 8639 String tag, String shortMsg, String longMsg, byte[] crashData) { 8640 app.notResponding = true; 8641 app.notRespondingReport = generateProcessError(app, 8642 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, tag, shortMsg, longMsg, 8643 crashData); 8644 startAppProblemLocked(app); 8645 app.stopFreezingAllLocked(); 8646 } 8647 8648 /** 8649 * Generate a process error record, suitable for attachment to a ProcessRecord. 8650 * 8651 * @param app The ProcessRecord in which the error occurred. 8652 * @param condition Crashing, Application Not Responding, etc. Values are defined in 8653 * ActivityManager.AppErrorStateInfo 8654 * @param tag The tag that was passed into handleApplicationError(). Typically the classname. 8655 * @param shortMsg Short message describing the crash. 8656 * @param longMsg Long message describing the crash. 8657 * @param crashData Raw data passed into handleApplicationError(). Typically a stack trace. 8658 * 8659 * @return Returns a fully-formed AppErrorStateInfo record. 8660 */ 8661 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 8662 int condition, String tag, String shortMsg, String longMsg, byte[] crashData) { 8663 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 8664 8665 report.condition = condition; 8666 report.processName = app.processName; 8667 report.pid = app.pid; 8668 report.uid = app.info.uid; 8669 report.tag = tag; 8670 report.shortMsg = shortMsg; 8671 report.longMsg = longMsg; 8672 report.crashData = crashData; 8673 8674 return report; 8675 } 8676 8677 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog, 8678 boolean crashed) { 8679 synchronized (this) { 8680 app.crashing = false; 8681 app.crashingReport = null; 8682 app.notResponding = false; 8683 app.notRespondingReport = null; 8684 if (app.anrDialog == fromDialog) { 8685 app.anrDialog = null; 8686 } 8687 if (app.waitDialog == fromDialog) { 8688 app.waitDialog = null; 8689 } 8690 if (app.pid > 0 && app.pid != MY_PID) { 8691 if (crashed) { 8692 handleAppCrashLocked(app); 8693 } 8694 Log.i(ActivityManagerService.TAG, "Killing process " 8695 + app.processName 8696 + " (pid=" + app.pid + ") at user's request"); 8697 Process.killProcess(app.pid); 8698 } 8699 8700 } 8701 } 8702 8703 boolean handleAppCrashLocked(ProcessRecord app) { 8704 long now = SystemClock.uptimeMillis(); 8705 8706 Long crashTime = mProcessCrashTimes.get(app.info.processName, 8707 app.info.uid); 8708 if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) { 8709 // This process loses! 8710 Log.w(TAG, "Process " + app.info.processName 8711 + " has crashed too many times: killing!"); 8712 EventLog.writeEvent(LOG_AM_PROCESS_CRASHED_TOO_MUCH, 8713 app.info.processName, app.info.uid); 8714 killServicesLocked(app, false); 8715 for (int i=mHistory.size()-1; i>=0; i--) { 8716 HistoryRecord r = (HistoryRecord)mHistory.get(i); 8717 if (r.app == app) { 8718 if (Config.LOGD) Log.d( 8719 TAG, " Force finishing activity " 8720 + r.intent.getComponent().flattenToShortString()); 8721 finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 8722 } 8723 } 8724 if (!app.persistent) { 8725 // We don't want to start this process again until the user 8726 // explicitly does so... but for persistent process, we really 8727 // need to keep it running. If a persistent process is actually 8728 // repeatedly crashing, then badness for everyone. 8729 EventLog.writeEvent(LOG_AM_PROCESS_BAD, app.info.uid, 8730 app.info.processName); 8731 mBadProcesses.put(app.info.processName, app.info.uid, now); 8732 app.bad = true; 8733 mProcessCrashTimes.remove(app.info.processName, app.info.uid); 8734 app.removed = true; 8735 removeProcessLocked(app, false); 8736 return false; 8737 } 8738 } 8739 8740 // Bump up the crash count of any services currently running in the proc. 8741 if (app.services.size() != 0) { 8742 // Any services running in the application need to be placed 8743 // back in the pending list. 8744 Iterator it = app.services.iterator(); 8745 while (it.hasNext()) { 8746 ServiceRecord sr = (ServiceRecord)it.next(); 8747 sr.crashCount++; 8748 } 8749 } 8750 8751 mProcessCrashTimes.put(app.info.processName, app.info.uid, now); 8752 return true; 8753 } 8754 8755 void startAppProblemLocked(ProcessRecord app) { 8756 app.errorReportReceiver = getErrorReportReceiver(app); 8757 skipCurrentReceiverLocked(app); 8758 } 8759 8760 void skipCurrentReceiverLocked(ProcessRecord app) { 8761 boolean reschedule = false; 8762 BroadcastRecord r = app.curReceiver; 8763 if (r != null) { 8764 // The current broadcast is waiting for this app's receiver 8765 // to be finished. Looks like that's not going to happen, so 8766 // let the broadcast continue. 8767 logBroadcastReceiverDiscard(r); 8768 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 8769 r.resultExtras, r.resultAbort, true); 8770 reschedule = true; 8771 } 8772 r = mPendingBroadcast; 8773 if (r != null && r.curApp == app) { 8774 if (DEBUG_BROADCAST) Log.v(TAG, 8775 "skip & discard pending app " + r); 8776 logBroadcastReceiverDiscard(r); 8777 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 8778 r.resultExtras, r.resultAbort, true); 8779 reschedule = true; 8780 } 8781 if (reschedule) { 8782 scheduleBroadcastsLocked(); 8783 } 8784 } 8785 8786 public int handleApplicationError(IBinder app, int flags, 8787 String tag, String shortMsg, String longMsg, byte[] crashData) { 8788 AppErrorResult result = new AppErrorResult(); 8789 ProcessRecord r = null; 8790 synchronized (this) { 8791 if (app != null) { 8792 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8793 final int NA = apps.size(); 8794 for (int ia=0; ia<NA; ia++) { 8795 ProcessRecord p = apps.valueAt(ia); 8796 if (p.thread != null && p.thread.asBinder() == app) { 8797 r = p; 8798 break; 8799 } 8800 } 8801 } 8802 } 8803 8804 if (r != null) { 8805 // The application has crashed. Send the SIGQUIT to the process so 8806 // that it can dump its state. 8807 Process.sendSignal(r.pid, Process.SIGNAL_QUIT); 8808 //Log.i(TAG, "Current system threads:"); 8809 //Process.sendSignal(MY_PID, Process.SIGNAL_QUIT); 8810 } 8811 8812 if (mController != null) { 8813 try { 8814 String name = r != null ? r.processName : null; 8815 int pid = r != null ? r.pid : Binder.getCallingPid(); 8816 if (!mController.appCrashed(name, pid, 8817 shortMsg, longMsg, crashData)) { 8818 Log.w(TAG, "Force-killing crashed app " + name 8819 + " at watcher's request"); 8820 Process.killProcess(pid); 8821 return 0; 8822 } 8823 } catch (RemoteException e) { 8824 mController = null; 8825 } 8826 } 8827 8828 final long origId = Binder.clearCallingIdentity(); 8829 8830 // If this process is running instrumentation, finish it. 8831 if (r != null && r.instrumentationClass != null) { 8832 Log.w(TAG, "Error in app " + r.processName 8833 + " running instrumentation " + r.instrumentationClass + ":"); 8834 if (shortMsg != null) Log.w(TAG, " " + shortMsg); 8835 if (longMsg != null) Log.w(TAG, " " + longMsg); 8836 Bundle info = new Bundle(); 8837 info.putString("shortMsg", shortMsg); 8838 info.putString("longMsg", longMsg); 8839 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8840 Binder.restoreCallingIdentity(origId); 8841 return 0; 8842 } 8843 8844 if (r != null) { 8845 if (!makeAppCrashingLocked(r, tag, shortMsg, longMsg, crashData)) { 8846 return 0; 8847 } 8848 } else { 8849 Log.w(TAG, "Some application object " + app + " tag " + tag 8850 + " has crashed, but I don't know who it is."); 8851 Log.w(TAG, "ShortMsg:" + shortMsg); 8852 Log.w(TAG, "LongMsg:" + longMsg); 8853 Binder.restoreCallingIdentity(origId); 8854 return 0; 8855 } 8856 8857 Message msg = Message.obtain(); 8858 msg.what = SHOW_ERROR_MSG; 8859 HashMap data = new HashMap(); 8860 data.put("result", result); 8861 data.put("app", r); 8862 data.put("flags", flags); 8863 data.put("shortMsg", shortMsg); 8864 data.put("longMsg", longMsg); 8865 if (r != null && (r.info.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 8866 // For system processes, submit crash data to the server. 8867 data.put("crashData", crashData); 8868 } 8869 msg.obj = data; 8870 mHandler.sendMessage(msg); 8871 8872 Binder.restoreCallingIdentity(origId); 8873 } 8874 8875 int res = result.get(); 8876 8877 Intent appErrorIntent = null; 8878 synchronized (this) { 8879 if (r != null) { 8880 mProcessCrashTimes.put(r.info.processName, r.info.uid, 8881 SystemClock.uptimeMillis()); 8882 } 8883 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8884 appErrorIntent = createAppErrorIntentLocked(r); 8885 res = AppErrorDialog.FORCE_QUIT; 8886 } 8887 } 8888 8889 if (appErrorIntent != null) { 8890 try { 8891 mContext.startActivity(appErrorIntent); 8892 } catch (ActivityNotFoundException e) { 8893 Log.w(TAG, "bug report receiver dissappeared", e); 8894 } 8895 } 8896 8897 return res; 8898 } 8899 8900 Intent createAppErrorIntentLocked(ProcessRecord r) { 8901 ApplicationErrorReport report = createAppErrorReportLocked(r); 8902 if (report == null) { 8903 return null; 8904 } 8905 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8906 result.setComponent(r.errorReportReceiver); 8907 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8908 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8909 return result; 8910 } 8911 8912 ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r) { 8913 if (r.errorReportReceiver == null) { 8914 return null; 8915 } 8916 8917 if (!r.crashing && !r.notResponding) { 8918 return null; 8919 } 8920 8921 try { 8922 ApplicationErrorReport report = new ApplicationErrorReport(); 8923 report.packageName = r.info.packageName; 8924 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8925 report.processName = r.processName; 8926 8927 if (r.crashing) { 8928 report.type = ApplicationErrorReport.TYPE_CRASH; 8929 report.crashInfo = new ApplicationErrorReport.CrashInfo(); 8930 8931 ByteArrayInputStream byteStream = new ByteArrayInputStream( 8932 r.crashingReport.crashData); 8933 DataInputStream dataStream = new DataInputStream(byteStream); 8934 CrashData crashData = new CrashData(dataStream); 8935 ThrowableData throwData = crashData.getThrowableData(); 8936 8937 report.time = crashData.getTime(); 8938 report.crashInfo.stackTrace = throwData.toString(); 8939 8940 // Extract the source of the exception, useful for report 8941 // clustering. Also extract the "deepest" non-null exception 8942 // message. 8943 String exceptionMessage = throwData.getMessage(); 8944 while (throwData.getCause() != null) { 8945 throwData = throwData.getCause(); 8946 String msg = throwData.getMessage(); 8947 if (msg != null && msg.length() > 0) { 8948 exceptionMessage = msg; 8949 } 8950 } 8951 StackTraceElementData trace = throwData.getStackTrace()[0]; 8952 report.crashInfo.exceptionMessage = exceptionMessage; 8953 report.crashInfo.exceptionClassName = throwData.getType(); 8954 report.crashInfo.throwFileName = trace.getFileName(); 8955 report.crashInfo.throwClassName = trace.getClassName(); 8956 report.crashInfo.throwMethodName = trace.getMethodName(); 8957 report.crashInfo.throwLineNumber = trace.getLineNumber(); 8958 } else if (r.notResponding) { 8959 report.type = ApplicationErrorReport.TYPE_ANR; 8960 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8961 8962 report.anrInfo.activity = r.notRespondingReport.tag; 8963 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8964 report.anrInfo.info = r.notRespondingReport.longMsg; 8965 } 8966 8967 return report; 8968 } catch (IOException e) { 8969 // we don't send it 8970 } 8971 8972 return null; 8973 } 8974 8975 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8976 // assume our apps are happy - lazy create the list 8977 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8978 8979 synchronized (this) { 8980 8981 // iterate across all processes 8982 final int N = mLRUProcesses.size(); 8983 for (int i = 0; i < N; i++) { 8984 ProcessRecord app = mLRUProcesses.get(i); 8985 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8986 // This one's in trouble, so we'll generate a report for it 8987 // crashes are higher priority (in case there's a crash *and* an anr) 8988 ActivityManager.ProcessErrorStateInfo report = null; 8989 if (app.crashing) { 8990 report = app.crashingReport; 8991 } else if (app.notResponding) { 8992 report = app.notRespondingReport; 8993 } 8994 8995 if (report != null) { 8996 if (errList == null) { 8997 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8998 } 8999 errList.add(report); 9000 } else { 9001 Log.w(TAG, "Missing app error report, app = " + app.processName + 9002 " crashing = " + app.crashing + 9003 " notResponding = " + app.notResponding); 9004 } 9005 } 9006 } 9007 } 9008 9009 return errList; 9010 } 9011 9012 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 9013 // Lazy instantiation of list 9014 List<ActivityManager.RunningAppProcessInfo> runList = null; 9015 synchronized (this) { 9016 // Iterate across all processes 9017 final int N = mLRUProcesses.size(); 9018 for (int i = 0; i < N; i++) { 9019 ProcessRecord app = mLRUProcesses.get(i); 9020 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 9021 // Generate process state info for running application 9022 ActivityManager.RunningAppProcessInfo currApp = 9023 new ActivityManager.RunningAppProcessInfo(app.processName, 9024 app.pid, app.getPackageList()); 9025 currApp.uid = app.info.uid; 9026 int adj = app.curAdj; 9027 if (adj >= CONTENT_PROVIDER_ADJ) { 9028 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY; 9029 } else if (adj >= HIDDEN_APP_MIN_ADJ) { 9030 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 9031 currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1; 9032 } else if (adj >= HOME_APP_ADJ) { 9033 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 9034 currApp.lru = 0; 9035 } else if (adj >= SECONDARY_SERVER_ADJ) { 9036 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 9037 } else if (adj >= VISIBLE_APP_ADJ) { 9038 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 9039 } else { 9040 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 9041 } 9042 currApp.importanceReasonCode = app.adjTypeCode; 9043 if (app.adjSource instanceof ProcessRecord) { 9044 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 9045 } else if (app.adjSource instanceof HistoryRecord) { 9046 HistoryRecord r = (HistoryRecord)app.adjSource; 9047 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 9048 } 9049 if (app.adjTarget instanceof ComponentName) { 9050 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 9051 } 9052 //Log.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 9053 // + " lru=" + currApp.lru); 9054 if (runList == null) { 9055 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 9056 } 9057 runList.add(currApp); 9058 } 9059 } 9060 } 9061 return runList; 9062 } 9063 9064 @Override 9065 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 9066 synchronized (this) { 9067 if (checkCallingPermission(android.Manifest.permission.DUMP) 9068 != PackageManager.PERMISSION_GRANTED) { 9069 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 9070 + Binder.getCallingPid() 9071 + ", uid=" + Binder.getCallingUid() 9072 + " without permission " 9073 + android.Manifest.permission.DUMP); 9074 return; 9075 } 9076 if (args.length != 0 && "service".equals(args[0])) { 9077 dumpService(fd, pw, args); 9078 return; 9079 } 9080 pw.println("Activities in Current Activity Manager State:"); 9081 dumpHistoryList(pw, mHistory, " ", "Hist", true); 9082 pw.println(" "); 9083 pw.println(" Running activities (most recent first):"); 9084 dumpHistoryList(pw, mLRUActivities, " ", "Run", false); 9085 if (mWaitingVisibleActivities.size() > 0) { 9086 pw.println(" "); 9087 pw.println(" Activities waiting for another to become visible:"); 9088 dumpHistoryList(pw, mWaitingVisibleActivities, " ", "Wait", false); 9089 } 9090 if (mStoppingActivities.size() > 0) { 9091 pw.println(" "); 9092 pw.println(" Activities waiting to stop:"); 9093 dumpHistoryList(pw, mStoppingActivities, " ", "Stop", false); 9094 } 9095 if (mFinishingActivities.size() > 0) { 9096 pw.println(" "); 9097 pw.println(" Activities waiting to finish:"); 9098 dumpHistoryList(pw, mFinishingActivities, " ", "Fin", false); 9099 } 9100 9101 pw.println(" "); 9102 pw.println(" mPausingActivity: " + mPausingActivity); 9103 pw.println(" mResumedActivity: " + mResumedActivity); 9104 pw.println(" mFocusedActivity: " + mFocusedActivity); 9105 pw.println(" mLastPausedActivity: " + mLastPausedActivity); 9106 9107 if (mRecentTasks.size() > 0) { 9108 pw.println(" "); 9109 pw.println("Recent tasks in Current Activity Manager State:"); 9110 9111 final int N = mRecentTasks.size(); 9112 for (int i=0; i<N; i++) { 9113 TaskRecord tr = mRecentTasks.get(i); 9114 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 9115 pw.println(tr); 9116 mRecentTasks.get(i).dump(pw, " "); 9117 } 9118 } 9119 9120 pw.println(" "); 9121 pw.println(" mCurTask: " + mCurTask); 9122 9123 pw.println(" "); 9124 pw.println("Processes in Current Activity Manager State:"); 9125 9126 boolean needSep = false; 9127 int numPers = 0; 9128 9129 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 9130 final int NA = procs.size(); 9131 for (int ia=0; ia<NA; ia++) { 9132 if (!needSep) { 9133 pw.println(" All known processes:"); 9134 needSep = true; 9135 } 9136 ProcessRecord r = procs.valueAt(ia); 9137 pw.print(r.persistent ? " *PERS*" : " *APP*"); 9138 pw.print(" UID "); pw.print(procs.keyAt(ia)); 9139 pw.print(" "); pw.println(r); 9140 r.dump(pw, " "); 9141 if (r.persistent) { 9142 numPers++; 9143 } 9144 } 9145 } 9146 9147 if (mLRUProcesses.size() > 0) { 9148 if (needSep) pw.println(" "); 9149 needSep = true; 9150 pw.println(" Running processes (most recent first):"); 9151 dumpProcessList(pw, mLRUProcesses, " ", 9152 "App ", "PERS", true); 9153 needSep = true; 9154 } 9155 9156 synchronized (mPidsSelfLocked) { 9157 if (mPidsSelfLocked.size() > 0) { 9158 if (needSep) pw.println(" "); 9159 needSep = true; 9160 pw.println(" PID mappings:"); 9161 for (int i=0; i<mPidsSelfLocked.size(); i++) { 9162 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 9163 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 9164 } 9165 } 9166 } 9167 9168 if (mForegroundProcesses.size() > 0) { 9169 if (needSep) pw.println(" "); 9170 needSep = true; 9171 pw.println(" Foreground Processes:"); 9172 for (int i=0; i<mForegroundProcesses.size(); i++) { 9173 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 9174 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 9175 } 9176 } 9177 9178 if (mPersistentStartingProcesses.size() > 0) { 9179 if (needSep) pw.println(" "); 9180 needSep = true; 9181 pw.println(" Persisent processes that are starting:"); 9182 dumpProcessList(pw, mPersistentStartingProcesses, " ", 9183 "Starting Norm", "Restarting PERS", false); 9184 } 9185 9186 if (mStartingProcesses.size() > 0) { 9187 if (needSep) pw.println(" "); 9188 needSep = true; 9189 pw.println(" Processes that are starting:"); 9190 dumpProcessList(pw, mStartingProcesses, " ", 9191 "Starting Norm", "Starting PERS", false); 9192 } 9193 9194 if (mRemovedProcesses.size() > 0) { 9195 if (needSep) pw.println(" "); 9196 needSep = true; 9197 pw.println(" Processes that are being removed:"); 9198 dumpProcessList(pw, mRemovedProcesses, " ", 9199 "Removed Norm", "Removed PERS", false); 9200 } 9201 9202 if (mProcessesOnHold.size() > 0) { 9203 if (needSep) pw.println(" "); 9204 needSep = true; 9205 pw.println(" Processes that are on old until the system is ready:"); 9206 dumpProcessList(pw, mProcessesOnHold, " ", 9207 "OnHold Norm", "OnHold PERS", false); 9208 } 9209 9210 if (mProcessesToGc.size() > 0) { 9211 if (needSep) pw.println(" "); 9212 needSep = true; 9213 pw.println(" Processes that are waiting to GC:"); 9214 long now = SystemClock.uptimeMillis(); 9215 for (int i=0; i<mProcessesToGc.size(); i++) { 9216 ProcessRecord proc = mProcessesToGc.get(i); 9217 pw.print(" Process "); pw.println(proc); 9218 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9219 pw.print(", last gced="); 9220 pw.print(now-proc.lastRequestedGc); 9221 pw.print(" ms ago, last lowMem="); 9222 pw.print(now-proc.lastLowMemory); 9223 pw.println(" ms ago"); 9224 9225 } 9226 } 9227 9228 if (mProcessCrashTimes.getMap().size() > 0) { 9229 if (needSep) pw.println(" "); 9230 needSep = true; 9231 pw.println(" Time since processes crashed:"); 9232 long now = SystemClock.uptimeMillis(); 9233 for (Map.Entry<String, SparseArray<Long>> procs 9234 : mProcessCrashTimes.getMap().entrySet()) { 9235 SparseArray<Long> uids = procs.getValue(); 9236 final int N = uids.size(); 9237 for (int i=0; i<N; i++) { 9238 pw.print(" Process "); pw.print(procs.getKey()); 9239 pw.print(" uid "); pw.print(uids.keyAt(i)); 9240 pw.print(": last crashed "); 9241 pw.print((now-uids.valueAt(i))); 9242 pw.println(" ms ago"); 9243 } 9244 } 9245 } 9246 9247 if (mBadProcesses.getMap().size() > 0) { 9248 if (needSep) pw.println(" "); 9249 needSep = true; 9250 pw.println(" Bad processes:"); 9251 for (Map.Entry<String, SparseArray<Long>> procs 9252 : mBadProcesses.getMap().entrySet()) { 9253 SparseArray<Long> uids = procs.getValue(); 9254 final int N = uids.size(); 9255 for (int i=0; i<N; i++) { 9256 pw.print(" Bad process "); pw.print(procs.getKey()); 9257 pw.print(" uid "); pw.print(uids.keyAt(i)); 9258 pw.print(": crashed at time "); 9259 pw.println(uids.valueAt(i)); 9260 } 9261 } 9262 } 9263 9264 pw.println(" "); 9265 pw.println(" Total persistent processes: " + numPers); 9266 pw.println(" mHomeProcess: " + mHomeProcess); 9267 pw.println(" mConfiguration: " + mConfiguration); 9268 pw.println(" mStartRunning=" + mStartRunning 9269 + " mSystemReady=" + mSystemReady 9270 + " mBooting=" + mBooting 9271 + " mBooted=" + mBooted 9272 + " mFactoryTest=" + mFactoryTest); 9273 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown); 9274 pw.println(" mGoingToSleep=" + mGoingToSleep); 9275 pw.println(" mLaunchingActivity=" + mLaunchingActivity); 9276 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9277 + " mDebugTransient=" + mDebugTransient 9278 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9279 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9280 + " mController=" + mController); 9281 } 9282 } 9283 9284 /** 9285 * There are three ways to call this: 9286 * - no service specified: dump all the services 9287 * - a flattened component name that matched an existing service was specified as the 9288 * first arg: dump that one service 9289 * - the first arg isn't the flattened component name of an existing service: 9290 * dump all services whose component contains the first arg as a substring 9291 */ 9292 protected void dumpService(FileDescriptor fd, PrintWriter pw, String[] args) { 9293 String[] newArgs; 9294 String componentNameString; 9295 ServiceRecord r; 9296 if (args.length == 1) { 9297 componentNameString = null; 9298 newArgs = EMPTY_STRING_ARRAY; 9299 r = null; 9300 } else { 9301 componentNameString = args[1]; 9302 ComponentName componentName = ComponentName.unflattenFromString(componentNameString); 9303 r = componentName != null ? mServices.get(componentName) : null; 9304 newArgs = new String[args.length - 2]; 9305 if (args.length > 2) System.arraycopy(args, 2, newArgs, 0, args.length - 2); 9306 } 9307 9308 if (r != null) { 9309 dumpService(fd, pw, r, newArgs); 9310 } else { 9311 for (ServiceRecord r1 : mServices.values()) { 9312 if (componentNameString == null 9313 || r1.name.flattenToString().contains(componentNameString)) { 9314 dumpService(fd, pw, r1, newArgs); 9315 } 9316 } 9317 } 9318 } 9319 9320 /** 9321 * Invokes IApplicationThread.dumpService() on the thread of the specified service if 9322 * there is a thread associated with the service. 9323 */ 9324 private void dumpService(FileDescriptor fd, PrintWriter pw, ServiceRecord r, String[] args) { 9325 pw.println(" Service " + r.name.flattenToString()); 9326 if (r.app != null && r.app.thread != null) { 9327 try { 9328 // flush anything that is already in the PrintWriter since the thread is going 9329 // to write to the file descriptor directly 9330 pw.flush(); 9331 r.app.thread.dumpService(fd, r, args); 9332 pw.print("\n"); 9333 } catch (RemoteException e) { 9334 pw.println("got a RemoteException while dumping the service"); 9335 } 9336 } 9337 } 9338 9339 void dumpBroadcasts(PrintWriter pw) { 9340 synchronized (this) { 9341 if (checkCallingPermission(android.Manifest.permission.DUMP) 9342 != PackageManager.PERMISSION_GRANTED) { 9343 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 9344 + Binder.getCallingPid() 9345 + ", uid=" + Binder.getCallingUid() 9346 + " without permission " 9347 + android.Manifest.permission.DUMP); 9348 return; 9349 } 9350 pw.println("Broadcasts in Current Activity Manager State:"); 9351 9352 if (mRegisteredReceivers.size() > 0) { 9353 pw.println(" "); 9354 pw.println(" Registered Receivers:"); 9355 Iterator it = mRegisteredReceivers.values().iterator(); 9356 while (it.hasNext()) { 9357 ReceiverList r = (ReceiverList)it.next(); 9358 pw.print(" * "); pw.println(r); 9359 r.dump(pw, " "); 9360 } 9361 } 9362 9363 pw.println(" "); 9364 pw.println("Receiver Resolver Table:"); 9365 mReceiverResolver.dump(pw, " "); 9366 9367 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0 9368 || mPendingBroadcast != null) { 9369 if (mParallelBroadcasts.size() > 0) { 9370 pw.println(" "); 9371 pw.println(" Active broadcasts:"); 9372 } 9373 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) { 9374 pw.println(" Broadcast #" + i + ":"); 9375 mParallelBroadcasts.get(i).dump(pw, " "); 9376 } 9377 if (mOrderedBroadcasts.size() > 0) { 9378 pw.println(" "); 9379 pw.println(" Active serialized broadcasts:"); 9380 } 9381 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) { 9382 pw.println(" Serialized Broadcast #" + i + ":"); 9383 mOrderedBroadcasts.get(i).dump(pw, " "); 9384 } 9385 pw.println(" "); 9386 pw.println(" Pending broadcast:"); 9387 if (mPendingBroadcast != null) { 9388 mPendingBroadcast.dump(pw, " "); 9389 } else { 9390 pw.println(" (null)"); 9391 } 9392 } 9393 9394 pw.println(" "); 9395 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled); 9396 if (mStickyBroadcasts != null) { 9397 pw.println(" "); 9398 pw.println(" Sticky broadcasts:"); 9399 StringBuilder sb = new StringBuilder(128); 9400 for (Map.Entry<String, ArrayList<Intent>> ent 9401 : mStickyBroadcasts.entrySet()) { 9402 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9403 pw.println(":"); 9404 ArrayList<Intent> intents = ent.getValue(); 9405 final int N = intents.size(); 9406 for (int i=0; i<N; i++) { 9407 sb.setLength(0); 9408 sb.append(" Intent: "); 9409 intents.get(i).toShortString(sb, true, false); 9410 pw.println(sb.toString()); 9411 Bundle bundle = intents.get(i).getExtras(); 9412 if (bundle != null) { 9413 pw.print(" "); 9414 pw.println(bundle.toString()); 9415 } 9416 } 9417 } 9418 } 9419 9420 pw.println(" "); 9421 pw.println(" mHandler:"); 9422 mHandler.dump(new PrintWriterPrinter(pw), " "); 9423 } 9424 } 9425 9426 void dumpServices(PrintWriter pw) { 9427 synchronized (this) { 9428 if (checkCallingPermission(android.Manifest.permission.DUMP) 9429 != PackageManager.PERMISSION_GRANTED) { 9430 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 9431 + Binder.getCallingPid() 9432 + ", uid=" + Binder.getCallingUid() 9433 + " without permission " 9434 + android.Manifest.permission.DUMP); 9435 return; 9436 } 9437 pw.println("Services in Current Activity Manager State:"); 9438 9439 boolean needSep = false; 9440 9441 if (mServices.size() > 0) { 9442 pw.println(" Active services:"); 9443 Iterator<ServiceRecord> it = mServices.values().iterator(); 9444 while (it.hasNext()) { 9445 ServiceRecord r = it.next(); 9446 pw.print(" * "); pw.println(r); 9447 r.dump(pw, " "); 9448 } 9449 needSep = true; 9450 } 9451 9452 if (mPendingServices.size() > 0) { 9453 if (needSep) pw.println(" "); 9454 pw.println(" Pending services:"); 9455 for (int i=0; i<mPendingServices.size(); i++) { 9456 ServiceRecord r = mPendingServices.get(i); 9457 pw.print(" * Pending "); pw.println(r); 9458 r.dump(pw, " "); 9459 } 9460 needSep = true; 9461 } 9462 9463 if (mRestartingServices.size() > 0) { 9464 if (needSep) pw.println(" "); 9465 pw.println(" Restarting services:"); 9466 for (int i=0; i<mRestartingServices.size(); i++) { 9467 ServiceRecord r = mRestartingServices.get(i); 9468 pw.print(" * Restarting "); pw.println(r); 9469 r.dump(pw, " "); 9470 } 9471 needSep = true; 9472 } 9473 9474 if (mStoppingServices.size() > 0) { 9475 if (needSep) pw.println(" "); 9476 pw.println(" Stopping services:"); 9477 for (int i=0; i<mStoppingServices.size(); i++) { 9478 ServiceRecord r = mStoppingServices.get(i); 9479 pw.print(" * Stopping "); pw.println(r); 9480 r.dump(pw, " "); 9481 } 9482 needSep = true; 9483 } 9484 9485 if (mServiceConnections.size() > 0) { 9486 if (needSep) pw.println(" "); 9487 pw.println(" Connection bindings to services:"); 9488 Iterator<ConnectionRecord> it 9489 = mServiceConnections.values().iterator(); 9490 while (it.hasNext()) { 9491 ConnectionRecord r = it.next(); 9492 pw.print(" * "); pw.println(r); 9493 r.dump(pw, " "); 9494 } 9495 } 9496 } 9497 } 9498 9499 void dumpProviders(PrintWriter pw) { 9500 synchronized (this) { 9501 if (checkCallingPermission(android.Manifest.permission.DUMP) 9502 != PackageManager.PERMISSION_GRANTED) { 9503 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 9504 + Binder.getCallingPid() 9505 + ", uid=" + Binder.getCallingUid() 9506 + " without permission " 9507 + android.Manifest.permission.DUMP); 9508 return; 9509 } 9510 9511 pw.println("Content Providers in Current Activity Manager State:"); 9512 9513 boolean needSep = false; 9514 9515 if (mProvidersByClass.size() > 0) { 9516 if (needSep) pw.println(" "); 9517 pw.println(" Published content providers (by class):"); 9518 Iterator it = mProvidersByClass.entrySet().iterator(); 9519 while (it.hasNext()) { 9520 Map.Entry e = (Map.Entry)it.next(); 9521 ContentProviderRecord r = (ContentProviderRecord)e.getValue(); 9522 pw.print(" * "); pw.println(r); 9523 r.dump(pw, " "); 9524 } 9525 needSep = true; 9526 } 9527 9528 if (mProvidersByName.size() > 0) { 9529 pw.println(" "); 9530 pw.println(" Authority to provider mappings:"); 9531 Iterator it = mProvidersByName.entrySet().iterator(); 9532 while (it.hasNext()) { 9533 Map.Entry e = (Map.Entry)it.next(); 9534 ContentProviderRecord r = (ContentProviderRecord)e.getValue(); 9535 pw.print(" "); pw.print(e.getKey()); pw.print(": "); 9536 pw.println(r); 9537 } 9538 needSep = true; 9539 } 9540 9541 if (mLaunchingProviders.size() > 0) { 9542 if (needSep) pw.println(" "); 9543 pw.println(" Launching content providers:"); 9544 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9545 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9546 pw.println(mLaunchingProviders.get(i)); 9547 } 9548 needSep = true; 9549 } 9550 9551 if (mGrantedUriPermissions.size() > 0) { 9552 pw.println(); 9553 pw.println("Granted Uri Permissions:"); 9554 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9555 int uid = mGrantedUriPermissions.keyAt(i); 9556 HashMap<Uri, UriPermission> perms 9557 = mGrantedUriPermissions.valueAt(i); 9558 pw.print(" * UID "); pw.print(uid); 9559 pw.println(" holds:"); 9560 for (UriPermission perm : perms.values()) { 9561 pw.print(" "); pw.println(perm); 9562 perm.dump(pw, " "); 9563 } 9564 } 9565 } 9566 } 9567 } 9568 9569 void dumpSenders(PrintWriter pw) { 9570 synchronized (this) { 9571 if (checkCallingPermission(android.Manifest.permission.DUMP) 9572 != PackageManager.PERMISSION_GRANTED) { 9573 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 9574 + Binder.getCallingPid() 9575 + ", uid=" + Binder.getCallingUid() 9576 + " without permission " 9577 + android.Manifest.permission.DUMP); 9578 return; 9579 } 9580 9581 pw.println("Pending Intents in Current Activity Manager State:"); 9582 9583 if (this.mIntentSenderRecords.size() > 0) { 9584 Iterator<WeakReference<PendingIntentRecord>> it 9585 = mIntentSenderRecords.values().iterator(); 9586 while (it.hasNext()) { 9587 WeakReference<PendingIntentRecord> ref = it.next(); 9588 PendingIntentRecord rec = ref != null ? ref.get(): null; 9589 if (rec != null) { 9590 pw.print(" * "); pw.println(rec); 9591 rec.dump(pw, " "); 9592 } else { 9593 pw.print(" * "); pw.print(ref); 9594 } 9595 } 9596 } 9597 } 9598 } 9599 9600 private static final void dumpHistoryList(PrintWriter pw, List list, 9601 String prefix, String label, boolean complete) { 9602 TaskRecord lastTask = null; 9603 for (int i=list.size()-1; i>=0; i--) { 9604 HistoryRecord r = (HistoryRecord)list.get(i); 9605 final boolean full = complete || !r.inHistory; 9606 if (lastTask != r.task) { 9607 lastTask = r.task; 9608 pw.print(prefix); 9609 pw.print(full ? "* " : " "); 9610 pw.println(lastTask); 9611 if (full) { 9612 lastTask.dump(pw, prefix + " "); 9613 } 9614 } 9615 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9616 pw.print(" #"); pw.print(i); pw.print(": "); 9617 pw.println(r); 9618 if (full) { 9619 r.dump(pw, prefix + " "); 9620 } 9621 } 9622 } 9623 9624 private static final int dumpProcessList(PrintWriter pw, List list, 9625 String prefix, String normalLabel, String persistentLabel, 9626 boolean inclOomAdj) { 9627 int numPers = 0; 9628 for (int i=list.size()-1; i>=0; i--) { 9629 ProcessRecord r = (ProcessRecord)list.get(i); 9630 if (false) { 9631 pw.println(prefix + (r.persistent ? persistentLabel : normalLabel) 9632 + " #" + i + ":"); 9633 r.dump(pw, prefix + " "); 9634 } else if (inclOomAdj) { 9635 pw.println(String.format("%s%s #%2d: adj=%4d/%d %s (%s)", 9636 prefix, (r.persistent ? persistentLabel : normalLabel), 9637 i, r.setAdj, r.setSchedGroup, r.toString(), r.adjType)); 9638 if (r.adjSource != null || r.adjTarget != null) { 9639 pw.println(prefix + " " + r.adjTarget 9640 + " used by " + r.adjSource); 9641 } 9642 } else { 9643 pw.println(String.format("%s%s #%2d: %s", 9644 prefix, (r.persistent ? persistentLabel : normalLabel), 9645 i, r.toString())); 9646 } 9647 if (r.persistent) { 9648 numPers++; 9649 } 9650 } 9651 return numPers; 9652 } 9653 9654 private static final void dumpApplicationMemoryUsage(FileDescriptor fd, 9655 PrintWriter pw, List list, String prefix, String[] args) { 9656 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 9657 long uptime = SystemClock.uptimeMillis(); 9658 long realtime = SystemClock.elapsedRealtime(); 9659 9660 if (isCheckinRequest) { 9661 // short checkin version 9662 pw.println(uptime + "," + realtime); 9663 pw.flush(); 9664 } else { 9665 pw.println("Applications Memory Usage (kB):"); 9666 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9667 } 9668 for (int i = list.size() - 1 ; i >= 0 ; i--) { 9669 ProcessRecord r = (ProcessRecord)list.get(i); 9670 if (r.thread != null) { 9671 if (!isCheckinRequest) { 9672 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 9673 pw.flush(); 9674 } 9675 try { 9676 r.thread.asBinder().dump(fd, args); 9677 } catch (RemoteException e) { 9678 if (!isCheckinRequest) { 9679 pw.println("Got RemoteException!"); 9680 pw.flush(); 9681 } 9682 } 9683 } 9684 } 9685 } 9686 9687 /** 9688 * Searches array of arguments for the specified string 9689 * @param args array of argument strings 9690 * @param value value to search for 9691 * @return true if the value is contained in the array 9692 */ 9693 private static boolean scanArgs(String[] args, String value) { 9694 if (args != null) { 9695 for (String arg : args) { 9696 if (value.equals(arg)) { 9697 return true; 9698 } 9699 } 9700 } 9701 return false; 9702 } 9703 9704 private final int indexOfTokenLocked(IBinder token) { 9705 int count = mHistory.size(); 9706 9707 // convert the token to an entry in the history. 9708 HistoryRecord r = null; 9709 int index = -1; 9710 for (int i=count-1; i>=0; i--) { 9711 Object o = mHistory.get(i); 9712 if (o == token) { 9713 r = (HistoryRecord)o; 9714 index = i; 9715 break; 9716 } 9717 } 9718 9719 return index; 9720 } 9721 9722 private final void killServicesLocked(ProcessRecord app, 9723 boolean allowRestart) { 9724 // Report disconnected services. 9725 if (false) { 9726 // XXX we are letting the client link to the service for 9727 // death notifications. 9728 if (app.services.size() > 0) { 9729 Iterator it = app.services.iterator(); 9730 while (it.hasNext()) { 9731 ServiceRecord r = (ServiceRecord)it.next(); 9732 if (r.connections.size() > 0) { 9733 Iterator<ConnectionRecord> jt 9734 = r.connections.values().iterator(); 9735 while (jt.hasNext()) { 9736 ConnectionRecord c = jt.next(); 9737 if (c.binding.client != app) { 9738 try { 9739 //c.conn.connected(r.className, null); 9740 } catch (Exception e) { 9741 // todo: this should be asynchronous! 9742 Log.w(TAG, "Exception thrown disconnected servce " 9743 + r.shortName 9744 + " from app " + app.processName, e); 9745 } 9746 } 9747 } 9748 } 9749 } 9750 } 9751 } 9752 9753 // Clean up any connections this application has to other services. 9754 if (app.connections.size() > 0) { 9755 Iterator<ConnectionRecord> it = app.connections.iterator(); 9756 while (it.hasNext()) { 9757 ConnectionRecord r = it.next(); 9758 removeConnectionLocked(r, app, null); 9759 } 9760 } 9761 app.connections.clear(); 9762 9763 if (app.services.size() != 0) { 9764 // Any services running in the application need to be placed 9765 // back in the pending list. 9766 Iterator it = app.services.iterator(); 9767 while (it.hasNext()) { 9768 ServiceRecord sr = (ServiceRecord)it.next(); 9769 synchronized (sr.stats.getBatteryStats()) { 9770 sr.stats.stopLaunchedLocked(); 9771 } 9772 sr.app = null; 9773 sr.executeNesting = 0; 9774 mStoppingServices.remove(sr); 9775 9776 boolean hasClients = sr.bindings.size() > 0; 9777 if (hasClients) { 9778 Iterator<IntentBindRecord> bindings 9779 = sr.bindings.values().iterator(); 9780 while (bindings.hasNext()) { 9781 IntentBindRecord b = bindings.next(); 9782 if (DEBUG_SERVICE) Log.v(TAG, "Killing binding " + b 9783 + ": shouldUnbind=" + b.hasBound); 9784 b.binder = null; 9785 b.requested = b.received = b.hasBound = false; 9786 } 9787 } 9788 9789 if (sr.crashCount >= 2) { 9790 Log.w(TAG, "Service crashed " + sr.crashCount 9791 + " times, stopping: " + sr); 9792 EventLog.writeEvent(LOG_AM_SERVICE_CRASHED_TOO_MUCH, 9793 sr.crashCount, sr.shortName, app.pid); 9794 bringDownServiceLocked(sr, true); 9795 } else if (!allowRestart) { 9796 bringDownServiceLocked(sr, true); 9797 } else { 9798 boolean canceled = scheduleServiceRestartLocked(sr, true); 9799 9800 // Should the service remain running? Note that in the 9801 // extreme case of so many attempts to deliver a command 9802 // that it failed, that we also will stop it here. 9803 if (sr.startRequested && (sr.stopIfKilled || canceled)) { 9804 if (sr.pendingStarts.size() == 0) { 9805 sr.startRequested = false; 9806 if (!hasClients) { 9807 // Whoops, no reason to restart! 9808 bringDownServiceLocked(sr, true); 9809 } 9810 } 9811 } 9812 } 9813 } 9814 9815 if (!allowRestart) { 9816 app.services.clear(); 9817 } 9818 } 9819 9820 // Make sure we have no more records on the stopping list. 9821 int i = mStoppingServices.size(); 9822 while (i > 0) { 9823 i--; 9824 ServiceRecord sr = mStoppingServices.get(i); 9825 if (sr.app == app) { 9826 mStoppingServices.remove(i); 9827 } 9828 } 9829 9830 app.executingServices.clear(); 9831 } 9832 9833 private final void removeDyingProviderLocked(ProcessRecord proc, 9834 ContentProviderRecord cpr) { 9835 synchronized (cpr) { 9836 cpr.launchingApp = null; 9837 cpr.notifyAll(); 9838 } 9839 9840 mProvidersByClass.remove(cpr.info.name); 9841 String names[] = cpr.info.authority.split(";"); 9842 for (int j = 0; j < names.length; j++) { 9843 mProvidersByName.remove(names[j]); 9844 } 9845 9846 Iterator<ProcessRecord> cit = cpr.clients.iterator(); 9847 while (cit.hasNext()) { 9848 ProcessRecord capp = cit.next(); 9849 if (!capp.persistent && capp.thread != null 9850 && capp.pid != 0 9851 && capp.pid != MY_PID) { 9852 Log.i(TAG, "Killing app " + capp.processName 9853 + " (pid " + capp.pid 9854 + ") because provider " + cpr.info.name 9855 + " is in dying process " + proc.processName); 9856 Process.killProcess(capp.pid); 9857 } 9858 } 9859 9860 mLaunchingProviders.remove(cpr); 9861 } 9862 9863 /** 9864 * Main code for cleaning up a process when it has gone away. This is 9865 * called both as a result of the process dying, or directly when stopping 9866 * a process when running in single process mode. 9867 */ 9868 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 9869 boolean restarting, int index) { 9870 if (index >= 0) { 9871 mLRUProcesses.remove(index); 9872 } 9873 9874 mProcessesToGc.remove(app); 9875 9876 // Dismiss any open dialogs. 9877 if (app.crashDialog != null) { 9878 app.crashDialog.dismiss(); 9879 app.crashDialog = null; 9880 } 9881 if (app.anrDialog != null) { 9882 app.anrDialog.dismiss(); 9883 app.anrDialog = null; 9884 } 9885 if (app.waitDialog != null) { 9886 app.waitDialog.dismiss(); 9887 app.waitDialog = null; 9888 } 9889 9890 app.crashing = false; 9891 app.notResponding = false; 9892 9893 app.resetPackageList(); 9894 app.thread = null; 9895 app.forcingToForeground = null; 9896 app.foregroundServices = false; 9897 9898 killServicesLocked(app, true); 9899 9900 boolean restart = false; 9901 9902 int NL = mLaunchingProviders.size(); 9903 9904 // Remove published content providers. 9905 if (!app.pubProviders.isEmpty()) { 9906 Iterator it = app.pubProviders.values().iterator(); 9907 while (it.hasNext()) { 9908 ContentProviderRecord cpr = (ContentProviderRecord)it.next(); 9909 cpr.provider = null; 9910 cpr.app = null; 9911 9912 // See if someone is waiting for this provider... in which 9913 // case we don't remove it, but just let it restart. 9914 int i = 0; 9915 if (!app.bad) { 9916 for (; i<NL; i++) { 9917 if (mLaunchingProviders.get(i) == cpr) { 9918 restart = true; 9919 break; 9920 } 9921 } 9922 } else { 9923 i = NL; 9924 } 9925 9926 if (i >= NL) { 9927 removeDyingProviderLocked(app, cpr); 9928 NL = mLaunchingProviders.size(); 9929 } 9930 } 9931 app.pubProviders.clear(); 9932 } 9933 9934 // Look through the content providers we are waiting to have launched, 9935 // and if any run in this process then either schedule a restart of 9936 // the process or kill the client waiting for it if this process has 9937 // gone bad. 9938 for (int i=0; i<NL; i++) { 9939 ContentProviderRecord cpr = (ContentProviderRecord) 9940 mLaunchingProviders.get(i); 9941 if (cpr.launchingApp == app) { 9942 if (!app.bad) { 9943 restart = true; 9944 } else { 9945 removeDyingProviderLocked(app, cpr); 9946 NL = mLaunchingProviders.size(); 9947 } 9948 } 9949 } 9950 9951 // Unregister from connected content providers. 9952 if (!app.conProviders.isEmpty()) { 9953 Iterator it = app.conProviders.keySet().iterator(); 9954 while (it.hasNext()) { 9955 ContentProviderRecord cpr = (ContentProviderRecord)it.next(); 9956 cpr.clients.remove(app); 9957 } 9958 app.conProviders.clear(); 9959 } 9960 9961 // At this point there may be remaining entries in mLaunchingProviders 9962 // where we were the only one waiting, so they are no longer of use. 9963 // Look for these and clean up if found. 9964 // XXX Commented out for now. Trying to figure out a way to reproduce 9965 // the actual situation to identify what is actually going on. 9966 if (false) { 9967 for (int i=0; i<NL; i++) { 9968 ContentProviderRecord cpr = (ContentProviderRecord) 9969 mLaunchingProviders.get(i); 9970 if (cpr.clients.size() <= 0 && cpr.externals <= 0) { 9971 synchronized (cpr) { 9972 cpr.launchingApp = null; 9973 cpr.notifyAll(); 9974 } 9975 } 9976 } 9977 } 9978 9979 skipCurrentReceiverLocked(app); 9980 9981 // Unregister any receivers. 9982 if (app.receivers.size() > 0) { 9983 Iterator<ReceiverList> it = app.receivers.iterator(); 9984 while (it.hasNext()) { 9985 removeReceiverLocked(it.next()); 9986 } 9987 app.receivers.clear(); 9988 } 9989 9990 // If the app is undergoing backup, tell the backup manager about it 9991 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 9992 if (DEBUG_BACKUP) Log.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 9993 try { 9994 IBackupManager bm = IBackupManager.Stub.asInterface( 9995 ServiceManager.getService(Context.BACKUP_SERVICE)); 9996 bm.agentDisconnected(app.info.packageName); 9997 } catch (RemoteException e) { 9998 // can't happen; backup manager is local 9999 } 10000 } 10001 10002 // If the caller is restarting this app, then leave it in its 10003 // current lists and let the caller take care of it. 10004 if (restarting) { 10005 return; 10006 } 10007 10008 if (!app.persistent) { 10009 if (DEBUG_PROCESSES) Log.v(TAG, 10010 "Removing non-persistent process during cleanup: " + app); 10011 mProcessNames.remove(app.processName, app.info.uid); 10012 } else if (!app.removed) { 10013 // This app is persistent, so we need to keep its record around. 10014 // If it is not already on the pending app list, add it there 10015 // and start a new process for it. 10016 app.thread = null; 10017 app.forcingToForeground = null; 10018 app.foregroundServices = false; 10019 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10020 mPersistentStartingProcesses.add(app); 10021 restart = true; 10022 } 10023 } 10024 mProcessesOnHold.remove(app); 10025 10026 if (app == mHomeProcess) { 10027 mHomeProcess = null; 10028 } 10029 10030 if (restart) { 10031 // We have components that still need to be running in the 10032 // process, so re-launch it. 10033 mProcessNames.put(app.processName, app.info.uid, app); 10034 startProcessLocked(app, "restart", app.processName); 10035 } else if (app.pid > 0 && app.pid != MY_PID) { 10036 // Goodbye! 10037 synchronized (mPidsSelfLocked) { 10038 mPidsSelfLocked.remove(app.pid); 10039 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10040 } 10041 app.setPid(0); 10042 } 10043 } 10044 10045 // ========================================================= 10046 // SERVICES 10047 // ========================================================= 10048 10049 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) { 10050 ActivityManager.RunningServiceInfo info = 10051 new ActivityManager.RunningServiceInfo(); 10052 info.service = r.name; 10053 if (r.app != null) { 10054 info.pid = r.app.pid; 10055 } 10056 info.uid = r.appInfo.uid; 10057 info.process = r.processName; 10058 info.foreground = r.isForeground; 10059 info.activeSince = r.createTime; 10060 info.started = r.startRequested; 10061 info.clientCount = r.connections.size(); 10062 info.crashCount = r.crashCount; 10063 info.lastActivityTime = r.lastActivity; 10064 if (r.isForeground) { 10065 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND; 10066 } 10067 if (r.startRequested) { 10068 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED; 10069 } 10070 if (r.app != null && r.app.pid == Process.myPid()) { 10071 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS; 10072 } 10073 if (r.app != null && r.app.persistent) { 10074 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS; 10075 } 10076 for (ConnectionRecord conn : r.connections.values()) { 10077 if (conn.clientLabel != 0) { 10078 info.clientPackage = conn.binding.client.info.packageName; 10079 info.clientLabel = conn.clientLabel; 10080 break; 10081 } 10082 } 10083 return info; 10084 } 10085 10086 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10087 int flags) { 10088 synchronized (this) { 10089 ArrayList<ActivityManager.RunningServiceInfo> res 10090 = new ArrayList<ActivityManager.RunningServiceInfo>(); 10091 10092 if (mServices.size() > 0) { 10093 Iterator<ServiceRecord> it = mServices.values().iterator(); 10094 while (it.hasNext() && res.size() < maxNum) { 10095 res.add(makeRunningServiceInfoLocked(it.next())); 10096 } 10097 } 10098 10099 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) { 10100 ServiceRecord r = mRestartingServices.get(i); 10101 ActivityManager.RunningServiceInfo info = 10102 makeRunningServiceInfoLocked(r); 10103 info.restarting = r.nextRestartTime; 10104 res.add(info); 10105 } 10106 10107 return res; 10108 } 10109 } 10110 10111 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10112 synchronized (this) { 10113 ServiceRecord r = mServices.get(name); 10114 if (r != null) { 10115 for (ConnectionRecord conn : r.connections.values()) { 10116 if (conn.clientIntent != null) { 10117 return conn.clientIntent; 10118 } 10119 } 10120 } 10121 } 10122 return null; 10123 } 10124 10125 private final ServiceRecord findServiceLocked(ComponentName name, 10126 IBinder token) { 10127 ServiceRecord r = mServices.get(name); 10128 return r == token ? r : null; 10129 } 10130 10131 private final class ServiceLookupResult { 10132 final ServiceRecord record; 10133 final String permission; 10134 10135 ServiceLookupResult(ServiceRecord _record, String _permission) { 10136 record = _record; 10137 permission = _permission; 10138 } 10139 }; 10140 10141 private ServiceLookupResult findServiceLocked(Intent service, 10142 String resolvedType) { 10143 ServiceRecord r = null; 10144 if (service.getComponent() != null) { 10145 r = mServices.get(service.getComponent()); 10146 } 10147 if (r == null) { 10148 Intent.FilterComparison filter = new Intent.FilterComparison(service); 10149 r = mServicesByIntent.get(filter); 10150 } 10151 10152 if (r == null) { 10153 try { 10154 ResolveInfo rInfo = 10155 ActivityThread.getPackageManager().resolveService( 10156 service, resolvedType, 0); 10157 ServiceInfo sInfo = 10158 rInfo != null ? rInfo.serviceInfo : null; 10159 if (sInfo == null) { 10160 return null; 10161 } 10162 10163 ComponentName name = new ComponentName( 10164 sInfo.applicationInfo.packageName, sInfo.name); 10165 r = mServices.get(name); 10166 } catch (RemoteException ex) { 10167 // pm is in same process, this will never happen. 10168 } 10169 } 10170 if (r != null) { 10171 int callingPid = Binder.getCallingPid(); 10172 int callingUid = Binder.getCallingUid(); 10173 if (checkComponentPermission(r.permission, 10174 callingPid, callingUid, r.exported ? -1 : r.appInfo.uid) 10175 != PackageManager.PERMISSION_GRANTED) { 10176 Log.w(TAG, "Permission Denial: Accessing service " + r.name 10177 + " from pid=" + callingPid 10178 + ", uid=" + callingUid 10179 + " requires " + r.permission); 10180 return new ServiceLookupResult(null, r.permission); 10181 } 10182 return new ServiceLookupResult(r, null); 10183 } 10184 return null; 10185 } 10186 10187 private class ServiceRestarter implements Runnable { 10188 private ServiceRecord mService; 10189 10190 void setService(ServiceRecord service) { 10191 mService = service; 10192 } 10193 10194 public void run() { 10195 synchronized(ActivityManagerService.this) { 10196 performServiceRestartLocked(mService); 10197 } 10198 } 10199 } 10200 10201 private ServiceLookupResult retrieveServiceLocked(Intent service, 10202 String resolvedType, int callingPid, int callingUid) { 10203 ServiceRecord r = null; 10204 if (service.getComponent() != null) { 10205 r = mServices.get(service.getComponent()); 10206 } 10207 Intent.FilterComparison filter = new Intent.FilterComparison(service); 10208 r = mServicesByIntent.get(filter); 10209 if (r == null) { 10210 try { 10211 ResolveInfo rInfo = 10212 ActivityThread.getPackageManager().resolveService( 10213 service, resolvedType, STOCK_PM_FLAGS); 10214 ServiceInfo sInfo = 10215 rInfo != null ? rInfo.serviceInfo : null; 10216 if (sInfo == null) { 10217 Log.w(TAG, "Unable to start service " + service + 10218 ": not found"); 10219 return null; 10220 } 10221 10222 ComponentName name = new ComponentName( 10223 sInfo.applicationInfo.packageName, sInfo.name); 10224 r = mServices.get(name); 10225 if (r == null) { 10226 filter = new Intent.FilterComparison(service.cloneFilter()); 10227 ServiceRestarter res = new ServiceRestarter(); 10228 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10229 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10230 synchronized (stats) { 10231 ss = stats.getServiceStatsLocked( 10232 sInfo.applicationInfo.uid, sInfo.packageName, 10233 sInfo.name); 10234 } 10235 r = new ServiceRecord(ss, name, filter, sInfo, res); 10236 res.setService(r); 10237 mServices.put(name, r); 10238 mServicesByIntent.put(filter, r); 10239 10240 // Make sure this component isn't in the pending list. 10241 int N = mPendingServices.size(); 10242 for (int i=0; i<N; i++) { 10243 ServiceRecord pr = mPendingServices.get(i); 10244 if (pr.name.equals(name)) { 10245 mPendingServices.remove(i); 10246 i--; 10247 N--; 10248 } 10249 } 10250 } 10251 } catch (RemoteException ex) { 10252 // pm is in same process, this will never happen. 10253 } 10254 } 10255 if (r != null) { 10256 if (checkComponentPermission(r.permission, 10257 callingPid, callingUid, r.exported ? -1 : r.appInfo.uid) 10258 != PackageManager.PERMISSION_GRANTED) { 10259 Log.w(TAG, "Permission Denial: Accessing service " + r.name 10260 + " from pid=" + Binder.getCallingPid() 10261 + ", uid=" + Binder.getCallingUid() 10262 + " requires " + r.permission); 10263 return new ServiceLookupResult(null, r.permission); 10264 } 10265 return new ServiceLookupResult(r, null); 10266 } 10267 return null; 10268 } 10269 10270 private final void bumpServiceExecutingLocked(ServiceRecord r) { 10271 long now = SystemClock.uptimeMillis(); 10272 if (r.executeNesting == 0 && r.app != null) { 10273 if (r.app.executingServices.size() == 0) { 10274 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 10275 msg.obj = r.app; 10276 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT); 10277 } 10278 r.app.executingServices.add(r); 10279 } 10280 r.executeNesting++; 10281 r.executingStart = now; 10282 } 10283 10284 private final void sendServiceArgsLocked(ServiceRecord r, 10285 boolean oomAdjusted) { 10286 final int N = r.pendingStarts.size(); 10287 if (N == 0) { 10288 return; 10289 } 10290 10291 int i = 0; 10292 while (i < N) { 10293 try { 10294 ServiceRecord.StartItem si = r.pendingStarts.get(i); 10295 if (DEBUG_SERVICE) Log.v(TAG, "Sending arguments to service: " 10296 + r.name + " " + r.intent + " args=" + si.intent); 10297 if (si.intent == null && N > 1) { 10298 // If somehow we got a dummy start at the front, then 10299 // just drop it here. 10300 i++; 10301 continue; 10302 } 10303 bumpServiceExecutingLocked(r); 10304 if (!oomAdjusted) { 10305 oomAdjusted = true; 10306 updateOomAdjLocked(r.app); 10307 } 10308 int flags = 0; 10309 if (si.deliveryCount > 0) { 10310 flags |= Service.START_FLAG_RETRY; 10311 } 10312 if (si.doneExecutingCount > 0) { 10313 flags |= Service.START_FLAG_REDELIVERY; 10314 } 10315 r.app.thread.scheduleServiceArgs(r, si.id, flags, si.intent); 10316 si.deliveredTime = SystemClock.uptimeMillis(); 10317 r.deliveredStarts.add(si); 10318 si.deliveryCount++; 10319 i++; 10320 } catch (RemoteException e) { 10321 // Remote process gone... we'll let the normal cleanup take 10322 // care of this. 10323 break; 10324 } catch (Exception e) { 10325 Log.w(TAG, "Unexpected exception", e); 10326 break; 10327 } 10328 } 10329 if (i == N) { 10330 r.pendingStarts.clear(); 10331 } else { 10332 while (i > 0) { 10333 i--; 10334 r.pendingStarts.remove(i); 10335 } 10336 } 10337 } 10338 10339 private final boolean requestServiceBindingLocked(ServiceRecord r, 10340 IntentBindRecord i, boolean rebind) { 10341 if (r.app == null || r.app.thread == null) { 10342 // If service is not currently running, can't yet bind. 10343 return false; 10344 } 10345 if ((!i.requested || rebind) && i.apps.size() > 0) { 10346 try { 10347 bumpServiceExecutingLocked(r); 10348 if (DEBUG_SERVICE) Log.v(TAG, "Connecting binding " + i 10349 + ": shouldUnbind=" + i.hasBound); 10350 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind); 10351 if (!rebind) { 10352 i.requested = true; 10353 } 10354 i.hasBound = true; 10355 i.doRebind = false; 10356 } catch (RemoteException e) { 10357 return false; 10358 } 10359 } 10360 return true; 10361 } 10362 10363 private final void requestServiceBindingsLocked(ServiceRecord r) { 10364 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator(); 10365 while (bindings.hasNext()) { 10366 IntentBindRecord i = bindings.next(); 10367 if (!requestServiceBindingLocked(r, i, false)) { 10368 break; 10369 } 10370 } 10371 } 10372 10373 private final void realStartServiceLocked(ServiceRecord r, 10374 ProcessRecord app) throws RemoteException { 10375 if (app.thread == null) { 10376 throw new RemoteException(); 10377 } 10378 10379 r.app = app; 10380 r.restartTime = r.lastActivity = SystemClock.uptimeMillis(); 10381 10382 app.services.add(r); 10383 bumpServiceExecutingLocked(r); 10384 updateLRUListLocked(app, true); 10385 10386 boolean created = false; 10387 try { 10388 if (DEBUG_SERVICE) Log.v(TAG, "Scheduling start service: " 10389 + r.name + " " + r.intent); 10390 mStringBuilder.setLength(0); 10391 r.intent.getIntent().toShortString(mStringBuilder, false, true); 10392 EventLog.writeEvent(LOG_AM_CREATE_SERVICE, 10393 System.identityHashCode(r), r.shortName, 10394 mStringBuilder.toString(), r.app.pid); 10395 synchronized (r.stats.getBatteryStats()) { 10396 r.stats.startLaunchedLocked(); 10397 } 10398 ensurePackageDexOpt(r.serviceInfo.packageName); 10399 app.thread.scheduleCreateService(r, r.serviceInfo); 10400 r.postNotification(); 10401 created = true; 10402 } finally { 10403 if (!created) { 10404 app.services.remove(r); 10405 scheduleServiceRestartLocked(r, false); 10406 } 10407 } 10408 10409 requestServiceBindingsLocked(r); 10410 10411 // If the service is in the started state, and there are no 10412 // pending arguments, then fake up one so its onStartCommand() will 10413 // be called. 10414 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) { 10415 r.lastStartId++; 10416 if (r.lastStartId < 1) { 10417 r.lastStartId = 1; 10418 } 10419 r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, null)); 10420 } 10421 10422 sendServiceArgsLocked(r, true); 10423 } 10424 10425 private final boolean scheduleServiceRestartLocked(ServiceRecord r, 10426 boolean allowCancel) { 10427 boolean canceled = false; 10428 10429 final long now = SystemClock.uptimeMillis(); 10430 long minDuration = SERVICE_RESTART_DURATION; 10431 long resetTime = SERVICE_RESET_RUN_DURATION; 10432 10433 // Any delivered but not yet finished starts should be put back 10434 // on the pending list. 10435 final int N = r.deliveredStarts.size(); 10436 if (N > 0) { 10437 for (int i=N-1; i>=0; i--) { 10438 ServiceRecord.StartItem si = r.deliveredStarts.get(i); 10439 if (si.intent == null) { 10440 // We'll generate this again if needed. 10441 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT 10442 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) { 10443 r.pendingStarts.add(0, si); 10444 long dur = SystemClock.uptimeMillis() - si.deliveredTime; 10445 dur *= 2; 10446 if (minDuration < dur) minDuration = dur; 10447 if (resetTime < dur) resetTime = dur; 10448 } else { 10449 Log.w(TAG, "Canceling start item " + si.intent + " in service " 10450 + r.name); 10451 canceled = true; 10452 } 10453 } 10454 r.deliveredStarts.clear(); 10455 } 10456 10457 r.totalRestartCount++; 10458 if (r.restartDelay == 0) { 10459 r.restartCount++; 10460 r.restartDelay = minDuration; 10461 } else { 10462 // If it has been a "reasonably long time" since the service 10463 // was started, then reset our restart duration back to 10464 // the beginning, so we don't infinitely increase the duration 10465 // on a service that just occasionally gets killed (which is 10466 // a normal case, due to process being killed to reclaim memory). 10467 if (now > (r.restartTime+resetTime)) { 10468 r.restartCount = 1; 10469 r.restartDelay = minDuration; 10470 } else { 10471 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR; 10472 if (r.restartDelay < minDuration) { 10473 r.restartDelay = minDuration; 10474 } 10475 } 10476 } 10477 10478 r.nextRestartTime = now + r.restartDelay; 10479 10480 // Make sure that we don't end up restarting a bunch of services 10481 // all at the same time. 10482 boolean repeat; 10483 do { 10484 repeat = false; 10485 for (int i=mRestartingServices.size()-1; i>=0; i--) { 10486 ServiceRecord r2 = mRestartingServices.get(i); 10487 if (r2 != r && r.nextRestartTime 10488 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN) 10489 && r.nextRestartTime 10490 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) { 10491 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN; 10492 r.restartDelay = r.nextRestartTime - now; 10493 repeat = true; 10494 break; 10495 } 10496 } 10497 } while (repeat); 10498 10499 if (!mRestartingServices.contains(r)) { 10500 mRestartingServices.add(r); 10501 } 10502 10503 r.cancelNotification(); 10504 10505 mHandler.removeCallbacks(r.restarter); 10506 mHandler.postAtTime(r.restarter, r.nextRestartTime); 10507 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay; 10508 Log.w(TAG, "Scheduling restart of crashed service " 10509 + r.shortName + " in " + r.restartDelay + "ms"); 10510 EventLog.writeEvent(LOG_AM_SCHEDULE_SERVICE_RESTART, 10511 r.shortName, r.restartDelay); 10512 10513 Message msg = Message.obtain(); 10514 msg.what = SERVICE_ERROR_MSG; 10515 msg.obj = r; 10516 mHandler.sendMessage(msg); 10517 10518 return canceled; 10519 } 10520 10521 final void performServiceRestartLocked(ServiceRecord r) { 10522 if (!mRestartingServices.contains(r)) { 10523 return; 10524 } 10525 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true); 10526 } 10527 10528 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) { 10529 if (r.restartDelay == 0) { 10530 return false; 10531 } 10532 r.resetRestartCounter(); 10533 mRestartingServices.remove(r); 10534 mHandler.removeCallbacks(r.restarter); 10535 return true; 10536 } 10537 10538 private final boolean bringUpServiceLocked(ServiceRecord r, 10539 int intentFlags, boolean whileRestarting) { 10540 //Log.i(TAG, "Bring up service:"); 10541 //r.dump(" "); 10542 10543 if (r.app != null && r.app.thread != null) { 10544 sendServiceArgsLocked(r, false); 10545 return true; 10546 } 10547 10548 if (!whileRestarting && r.restartDelay > 0) { 10549 // If waiting for a restart, then do nothing. 10550 return true; 10551 } 10552 10553 if (DEBUG_SERVICE) Log.v(TAG, "Bringing up service " + r.name 10554 + " " + r.intent); 10555 10556 // We are now bringing the service up, so no longer in the 10557 // restarting state. 10558 mRestartingServices.remove(r); 10559 10560 final String appName = r.processName; 10561 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid); 10562 if (app != null && app.thread != null) { 10563 try { 10564 realStartServiceLocked(r, app); 10565 return true; 10566 } catch (RemoteException e) { 10567 Log.w(TAG, "Exception when starting service " + r.shortName, e); 10568 } 10569 10570 // If a dead object exception was thrown -- fall through to 10571 // restart the application. 10572 } 10573 10574 // Not running -- get it started, and enqueue this service record 10575 // to be executed when the app comes up. 10576 if (startProcessLocked(appName, r.appInfo, true, intentFlags, 10577 "service", r.name, false) == null) { 10578 Log.w(TAG, "Unable to launch app " 10579 + r.appInfo.packageName + "/" 10580 + r.appInfo.uid + " for service " 10581 + r.intent.getIntent() + ": process is bad"); 10582 bringDownServiceLocked(r, true); 10583 return false; 10584 } 10585 10586 if (!mPendingServices.contains(r)) { 10587 mPendingServices.add(r); 10588 } 10589 10590 return true; 10591 } 10592 10593 private final void bringDownServiceLocked(ServiceRecord r, boolean force) { 10594 //Log.i(TAG, "Bring down service:"); 10595 //r.dump(" "); 10596 10597 // Does it still need to run? 10598 if (!force && r.startRequested) { 10599 return; 10600 } 10601 if (r.connections.size() > 0) { 10602 if (!force) { 10603 // XXX should probably keep a count of the number of auto-create 10604 // connections directly in the service. 10605 Iterator<ConnectionRecord> it = r.connections.values().iterator(); 10606 while (it.hasNext()) { 10607 ConnectionRecord cr = it.next(); 10608 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) { 10609 return; 10610 } 10611 } 10612 } 10613 10614 // Report to all of the connections that the service is no longer 10615 // available. 10616 Iterator<ConnectionRecord> it = r.connections.values().iterator(); 10617 while (it.hasNext()) { 10618 ConnectionRecord c = it.next(); 10619 try { 10620 // todo: shouldn't be a synchronous call! 10621 c.conn.connected(r.name, null); 10622 } catch (Exception e) { 10623 Log.w(TAG, "Failure disconnecting service " + r.name + 10624 " to connection " + c.conn.asBinder() + 10625 " (in " + c.binding.client.processName + ")", e); 10626 } 10627 } 10628 } 10629 10630 // Tell the service that it has been unbound. 10631 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) { 10632 Iterator<IntentBindRecord> it = r.bindings.values().iterator(); 10633 while (it.hasNext()) { 10634 IntentBindRecord ibr = it.next(); 10635 if (DEBUG_SERVICE) Log.v(TAG, "Bringing down binding " + ibr 10636 + ": hasBound=" + ibr.hasBound); 10637 if (r.app != null && r.app.thread != null && ibr.hasBound) { 10638 try { 10639 bumpServiceExecutingLocked(r); 10640 updateOomAdjLocked(r.app); 10641 ibr.hasBound = false; 10642 r.app.thread.scheduleUnbindService(r, 10643 ibr.intent.getIntent()); 10644 } catch (Exception e) { 10645 Log.w(TAG, "Exception when unbinding service " 10646 + r.shortName, e); 10647 serviceDoneExecutingLocked(r, true); 10648 } 10649 } 10650 } 10651 } 10652 10653 if (DEBUG_SERVICE) Log.v(TAG, "Bringing down service " + r.name 10654 + " " + r.intent); 10655 EventLog.writeEvent(LOG_AM_DESTROY_SERVICE, 10656 System.identityHashCode(r), r.shortName, 10657 (r.app != null) ? r.app.pid : -1); 10658 10659 mServices.remove(r.name); 10660 mServicesByIntent.remove(r.intent); 10661 if (localLOGV) Log.v(TAG, "BRING DOWN SERVICE: " + r.shortName); 10662 r.totalRestartCount = 0; 10663 unscheduleServiceRestartLocked(r); 10664 10665 // Also make sure it is not on the pending list. 10666 int N = mPendingServices.size(); 10667 for (int i=0; i<N; i++) { 10668 if (mPendingServices.get(i) == r) { 10669 mPendingServices.remove(i); 10670 if (DEBUG_SERVICE) Log.v( 10671 TAG, "Removed pending service: " + r.shortName); 10672 i--; 10673 N--; 10674 } 10675 } 10676 10677 r.cancelNotification(); 10678 r.isForeground = false; 10679 r.foregroundId = 0; 10680 r.foregroundNoti = null; 10681 10682 // Clear start entries. 10683 r.deliveredStarts.clear(); 10684 r.pendingStarts.clear(); 10685 10686 if (r.app != null) { 10687 synchronized (r.stats.getBatteryStats()) { 10688 r.stats.stopLaunchedLocked(); 10689 } 10690 r.app.services.remove(r); 10691 if (r.app.thread != null) { 10692 try { 10693 if (DEBUG_SERVICE) Log.v(TAG, 10694 "Stopping service: " + r.shortName); 10695 bumpServiceExecutingLocked(r); 10696 mStoppingServices.add(r); 10697 updateOomAdjLocked(r.app); 10698 r.app.thread.scheduleStopService(r); 10699 } catch (Exception e) { 10700 Log.w(TAG, "Exception when stopping service " 10701 + r.shortName, e); 10702 serviceDoneExecutingLocked(r, true); 10703 } 10704 updateServiceForegroundLocked(r.app, false); 10705 } else { 10706 if (DEBUG_SERVICE) Log.v( 10707 TAG, "Removed service that has no process: " + r.shortName); 10708 } 10709 } else { 10710 if (DEBUG_SERVICE) Log.v( 10711 TAG, "Removed service that is not running: " + r.shortName); 10712 } 10713 } 10714 10715 ComponentName startServiceLocked(IApplicationThread caller, 10716 Intent service, String resolvedType, 10717 int callingPid, int callingUid) { 10718 synchronized(this) { 10719 if (DEBUG_SERVICE) Log.v(TAG, "startService: " + service 10720 + " type=" + resolvedType + " args=" + service.getExtras()); 10721 10722 if (caller != null) { 10723 final ProcessRecord callerApp = getRecordForAppLocked(caller); 10724 if (callerApp == null) { 10725 throw new SecurityException( 10726 "Unable to find app for caller " + caller 10727 + " (pid=" + Binder.getCallingPid() 10728 + ") when starting service " + service); 10729 } 10730 } 10731 10732 ServiceLookupResult res = 10733 retrieveServiceLocked(service, resolvedType, 10734 callingPid, callingUid); 10735 if (res == null) { 10736 return null; 10737 } 10738 if (res.record == null) { 10739 return new ComponentName("!", res.permission != null 10740 ? res.permission : "private to package"); 10741 } 10742 ServiceRecord r = res.record; 10743 if (unscheduleServiceRestartLocked(r)) { 10744 if (DEBUG_SERVICE) Log.v(TAG, "START SERVICE WHILE RESTART PENDING: " 10745 + r.shortName); 10746 } 10747 r.startRequested = true; 10748 r.callStart = false; 10749 r.lastStartId++; 10750 if (r.lastStartId < 1) { 10751 r.lastStartId = 1; 10752 } 10753 r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, service)); 10754 r.lastActivity = SystemClock.uptimeMillis(); 10755 synchronized (r.stats.getBatteryStats()) { 10756 r.stats.startRunningLocked(); 10757 } 10758 if (!bringUpServiceLocked(r, service.getFlags(), false)) { 10759 return new ComponentName("!", "Service process is bad"); 10760 } 10761 return r.name; 10762 } 10763 } 10764 10765 public ComponentName startService(IApplicationThread caller, Intent service, 10766 String resolvedType) { 10767 // Refuse possible leaked file descriptors 10768 if (service != null && service.hasFileDescriptors() == true) { 10769 throw new IllegalArgumentException("File descriptors passed in Intent"); 10770 } 10771 10772 synchronized(this) { 10773 final int callingPid = Binder.getCallingPid(); 10774 final int callingUid = Binder.getCallingUid(); 10775 final long origId = Binder.clearCallingIdentity(); 10776 ComponentName res = startServiceLocked(caller, service, 10777 resolvedType, callingPid, callingUid); 10778 Binder.restoreCallingIdentity(origId); 10779 return res; 10780 } 10781 } 10782 10783 ComponentName startServiceInPackage(int uid, 10784 Intent service, String resolvedType) { 10785 synchronized(this) { 10786 final long origId = Binder.clearCallingIdentity(); 10787 ComponentName res = startServiceLocked(null, service, 10788 resolvedType, -1, uid); 10789 Binder.restoreCallingIdentity(origId); 10790 return res; 10791 } 10792 } 10793 10794 public int stopService(IApplicationThread caller, Intent service, 10795 String resolvedType) { 10796 // Refuse possible leaked file descriptors 10797 if (service != null && service.hasFileDescriptors() == true) { 10798 throw new IllegalArgumentException("File descriptors passed in Intent"); 10799 } 10800 10801 synchronized(this) { 10802 if (DEBUG_SERVICE) Log.v(TAG, "stopService: " + service 10803 + " type=" + resolvedType); 10804 10805 final ProcessRecord callerApp = getRecordForAppLocked(caller); 10806 if (caller != null && callerApp == null) { 10807 throw new SecurityException( 10808 "Unable to find app for caller " + caller 10809 + " (pid=" + Binder.getCallingPid() 10810 + ") when stopping service " + service); 10811 } 10812 10813 // If this service is active, make sure it is stopped. 10814 ServiceLookupResult r = findServiceLocked(service, resolvedType); 10815 if (r != null) { 10816 if (r.record != null) { 10817 synchronized (r.record.stats.getBatteryStats()) { 10818 r.record.stats.stopRunningLocked(); 10819 } 10820 r.record.startRequested = false; 10821 r.record.callStart = false; 10822 final long origId = Binder.clearCallingIdentity(); 10823 bringDownServiceLocked(r.record, false); 10824 Binder.restoreCallingIdentity(origId); 10825 return 1; 10826 } 10827 return -1; 10828 } 10829 } 10830 10831 return 0; 10832 } 10833 10834 public IBinder peekService(Intent service, String resolvedType) { 10835 // Refuse possible leaked file descriptors 10836 if (service != null && service.hasFileDescriptors() == true) { 10837 throw new IllegalArgumentException("File descriptors passed in Intent"); 10838 } 10839 10840 IBinder ret = null; 10841 10842 synchronized(this) { 10843 ServiceLookupResult r = findServiceLocked(service, resolvedType); 10844 10845 if (r != null) { 10846 // r.record is null if findServiceLocked() failed the caller permission check 10847 if (r.record == null) { 10848 throw new SecurityException( 10849 "Permission Denial: Accessing service " + r.record.name 10850 + " from pid=" + Binder.getCallingPid() 10851 + ", uid=" + Binder.getCallingUid() 10852 + " requires " + r.permission); 10853 } 10854 IntentBindRecord ib = r.record.bindings.get(r.record.intent); 10855 if (ib != null) { 10856 ret = ib.binder; 10857 } 10858 } 10859 } 10860 10861 return ret; 10862 } 10863 10864 public boolean stopServiceToken(ComponentName className, IBinder token, 10865 int startId) { 10866 synchronized(this) { 10867 if (DEBUG_SERVICE) Log.v(TAG, "stopServiceToken: " + className 10868 + " " + token + " startId=" + startId); 10869 ServiceRecord r = findServiceLocked(className, token); 10870 if (r != null) { 10871 if (startId >= 0) { 10872 // Asked to only stop if done with all work. Note that 10873 // to avoid leaks, we will take this as dropping all 10874 // start items up to and including this one. 10875 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 10876 if (si != null) { 10877 while (r.deliveredStarts.size() > 0) { 10878 if (r.deliveredStarts.remove(0) == si) { 10879 break; 10880 } 10881 } 10882 } 10883 10884 if (r.lastStartId != startId) { 10885 return false; 10886 } 10887 10888 if (r.deliveredStarts.size() > 0) { 10889 Log.w(TAG, "stopServiceToken startId " + startId 10890 + " is last, but have " + r.deliveredStarts.size() 10891 + " remaining args"); 10892 } 10893 } 10894 10895 synchronized (r.stats.getBatteryStats()) { 10896 r.stats.stopRunningLocked(); 10897 r.startRequested = false; 10898 r.callStart = false; 10899 } 10900 final long origId = Binder.clearCallingIdentity(); 10901 bringDownServiceLocked(r, false); 10902 Binder.restoreCallingIdentity(origId); 10903 return true; 10904 } 10905 } 10906 return false; 10907 } 10908 10909 public void setServiceForeground(ComponentName className, IBinder token, 10910 int id, Notification notification, boolean removeNotification) { 10911 final long origId = Binder.clearCallingIdentity(); 10912 try { 10913 synchronized(this) { 10914 ServiceRecord r = findServiceLocked(className, token); 10915 if (r != null) { 10916 if (id != 0) { 10917 if (notification == null) { 10918 throw new IllegalArgumentException("null notification"); 10919 } 10920 if (r.foregroundId != id) { 10921 r.cancelNotification(); 10922 r.foregroundId = id; 10923 } 10924 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE; 10925 r.foregroundNoti = notification; 10926 r.isForeground = true; 10927 r.postNotification(); 10928 if (r.app != null) { 10929 updateServiceForegroundLocked(r.app, true); 10930 } 10931 } else { 10932 if (r.isForeground) { 10933 r.isForeground = false; 10934 if (r.app != null) { 10935 updateServiceForegroundLocked(r.app, true); 10936 } 10937 } 10938 if (removeNotification) { 10939 r.cancelNotification(); 10940 r.foregroundId = 0; 10941 r.foregroundNoti = null; 10942 } 10943 } 10944 } 10945 } 10946 } finally { 10947 Binder.restoreCallingIdentity(origId); 10948 } 10949 } 10950 10951 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) { 10952 boolean anyForeground = false; 10953 for (ServiceRecord sr : (HashSet<ServiceRecord>)proc.services) { 10954 if (sr.isForeground) { 10955 anyForeground = true; 10956 break; 10957 } 10958 } 10959 if (anyForeground != proc.foregroundServices) { 10960 proc.foregroundServices = anyForeground; 10961 if (oomAdj) { 10962 updateOomAdjLocked(); 10963 } 10964 } 10965 } 10966 10967 public int bindService(IApplicationThread caller, IBinder token, 10968 Intent service, String resolvedType, 10969 IServiceConnection connection, int flags) { 10970 // Refuse possible leaked file descriptors 10971 if (service != null && service.hasFileDescriptors() == true) { 10972 throw new IllegalArgumentException("File descriptors passed in Intent"); 10973 } 10974 10975 synchronized(this) { 10976 if (DEBUG_SERVICE) Log.v(TAG, "bindService: " + service 10977 + " type=" + resolvedType + " conn=" + connection.asBinder() 10978 + " flags=0x" + Integer.toHexString(flags)); 10979 final ProcessRecord callerApp = getRecordForAppLocked(caller); 10980 if (callerApp == null) { 10981 throw new SecurityException( 10982 "Unable to find app for caller " + caller 10983 + " (pid=" + Binder.getCallingPid() 10984 + ") when binding service " + service); 10985 } 10986 10987 HistoryRecord activity = null; 10988 if (token != null) { 10989 int aindex = indexOfTokenLocked(token); 10990 if (aindex < 0) { 10991 Log.w(TAG, "Binding with unknown activity: " + token); 10992 return 0; 10993 } 10994 activity = (HistoryRecord)mHistory.get(aindex); 10995 } 10996 10997 int clientLabel = 0; 10998 PendingIntent clientIntent = null; 10999 11000 if (callerApp.info.uid == Process.SYSTEM_UID) { 11001 // Hacky kind of thing -- allow system stuff to tell us 11002 // what they are, so we can report this elsewhere for 11003 // others to know why certain services are running. 11004 try { 11005 clientIntent = (PendingIntent)service.getParcelableExtra( 11006 Intent.EXTRA_CLIENT_INTENT); 11007 } catch (RuntimeException e) { 11008 } 11009 if (clientIntent != null) { 11010 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0); 11011 if (clientLabel != 0) { 11012 // There are no useful extras in the intent, trash them. 11013 // System code calling with this stuff just needs to know 11014 // this will happen. 11015 service = service.cloneFilter(); 11016 } 11017 } 11018 } 11019 11020 ServiceLookupResult res = 11021 retrieveServiceLocked(service, resolvedType, 11022 Binder.getCallingPid(), Binder.getCallingUid()); 11023 if (res == null) { 11024 return 0; 11025 } 11026 if (res.record == null) { 11027 return -1; 11028 } 11029 ServiceRecord s = res.record; 11030 11031 final long origId = Binder.clearCallingIdentity(); 11032 11033 if (unscheduleServiceRestartLocked(s)) { 11034 if (DEBUG_SERVICE) Log.v(TAG, "BIND SERVICE WHILE RESTART PENDING: " 11035 + s.shortName); 11036 } 11037 11038 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp); 11039 ConnectionRecord c = new ConnectionRecord(b, activity, 11040 connection, flags, clientLabel, clientIntent); 11041 11042 IBinder binder = connection.asBinder(); 11043 s.connections.put(binder, c); 11044 b.connections.add(c); 11045 if (activity != null) { 11046 if (activity.connections == null) { 11047 activity.connections = new HashSet<ConnectionRecord>(); 11048 } 11049 activity.connections.add(c); 11050 } 11051 b.client.connections.add(c); 11052 mServiceConnections.put(binder, c); 11053 11054 if ((flags&Context.BIND_AUTO_CREATE) != 0) { 11055 s.lastActivity = SystemClock.uptimeMillis(); 11056 if (!bringUpServiceLocked(s, service.getFlags(), false)) { 11057 return 0; 11058 } 11059 } 11060 11061 if (s.app != null) { 11062 // This could have made the service more important. 11063 updateOomAdjLocked(s.app); 11064 } 11065 11066 if (DEBUG_SERVICE) Log.v(TAG, "Bind " + s + " with " + b 11067 + ": received=" + b.intent.received 11068 + " apps=" + b.intent.apps.size() 11069 + " doRebind=" + b.intent.doRebind); 11070 11071 if (s.app != null && b.intent.received) { 11072 // Service is already running, so we can immediately 11073 // publish the connection. 11074 try { 11075 c.conn.connected(s.name, b.intent.binder); 11076 } catch (Exception e) { 11077 Log.w(TAG, "Failure sending service " + s.shortName 11078 + " to connection " + c.conn.asBinder() 11079 + " (in " + c.binding.client.processName + ")", e); 11080 } 11081 11082 // If this is the first app connected back to this binding, 11083 // and the service had previously asked to be told when 11084 // rebound, then do so. 11085 if (b.intent.apps.size() == 1 && b.intent.doRebind) { 11086 requestServiceBindingLocked(s, b.intent, true); 11087 } 11088 } else if (!b.intent.requested) { 11089 requestServiceBindingLocked(s, b.intent, false); 11090 } 11091 11092 Binder.restoreCallingIdentity(origId); 11093 } 11094 11095 return 1; 11096 } 11097 11098 private void removeConnectionLocked( 11099 ConnectionRecord c, ProcessRecord skipApp, HistoryRecord skipAct) { 11100 IBinder binder = c.conn.asBinder(); 11101 AppBindRecord b = c.binding; 11102 ServiceRecord s = b.service; 11103 s.connections.remove(binder); 11104 b.connections.remove(c); 11105 if (c.activity != null && c.activity != skipAct) { 11106 if (c.activity.connections != null) { 11107 c.activity.connections.remove(c); 11108 } 11109 } 11110 if (b.client != skipApp) { 11111 b.client.connections.remove(c); 11112 } 11113 mServiceConnections.remove(binder); 11114 11115 if (b.connections.size() == 0) { 11116 b.intent.apps.remove(b.client); 11117 } 11118 11119 if (DEBUG_SERVICE) Log.v(TAG, "Disconnecting binding " + b.intent 11120 + ": shouldUnbind=" + b.intent.hasBound); 11121 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0 11122 && b.intent.hasBound) { 11123 try { 11124 bumpServiceExecutingLocked(s); 11125 updateOomAdjLocked(s.app); 11126 b.intent.hasBound = false; 11127 // Assume the client doesn't want to know about a rebind; 11128 // we will deal with that later if it asks for one. 11129 b.intent.doRebind = false; 11130 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent()); 11131 } catch (Exception e) { 11132 Log.w(TAG, "Exception when unbinding service " + s.shortName, e); 11133 serviceDoneExecutingLocked(s, true); 11134 } 11135 } 11136 11137 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) { 11138 bringDownServiceLocked(s, false); 11139 } 11140 } 11141 11142 public boolean unbindService(IServiceConnection connection) { 11143 synchronized (this) { 11144 IBinder binder = connection.asBinder(); 11145 if (DEBUG_SERVICE) Log.v(TAG, "unbindService: conn=" + binder); 11146 ConnectionRecord r = mServiceConnections.get(binder); 11147 if (r == null) { 11148 Log.w(TAG, "Unbind failed: could not find connection for " 11149 + connection.asBinder()); 11150 return false; 11151 } 11152 11153 final long origId = Binder.clearCallingIdentity(); 11154 11155 removeConnectionLocked(r, null, null); 11156 11157 if (r.binding.service.app != null) { 11158 // This could have made the service less important. 11159 updateOomAdjLocked(r.binding.service.app); 11160 } 11161 11162 Binder.restoreCallingIdentity(origId); 11163 } 11164 11165 return true; 11166 } 11167 11168 public void publishService(IBinder token, Intent intent, IBinder service) { 11169 // Refuse possible leaked file descriptors 11170 if (intent != null && intent.hasFileDescriptors() == true) { 11171 throw new IllegalArgumentException("File descriptors passed in Intent"); 11172 } 11173 11174 synchronized(this) { 11175 if (!(token instanceof ServiceRecord)) { 11176 throw new IllegalArgumentException("Invalid service token"); 11177 } 11178 ServiceRecord r = (ServiceRecord)token; 11179 11180 final long origId = Binder.clearCallingIdentity(); 11181 11182 if (DEBUG_SERVICE) Log.v(TAG, "PUBLISHING SERVICE " + r.name 11183 + " " + intent + ": " + service); 11184 if (r != null) { 11185 Intent.FilterComparison filter 11186 = new Intent.FilterComparison(intent); 11187 IntentBindRecord b = r.bindings.get(filter); 11188 if (b != null && !b.received) { 11189 b.binder = service; 11190 b.requested = true; 11191 b.received = true; 11192 if (r.connections.size() > 0) { 11193 Iterator<ConnectionRecord> it 11194 = r.connections.values().iterator(); 11195 while (it.hasNext()) { 11196 ConnectionRecord c = it.next(); 11197 if (!filter.equals(c.binding.intent.intent)) { 11198 if (DEBUG_SERVICE) Log.v( 11199 TAG, "Not publishing to: " + c); 11200 if (DEBUG_SERVICE) Log.v( 11201 TAG, "Bound intent: " + c.binding.intent.intent); 11202 if (DEBUG_SERVICE) Log.v( 11203 TAG, "Published intent: " + intent); 11204 continue; 11205 } 11206 if (DEBUG_SERVICE) Log.v(TAG, "Publishing to: " + c); 11207 try { 11208 c.conn.connected(r.name, service); 11209 } catch (Exception e) { 11210 Log.w(TAG, "Failure sending service " + r.name + 11211 " to connection " + c.conn.asBinder() + 11212 " (in " + c.binding.client.processName + ")", e); 11213 } 11214 } 11215 } 11216 } 11217 11218 serviceDoneExecutingLocked(r, mStoppingServices.contains(r)); 11219 11220 Binder.restoreCallingIdentity(origId); 11221 } 11222 } 11223 } 11224 11225 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 11226 // Refuse possible leaked file descriptors 11227 if (intent != null && intent.hasFileDescriptors() == true) { 11228 throw new IllegalArgumentException("File descriptors passed in Intent"); 11229 } 11230 11231 synchronized(this) { 11232 if (!(token instanceof ServiceRecord)) { 11233 throw new IllegalArgumentException("Invalid service token"); 11234 } 11235 ServiceRecord r = (ServiceRecord)token; 11236 11237 final long origId = Binder.clearCallingIdentity(); 11238 11239 if (r != null) { 11240 Intent.FilterComparison filter 11241 = new Intent.FilterComparison(intent); 11242 IntentBindRecord b = r.bindings.get(filter); 11243 if (DEBUG_SERVICE) Log.v(TAG, "unbindFinished in " + r 11244 + " at " + b + ": apps=" 11245 + (b != null ? b.apps.size() : 0)); 11246 if (b != null) { 11247 if (b.apps.size() > 0) { 11248 // Applications have already bound since the last 11249 // unbind, so just rebind right here. 11250 requestServiceBindingLocked(r, b, true); 11251 } else { 11252 // Note to tell the service the next time there is 11253 // a new client. 11254 b.doRebind = true; 11255 } 11256 } 11257 11258 serviceDoneExecutingLocked(r, mStoppingServices.contains(r)); 11259 11260 Binder.restoreCallingIdentity(origId); 11261 } 11262 } 11263 } 11264 11265 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 11266 synchronized(this) { 11267 if (!(token instanceof ServiceRecord)) { 11268 throw new IllegalArgumentException("Invalid service token"); 11269 } 11270 ServiceRecord r = (ServiceRecord)token; 11271 boolean inStopping = mStoppingServices.contains(token); 11272 if (r != null) { 11273 if (DEBUG_SERVICE) Log.v(TAG, "DONE EXECUTING SERVICE " + r.name 11274 + ": nesting=" + r.executeNesting 11275 + ", inStopping=" + inStopping); 11276 if (r != token) { 11277 Log.w(TAG, "Done executing service " + r.name 11278 + " with incorrect token: given " + token 11279 + ", expected " + r); 11280 return; 11281 } 11282 11283 if (type == 1) { 11284 // This is a call from a service start... take care of 11285 // book-keeping. 11286 r.callStart = true; 11287 switch (res) { 11288 case Service.START_STICKY_COMPATIBILITY: 11289 case Service.START_STICKY: { 11290 // We are done with the associated start arguments. 11291 r.findDeliveredStart(startId, true); 11292 // Don't stop if killed. 11293 r.stopIfKilled = false; 11294 break; 11295 } 11296 case Service.START_NOT_STICKY: { 11297 // We are done with the associated start arguments. 11298 r.findDeliveredStart(startId, true); 11299 if (r.lastStartId == startId) { 11300 // There is no more work, and this service 11301 // doesn't want to hang around if killed. 11302 r.stopIfKilled = true; 11303 } 11304 break; 11305 } 11306 case Service.START_REDELIVER_INTENT: { 11307 // We'll keep this item until they explicitly 11308 // call stop for it, but keep track of the fact 11309 // that it was delivered. 11310 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 11311 if (si != null) { 11312 si.deliveryCount = 0; 11313 si.doneExecutingCount++; 11314 // Don't stop if killed. 11315 r.stopIfKilled = true; 11316 } 11317 break; 11318 } 11319 default: 11320 throw new IllegalArgumentException( 11321 "Unknown service start result: " + res); 11322 } 11323 if (res == Service.START_STICKY_COMPATIBILITY) { 11324 r.callStart = false; 11325 } 11326 } 11327 11328 final long origId = Binder.clearCallingIdentity(); 11329 serviceDoneExecutingLocked(r, inStopping); 11330 Binder.restoreCallingIdentity(origId); 11331 } else { 11332 Log.w(TAG, "Done executing unknown service " + r.name 11333 + " with token " + token); 11334 } 11335 } 11336 } 11337 11338 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) { 11339 r.executeNesting--; 11340 if (r.executeNesting <= 0 && r.app != null) { 11341 r.app.executingServices.remove(r); 11342 if (r.app.executingServices.size() == 0) { 11343 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app); 11344 } 11345 if (inStopping) { 11346 mStoppingServices.remove(r); 11347 } 11348 updateOomAdjLocked(r.app); 11349 } 11350 } 11351 11352 void serviceTimeout(ProcessRecord proc) { 11353 synchronized(this) { 11354 if (proc.executingServices.size() == 0 || proc.thread == null) { 11355 return; 11356 } 11357 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT; 11358 Iterator<ServiceRecord> it = proc.executingServices.iterator(); 11359 ServiceRecord timeout = null; 11360 long nextTime = 0; 11361 while (it.hasNext()) { 11362 ServiceRecord sr = it.next(); 11363 if (sr.executingStart < maxTime) { 11364 timeout = sr; 11365 break; 11366 } 11367 if (sr.executingStart > nextTime) { 11368 nextTime = sr.executingStart; 11369 } 11370 } 11371 if (timeout != null && mLRUProcesses.contains(proc)) { 11372 Log.w(TAG, "Timeout executing service: " + timeout); 11373 appNotRespondingLocked(proc, null, null, "Executing service " 11374 + timeout.name); 11375 } else { 11376 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 11377 msg.obj = proc; 11378 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT); 11379 } 11380 } 11381 } 11382 11383 // ========================================================= 11384 // BACKUP AND RESTORE 11385 // ========================================================= 11386 11387 // Cause the target app to be launched if necessary and its backup agent 11388 // instantiated. The backup agent will invoke backupAgentCreated() on the 11389 // activity manager to announce its creation. 11390 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 11391 if (DEBUG_BACKUP) Log.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 11392 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 11393 11394 synchronized(this) { 11395 // !!! TODO: currently no check here that we're already bound 11396 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 11397 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 11398 synchronized (stats) { 11399 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 11400 } 11401 11402 BackupRecord r = new BackupRecord(ss, app, backupMode); 11403 ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName); 11404 // startProcessLocked() returns existing proc's record if it's already running 11405 ProcessRecord proc = startProcessLocked(app.processName, app, 11406 false, 0, "backup", hostingName, false); 11407 if (proc == null) { 11408 Log.e(TAG, "Unable to start backup agent process " + r); 11409 return false; 11410 } 11411 11412 r.app = proc; 11413 mBackupTarget = r; 11414 mBackupAppName = app.packageName; 11415 11416 // Try not to kill the process during backup 11417 updateOomAdjLocked(proc); 11418 11419 // If the process is already attached, schedule the creation of the backup agent now. 11420 // If it is not yet live, this will be done when it attaches to the framework. 11421 if (proc.thread != null) { 11422 if (DEBUG_BACKUP) Log.v(TAG, "Agent proc already running: " + proc); 11423 try { 11424 proc.thread.scheduleCreateBackupAgent(app, backupMode); 11425 } catch (RemoteException e) { 11426 // Will time out on the backup manager side 11427 } 11428 } else { 11429 if (DEBUG_BACKUP) Log.v(TAG, "Agent proc not running, waiting for attach"); 11430 } 11431 // Invariants: at this point, the target app process exists and the application 11432 // is either already running or in the process of coming up. mBackupTarget and 11433 // mBackupAppName describe the app, so that when it binds back to the AM we 11434 // know that it's scheduled for a backup-agent operation. 11435 } 11436 11437 return true; 11438 } 11439 11440 // A backup agent has just come up 11441 public void backupAgentCreated(String agentPackageName, IBinder agent) { 11442 if (DEBUG_BACKUP) Log.v(TAG, "backupAgentCreated: " + agentPackageName 11443 + " = " + agent); 11444 11445 synchronized(this) { 11446 if (!agentPackageName.equals(mBackupAppName)) { 11447 Log.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 11448 return; 11449 } 11450 11451 long oldIdent = Binder.clearCallingIdentity(); 11452 try { 11453 IBackupManager bm = IBackupManager.Stub.asInterface( 11454 ServiceManager.getService(Context.BACKUP_SERVICE)); 11455 bm.agentConnected(agentPackageName, agent); 11456 } catch (RemoteException e) { 11457 // can't happen; the backup manager service is local 11458 } catch (Exception e) { 11459 Log.w(TAG, "Exception trying to deliver BackupAgent binding: "); 11460 e.printStackTrace(); 11461 } finally { 11462 Binder.restoreCallingIdentity(oldIdent); 11463 } 11464 } 11465 } 11466 11467 // done with this agent 11468 public void unbindBackupAgent(ApplicationInfo appInfo) { 11469 if (DEBUG_BACKUP) Log.v(TAG, "unbindBackupAgent: " + appInfo); 11470 if (appInfo == null) { 11471 Log.w(TAG, "unbind backup agent for null app"); 11472 return; 11473 } 11474 11475 synchronized(this) { 11476 if (mBackupAppName == null) { 11477 Log.w(TAG, "Unbinding backup agent with no active backup"); 11478 return; 11479 } 11480 11481 if (!mBackupAppName.equals(appInfo.packageName)) { 11482 Log.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 11483 return; 11484 } 11485 11486 ProcessRecord proc = mBackupTarget.app; 11487 mBackupTarget = null; 11488 mBackupAppName = null; 11489 11490 // Not backing this app up any more; reset its OOM adjustment 11491 updateOomAdjLocked(proc); 11492 11493 // If the app crashed during backup, 'thread' will be null here 11494 if (proc.thread != null) { 11495 try { 11496 proc.thread.scheduleDestroyBackupAgent(appInfo); 11497 } catch (Exception e) { 11498 Log.e(TAG, "Exception when unbinding backup agent:"); 11499 e.printStackTrace(); 11500 } 11501 } 11502 } 11503 } 11504 // ========================================================= 11505 // BROADCASTS 11506 // ========================================================= 11507 11508 private final List getStickies(String action, IntentFilter filter, 11509 List cur) { 11510 final ContentResolver resolver = mContext.getContentResolver(); 11511 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 11512 if (list == null) { 11513 return cur; 11514 } 11515 int N = list.size(); 11516 for (int i=0; i<N; i++) { 11517 Intent intent = list.get(i); 11518 if (filter.match(resolver, intent, true, TAG) >= 0) { 11519 if (cur == null) { 11520 cur = new ArrayList<Intent>(); 11521 } 11522 cur.add(intent); 11523 } 11524 } 11525 return cur; 11526 } 11527 11528 private final void scheduleBroadcastsLocked() { 11529 if (DEBUG_BROADCAST) Log.v(TAG, "Schedule broadcasts: current=" 11530 + mBroadcastsScheduled); 11531 11532 if (mBroadcastsScheduled) { 11533 return; 11534 } 11535 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG); 11536 mBroadcastsScheduled = true; 11537 } 11538 11539 public Intent registerReceiver(IApplicationThread caller, 11540 IIntentReceiver receiver, IntentFilter filter, String permission) { 11541 synchronized(this) { 11542 ProcessRecord callerApp = null; 11543 if (caller != null) { 11544 callerApp = getRecordForAppLocked(caller); 11545 if (callerApp == null) { 11546 throw new SecurityException( 11547 "Unable to find app for caller " + caller 11548 + " (pid=" + Binder.getCallingPid() 11549 + ") when registering receiver " + receiver); 11550 } 11551 } 11552 11553 List allSticky = null; 11554 11555 // Look for any matching sticky broadcasts... 11556 Iterator actions = filter.actionsIterator(); 11557 if (actions != null) { 11558 while (actions.hasNext()) { 11559 String action = (String)actions.next(); 11560 allSticky = getStickies(action, filter, allSticky); 11561 } 11562 } else { 11563 allSticky = getStickies(null, filter, allSticky); 11564 } 11565 11566 // The first sticky in the list is returned directly back to 11567 // the client. 11568 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11569 11570 if (DEBUG_BROADCAST) Log.v(TAG, "Register receiver " + filter 11571 + ": " + sticky); 11572 11573 if (receiver == null) { 11574 return sticky; 11575 } 11576 11577 ReceiverList rl 11578 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11579 if (rl == null) { 11580 rl = new ReceiverList(this, callerApp, 11581 Binder.getCallingPid(), 11582 Binder.getCallingUid(), receiver); 11583 if (rl.app != null) { 11584 rl.app.receivers.add(rl); 11585 } else { 11586 try { 11587 receiver.asBinder().linkToDeath(rl, 0); 11588 } catch (RemoteException e) { 11589 return sticky; 11590 } 11591 rl.linkedToDeath = true; 11592 } 11593 mRegisteredReceivers.put(receiver.asBinder(), rl); 11594 } 11595 BroadcastFilter bf = new BroadcastFilter(filter, rl, permission); 11596 rl.add(bf); 11597 if (!bf.debugCheck()) { 11598 Log.w(TAG, "==> For Dynamic broadast"); 11599 } 11600 mReceiverResolver.addFilter(bf); 11601 11602 // Enqueue broadcasts for all existing stickies that match 11603 // this filter. 11604 if (allSticky != null) { 11605 ArrayList receivers = new ArrayList(); 11606 receivers.add(bf); 11607 11608 int N = allSticky.size(); 11609 for (int i=0; i<N; i++) { 11610 Intent intent = (Intent)allSticky.get(i); 11611 BroadcastRecord r = new BroadcastRecord(intent, null, 11612 null, -1, -1, null, receivers, null, 0, null, null, 11613 false, true); 11614 if (mParallelBroadcasts.size() == 0) { 11615 scheduleBroadcastsLocked(); 11616 } 11617 mParallelBroadcasts.add(r); 11618 } 11619 } 11620 11621 return sticky; 11622 } 11623 } 11624 11625 public void unregisterReceiver(IIntentReceiver receiver) { 11626 if (DEBUG_BROADCAST) Log.v(TAG, "Unregister receiver: " + receiver); 11627 11628 boolean doNext = false; 11629 11630 synchronized(this) { 11631 ReceiverList rl 11632 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11633 if (rl != null) { 11634 if (rl.curBroadcast != null) { 11635 BroadcastRecord r = rl.curBroadcast; 11636 doNext = finishReceiverLocked( 11637 receiver.asBinder(), r.resultCode, r.resultData, 11638 r.resultExtras, r.resultAbort, true); 11639 } 11640 11641 if (rl.app != null) { 11642 rl.app.receivers.remove(rl); 11643 } 11644 removeReceiverLocked(rl); 11645 if (rl.linkedToDeath) { 11646 rl.linkedToDeath = false; 11647 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11648 } 11649 } 11650 } 11651 11652 if (!doNext) { 11653 return; 11654 } 11655 11656 final long origId = Binder.clearCallingIdentity(); 11657 processNextBroadcast(false); 11658 trimApplications(); 11659 Binder.restoreCallingIdentity(origId); 11660 } 11661 11662 void removeReceiverLocked(ReceiverList rl) { 11663 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11664 int N = rl.size(); 11665 for (int i=0; i<N; i++) { 11666 mReceiverResolver.removeFilter(rl.get(i)); 11667 } 11668 } 11669 11670 private final int broadcastIntentLocked(ProcessRecord callerApp, 11671 String callerPackage, Intent intent, String resolvedType, 11672 IIntentReceiver resultTo, int resultCode, String resultData, 11673 Bundle map, String requiredPermission, 11674 boolean ordered, boolean sticky, int callingPid, int callingUid) { 11675 intent = new Intent(intent); 11676 11677 if (DEBUG_BROADCAST_LIGHT) Log.v( 11678 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11679 + " ordered=" + ordered); 11680 if ((resultTo != null) && !ordered) { 11681 Log.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11682 } 11683 11684 // Handle special intents: if this broadcast is from the package 11685 // manager about a package being removed, we need to remove all of 11686 // its activities from the history stack. 11687 final boolean uidRemoved = intent.ACTION_UID_REMOVED.equals( 11688 intent.getAction()); 11689 if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11690 || intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11691 || uidRemoved) { 11692 if (checkComponentPermission( 11693 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11694 callingPid, callingUid, -1) 11695 == PackageManager.PERMISSION_GRANTED) { 11696 if (uidRemoved) { 11697 final Bundle intentExtras = intent.getExtras(); 11698 final int uid = intentExtras != null 11699 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11700 if (uid >= 0) { 11701 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11702 synchronized (bs) { 11703 bs.removeUidStatsLocked(uid); 11704 } 11705 } 11706 } else { 11707 Uri data = intent.getData(); 11708 String ssp; 11709 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11710 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11711 uninstallPackageLocked(ssp, 11712 intent.getIntExtra(Intent.EXTRA_UID, -1), false); 11713 AttributeCache ac = AttributeCache.instance(); 11714 if (ac != null) { 11715 ac.removePackage(ssp); 11716 } 11717 } 11718 } 11719 } 11720 } else { 11721 String msg = "Permission Denial: " + intent.getAction() 11722 + " broadcast from " + callerPackage + " (pid=" + callingPid 11723 + ", uid=" + callingUid + ")" 11724 + " requires " 11725 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11726 Log.w(TAG, msg); 11727 throw new SecurityException(msg); 11728 } 11729 } 11730 11731 /* 11732 * If this is the time zone changed action, queue up a message that will reset the timezone 11733 * of all currently running processes. This message will get queued up before the broadcast 11734 * happens. 11735 */ 11736 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11737 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11738 } 11739 11740 /* 11741 * Prevent non-system code (defined here to be non-persistent 11742 * processes) from sending protected broadcasts. 11743 */ 11744 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11745 || callingUid == Process.SHELL_UID || callingUid == 0) { 11746 // Always okay. 11747 } else if (callerApp == null || !callerApp.persistent) { 11748 try { 11749 if (ActivityThread.getPackageManager().isProtectedBroadcast( 11750 intent.getAction())) { 11751 String msg = "Permission Denial: not allowed to send broadcast " 11752 + intent.getAction() + " from pid=" 11753 + callingPid + ", uid=" + callingUid; 11754 Log.w(TAG, msg); 11755 throw new SecurityException(msg); 11756 } 11757 } catch (RemoteException e) { 11758 Log.w(TAG, "Remote exception", e); 11759 return BROADCAST_SUCCESS; 11760 } 11761 } 11762 11763 // Add to the sticky list if requested. 11764 if (sticky) { 11765 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11766 callingPid, callingUid) 11767 != PackageManager.PERMISSION_GRANTED) { 11768 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11769 + callingPid + ", uid=" + callingUid 11770 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11771 Log.w(TAG, msg); 11772 throw new SecurityException(msg); 11773 } 11774 if (requiredPermission != null) { 11775 Log.w(TAG, "Can't broadcast sticky intent " + intent 11776 + " and enforce permission " + requiredPermission); 11777 return BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11778 } 11779 if (intent.getComponent() != null) { 11780 throw new SecurityException( 11781 "Sticky broadcasts can't target a specific component"); 11782 } 11783 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11784 if (list == null) { 11785 list = new ArrayList<Intent>(); 11786 mStickyBroadcasts.put(intent.getAction(), list); 11787 } 11788 int N = list.size(); 11789 int i; 11790 for (i=0; i<N; i++) { 11791 if (intent.filterEquals(list.get(i))) { 11792 // This sticky already exists, replace it. 11793 list.set(i, new Intent(intent)); 11794 break; 11795 } 11796 } 11797 if (i >= N) { 11798 list.add(new Intent(intent)); 11799 } 11800 } 11801 11802 // Figure out who all will receive this broadcast. 11803 List receivers = null; 11804 List<BroadcastFilter> registeredReceivers = null; 11805 try { 11806 if (intent.getComponent() != null) { 11807 // Broadcast is going to one specific receiver class... 11808 ActivityInfo ai = ActivityThread.getPackageManager(). 11809 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS); 11810 if (ai != null) { 11811 receivers = new ArrayList(); 11812 ResolveInfo ri = new ResolveInfo(); 11813 ri.activityInfo = ai; 11814 receivers.add(ri); 11815 } 11816 } else { 11817 // Need to resolve the intent to interested receivers... 11818 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11819 == 0) { 11820 receivers = 11821 ActivityThread.getPackageManager().queryIntentReceivers( 11822 intent, resolvedType, STOCK_PM_FLAGS); 11823 } 11824 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false); 11825 } 11826 } catch (RemoteException ex) { 11827 // pm is in same process, this will never happen. 11828 } 11829 11830 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11831 if (!ordered && NR > 0) { 11832 // If we are not serializing this broadcast, then send the 11833 // registered receivers separately so they don't wait for the 11834 // components to be launched. 11835 BroadcastRecord r = new BroadcastRecord(intent, callerApp, 11836 callerPackage, callingPid, callingUid, requiredPermission, 11837 registeredReceivers, resultTo, resultCode, resultData, map, 11838 ordered, false); 11839 if (DEBUG_BROADCAST) Log.v( 11840 TAG, "Enqueueing parallel broadcast " + r 11841 + ": prev had " + mParallelBroadcasts.size()); 11842 mParallelBroadcasts.add(r); 11843 scheduleBroadcastsLocked(); 11844 registeredReceivers = null; 11845 NR = 0; 11846 } 11847 11848 // Merge into one list. 11849 int ir = 0; 11850 if (receivers != null) { 11851 // A special case for PACKAGE_ADDED: do not allow the package 11852 // being added to see this broadcast. This prevents them from 11853 // using this as a back door to get run as soon as they are 11854 // installed. Maybe in the future we want to have a special install 11855 // broadcast or such for apps, but we'd like to deliberately make 11856 // this decision. 11857 boolean skip = false; 11858 if (intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11859 skip = true; 11860 } else if (intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())) { 11861 skip = true; 11862 } else if (intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11863 skip = true; 11864 } 11865 String skipPackage = (skip && intent.getData() != null) 11866 ? intent.getData().getSchemeSpecificPart() 11867 : null; 11868 if (skipPackage != null && receivers != null) { 11869 int NT = receivers.size(); 11870 for (int it=0; it<NT; it++) { 11871 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11872 if (curt.activityInfo.packageName.equals(skipPackage)) { 11873 receivers.remove(it); 11874 it--; 11875 NT--; 11876 } 11877 } 11878 } 11879 11880 int NT = receivers != null ? receivers.size() : 0; 11881 int it = 0; 11882 ResolveInfo curt = null; 11883 BroadcastFilter curr = null; 11884 while (it < NT && ir < NR) { 11885 if (curt == null) { 11886 curt = (ResolveInfo)receivers.get(it); 11887 } 11888 if (curr == null) { 11889 curr = registeredReceivers.get(ir); 11890 } 11891 if (curr.getPriority() >= curt.priority) { 11892 // Insert this broadcast record into the final list. 11893 receivers.add(it, curr); 11894 ir++; 11895 curr = null; 11896 it++; 11897 NT++; 11898 } else { 11899 // Skip to the next ResolveInfo in the final list. 11900 it++; 11901 curt = null; 11902 } 11903 } 11904 } 11905 while (ir < NR) { 11906 if (receivers == null) { 11907 receivers = new ArrayList(); 11908 } 11909 receivers.add(registeredReceivers.get(ir)); 11910 ir++; 11911 } 11912 11913 if ((receivers != null && receivers.size() > 0) 11914 || resultTo != null) { 11915 BroadcastRecord r = new BroadcastRecord(intent, callerApp, 11916 callerPackage, callingPid, callingUid, requiredPermission, 11917 receivers, resultTo, resultCode, resultData, map, ordered, false); 11918 if (DEBUG_BROADCAST) Log.v( 11919 TAG, "Enqueueing ordered broadcast " + r 11920 + ": prev had " + mOrderedBroadcasts.size()); 11921 if (DEBUG_BROADCAST) { 11922 int seq = r.intent.getIntExtra("seq", -1); 11923 Log.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11924 } 11925 mOrderedBroadcasts.add(r); 11926 scheduleBroadcastsLocked(); 11927 } 11928 11929 return BROADCAST_SUCCESS; 11930 } 11931 11932 public final int broadcastIntent(IApplicationThread caller, 11933 Intent intent, String resolvedType, IIntentReceiver resultTo, 11934 int resultCode, String resultData, Bundle map, 11935 String requiredPermission, boolean serialized, boolean sticky) { 11936 // Refuse possible leaked file descriptors 11937 if (intent != null && intent.hasFileDescriptors() == true) { 11938 throw new IllegalArgumentException("File descriptors passed in Intent"); 11939 } 11940 11941 synchronized(this) { 11942 int flags = intent.getFlags(); 11943 11944 if (!mSystemReady) { 11945 // if the caller really truly claims to know what they're doing, go 11946 // ahead and allow the broadcast without launching any receivers 11947 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11948 intent = new Intent(intent); 11949 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11950 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0){ 11951 Log.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11952 + " before boot completion"); 11953 throw new IllegalStateException("Cannot broadcast before boot completed"); 11954 } 11955 } 11956 11957 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11958 throw new IllegalArgumentException( 11959 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11960 } 11961 11962 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11963 final int callingPid = Binder.getCallingPid(); 11964 final int callingUid = Binder.getCallingUid(); 11965 final long origId = Binder.clearCallingIdentity(); 11966 int res = broadcastIntentLocked(callerApp, 11967 callerApp != null ? callerApp.info.packageName : null, 11968 intent, resolvedType, resultTo, 11969 resultCode, resultData, map, requiredPermission, serialized, 11970 sticky, callingPid, callingUid); 11971 Binder.restoreCallingIdentity(origId); 11972 return res; 11973 } 11974 } 11975 11976 int broadcastIntentInPackage(String packageName, int uid, 11977 Intent intent, String resolvedType, IIntentReceiver resultTo, 11978 int resultCode, String resultData, Bundle map, 11979 String requiredPermission, boolean serialized, boolean sticky) { 11980 synchronized(this) { 11981 final long origId = Binder.clearCallingIdentity(); 11982 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11983 resultTo, resultCode, resultData, map, requiredPermission, 11984 serialized, sticky, -1, uid); 11985 Binder.restoreCallingIdentity(origId); 11986 return res; 11987 } 11988 } 11989 11990 public final void unbroadcastIntent(IApplicationThread caller, 11991 Intent intent) { 11992 // Refuse possible leaked file descriptors 11993 if (intent != null && intent.hasFileDescriptors() == true) { 11994 throw new IllegalArgumentException("File descriptors passed in Intent"); 11995 } 11996 11997 synchronized(this) { 11998 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11999 != PackageManager.PERMISSION_GRANTED) { 12000 String msg = "Permission Denial: unbroadcastIntent() from pid=" 12001 + Binder.getCallingPid() 12002 + ", uid=" + Binder.getCallingUid() 12003 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 12004 Log.w(TAG, msg); 12005 throw new SecurityException(msg); 12006 } 12007 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 12008 if (list != null) { 12009 int N = list.size(); 12010 int i; 12011 for (i=0; i<N; i++) { 12012 if (intent.filterEquals(list.get(i))) { 12013 list.remove(i); 12014 break; 12015 } 12016 } 12017 } 12018 } 12019 } 12020 12021 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 12022 String resultData, Bundle resultExtras, boolean resultAbort, 12023 boolean explicit) { 12024 if (mOrderedBroadcasts.size() == 0) { 12025 if (explicit) { 12026 Log.w(TAG, "finishReceiver called but no pending broadcasts"); 12027 } 12028 return false; 12029 } 12030 BroadcastRecord r = mOrderedBroadcasts.get(0); 12031 if (r.receiver == null) { 12032 if (explicit) { 12033 Log.w(TAG, "finishReceiver called but none active"); 12034 } 12035 return false; 12036 } 12037 if (r.receiver != receiver) { 12038 Log.w(TAG, "finishReceiver called but active receiver is different"); 12039 return false; 12040 } 12041 int state = r.state; 12042 r.state = r.IDLE; 12043 if (state == r.IDLE) { 12044 if (explicit) { 12045 Log.w(TAG, "finishReceiver called but state is IDLE"); 12046 } 12047 } 12048 r.receiver = null; 12049 r.intent.setComponent(null); 12050 if (r.curApp != null) { 12051 r.curApp.curReceiver = null; 12052 } 12053 if (r.curFilter != null) { 12054 r.curFilter.receiverList.curBroadcast = null; 12055 } 12056 r.curFilter = null; 12057 r.curApp = null; 12058 r.curComponent = null; 12059 r.curReceiver = null; 12060 mPendingBroadcast = null; 12061 12062 r.resultCode = resultCode; 12063 r.resultData = resultData; 12064 r.resultExtras = resultExtras; 12065 r.resultAbort = resultAbort; 12066 12067 // We will process the next receiver right now if this is finishing 12068 // an app receiver (which is always asynchronous) or after we have 12069 // come back from calling a receiver. 12070 return state == BroadcastRecord.APP_RECEIVE 12071 || state == BroadcastRecord.CALL_DONE_RECEIVE; 12072 } 12073 12074 public void finishReceiver(IBinder who, int resultCode, String resultData, 12075 Bundle resultExtras, boolean resultAbort) { 12076 if (DEBUG_BROADCAST) Log.v(TAG, "Finish receiver: " + who); 12077 12078 // Refuse possible leaked file descriptors 12079 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 12080 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12081 } 12082 12083 boolean doNext; 12084 12085 final long origId = Binder.clearCallingIdentity(); 12086 12087 synchronized(this) { 12088 doNext = finishReceiverLocked( 12089 who, resultCode, resultData, resultExtras, resultAbort, true); 12090 } 12091 12092 if (doNext) { 12093 processNextBroadcast(false); 12094 } 12095 trimApplications(); 12096 12097 Binder.restoreCallingIdentity(origId); 12098 } 12099 12100 private final void logBroadcastReceiverDiscard(BroadcastRecord r) { 12101 if (r.nextReceiver > 0) { 12102 Object curReceiver = r.receivers.get(r.nextReceiver-1); 12103 if (curReceiver instanceof BroadcastFilter) { 12104 BroadcastFilter bf = (BroadcastFilter) curReceiver; 12105 EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_FILTER, 12106 System.identityHashCode(r), 12107 r.intent.getAction(), 12108 r.nextReceiver - 1, 12109 System.identityHashCode(bf)); 12110 } else { 12111 EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_APP, 12112 System.identityHashCode(r), 12113 r.intent.getAction(), 12114 r.nextReceiver - 1, 12115 ((ResolveInfo)curReceiver).toString()); 12116 } 12117 } else { 12118 Log.w(TAG, "Discarding broadcast before first receiver is invoked: " 12119 + r); 12120 EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_APP, 12121 System.identityHashCode(r), 12122 r.intent.getAction(), 12123 r.nextReceiver, 12124 "NONE"); 12125 } 12126 } 12127 12128 private final void broadcastTimeout() { 12129 synchronized (this) { 12130 if (mOrderedBroadcasts.size() == 0) { 12131 return; 12132 } 12133 long now = SystemClock.uptimeMillis(); 12134 BroadcastRecord r = mOrderedBroadcasts.get(0); 12135 if ((r.startTime+BROADCAST_TIMEOUT) > now) { 12136 if (DEBUG_BROADCAST) Log.v(TAG, 12137 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for " 12138 + (r.startTime + BROADCAST_TIMEOUT)); 12139 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG); 12140 mHandler.sendMessageAtTime(msg, r.startTime+BROADCAST_TIMEOUT); 12141 return; 12142 } 12143 12144 Log.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver); 12145 r.startTime = now; 12146 r.anrCount++; 12147 12148 // Current receiver has passed its expiration date. 12149 if (r.nextReceiver <= 0) { 12150 Log.w(TAG, "Timeout on receiver with nextReceiver <= 0"); 12151 return; 12152 } 12153 12154 ProcessRecord app = null; 12155 12156 Object curReceiver = r.receivers.get(r.nextReceiver-1); 12157 Log.w(TAG, "Receiver during timeout: " + curReceiver); 12158 logBroadcastReceiverDiscard(r); 12159 if (curReceiver instanceof BroadcastFilter) { 12160 BroadcastFilter bf = (BroadcastFilter)curReceiver; 12161 if (bf.receiverList.pid != 0 12162 && bf.receiverList.pid != MY_PID) { 12163 synchronized (this.mPidsSelfLocked) { 12164 app = this.mPidsSelfLocked.get( 12165 bf.receiverList.pid); 12166 } 12167 } 12168 } else { 12169 app = r.curApp; 12170 } 12171 12172 if (app != null) { 12173 appNotRespondingLocked(app, null, null, 12174 "Broadcast of " + r.intent.toString()); 12175 } 12176 12177 if (mPendingBroadcast == r) { 12178 mPendingBroadcast = null; 12179 } 12180 12181 // Move on to the next receiver. 12182 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 12183 r.resultExtras, r.resultAbort, true); 12184 scheduleBroadcastsLocked(); 12185 } 12186 } 12187 12188 private final void processCurBroadcastLocked(BroadcastRecord r, 12189 ProcessRecord app) throws RemoteException { 12190 if (app.thread == null) { 12191 throw new RemoteException(); 12192 } 12193 r.receiver = app.thread.asBinder(); 12194 r.curApp = app; 12195 app.curReceiver = r; 12196 updateLRUListLocked(app, true); 12197 12198 // Tell the application to launch this receiver. 12199 r.intent.setComponent(r.curComponent); 12200 12201 boolean started = false; 12202 try { 12203 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, 12204 "Delivering to component " + r.curComponent 12205 + ": " + r); 12206 ensurePackageDexOpt(r.intent.getComponent().getPackageName()); 12207 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver, 12208 r.resultCode, r.resultData, r.resultExtras, r.ordered); 12209 started = true; 12210 } finally { 12211 if (!started) { 12212 r.receiver = null; 12213 r.curApp = null; 12214 app.curReceiver = null; 12215 } 12216 } 12217 12218 } 12219 12220 static void performReceive(ProcessRecord app, IIntentReceiver receiver, 12221 Intent intent, int resultCode, String data, Bundle extras, 12222 boolean ordered, boolean sticky) throws RemoteException { 12223 if (app != null && app.thread != null) { 12224 // If we have an app thread, do the call through that so it is 12225 // correctly ordered with other one-way calls. 12226 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode, 12227 data, extras, ordered, sticky); 12228 } else { 12229 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky); 12230 } 12231 } 12232 12233 private final void deliverToRegisteredReceiver(BroadcastRecord r, 12234 BroadcastFilter filter, boolean ordered) { 12235 boolean skip = false; 12236 if (filter.requiredPermission != null) { 12237 int perm = checkComponentPermission(filter.requiredPermission, 12238 r.callingPid, r.callingUid, -1); 12239 if (perm != PackageManager.PERMISSION_GRANTED) { 12240 Log.w(TAG, "Permission Denial: broadcasting " 12241 + r.intent.toString() 12242 + " from " + r.callerPackage + " (pid=" 12243 + r.callingPid + ", uid=" + r.callingUid + ")" 12244 + " requires " + filter.requiredPermission 12245 + " due to registered receiver " + filter); 12246 skip = true; 12247 } 12248 } 12249 if (r.requiredPermission != null) { 12250 int perm = checkComponentPermission(r.requiredPermission, 12251 filter.receiverList.pid, filter.receiverList.uid, -1); 12252 if (perm != PackageManager.PERMISSION_GRANTED) { 12253 Log.w(TAG, "Permission Denial: receiving " 12254 + r.intent.toString() 12255 + " to " + filter.receiverList.app 12256 + " (pid=" + filter.receiverList.pid 12257 + ", uid=" + filter.receiverList.uid + ")" 12258 + " requires " + r.requiredPermission 12259 + " due to sender " + r.callerPackage 12260 + " (uid " + r.callingUid + ")"); 12261 skip = true; 12262 } 12263 } 12264 12265 if (!skip) { 12266 // If this is not being sent as an ordered broadcast, then we 12267 // don't want to touch the fields that keep track of the current 12268 // state of ordered broadcasts. 12269 if (ordered) { 12270 r.receiver = filter.receiverList.receiver.asBinder(); 12271 r.curFilter = filter; 12272 filter.receiverList.curBroadcast = r; 12273 r.state = BroadcastRecord.CALL_IN_RECEIVE; 12274 if (filter.receiverList.app != null) { 12275 // Bump hosting application to no longer be in background 12276 // scheduling class. Note that we can't do that if there 12277 // isn't an app... but we can only be in that case for 12278 // things that directly call the IActivityManager API, which 12279 // are already core system stuff so don't matter for this. 12280 r.curApp = filter.receiverList.app; 12281 filter.receiverList.app.curReceiver = r; 12282 updateOomAdjLocked(); 12283 } 12284 } 12285 try { 12286 if (DEBUG_BROADCAST_LIGHT) { 12287 int seq = r.intent.getIntExtra("seq", -1); 12288 Log.i(TAG, "Delivering to " + filter.receiverList.app 12289 + " (seq=" + seq + "): " + r); 12290 } 12291 performReceive(filter.receiverList.app, filter.receiverList.receiver, 12292 new Intent(r.intent), r.resultCode, 12293 r.resultData, r.resultExtras, r.ordered, r.sticky); 12294 if (ordered) { 12295 r.state = BroadcastRecord.CALL_DONE_RECEIVE; 12296 } 12297 } catch (RemoteException e) { 12298 Log.w(TAG, "Failure sending broadcast " + r.intent, e); 12299 if (ordered) { 12300 r.receiver = null; 12301 r.curFilter = null; 12302 filter.receiverList.curBroadcast = null; 12303 if (filter.receiverList.app != null) { 12304 filter.receiverList.app.curReceiver = null; 12305 } 12306 } 12307 } 12308 } 12309 } 12310 12311 private final void processNextBroadcast(boolean fromMsg) { 12312 synchronized(this) { 12313 BroadcastRecord r; 12314 12315 if (DEBUG_BROADCAST) Log.v(TAG, "processNextBroadcast: " 12316 + mParallelBroadcasts.size() + " broadcasts, " 12317 + mOrderedBroadcasts.size() + " serialized broadcasts"); 12318 12319 updateCpuStats(); 12320 12321 if (fromMsg) { 12322 mBroadcastsScheduled = false; 12323 } 12324 12325 // First, deliver any non-serialized broadcasts right away. 12326 while (mParallelBroadcasts.size() > 0) { 12327 r = mParallelBroadcasts.remove(0); 12328 final int N = r.receivers.size(); 12329 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Processing parallel broadcast " 12330 + r); 12331 for (int i=0; i<N; i++) { 12332 Object target = r.receivers.get(i); 12333 if (DEBUG_BROADCAST) Log.v(TAG, 12334 "Delivering non-serialized to registered " 12335 + target + ": " + r); 12336 deliverToRegisteredReceiver(r, (BroadcastFilter)target, false); 12337 } 12338 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Done with parallel broadcast " 12339 + r); 12340 } 12341 12342 // Now take care of the next serialized one... 12343 12344 // If we are waiting for a process to come up to handle the next 12345 // broadcast, then do nothing at this point. Just in case, we 12346 // check that the process we're waiting for still exists. 12347 if (mPendingBroadcast != null) { 12348 if (DEBUG_BROADCAST_LIGHT) { 12349 Log.v(TAG, "processNextBroadcast: waiting for " 12350 + mPendingBroadcast.curApp); 12351 } 12352 12353 boolean isDead; 12354 synchronized (mPidsSelfLocked) { 12355 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null); 12356 } 12357 if (!isDead) { 12358 // It's still alive, so keep waiting 12359 return; 12360 } else { 12361 Log.w(TAG, "pending app " + mPendingBroadcast.curApp 12362 + " died before responding to broadcast"); 12363 mPendingBroadcast = null; 12364 } 12365 } 12366 12367 boolean looped = false; 12368 12369 do { 12370 if (mOrderedBroadcasts.size() == 0) { 12371 // No more broadcasts pending, so all done! 12372 scheduleAppGcsLocked(); 12373 if (looped) { 12374 // If we had finished the last ordered broadcast, then 12375 // make sure all processes have correct oom and sched 12376 // adjustments. 12377 updateOomAdjLocked(); 12378 } 12379 return; 12380 } 12381 r = mOrderedBroadcasts.get(0); 12382 boolean forceReceive = false; 12383 12384 // Ensure that even if something goes awry with the timeout 12385 // detection, we catch "hung" broadcasts here, discard them, 12386 // and continue to make progress. 12387 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0; 12388 long now = SystemClock.uptimeMillis(); 12389 if (r.dispatchTime > 0) { 12390 if ((numReceivers > 0) && 12391 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) { 12392 Log.w(TAG, "Hung broadcast discarded after timeout failure:" 12393 + " now=" + now 12394 + " dispatchTime=" + r.dispatchTime 12395 + " startTime=" + r.startTime 12396 + " intent=" + r.intent 12397 + " numReceivers=" + numReceivers 12398 + " nextReceiver=" + r.nextReceiver 12399 + " state=" + r.state); 12400 broadcastTimeout(); // forcibly finish this broadcast 12401 forceReceive = true; 12402 r.state = BroadcastRecord.IDLE; 12403 } 12404 } 12405 12406 if (r.state != BroadcastRecord.IDLE) { 12407 if (DEBUG_BROADCAST) Log.d(TAG, 12408 "processNextBroadcast() called when not idle (state=" 12409 + r.state + ")"); 12410 return; 12411 } 12412 12413 if (r.receivers == null || r.nextReceiver >= numReceivers 12414 || r.resultAbort || forceReceive) { 12415 // No more receivers for this broadcast! Send the final 12416 // result if requested... 12417 if (r.resultTo != null) { 12418 try { 12419 if (DEBUG_BROADCAST) { 12420 int seq = r.intent.getIntExtra("seq", -1); 12421 Log.i(TAG, "Finishing broadcast " + r.intent.getAction() 12422 + " seq=" + seq + " app=" + r.callerApp); 12423 } 12424 performReceive(r.callerApp, r.resultTo, 12425 new Intent(r.intent), r.resultCode, 12426 r.resultData, r.resultExtras, false, false); 12427 } catch (RemoteException e) { 12428 Log.w(TAG, "Failure sending broadcast result of " + r.intent, e); 12429 } 12430 } 12431 12432 if (DEBUG_BROADCAST) Log.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG"); 12433 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG); 12434 12435 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Finished with ordered broadcast " 12436 + r); 12437 12438 // ... and on to the next... 12439 mOrderedBroadcasts.remove(0); 12440 r = null; 12441 looped = true; 12442 continue; 12443 } 12444 } while (r == null); 12445 12446 // Get the next receiver... 12447 int recIdx = r.nextReceiver++; 12448 12449 // Keep track of when this receiver started, and make sure there 12450 // is a timeout message pending to kill it if need be. 12451 r.startTime = SystemClock.uptimeMillis(); 12452 if (recIdx == 0) { 12453 r.dispatchTime = r.startTime; 12454 12455 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Processing ordered broadcast " 12456 + r); 12457 if (DEBUG_BROADCAST) Log.v(TAG, 12458 "Submitting BROADCAST_TIMEOUT_MSG for " 12459 + (r.startTime + BROADCAST_TIMEOUT)); 12460 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG); 12461 mHandler.sendMessageAtTime(msg, r.startTime+BROADCAST_TIMEOUT); 12462 } 12463 12464 Object nextReceiver = r.receivers.get(recIdx); 12465 if (nextReceiver instanceof BroadcastFilter) { 12466 // Simple case: this is a registered receiver who gets 12467 // a direct call. 12468 BroadcastFilter filter = (BroadcastFilter)nextReceiver; 12469 if (DEBUG_BROADCAST) Log.v(TAG, 12470 "Delivering serialized to registered " 12471 + filter + ": " + r); 12472 deliverToRegisteredReceiver(r, filter, r.ordered); 12473 if (r.receiver == null || !r.ordered) { 12474 // The receiver has already finished, so schedule to 12475 // process the next one. 12476 r.state = BroadcastRecord.IDLE; 12477 scheduleBroadcastsLocked(); 12478 } 12479 return; 12480 } 12481 12482 // Hard case: need to instantiate the receiver, possibly 12483 // starting its application process to host it. 12484 12485 ResolveInfo info = 12486 (ResolveInfo)nextReceiver; 12487 12488 boolean skip = false; 12489 int perm = checkComponentPermission(info.activityInfo.permission, 12490 r.callingPid, r.callingUid, 12491 info.activityInfo.exported 12492 ? -1 : info.activityInfo.applicationInfo.uid); 12493 if (perm != PackageManager.PERMISSION_GRANTED) { 12494 Log.w(TAG, "Permission Denial: broadcasting " 12495 + r.intent.toString() 12496 + " from " + r.callerPackage + " (pid=" + r.callingPid 12497 + ", uid=" + r.callingUid + ")" 12498 + " requires " + info.activityInfo.permission 12499 + " due to receiver " + info.activityInfo.packageName 12500 + "/" + info.activityInfo.name); 12501 skip = true; 12502 } 12503 if (r.callingUid != Process.SYSTEM_UID && 12504 r.requiredPermission != null) { 12505 try { 12506 perm = ActivityThread.getPackageManager(). 12507 checkPermission(r.requiredPermission, 12508 info.activityInfo.applicationInfo.packageName); 12509 } catch (RemoteException e) { 12510 perm = PackageManager.PERMISSION_DENIED; 12511 } 12512 if (perm != PackageManager.PERMISSION_GRANTED) { 12513 Log.w(TAG, "Permission Denial: receiving " 12514 + r.intent + " to " 12515 + info.activityInfo.applicationInfo.packageName 12516 + " requires " + r.requiredPermission 12517 + " due to sender " + r.callerPackage 12518 + " (uid " + r.callingUid + ")"); 12519 skip = true; 12520 } 12521 } 12522 if (r.curApp != null && r.curApp.crashing) { 12523 // If the target process is crashing, just skip it. 12524 skip = true; 12525 } 12526 12527 if (skip) { 12528 r.receiver = null; 12529 r.curFilter = null; 12530 r.state = BroadcastRecord.IDLE; 12531 scheduleBroadcastsLocked(); 12532 return; 12533 } 12534 12535 r.state = BroadcastRecord.APP_RECEIVE; 12536 String targetProcess = info.activityInfo.processName; 12537 r.curComponent = new ComponentName( 12538 info.activityInfo.applicationInfo.packageName, 12539 info.activityInfo.name); 12540 r.curReceiver = info.activityInfo; 12541 12542 // Is this receiver's application already running? 12543 ProcessRecord app = getProcessRecordLocked(targetProcess, 12544 info.activityInfo.applicationInfo.uid); 12545 if (app != null && app.thread != null) { 12546 try { 12547 processCurBroadcastLocked(r, app); 12548 return; 12549 } catch (RemoteException e) { 12550 Log.w(TAG, "Exception when sending broadcast to " 12551 + r.curComponent, e); 12552 } 12553 12554 // If a dead object exception was thrown -- fall through to 12555 // restart the application. 12556 } 12557 12558 // Not running -- get it started, to be executed when the app comes up. 12559 if ((r.curApp=startProcessLocked(targetProcess, 12560 info.activityInfo.applicationInfo, true, 12561 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND, 12562 "broadcast", r.curComponent, 12563 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0)) 12564 == null) { 12565 // Ah, this recipient is unavailable. Finish it if necessary, 12566 // and mark the broadcast record as ready for the next. 12567 Log.w(TAG, "Unable to launch app " 12568 + info.activityInfo.applicationInfo.packageName + "/" 12569 + info.activityInfo.applicationInfo.uid + " for broadcast " 12570 + r.intent + ": process is bad"); 12571 logBroadcastReceiverDiscard(r); 12572 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 12573 r.resultExtras, r.resultAbort, true); 12574 scheduleBroadcastsLocked(); 12575 r.state = BroadcastRecord.IDLE; 12576 return; 12577 } 12578 12579 mPendingBroadcast = r; 12580 } 12581 } 12582 12583 // ========================================================= 12584 // INSTRUMENTATION 12585 // ========================================================= 12586 12587 public boolean startInstrumentation(ComponentName className, 12588 String profileFile, int flags, Bundle arguments, 12589 IInstrumentationWatcher watcher) { 12590 // Refuse possible leaked file descriptors 12591 if (arguments != null && arguments.hasFileDescriptors()) { 12592 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12593 } 12594 12595 synchronized(this) { 12596 InstrumentationInfo ii = null; 12597 ApplicationInfo ai = null; 12598 try { 12599 ii = mContext.getPackageManager().getInstrumentationInfo( 12600 className, STOCK_PM_FLAGS); 12601 ai = mContext.getPackageManager().getApplicationInfo( 12602 ii.targetPackage, STOCK_PM_FLAGS); 12603 } catch (PackageManager.NameNotFoundException e) { 12604 } 12605 if (ii == null) { 12606 reportStartInstrumentationFailure(watcher, className, 12607 "Unable to find instrumentation info for: " + className); 12608 return false; 12609 } 12610 if (ai == null) { 12611 reportStartInstrumentationFailure(watcher, className, 12612 "Unable to find instrumentation target package: " + ii.targetPackage); 12613 return false; 12614 } 12615 12616 int match = mContext.getPackageManager().checkSignatures( 12617 ii.targetPackage, ii.packageName); 12618 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 12619 String msg = "Permission Denial: starting instrumentation " 12620 + className + " from pid=" 12621 + Binder.getCallingPid() 12622 + ", uid=" + Binder.getCallingPid() 12623 + " not allowed because package " + ii.packageName 12624 + " does not have a signature matching the target " 12625 + ii.targetPackage; 12626 reportStartInstrumentationFailure(watcher, className, msg); 12627 throw new SecurityException(msg); 12628 } 12629 12630 final long origId = Binder.clearCallingIdentity(); 12631 uninstallPackageLocked(ii.targetPackage, -1, true); 12632 ProcessRecord app = addAppLocked(ai); 12633 app.instrumentationClass = className; 12634 app.instrumentationInfo = ai; 12635 app.instrumentationProfileFile = profileFile; 12636 app.instrumentationArguments = arguments; 12637 app.instrumentationWatcher = watcher; 12638 app.instrumentationResultClass = className; 12639 Binder.restoreCallingIdentity(origId); 12640 } 12641 12642 return true; 12643 } 12644 12645 /** 12646 * Report errors that occur while attempting to start Instrumentation. Always writes the 12647 * error to the logs, but if somebody is watching, send the report there too. This enables 12648 * the "am" command to report errors with more information. 12649 * 12650 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 12651 * @param cn The component name of the instrumentation. 12652 * @param report The error report. 12653 */ 12654 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 12655 ComponentName cn, String report) { 12656 Log.w(TAG, report); 12657 try { 12658 if (watcher != null) { 12659 Bundle results = new Bundle(); 12660 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 12661 results.putString("Error", report); 12662 watcher.instrumentationStatus(cn, -1, results); 12663 } 12664 } catch (RemoteException e) { 12665 Log.w(TAG, e); 12666 } 12667 } 12668 12669 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 12670 if (app.instrumentationWatcher != null) { 12671 try { 12672 // NOTE: IInstrumentationWatcher *must* be oneway here 12673 app.instrumentationWatcher.instrumentationFinished( 12674 app.instrumentationClass, 12675 resultCode, 12676 results); 12677 } catch (RemoteException e) { 12678 } 12679 } 12680 app.instrumentationWatcher = null; 12681 app.instrumentationClass = null; 12682 app.instrumentationInfo = null; 12683 app.instrumentationProfileFile = null; 12684 app.instrumentationArguments = null; 12685 12686 uninstallPackageLocked(app.processName, -1, false); 12687 } 12688 12689 public void finishInstrumentation(IApplicationThread target, 12690 int resultCode, Bundle results) { 12691 // Refuse possible leaked file descriptors 12692 if (results != null && results.hasFileDescriptors()) { 12693 throw new IllegalArgumentException("File descriptors passed in Intent"); 12694 } 12695 12696 synchronized(this) { 12697 ProcessRecord app = getRecordForAppLocked(target); 12698 if (app == null) { 12699 Log.w(TAG, "finishInstrumentation: no app for " + target); 12700 return; 12701 } 12702 final long origId = Binder.clearCallingIdentity(); 12703 finishInstrumentationLocked(app, resultCode, results); 12704 Binder.restoreCallingIdentity(origId); 12705 } 12706 } 12707 12708 // ========================================================= 12709 // CONFIGURATION 12710 // ========================================================= 12711 12712 public ConfigurationInfo getDeviceConfigurationInfo() { 12713 ConfigurationInfo config = new ConfigurationInfo(); 12714 synchronized (this) { 12715 config.reqTouchScreen = mConfiguration.touchscreen; 12716 config.reqKeyboardType = mConfiguration.keyboard; 12717 config.reqNavigation = mConfiguration.navigation; 12718 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 12719 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 12720 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 12721 } 12722 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 12723 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 12724 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 12725 } 12726 config.reqGlEsVersion = GL_ES_VERSION; 12727 } 12728 return config; 12729 } 12730 12731 public Configuration getConfiguration() { 12732 Configuration ci; 12733 synchronized(this) { 12734 ci = new Configuration(mConfiguration); 12735 } 12736 return ci; 12737 } 12738 12739 public void updateConfiguration(Configuration values) { 12740 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12741 "updateConfiguration()"); 12742 12743 synchronized(this) { 12744 if (values == null && mWindowManager != null) { 12745 // sentinel: fetch the current configuration from the window manager 12746 values = mWindowManager.computeNewConfiguration(); 12747 } 12748 12749 final long origId = Binder.clearCallingIdentity(); 12750 updateConfigurationLocked(values, null); 12751 Binder.restoreCallingIdentity(origId); 12752 } 12753 } 12754 12755 /** 12756 * Do either or both things: (1) change the current configuration, and (2) 12757 * make sure the given activity is running with the (now) current 12758 * configuration. Returns true if the activity has been left running, or 12759 * false if <var>starting</var> is being destroyed to match the new 12760 * configuration. 12761 */ 12762 public boolean updateConfigurationLocked(Configuration values, 12763 HistoryRecord starting) { 12764 int changes = 0; 12765 12766 boolean kept = true; 12767 12768 if (values != null) { 12769 Configuration newConfig = new Configuration(mConfiguration); 12770 changes = newConfig.updateFrom(values); 12771 if (changes != 0) { 12772 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 12773 Log.i(TAG, "Updating configuration to: " + values); 12774 } 12775 12776 EventLog.writeEvent(LOG_CONFIGURATION_CHANGED, changes); 12777 12778 if (values.locale != null) { 12779 saveLocaleLocked(values.locale, 12780 !values.locale.equals(mConfiguration.locale), 12781 values.userSetLocale); 12782 } 12783 12784 mConfiguration = newConfig; 12785 Log.i(TAG, "Config changed: " + newConfig); 12786 12787 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 12788 msg.obj = new Configuration(mConfiguration); 12789 mHandler.sendMessage(msg); 12790 12791 final int N = mLRUProcesses.size(); 12792 for (int i=0; i<N; i++) { 12793 ProcessRecord app = mLRUProcesses.get(i); 12794 try { 12795 if (app.thread != null) { 12796 if (DEBUG_CONFIGURATION) Log.v(TAG, "Sending to proc " 12797 + app.processName + " new config " + mConfiguration); 12798 app.thread.scheduleConfigurationChanged(mConfiguration); 12799 } 12800 } catch (Exception e) { 12801 } 12802 } 12803 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 12804 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 12805 null, false, false, MY_PID, Process.SYSTEM_UID); 12806 12807 AttributeCache ac = AttributeCache.instance(); 12808 if (ac != null) { 12809 ac.updateConfiguration(mConfiguration); 12810 } 12811 } 12812 } 12813 12814 if (changes != 0 && starting == null) { 12815 // If the configuration changed, and the caller is not already 12816 // in the process of starting an activity, then find the top 12817 // activity to check if its configuration needs to change. 12818 starting = topRunningActivityLocked(null); 12819 } 12820 12821 if (starting != null) { 12822 kept = ensureActivityConfigurationLocked(starting, changes); 12823 if (kept) { 12824 // If this didn't result in the starting activity being 12825 // destroyed, then we need to make sure at this point that all 12826 // other activities are made visible. 12827 if (DEBUG_SWITCH) Log.i(TAG, "Config didn't destroy " + starting 12828 + ", ensuring others are correct."); 12829 ensureActivitiesVisibleLocked(starting, changes); 12830 } 12831 } 12832 12833 return kept; 12834 } 12835 12836 private final boolean relaunchActivityLocked(HistoryRecord r, 12837 int changes, boolean andResume) { 12838 List<ResultInfo> results = null; 12839 List<Intent> newIntents = null; 12840 if (andResume) { 12841 results = r.results; 12842 newIntents = r.newIntents; 12843 } 12844 if (DEBUG_SWITCH) Log.v(TAG, "Relaunching: " + r 12845 + " with results=" + results + " newIntents=" + newIntents 12846 + " andResume=" + andResume); 12847 EventLog.writeEvent(andResume ? LOG_AM_RELAUNCH_RESUME_ACTIVITY 12848 : LOG_AM_RELAUNCH_ACTIVITY, System.identityHashCode(r), 12849 r.task.taskId, r.shortComponentName); 12850 12851 r.startFreezingScreenLocked(r.app, 0); 12852 12853 try { 12854 if (DEBUG_SWITCH) Log.i(TAG, "Switch is restarting resumed " + r); 12855 r.app.thread.scheduleRelaunchActivity(r, results, newIntents, 12856 changes, !andResume); 12857 // Note: don't need to call pauseIfSleepingLocked() here, because 12858 // the caller will only pass in 'andResume' if this activity is 12859 // currently resumed, which implies we aren't sleeping. 12860 } catch (RemoteException e) { 12861 return false; 12862 } 12863 12864 if (andResume) { 12865 r.results = null; 12866 r.newIntents = null; 12867 reportResumedActivityLocked(r); 12868 } 12869 12870 return true; 12871 } 12872 12873 /** 12874 * Make sure the given activity matches the current configuration. Returns 12875 * false if the activity had to be destroyed. Returns true if the 12876 * configuration is the same, or the activity will remain running as-is 12877 * for whatever reason. Ensures the HistoryRecord is updated with the 12878 * correct configuration and all other bookkeeping is handled. 12879 */ 12880 private final boolean ensureActivityConfigurationLocked(HistoryRecord r, 12881 int globalChanges) { 12882 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 12883 "Ensuring correct configuration: " + r); 12884 12885 // Short circuit: if the two configurations are the exact same 12886 // object (the common case), then there is nothing to do. 12887 Configuration newConfig = mConfiguration; 12888 if (r.configuration == newConfig) { 12889 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 12890 "Configuration unchanged in " + r); 12891 return true; 12892 } 12893 12894 // We don't worry about activities that are finishing. 12895 if (r.finishing) { 12896 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 12897 "Configuration doesn't matter in finishing " + r); 12898 r.stopFreezingScreenLocked(false); 12899 return true; 12900 } 12901 12902 // Okay we now are going to make this activity have the new config. 12903 // But then we need to figure out how it needs to deal with that. 12904 Configuration oldConfig = r.configuration; 12905 r.configuration = newConfig; 12906 12907 // If the activity isn't currently running, just leave the new 12908 // configuration and it will pick that up next time it starts. 12909 if (r.app == null || r.app.thread == null) { 12910 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 12911 "Configuration doesn't matter not running " + r); 12912 r.stopFreezingScreenLocked(false); 12913 return true; 12914 } 12915 12916 // If the activity isn't persistent, there is a chance we will 12917 // need to restart it. 12918 if (!r.persistent) { 12919 12920 // Figure out what has changed between the two configurations. 12921 int changes = oldConfig.diff(newConfig); 12922 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 12923 Log.v(TAG, "Checking to restart " + r.info.name + ": changed=0x" 12924 + Integer.toHexString(changes) + ", handles=0x" 12925 + Integer.toHexString(r.info.configChanges) 12926 + ", newConfig=" + newConfig); 12927 } 12928 if ((changes&(~r.info.configChanges)) != 0) { 12929 // Aha, the activity isn't handling the change, so DIE DIE DIE. 12930 r.configChangeFlags |= changes; 12931 r.startFreezingScreenLocked(r.app, globalChanges); 12932 if (r.app == null || r.app.thread == null) { 12933 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 12934 "Switch is destroying non-running " + r); 12935 destroyActivityLocked(r, true); 12936 } else if (r.state == ActivityState.PAUSING) { 12937 // A little annoying: we are waiting for this activity to 12938 // finish pausing. Let's not do anything now, but just 12939 // flag that it needs to be restarted when done pausing. 12940 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 12941 "Switch is skipping already pausing " + r); 12942 r.configDestroy = true; 12943 return true; 12944 } else if (r.state == ActivityState.RESUMED) { 12945 // Try to optimize this case: the configuration is changing 12946 // and we need to restart the top, resumed activity. 12947 // Instead of doing the normal handshaking, just say 12948 // "restart!". 12949 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 12950 "Switch is restarting resumed " + r); 12951 relaunchActivityLocked(r, r.configChangeFlags, true); 12952 r.configChangeFlags = 0; 12953 } else { 12954 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 12955 "Switch is restarting non-resumed " + r); 12956 relaunchActivityLocked(r, r.configChangeFlags, false); 12957 r.configChangeFlags = 0; 12958 } 12959 12960 // All done... tell the caller we weren't able to keep this 12961 // activity around. 12962 return false; 12963 } 12964 } 12965 12966 // Default case: the activity can handle this new configuration, so 12967 // hand it over. Note that we don't need to give it the new 12968 // configuration, since we always send configuration changes to all 12969 // process when they happen so it can just use whatever configuration 12970 // it last got. 12971 if (r.app != null && r.app.thread != null) { 12972 try { 12973 if (DEBUG_CONFIGURATION) Log.v(TAG, "Sending new config to " + r); 12974 r.app.thread.scheduleActivityConfigurationChanged(r); 12975 } catch (RemoteException e) { 12976 // If process died, whatever. 12977 } 12978 } 12979 r.stopFreezingScreenLocked(false); 12980 12981 return true; 12982 } 12983 12984 /** 12985 * Save the locale. You must be inside a synchronized (this) block. 12986 */ 12987 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 12988 if(isDiff) { 12989 SystemProperties.set("user.language", l.getLanguage()); 12990 SystemProperties.set("user.region", l.getCountry()); 12991 } 12992 12993 if(isPersist) { 12994 SystemProperties.set("persist.sys.language", l.getLanguage()); 12995 SystemProperties.set("persist.sys.country", l.getCountry()); 12996 SystemProperties.set("persist.sys.localevar", l.getVariant()); 12997 } 12998 } 12999 13000 // ========================================================= 13001 // LIFETIME MANAGEMENT 13002 // ========================================================= 13003 13004 private final int computeOomAdjLocked( 13005 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) { 13006 if (mAdjSeq == app.adjSeq) { 13007 // This adjustment has already been computed. 13008 return app.curAdj; 13009 } 13010 13011 if (app.thread == null) { 13012 app.adjSeq = mAdjSeq; 13013 return (app.curAdj=EMPTY_APP_ADJ); 13014 } 13015 13016 if (app.maxAdj <= FOREGROUND_APP_ADJ) { 13017 // The max adjustment doesn't allow this app to be anything 13018 // below foreground, so it is not worth doing work for it. 13019 app.adjType = "fixed"; 13020 app.adjSeq = mAdjSeq; 13021 app.curRawAdj = app.maxAdj; 13022 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 13023 return (app.curAdj=app.maxAdj); 13024 } 13025 13026 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 13027 app.adjSource = null; 13028 app.adjTarget = null; 13029 13030 // Determine the importance of the process, starting with most 13031 // important to least, and assign an appropriate OOM adjustment. 13032 int adj; 13033 int N; 13034 if (app == TOP_APP) { 13035 // The last app on the list is the foreground app. 13036 adj = FOREGROUND_APP_ADJ; 13037 app.adjType = "top-activity"; 13038 } else if (app.instrumentationClass != null) { 13039 // Don't want to kill running instrumentation. 13040 adj = FOREGROUND_APP_ADJ; 13041 app.adjType = "instrumentation"; 13042 } else if (app.persistentActivities > 0) { 13043 // Special persistent activities... shouldn't be used these days. 13044 adj = FOREGROUND_APP_ADJ; 13045 app.adjType = "persistent"; 13046 } else if (app.curReceiver != null || 13047 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) { 13048 // An app that is currently receiving a broadcast also 13049 // counts as being in the foreground. 13050 adj = FOREGROUND_APP_ADJ; 13051 app.adjType = "broadcast"; 13052 } else if (app.executingServices.size() > 0) { 13053 // An app that is currently executing a service callback also 13054 // counts as being in the foreground. 13055 adj = FOREGROUND_APP_ADJ; 13056 app.adjType = "exec-service"; 13057 } else if (app.foregroundServices) { 13058 // The user is aware of this app, so make it visible. 13059 adj = VISIBLE_APP_ADJ; 13060 app.adjType = "foreground-service"; 13061 } else if (app.forcingToForeground != null) { 13062 // The user is aware of this app, so make it visible. 13063 adj = VISIBLE_APP_ADJ; 13064 app.adjType = "force-foreground"; 13065 app.adjSource = app.forcingToForeground; 13066 } else if (app == mHomeProcess) { 13067 // This process is hosting what we currently consider to be the 13068 // home app, so we don't want to let it go into the background. 13069 adj = HOME_APP_ADJ; 13070 app.adjType = "home"; 13071 } else if ((N=app.activities.size()) != 0) { 13072 // This app is in the background with paused activities. 13073 adj = hiddenAdj; 13074 app.adjType = "bg-activities"; 13075 for (int j=0; j<N; j++) { 13076 if (((HistoryRecord)app.activities.get(j)).visible) { 13077 // This app has a visible activity! 13078 adj = VISIBLE_APP_ADJ; 13079 app.adjType = "visible"; 13080 break; 13081 } 13082 } 13083 } else { 13084 // A very not-needed process. 13085 adj = EMPTY_APP_ADJ; 13086 app.adjType = "empty"; 13087 } 13088 13089 // By default, we use the computed adjustment. It may be changed if 13090 // there are applications dependent on our services or providers, but 13091 // this gives us a baseline and makes sure we don't get into an 13092 // infinite recursion. 13093 app.adjSeq = mAdjSeq; 13094 app.curRawAdj = adj; 13095 app.curAdj = adj <= app.maxAdj ? adj : app.maxAdj; 13096 13097 if (mBackupTarget != null && app == mBackupTarget.app) { 13098 // If possible we want to avoid killing apps while they're being backed up 13099 if (adj > BACKUP_APP_ADJ) { 13100 if (DEBUG_BACKUP) Log.v(TAG, "oom BACKUP_APP_ADJ for " + app); 13101 adj = BACKUP_APP_ADJ; 13102 app.adjType = "backup"; 13103 } 13104 } 13105 13106 if (app.services.size() != 0 && adj > FOREGROUND_APP_ADJ) { 13107 final long now = SystemClock.uptimeMillis(); 13108 // This process is more important if the top activity is 13109 // bound to the service. 13110 Iterator jt = app.services.iterator(); 13111 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) { 13112 ServiceRecord s = (ServiceRecord)jt.next(); 13113 if (s.startRequested) { 13114 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) { 13115 // This service has seen some activity within 13116 // recent memory, so we will keep its process ahead 13117 // of the background processes. 13118 if (adj > SECONDARY_SERVER_ADJ) { 13119 adj = SECONDARY_SERVER_ADJ; 13120 app.adjType = "started-services"; 13121 } 13122 } 13123 } 13124 if (s.connections.size() > 0 && adj > FOREGROUND_APP_ADJ) { 13125 Iterator<ConnectionRecord> kt 13126 = s.connections.values().iterator(); 13127 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) { 13128 // XXX should compute this based on the max of 13129 // all connected clients. 13130 ConnectionRecord cr = kt.next(); 13131 if (cr.binding.client == app) { 13132 // Binding to ourself is not interesting. 13133 continue; 13134 } 13135 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) { 13136 ProcessRecord client = cr.binding.client; 13137 int myHiddenAdj = hiddenAdj; 13138 if (myHiddenAdj > client.hiddenAdj) { 13139 if (client.hiddenAdj > VISIBLE_APP_ADJ) { 13140 myHiddenAdj = client.hiddenAdj; 13141 } else { 13142 myHiddenAdj = VISIBLE_APP_ADJ; 13143 } 13144 } 13145 int clientAdj = computeOomAdjLocked( 13146 client, myHiddenAdj, TOP_APP); 13147 if (adj > clientAdj) { 13148 adj = clientAdj > VISIBLE_APP_ADJ 13149 ? clientAdj : VISIBLE_APP_ADJ; 13150 app.adjType = "service"; 13151 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13152 .REASON_SERVICE_IN_USE; 13153 app.adjSource = cr.binding.client; 13154 app.adjTarget = s.serviceInfo.name; 13155 } 13156 } 13157 HistoryRecord a = cr.activity; 13158 //if (a != null) { 13159 // Log.i(TAG, "Connection to " + a ": state=" + a.state); 13160 //} 13161 if (a != null && adj > FOREGROUND_APP_ADJ && 13162 (a.state == ActivityState.RESUMED 13163 || a.state == ActivityState.PAUSING)) { 13164 adj = FOREGROUND_APP_ADJ; 13165 app.adjType = "service"; 13166 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13167 .REASON_SERVICE_IN_USE; 13168 app.adjSource = a; 13169 app.adjTarget = s.serviceInfo.name; 13170 } 13171 } 13172 } 13173 } 13174 13175 // Finally, f this process has active services running in it, we 13176 // would like to avoid killing it unless it would prevent the current 13177 // application from running. By default we put the process in 13178 // with the rest of the background processes; as we scan through 13179 // its services we may bump it up from there. 13180 if (adj > hiddenAdj) { 13181 adj = hiddenAdj; 13182 app.adjType = "bg-services"; 13183 } 13184 } 13185 13186 if (app.pubProviders.size() != 0 && adj > FOREGROUND_APP_ADJ) { 13187 Iterator jt = app.pubProviders.values().iterator(); 13188 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) { 13189 ContentProviderRecord cpr = (ContentProviderRecord)jt.next(); 13190 if (cpr.clients.size() != 0) { 13191 Iterator<ProcessRecord> kt = cpr.clients.iterator(); 13192 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) { 13193 ProcessRecord client = kt.next(); 13194 if (client == app) { 13195 // Being our own client is not interesting. 13196 continue; 13197 } 13198 int myHiddenAdj = hiddenAdj; 13199 if (myHiddenAdj > client.hiddenAdj) { 13200 if (client.hiddenAdj > FOREGROUND_APP_ADJ) { 13201 myHiddenAdj = client.hiddenAdj; 13202 } else { 13203 myHiddenAdj = FOREGROUND_APP_ADJ; 13204 } 13205 } 13206 int clientAdj = computeOomAdjLocked( 13207 client, myHiddenAdj, TOP_APP); 13208 if (adj > clientAdj) { 13209 adj = clientAdj > FOREGROUND_APP_ADJ 13210 ? clientAdj : FOREGROUND_APP_ADJ; 13211 app.adjType = "provider"; 13212 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13213 .REASON_PROVIDER_IN_USE; 13214 app.adjSource = client; 13215 app.adjTarget = cpr.info.name; 13216 } 13217 } 13218 } 13219 // If the provider has external (non-framework) process 13220 // dependencies, ensure that its adjustment is at least 13221 // FOREGROUND_APP_ADJ. 13222 if (cpr.externals != 0) { 13223 if (adj > FOREGROUND_APP_ADJ) { 13224 adj = FOREGROUND_APP_ADJ; 13225 app.adjType = "provider"; 13226 app.adjTarget = cpr.info.name; 13227 } 13228 } 13229 } 13230 13231 // Finally, if this process has published any content providers, 13232 // then its adjustment makes it at least as important as any of the 13233 // processes using those providers, and no less important than 13234 // CONTENT_PROVIDER_ADJ, which is just shy of EMPTY. 13235 if (adj > CONTENT_PROVIDER_ADJ) { 13236 adj = CONTENT_PROVIDER_ADJ; 13237 app.adjType = "pub-providers"; 13238 } 13239 } 13240 13241 app.curRawAdj = adj; 13242 13243 //Log.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 13244 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 13245 if (adj > app.maxAdj) { 13246 adj = app.maxAdj; 13247 } 13248 13249 app.curAdj = adj; 13250 app.curSchedGroup = adj > VISIBLE_APP_ADJ 13251 ? Process.THREAD_GROUP_BG_NONINTERACTIVE 13252 : Process.THREAD_GROUP_DEFAULT; 13253 13254 return adj; 13255 } 13256 13257 /** 13258 * Ask a given process to GC right now. 13259 */ 13260 final void performAppGcLocked(ProcessRecord app) { 13261 try { 13262 app.lastRequestedGc = SystemClock.uptimeMillis(); 13263 if (app.thread != null) { 13264 if (app.reportLowMemory) { 13265 app.reportLowMemory = false; 13266 app.thread.scheduleLowMemory(); 13267 } else { 13268 app.thread.processInBackground(); 13269 } 13270 } 13271 } catch (Exception e) { 13272 // whatever. 13273 } 13274 } 13275 13276 /** 13277 * Returns true if things are idle enough to perform GCs. 13278 */ 13279 private final boolean canGcNow() { 13280 return mParallelBroadcasts.size() == 0 13281 && mOrderedBroadcasts.size() == 0 13282 && (mSleeping || (mResumedActivity != null && 13283 mResumedActivity.idle)); 13284 } 13285 13286 /** 13287 * Perform GCs on all processes that are waiting for it, but only 13288 * if things are idle. 13289 */ 13290 final void performAppGcsLocked() { 13291 final int N = mProcessesToGc.size(); 13292 if (N <= 0) { 13293 return; 13294 } 13295 if (canGcNow()) { 13296 while (mProcessesToGc.size() > 0) { 13297 ProcessRecord proc = mProcessesToGc.remove(0); 13298 if (proc.curRawAdj > VISIBLE_APP_ADJ || proc.reportLowMemory) { 13299 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 13300 <= SystemClock.uptimeMillis()) { 13301 // To avoid spamming the system, we will GC processes one 13302 // at a time, waiting a few seconds between each. 13303 performAppGcLocked(proc); 13304 scheduleAppGcsLocked(); 13305 return; 13306 } else { 13307 // It hasn't been long enough since we last GCed this 13308 // process... put it in the list to wait for its time. 13309 addProcessToGcListLocked(proc); 13310 break; 13311 } 13312 } 13313 } 13314 13315 scheduleAppGcsLocked(); 13316 } 13317 } 13318 13319 /** 13320 * If all looks good, perform GCs on all processes waiting for them. 13321 */ 13322 final void performAppGcsIfAppropriateLocked() { 13323 if (canGcNow()) { 13324 performAppGcsLocked(); 13325 return; 13326 } 13327 // Still not idle, wait some more. 13328 scheduleAppGcsLocked(); 13329 } 13330 13331 /** 13332 * Schedule the execution of all pending app GCs. 13333 */ 13334 final void scheduleAppGcsLocked() { 13335 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 13336 13337 if (mProcessesToGc.size() > 0) { 13338 // Schedule a GC for the time to the next process. 13339 ProcessRecord proc = mProcessesToGc.get(0); 13340 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 13341 13342 long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL; 13343 long now = SystemClock.uptimeMillis(); 13344 if (when < (now+GC_TIMEOUT)) { 13345 when = now + GC_TIMEOUT; 13346 } 13347 mHandler.sendMessageAtTime(msg, when); 13348 } 13349 } 13350 13351 /** 13352 * Add a process to the array of processes waiting to be GCed. Keeps the 13353 * list in sorted order by the last GC time. The process can't already be 13354 * on the list. 13355 */ 13356 final void addProcessToGcListLocked(ProcessRecord proc) { 13357 boolean added = false; 13358 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 13359 if (mProcessesToGc.get(i).lastRequestedGc < 13360 proc.lastRequestedGc) { 13361 added = true; 13362 mProcessesToGc.add(i+1, proc); 13363 break; 13364 } 13365 } 13366 if (!added) { 13367 mProcessesToGc.add(0, proc); 13368 } 13369 } 13370 13371 /** 13372 * Set up to ask a process to GC itself. This will either do it 13373 * immediately, or put it on the list of processes to gc the next 13374 * time things are idle. 13375 */ 13376 final void scheduleAppGcLocked(ProcessRecord app) { 13377 long now = SystemClock.uptimeMillis(); 13378 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 13379 return; 13380 } 13381 if (!mProcessesToGc.contains(app)) { 13382 addProcessToGcListLocked(app); 13383 scheduleAppGcsLocked(); 13384 } 13385 } 13386 13387 private final boolean updateOomAdjLocked( 13388 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) { 13389 app.hiddenAdj = hiddenAdj; 13390 13391 if (app.thread == null) { 13392 return true; 13393 } 13394 13395 int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP); 13396 13397 if (app.pid != 0 && app.pid != MY_PID) { 13398 if (app.curRawAdj != app.setRawAdj) { 13399 if (app.curRawAdj > FOREGROUND_APP_ADJ 13400 && app.setRawAdj <= FOREGROUND_APP_ADJ) { 13401 // If this app is transitioning from foreground to 13402 // non-foreground, have it do a gc. 13403 scheduleAppGcLocked(app); 13404 } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ 13405 && app.setRawAdj < HIDDEN_APP_MIN_ADJ) { 13406 // Likewise do a gc when an app is moving in to the 13407 // background (such as a service stopping). 13408 scheduleAppGcLocked(app); 13409 } 13410 app.setRawAdj = app.curRawAdj; 13411 } 13412 if (adj != app.setAdj) { 13413 if (Process.setOomAdj(app.pid, adj)) { 13414 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v( 13415 TAG, "Set app " + app.processName + 13416 " oom adj to " + adj); 13417 app.setAdj = adj; 13418 } else { 13419 return false; 13420 } 13421 } 13422 if (app.setSchedGroup != app.curSchedGroup) { 13423 app.setSchedGroup = app.curSchedGroup; 13424 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v(TAG, 13425 "Setting process group of " + app.processName 13426 + " to " + app.curSchedGroup); 13427 if (true) { 13428 long oldId = Binder.clearCallingIdentity(); 13429 try { 13430 Process.setProcessGroup(app.pid, app.curSchedGroup); 13431 } catch (Exception e) { 13432 Log.w(TAG, "Failed setting process group of " + app.pid 13433 + " to " + app.curSchedGroup); 13434 e.printStackTrace(); 13435 } finally { 13436 Binder.restoreCallingIdentity(oldId); 13437 } 13438 } 13439 if (false) { 13440 if (app.thread != null) { 13441 try { 13442 app.thread.setSchedulingGroup(app.curSchedGroup); 13443 } catch (RemoteException e) { 13444 } 13445 } 13446 } 13447 } 13448 } 13449 13450 return true; 13451 } 13452 13453 private final HistoryRecord resumedAppLocked() { 13454 HistoryRecord resumedActivity = mResumedActivity; 13455 if (resumedActivity == null || resumedActivity.app == null) { 13456 resumedActivity = mPausingActivity; 13457 if (resumedActivity == null || resumedActivity.app == null) { 13458 resumedActivity = topRunningActivityLocked(null); 13459 } 13460 } 13461 return resumedActivity; 13462 } 13463 13464 private final boolean updateOomAdjLocked(ProcessRecord app) { 13465 final HistoryRecord TOP_ACT = resumedAppLocked(); 13466 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13467 int curAdj = app.curAdj; 13468 final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ 13469 && app.curAdj <= HIDDEN_APP_MAX_ADJ; 13470 13471 mAdjSeq++; 13472 13473 final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP); 13474 if (res) { 13475 final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ 13476 && app.curAdj <= HIDDEN_APP_MAX_ADJ; 13477 if (nowHidden != wasHidden) { 13478 // Changed to/from hidden state, so apps after it in the LRU 13479 // list may also be changed. 13480 updateOomAdjLocked(); 13481 } 13482 } 13483 return res; 13484 } 13485 13486 private final boolean updateOomAdjLocked() { 13487 boolean didOomAdj = true; 13488 final HistoryRecord TOP_ACT = resumedAppLocked(); 13489 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13490 13491 if (false) { 13492 RuntimeException e = new RuntimeException(); 13493 e.fillInStackTrace(); 13494 Log.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13495 } 13496 13497 mAdjSeq++; 13498 13499 // First try updating the OOM adjustment for each of the 13500 // application processes based on their current state. 13501 int i = mLRUProcesses.size(); 13502 int curHiddenAdj = HIDDEN_APP_MIN_ADJ; 13503 while (i > 0) { 13504 i--; 13505 ProcessRecord app = mLRUProcesses.get(i); 13506 if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) { 13507 if (curHiddenAdj < HIDDEN_APP_MAX_ADJ 13508 && app.curAdj == curHiddenAdj) { 13509 curHiddenAdj++; 13510 } 13511 } else { 13512 didOomAdj = false; 13513 } 13514 } 13515 13516 // todo: for now pretend like OOM ADJ didn't work, because things 13517 // aren't behaving as expected on Linux -- it's not killing processes. 13518 return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj; 13519 } 13520 13521 private final void trimApplications() { 13522 synchronized (this) { 13523 int i; 13524 13525 // First remove any unused application processes whose package 13526 // has been removed. 13527 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13528 final ProcessRecord app = mRemovedProcesses.get(i); 13529 if (app.activities.size() == 0 13530 && app.curReceiver == null && app.services.size() == 0) { 13531 Log.i( 13532 TAG, "Exiting empty application process " 13533 + app.processName + " (" 13534 + (app.thread != null ? app.thread.asBinder() : null) 13535 + ")\n"); 13536 if (app.pid > 0 && app.pid != MY_PID) { 13537 Process.killProcess(app.pid); 13538 } else { 13539 try { 13540 app.thread.scheduleExit(); 13541 } catch (Exception e) { 13542 // Ignore exceptions. 13543 } 13544 } 13545 cleanUpApplicationRecordLocked(app, false, -1); 13546 mRemovedProcesses.remove(i); 13547 13548 if (app.persistent) { 13549 if (app.persistent) { 13550 addAppLocked(app.info); 13551 } 13552 } 13553 } 13554 } 13555 13556 // Now try updating the OOM adjustment for each of the 13557 // application processes based on their current state. 13558 // If the setOomAdj() API is not supported, then go with our 13559 // back-up plan... 13560 if (!updateOomAdjLocked()) { 13561 13562 // Count how many processes are running services. 13563 int numServiceProcs = 0; 13564 for (i=mLRUProcesses.size()-1; i>=0; i--) { 13565 final ProcessRecord app = mLRUProcesses.get(i); 13566 13567 if (app.persistent || app.services.size() != 0 13568 || app.curReceiver != null 13569 || app.persistentActivities > 0) { 13570 // Don't count processes holding services against our 13571 // maximum process count. 13572 if (localLOGV) Log.v( 13573 TAG, "Not trimming app " + app + " with services: " 13574 + app.services); 13575 numServiceProcs++; 13576 } 13577 } 13578 13579 int curMaxProcs = mProcessLimit; 13580 if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES; 13581 if (mAlwaysFinishActivities) { 13582 curMaxProcs = 1; 13583 } 13584 curMaxProcs += numServiceProcs; 13585 13586 // Quit as many processes as we can to get down to the desired 13587 // process count. First remove any processes that no longer 13588 // have activites running in them. 13589 for ( i=0; 13590 i<mLRUProcesses.size() 13591 && mLRUProcesses.size() > curMaxProcs; 13592 i++) { 13593 final ProcessRecord app = mLRUProcesses.get(i); 13594 // Quit an application only if it is not currently 13595 // running any activities. 13596 if (!app.persistent && app.activities.size() == 0 13597 && app.curReceiver == null && app.services.size() == 0) { 13598 Log.i( 13599 TAG, "Exiting empty application process " 13600 + app.processName + " (" 13601 + (app.thread != null ? app.thread.asBinder() : null) 13602 + ")\n"); 13603 if (app.pid > 0 && app.pid != MY_PID) { 13604 Process.killProcess(app.pid); 13605 } else { 13606 try { 13607 app.thread.scheduleExit(); 13608 } catch (Exception e) { 13609 // Ignore exceptions. 13610 } 13611 } 13612 // todo: For now we assume the application is not buggy 13613 // or evil, and will quit as a result of our request. 13614 // Eventually we need to drive this off of the death 13615 // notification, and kill the process if it takes too long. 13616 cleanUpApplicationRecordLocked(app, false, i); 13617 i--; 13618 } 13619 } 13620 13621 // If we still have too many processes, now from the least 13622 // recently used process we start finishing activities. 13623 if (Config.LOGV) Log.v( 13624 TAG, "*** NOW HAVE " + mLRUProcesses.size() + 13625 " of " + curMaxProcs + " processes"); 13626 for ( i=0; 13627 i<mLRUProcesses.size() 13628 && mLRUProcesses.size() > curMaxProcs; 13629 i++) { 13630 final ProcessRecord app = mLRUProcesses.get(i); 13631 // Quit the application only if we have a state saved for 13632 // all of its activities. 13633 boolean canQuit = !app.persistent && app.curReceiver == null 13634 && app.services.size() == 0 13635 && app.persistentActivities == 0; 13636 int NUMA = app.activities.size(); 13637 int j; 13638 if (Config.LOGV) Log.v( 13639 TAG, "Looking to quit " + app.processName); 13640 for (j=0; j<NUMA && canQuit; j++) { 13641 HistoryRecord r = (HistoryRecord)app.activities.get(j); 13642 if (Config.LOGV) Log.v( 13643 TAG, " " + r.intent.getComponent().flattenToShortString() 13644 + ": frozen=" + r.haveState + ", visible=" + r.visible); 13645 canQuit = (r.haveState || !r.stateNotNeeded) 13646 && !r.visible && r.stopped; 13647 } 13648 if (canQuit) { 13649 // Finish all of the activities, and then the app itself. 13650 for (j=0; j<NUMA; j++) { 13651 HistoryRecord r = (HistoryRecord)app.activities.get(j); 13652 if (!r.finishing) { 13653 destroyActivityLocked(r, false); 13654 } 13655 r.resultTo = null; 13656 } 13657 Log.i(TAG, "Exiting application process " 13658 + app.processName + " (" 13659 + (app.thread != null ? app.thread.asBinder() : null) 13660 + ")\n"); 13661 if (app.pid > 0 && app.pid != MY_PID) { 13662 Process.killProcess(app.pid); 13663 } else { 13664 try { 13665 app.thread.scheduleExit(); 13666 } catch (Exception e) { 13667 // Ignore exceptions. 13668 } 13669 } 13670 // todo: For now we assume the application is not buggy 13671 // or evil, and will quit as a result of our request. 13672 // Eventually we need to drive this off of the death 13673 // notification, and kill the process if it takes too long. 13674 cleanUpApplicationRecordLocked(app, false, i); 13675 i--; 13676 //dump(); 13677 } 13678 } 13679 13680 } 13681 13682 int curMaxActivities = MAX_ACTIVITIES; 13683 if (mAlwaysFinishActivities) { 13684 curMaxActivities = 1; 13685 } 13686 13687 // Finally, if there are too many activities now running, try to 13688 // finish as many as we can to get back down to the limit. 13689 for ( i=0; 13690 i<mLRUActivities.size() 13691 && mLRUActivities.size() > curMaxActivities; 13692 i++) { 13693 final HistoryRecord r 13694 = (HistoryRecord)mLRUActivities.get(i); 13695 13696 // We can finish this one if we have its icicle saved and 13697 // it is not persistent. 13698 if ((r.haveState || !r.stateNotNeeded) && !r.visible 13699 && r.stopped && !r.persistent && !r.finishing) { 13700 final int origSize = mLRUActivities.size(); 13701 destroyActivityLocked(r, true); 13702 13703 // This will remove it from the LRU list, so keep 13704 // our index at the same value. Note that this check to 13705 // see if the size changes is just paranoia -- if 13706 // something unexpected happens, we don't want to end up 13707 // in an infinite loop. 13708 if (origSize > mLRUActivities.size()) { 13709 i--; 13710 } 13711 } 13712 } 13713 } 13714 } 13715 13716 /** This method sends the specified signal to each of the persistent apps */ 13717 public void signalPersistentProcesses(int sig) throws RemoteException { 13718 if (sig != Process.SIGNAL_USR1) { 13719 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13720 } 13721 13722 synchronized (this) { 13723 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13724 != PackageManager.PERMISSION_GRANTED) { 13725 throw new SecurityException("Requires permission " 13726 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13727 } 13728 13729 for (int i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) { 13730 ProcessRecord r = mLRUProcesses.get(i); 13731 if (r.thread != null && r.persistent) { 13732 Process.sendSignal(r.pid, sig); 13733 } 13734 } 13735 } 13736 } 13737 13738 public boolean profileControl(String process, boolean start, 13739 String path, ParcelFileDescriptor fd) throws RemoteException { 13740 13741 try { 13742 synchronized (this) { 13743 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13744 // its own permission. 13745 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13746 != PackageManager.PERMISSION_GRANTED) { 13747 throw new SecurityException("Requires permission " 13748 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13749 } 13750 13751 if (start && fd == null) { 13752 throw new IllegalArgumentException("null fd"); 13753 } 13754 13755 ProcessRecord proc = null; 13756 try { 13757 int pid = Integer.parseInt(process); 13758 synchronized (mPidsSelfLocked) { 13759 proc = mPidsSelfLocked.get(pid); 13760 } 13761 } catch (NumberFormatException e) { 13762 } 13763 13764 if (proc == null) { 13765 HashMap<String, SparseArray<ProcessRecord>> all 13766 = mProcessNames.getMap(); 13767 SparseArray<ProcessRecord> procs = all.get(process); 13768 if (procs != null && procs.size() > 0) { 13769 proc = procs.valueAt(0); 13770 } 13771 } 13772 13773 if (proc == null || proc.thread == null) { 13774 throw new IllegalArgumentException("Unknown process: " + process); 13775 } 13776 13777 boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0")); 13778 if (isSecure) { 13779 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13780 throw new SecurityException("Process not debuggable: " + proc); 13781 } 13782 } 13783 13784 proc.thread.profilerControl(start, path, fd); 13785 fd = null; 13786 return true; 13787 } 13788 } catch (RemoteException e) { 13789 throw new IllegalStateException("Process disappeared"); 13790 } finally { 13791 if (fd != null) { 13792 try { 13793 fd.close(); 13794 } catch (IOException e) { 13795 } 13796 } 13797 } 13798 } 13799 13800 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13801 public void monitor() { 13802 synchronized (this) { } 13803 } 13804} 13805