ActivityManagerService.java revision dc6b635cfa440454985461444c3cf1da8078cee1
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 || true; 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); 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); 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 MY_PID = Process.myPid(); 1440 1441 File dataDir = Environment.getDataDirectory(); 1442 File systemDir = new File(dataDir, "system"); 1443 systemDir.mkdirs(); 1444 mBatteryStatsService = new BatteryStatsService(new File( 1445 systemDir, "batterystats.bin").toString()); 1446 mBatteryStatsService.getActiveStatistics().readLocked(); 1447 mBatteryStatsService.getActiveStatistics().writeLocked(); 1448 1449 mUsageStatsService = new UsageStatsService( new File( 1450 systemDir, "usagestats").toString()); 1451 1452 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1453 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1454 1455 mConfiguration.makeDefault(); 1456 mProcessStats.init(); 1457 1458 // Add ourself to the Watchdog monitors. 1459 Watchdog.getInstance().addMonitor(this); 1460 1461 // These values are set in system/rootdir/init.rc on startup. 1462 FOREGROUND_APP_ADJ = 1463 Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_ADJ")); 1464 VISIBLE_APP_ADJ = 1465 Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_ADJ")); 1466 SECONDARY_SERVER_ADJ = 1467 Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_ADJ")); 1468 BACKUP_APP_ADJ = 1469 Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_ADJ")); 1470 HOME_APP_ADJ = 1471 Integer.valueOf(SystemProperties.get("ro.HOME_APP_ADJ")); 1472 HIDDEN_APP_MIN_ADJ = 1473 Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MIN_ADJ")); 1474 CONTENT_PROVIDER_ADJ = 1475 Integer.valueOf(SystemProperties.get("ro.CONTENT_PROVIDER_ADJ")); 1476 HIDDEN_APP_MAX_ADJ = CONTENT_PROVIDER_ADJ-1; 1477 EMPTY_APP_ADJ = 1478 Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_ADJ")); 1479 FOREGROUND_APP_MEM = 1480 Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_MEM"))*PAGE_SIZE; 1481 VISIBLE_APP_MEM = 1482 Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_MEM"))*PAGE_SIZE; 1483 SECONDARY_SERVER_MEM = 1484 Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_MEM"))*PAGE_SIZE; 1485 BACKUP_APP_MEM = 1486 Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_MEM"))*PAGE_SIZE; 1487 HOME_APP_MEM = 1488 Integer.valueOf(SystemProperties.get("ro.HOME_APP_MEM"))*PAGE_SIZE; 1489 HIDDEN_APP_MEM = 1490 Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MEM"))*PAGE_SIZE; 1491 EMPTY_APP_MEM = 1492 Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_MEM"))*PAGE_SIZE; 1493 1494 mProcessStatsThread = new Thread("ProcessStats") { 1495 public void run() { 1496 while (true) { 1497 try { 1498 try { 1499 synchronized(this) { 1500 final long now = SystemClock.uptimeMillis(); 1501 long nextCpuDelay = (mLastCpuTime+MONITOR_CPU_MAX_TIME)-now; 1502 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1503 //Log.i(TAG, "Cpu delay=" + nextCpuDelay 1504 // + ", write delay=" + nextWriteDelay); 1505 if (nextWriteDelay < nextCpuDelay) { 1506 nextCpuDelay = nextWriteDelay; 1507 } 1508 if (nextCpuDelay > 0) { 1509 this.wait(nextCpuDelay); 1510 } 1511 } 1512 } catch (InterruptedException e) { 1513 } 1514 1515 updateCpuStatsNow(); 1516 } catch (Exception e) { 1517 Log.e(TAG, "Unexpected exception collecting process stats", e); 1518 } 1519 } 1520 } 1521 }; 1522 mProcessStatsThread.start(); 1523 } 1524 1525 @Override 1526 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1527 throws RemoteException { 1528 try { 1529 return super.onTransact(code, data, reply, flags); 1530 } catch (RuntimeException e) { 1531 // The activity manager only throws security exceptions, so let's 1532 // log all others. 1533 if (!(e instanceof SecurityException)) { 1534 Log.e(TAG, "Activity Manager Crash", e); 1535 } 1536 throw e; 1537 } 1538 } 1539 1540 void updateCpuStats() { 1541 synchronized (mProcessStatsThread) { 1542 final long now = SystemClock.uptimeMillis(); 1543 if (mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) { 1544 mProcessStatsThread.notify(); 1545 } 1546 } 1547 } 1548 1549 void updateCpuStatsNow() { 1550 synchronized (mProcessStatsThread) { 1551 final long now = SystemClock.uptimeMillis(); 1552 boolean haveNewCpuStats = false; 1553 1554 if (MONITOR_CPU_USAGE && 1555 mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) { 1556 mLastCpuTime = now; 1557 haveNewCpuStats = true; 1558 mProcessStats.update(); 1559 //Log.i(TAG, mProcessStats.printCurrentState()); 1560 //Log.i(TAG, "Total CPU usage: " 1561 // + mProcessStats.getTotalCpuPercent() + "%"); 1562 1563 // Log the cpu usage if the property is set. 1564 if ("true".equals(SystemProperties.get("events.cpu"))) { 1565 int user = mProcessStats.getLastUserTime(); 1566 int system = mProcessStats.getLastSystemTime(); 1567 int iowait = mProcessStats.getLastIoWaitTime(); 1568 int irq = mProcessStats.getLastIrqTime(); 1569 int softIrq = mProcessStats.getLastSoftIrqTime(); 1570 int idle = mProcessStats.getLastIdleTime(); 1571 1572 int total = user + system + iowait + irq + softIrq + idle; 1573 if (total == 0) total = 1; 1574 1575 EventLog.writeEvent(LOG_CPU, 1576 ((user+system+iowait+irq+softIrq) * 100) / total, 1577 (user * 100) / total, 1578 (system * 100) / total, 1579 (iowait * 100) / total, 1580 (irq * 100) / total, 1581 (softIrq * 100) / total); 1582 } 1583 } 1584 1585 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1586 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1587 synchronized(bstats) { 1588 synchronized(mPidsSelfLocked) { 1589 if (haveNewCpuStats) { 1590 if (mBatteryStatsService.isOnBattery()) { 1591 final int N = mProcessStats.countWorkingStats(); 1592 for (int i=0; i<N; i++) { 1593 ProcessStats.Stats st 1594 = mProcessStats.getWorkingStats(i); 1595 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1596 if (pr != null) { 1597 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1598 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); 1599 ps.addSpeedStepTimes(cpuSpeedTimes); 1600 } else { 1601 BatteryStatsImpl.Uid.Proc ps = 1602 bstats.getProcessStatsLocked(st.name, st.pid); 1603 if (ps != null) { 1604 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); 1605 ps.addSpeedStepTimes(cpuSpeedTimes); 1606 } 1607 } 1608 } 1609 } 1610 } 1611 } 1612 1613 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1614 mLastWriteTime = now; 1615 mBatteryStatsService.getActiveStatistics().writeLocked(); 1616 } 1617 } 1618 } 1619 } 1620 1621 /** 1622 * Initialize the application bind args. These are passed to each 1623 * process when the bindApplication() IPC is sent to the process. They're 1624 * lazily setup to make sure the services are running when they're asked for. 1625 */ 1626 private HashMap<String, IBinder> getCommonServicesLocked() { 1627 if (mAppBindArgs == null) { 1628 mAppBindArgs = new HashMap<String, IBinder>(); 1629 1630 // Setup the application init args 1631 mAppBindArgs.put("package", ServiceManager.getService("package")); 1632 mAppBindArgs.put("window", ServiceManager.getService("window")); 1633 mAppBindArgs.put(Context.ALARM_SERVICE, 1634 ServiceManager.getService(Context.ALARM_SERVICE)); 1635 } 1636 return mAppBindArgs; 1637 } 1638 1639 private final void setFocusedActivityLocked(HistoryRecord r) { 1640 if (mFocusedActivity != r) { 1641 mFocusedActivity = r; 1642 mWindowManager.setFocusedApp(r, true); 1643 } 1644 } 1645 1646 private final void updateLRUListLocked(ProcessRecord app, 1647 boolean oomAdj) { 1648 // put it on the LRU to keep track of when it should be exited. 1649 int lrui = mLRUProcesses.indexOf(app); 1650 if (lrui >= 0) mLRUProcesses.remove(lrui); 1651 mLRUProcesses.add(app); 1652 //Log.i(TAG, "Putting proc to front: " + app.processName); 1653 if (oomAdj) { 1654 updateOomAdjLocked(); 1655 } 1656 } 1657 1658 private final boolean updateLRUListLocked(HistoryRecord r) { 1659 final boolean hadit = mLRUActivities.remove(r); 1660 mLRUActivities.add(r); 1661 return hadit; 1662 } 1663 1664 private final HistoryRecord topRunningActivityLocked(HistoryRecord notTop) { 1665 int i = mHistory.size()-1; 1666 while (i >= 0) { 1667 HistoryRecord r = (HistoryRecord)mHistory.get(i); 1668 if (!r.finishing && r != notTop) { 1669 return r; 1670 } 1671 i--; 1672 } 1673 return null; 1674 } 1675 1676 private final HistoryRecord topRunningNonDelayedActivityLocked(HistoryRecord notTop) { 1677 int i = mHistory.size()-1; 1678 while (i >= 0) { 1679 HistoryRecord r = (HistoryRecord)mHistory.get(i); 1680 if (!r.finishing && !r.delayedResume && r != notTop) { 1681 return r; 1682 } 1683 i--; 1684 } 1685 return null; 1686 } 1687 1688 /** 1689 * This is a simplified version of topRunningActivityLocked that provides a number of 1690 * optional skip-over modes. It is intended for use with the ActivityController hook only. 1691 * 1692 * @param token If non-null, any history records matching this token will be skipped. 1693 * @param taskId If non-zero, we'll attempt to skip over records with the same task ID. 1694 * 1695 * @return Returns the HistoryRecord of the next activity on the stack. 1696 */ 1697 private final HistoryRecord topRunningActivityLocked(IBinder token, int taskId) { 1698 int i = mHistory.size()-1; 1699 while (i >= 0) { 1700 HistoryRecord r = (HistoryRecord)mHistory.get(i); 1701 // Note: the taskId check depends on real taskId fields being non-zero 1702 if (!r.finishing && (token != r) && (taskId != r.task.taskId)) { 1703 return r; 1704 } 1705 i--; 1706 } 1707 return null; 1708 } 1709 1710 private final ProcessRecord getProcessRecordLocked( 1711 String processName, int uid) { 1712 if (uid == Process.SYSTEM_UID) { 1713 // The system gets to run in any process. If there are multiple 1714 // processes with the same uid, just pick the first (this 1715 // should never happen). 1716 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1717 processName); 1718 return procs != null ? procs.valueAt(0) : null; 1719 } 1720 ProcessRecord proc = mProcessNames.get(processName, uid); 1721 return proc; 1722 } 1723 1724 private void ensurePackageDexOpt(String packageName) { 1725 IPackageManager pm = ActivityThread.getPackageManager(); 1726 try { 1727 if (pm.performDexOpt(packageName)) { 1728 mDidDexOpt = true; 1729 } 1730 } catch (RemoteException e) { 1731 } 1732 } 1733 1734 private boolean isNextTransitionForward() { 1735 int transit = mWindowManager.getPendingAppTransition(); 1736 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1737 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1738 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1739 } 1740 1741 private final boolean realStartActivityLocked(HistoryRecord r, 1742 ProcessRecord app, boolean andResume, boolean checkConfig) 1743 throws RemoteException { 1744 1745 r.startFreezingScreenLocked(app, 0); 1746 mWindowManager.setAppVisibility(r, true); 1747 1748 // Have the window manager re-evaluate the orientation of 1749 // the screen based on the new activity order. Note that 1750 // as a result of this, it can call back into the activity 1751 // manager with a new orientation. We don't care about that, 1752 // because the activity is not currently running so we are 1753 // just restarting it anyway. 1754 if (checkConfig) { 1755 Configuration config = mWindowManager.updateOrientationFromAppTokens( 1756 mConfiguration, 1757 r.mayFreezeScreenLocked(app) ? r : null); 1758 updateConfigurationLocked(config, r); 1759 } 1760 1761 r.app = app; 1762 1763 if (localLOGV) Log.v(TAG, "Launching: " + r); 1764 1765 int idx = app.activities.indexOf(r); 1766 if (idx < 0) { 1767 app.activities.add(r); 1768 } 1769 updateLRUListLocked(app, true); 1770 1771 try { 1772 if (app.thread == null) { 1773 throw new RemoteException(); 1774 } 1775 List<ResultInfo> results = null; 1776 List<Intent> newIntents = null; 1777 if (andResume) { 1778 results = r.results; 1779 newIntents = r.newIntents; 1780 } 1781 if (DEBUG_SWITCH) Log.v(TAG, "Launching: " + r 1782 + " icicle=" + r.icicle 1783 + " with results=" + results + " newIntents=" + newIntents 1784 + " andResume=" + andResume); 1785 if (andResume) { 1786 EventLog.writeEvent(LOG_AM_RESTART_ACTIVITY, 1787 System.identityHashCode(r), 1788 r.task.taskId, r.shortComponentName); 1789 } 1790 if (r.isHomeActivity) { 1791 mHomeProcess = app; 1792 } 1793 ensurePackageDexOpt(r.intent.getComponent().getPackageName()); 1794 app.thread.scheduleLaunchActivity(new Intent(r.intent), r, 1795 System.identityHashCode(r), 1796 r.info, r.icicle, results, newIntents, !andResume, 1797 isNextTransitionForward()); 1798 } catch (RemoteException e) { 1799 if (r.launchFailed) { 1800 // This is the second time we failed -- finish activity 1801 // and give up. 1802 Log.e(TAG, "Second failure launching " 1803 + r.intent.getComponent().flattenToShortString() 1804 + ", giving up", e); 1805 appDiedLocked(app, app.pid, app.thread); 1806 requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null, 1807 "2nd-crash"); 1808 return false; 1809 } 1810 1811 // This is the first time we failed -- restart process and 1812 // retry. 1813 app.activities.remove(r); 1814 throw e; 1815 } 1816 1817 r.launchFailed = false; 1818 if (updateLRUListLocked(r)) { 1819 Log.w(TAG, "Activity " + r 1820 + " being launched, but already in LRU list"); 1821 } 1822 1823 if (andResume) { 1824 // As part of the process of launching, ActivityThread also performs 1825 // a resume. 1826 r.state = ActivityState.RESUMED; 1827 r.icicle = null; 1828 r.haveState = false; 1829 r.stopped = false; 1830 mResumedActivity = r; 1831 r.task.touchActiveTime(); 1832 completeResumeLocked(r); 1833 pauseIfSleepingLocked(); 1834 } else { 1835 // This activity is not starting in the resumed state... which 1836 // should look like we asked it to pause+stop (but remain visible), 1837 // and it has done so and reported back the current icicle and 1838 // other state. 1839 r.state = ActivityState.STOPPED; 1840 r.stopped = true; 1841 } 1842 1843 // Launch the new version setup screen if needed. We do this -after- 1844 // launching the initial activity (that is, home), so that it can have 1845 // a chance to initialize itself while in the background, making the 1846 // switch back to it faster and look better. 1847 startSetupActivityLocked(); 1848 1849 return true; 1850 } 1851 1852 private final void startSpecificActivityLocked(HistoryRecord r, 1853 boolean andResume, boolean checkConfig) { 1854 // Is this activity's application already running? 1855 ProcessRecord app = getProcessRecordLocked(r.processName, 1856 r.info.applicationInfo.uid); 1857 1858 if (r.startTime == 0) { 1859 r.startTime = SystemClock.uptimeMillis(); 1860 if (mInitialStartTime == 0) { 1861 mInitialStartTime = r.startTime; 1862 } 1863 } else if (mInitialStartTime == 0) { 1864 mInitialStartTime = SystemClock.uptimeMillis(); 1865 } 1866 1867 if (app != null && app.thread != null) { 1868 try { 1869 realStartActivityLocked(r, app, andResume, checkConfig); 1870 return; 1871 } catch (RemoteException e) { 1872 Log.w(TAG, "Exception when starting activity " 1873 + r.intent.getComponent().flattenToShortString(), e); 1874 } 1875 1876 // If a dead object exception was thrown -- fall through to 1877 // restart the application. 1878 } 1879 1880 startProcessLocked(r.processName, r.info.applicationInfo, true, 0, 1881 "activity", r.intent.getComponent(), false); 1882 } 1883 1884 private final ProcessRecord startProcessLocked(String processName, 1885 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1886 String hostingType, ComponentName hostingName, boolean allowWhileBooting) { 1887 ProcessRecord app = getProcessRecordLocked(processName, info.uid); 1888 // We don't have to do anything more if: 1889 // (1) There is an existing application record; and 1890 // (2) The caller doesn't think it is dead, OR there is no thread 1891 // object attached to it so we know it couldn't have crashed; and 1892 // (3) There is a pid assigned to it, so it is either starting or 1893 // already running. 1894 if (DEBUG_PROCESSES) Log.v(TAG, "startProcess: name=" + processName 1895 + " app=" + app + " knownToBeDead=" + knownToBeDead 1896 + " thread=" + (app != null ? app.thread : null) 1897 + " pid=" + (app != null ? app.pid : -1)); 1898 if (app != null && 1899 (!knownToBeDead || app.thread == null) && app.pid > 0) { 1900 return app; 1901 } 1902 1903 String hostingNameStr = hostingName != null 1904 ? hostingName.flattenToShortString() : null; 1905 1906 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1907 // If we are in the background, then check to see if this process 1908 // is bad. If so, we will just silently fail. 1909 if (mBadProcesses.get(info.processName, info.uid) != null) { 1910 return null; 1911 } 1912 } else { 1913 // When the user is explicitly starting a process, then clear its 1914 // crash count so that we won't make it bad until they see at 1915 // least one crash dialog again, and make the process good again 1916 // if it had been bad. 1917 mProcessCrashTimes.remove(info.processName, info.uid); 1918 if (mBadProcesses.get(info.processName, info.uid) != null) { 1919 EventLog.writeEvent(LOG_AM_PROCESS_GOOD, info.uid, 1920 info.processName); 1921 mBadProcesses.remove(info.processName, info.uid); 1922 if (app != null) { 1923 app.bad = false; 1924 } 1925 } 1926 } 1927 1928 if (app == null) { 1929 app = newProcessRecordLocked(null, info, processName); 1930 mProcessNames.put(processName, info.uid, app); 1931 } else { 1932 // If this is a new package in the process, add the package to the list 1933 app.addPackage(info.packageName); 1934 } 1935 1936 // If the system is not ready yet, then hold off on starting this 1937 // process until it is. 1938 if (!mSystemReady 1939 && !isAllowedWhileBooting(info) 1940 && !allowWhileBooting) { 1941 if (!mProcessesOnHold.contains(app)) { 1942 mProcessesOnHold.add(app); 1943 } 1944 return app; 1945 } 1946 1947 startProcessLocked(app, hostingType, hostingNameStr); 1948 return (app.pid != 0) ? app : null; 1949 } 1950 1951 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1952 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1953 } 1954 1955 private final void startProcessLocked(ProcessRecord app, 1956 String hostingType, String hostingNameStr) { 1957 if (app.pid > 0 && app.pid != MY_PID) { 1958 synchronized (mPidsSelfLocked) { 1959 mPidsSelfLocked.remove(app.pid); 1960 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1961 } 1962 app.pid = 0; 1963 } 1964 1965 mProcessesOnHold.remove(app); 1966 1967 updateCpuStats(); 1968 1969 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 1970 mProcDeaths[0] = 0; 1971 1972 try { 1973 int uid = app.info.uid; 1974 int[] gids = null; 1975 try { 1976 gids = mContext.getPackageManager().getPackageGids( 1977 app.info.packageName); 1978 } catch (PackageManager.NameNotFoundException e) { 1979 Log.w(TAG, "Unable to retrieve gids", e); 1980 } 1981 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 1982 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 1983 && mTopComponent != null 1984 && app.processName.equals(mTopComponent.getPackageName())) { 1985 uid = 0; 1986 } 1987 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 1988 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 1989 uid = 0; 1990 } 1991 } 1992 int debugFlags = 0; 1993 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 1994 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 1995 } 1996 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 1997 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 1998 } 1999 if ("1".equals(SystemProperties.get("debug.assert"))) { 2000 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2001 } 2002 int pid = Process.start("android.app.ActivityThread", 2003 mSimpleProcessManagement ? app.processName : null, uid, uid, 2004 gids, debugFlags, null); 2005 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2006 synchronized (bs) { 2007 if (bs.isOnBattery()) { 2008 app.batteryStats.incStartsLocked(); 2009 } 2010 } 2011 2012 EventLog.writeEvent(LOG_AM_PROCESS_START, pid, uid, 2013 app.processName, hostingType, 2014 hostingNameStr != null ? hostingNameStr : ""); 2015 2016 if (app.persistent) { 2017 Watchdog.getInstance().processStarted(app, app.processName, pid); 2018 } 2019 2020 StringBuilder buf = mStringBuilder; 2021 buf.setLength(0); 2022 buf.append("Start proc "); 2023 buf.append(app.processName); 2024 buf.append(" for "); 2025 buf.append(hostingType); 2026 if (hostingNameStr != null) { 2027 buf.append(" "); 2028 buf.append(hostingNameStr); 2029 } 2030 buf.append(": pid="); 2031 buf.append(pid); 2032 buf.append(" uid="); 2033 buf.append(uid); 2034 buf.append(" gids={"); 2035 if (gids != null) { 2036 for (int gi=0; gi<gids.length; gi++) { 2037 if (gi != 0) buf.append(", "); 2038 buf.append(gids[gi]); 2039 2040 } 2041 } 2042 buf.append("}"); 2043 Log.i(TAG, buf.toString()); 2044 if (pid == 0 || pid == MY_PID) { 2045 // Processes are being emulated with threads. 2046 app.pid = MY_PID; 2047 app.removed = false; 2048 mStartingProcesses.add(app); 2049 } else if (pid > 0) { 2050 app.pid = pid; 2051 app.removed = false; 2052 synchronized (mPidsSelfLocked) { 2053 this.mPidsSelfLocked.put(pid, app); 2054 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2055 msg.obj = app; 2056 mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT); 2057 } 2058 } else { 2059 app.pid = 0; 2060 RuntimeException e = new RuntimeException( 2061 "Failure starting process " + app.processName 2062 + ": returned pid=" + pid); 2063 Log.e(TAG, e.getMessage(), e); 2064 } 2065 } catch (RuntimeException e) { 2066 // XXX do better error recovery. 2067 app.pid = 0; 2068 Log.e(TAG, "Failure starting process " + app.processName, e); 2069 } 2070 } 2071 2072 private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) { 2073 if (mPausingActivity != null) { 2074 RuntimeException e = new RuntimeException(); 2075 Log.e(TAG, "Trying to pause when pause is already pending for " 2076 + mPausingActivity, e); 2077 } 2078 HistoryRecord prev = mResumedActivity; 2079 if (prev == null) { 2080 RuntimeException e = new RuntimeException(); 2081 Log.e(TAG, "Trying to pause when nothing is resumed", e); 2082 resumeTopActivityLocked(null); 2083 return; 2084 } 2085 if (DEBUG_PAUSE) Log.v(TAG, "Start pausing: " + prev); 2086 mResumedActivity = null; 2087 mPausingActivity = prev; 2088 mLastPausedActivity = prev; 2089 prev.state = ActivityState.PAUSING; 2090 prev.task.touchActiveTime(); 2091 2092 updateCpuStats(); 2093 2094 if (prev.app != null && prev.app.thread != null) { 2095 if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending pause: " + prev); 2096 try { 2097 EventLog.writeEvent(LOG_AM_PAUSE_ACTIVITY, 2098 System.identityHashCode(prev), 2099 prev.shortComponentName); 2100 prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving, 2101 prev.configChangeFlags); 2102 updateUsageStats(prev, false); 2103 } catch (Exception e) { 2104 // Ignore exception, if process died other code will cleanup. 2105 Log.w(TAG, "Exception thrown during pause", e); 2106 mPausingActivity = null; 2107 mLastPausedActivity = null; 2108 } 2109 } else { 2110 mPausingActivity = null; 2111 mLastPausedActivity = null; 2112 } 2113 2114 // If we are not going to sleep, we want to ensure the device is 2115 // awake until the next activity is started. 2116 if (!mSleeping && !mShuttingDown) { 2117 mLaunchingActivity.acquire(); 2118 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) { 2119 // To be safe, don't allow the wake lock to be held for too long. 2120 Message msg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG); 2121 mHandler.sendMessageDelayed(msg, LAUNCH_TIMEOUT); 2122 } 2123 } 2124 2125 2126 if (mPausingActivity != null) { 2127 // Have the window manager pause its key dispatching until the new 2128 // activity has started. If we're pausing the activity just because 2129 // the screen is being turned off and the UI is sleeping, don't interrupt 2130 // key dispatch; the same activity will pick it up again on wakeup. 2131 if (!uiSleeping) { 2132 prev.pauseKeyDispatchingLocked(); 2133 } else { 2134 if (DEBUG_PAUSE) Log.v(TAG, "Key dispatch not paused for screen off"); 2135 } 2136 2137 // Schedule a pause timeout in case the app doesn't respond. 2138 // We don't give it much time because this directly impacts the 2139 // responsiveness seen by the user. 2140 Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG); 2141 msg.obj = prev; 2142 mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT); 2143 if (DEBUG_PAUSE) Log.v(TAG, "Waiting for pause to complete..."); 2144 } else { 2145 // This activity failed to schedule the 2146 // pause, so just treat it as being paused now. 2147 if (DEBUG_PAUSE) Log.v(TAG, "Activity not running, resuming next."); 2148 resumeTopActivityLocked(null); 2149 } 2150 } 2151 2152 private final void completePauseLocked() { 2153 HistoryRecord prev = mPausingActivity; 2154 if (DEBUG_PAUSE) Log.v(TAG, "Complete pause: " + prev); 2155 2156 if (prev != null) { 2157 if (prev.finishing) { 2158 if (DEBUG_PAUSE) Log.v(TAG, "Executing finish of activity: " + prev); 2159 prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE); 2160 } else if (prev.app != null) { 2161 if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending stop: " + prev); 2162 if (prev.waitingVisible) { 2163 prev.waitingVisible = false; 2164 mWaitingVisibleActivities.remove(prev); 2165 if (DEBUG_SWITCH || DEBUG_PAUSE) Log.v( 2166 TAG, "Complete pause, no longer waiting: " + prev); 2167 } 2168 if (prev.configDestroy) { 2169 // The previous is being paused because the configuration 2170 // is changing, which means it is actually stopping... 2171 // To juggle the fact that we are also starting a new 2172 // instance right now, we need to first completely stop 2173 // the current instance before starting the new one. 2174 if (DEBUG_PAUSE) Log.v(TAG, "Destroying after pause: " + prev); 2175 destroyActivityLocked(prev, true); 2176 } else { 2177 mStoppingActivities.add(prev); 2178 if (mStoppingActivities.size() > 3) { 2179 // If we already have a few activities waiting to stop, 2180 // then give up on things going idle and start clearing 2181 // them out. 2182 if (DEBUG_PAUSE) Log.v(TAG, "To many pending stops, forcing idle"); 2183 Message msg = Message.obtain(); 2184 msg.what = ActivityManagerService.IDLE_NOW_MSG; 2185 mHandler.sendMessage(msg); 2186 } 2187 } 2188 } else { 2189 if (DEBUG_PAUSE) Log.v(TAG, "App died during pause, not stopping: " + prev); 2190 prev = null; 2191 } 2192 mPausingActivity = null; 2193 } 2194 2195 if (!mSleeping && !mShuttingDown) { 2196 resumeTopActivityLocked(prev); 2197 } else { 2198 if (mGoingToSleep.isHeld()) { 2199 mGoingToSleep.release(); 2200 } 2201 if (mShuttingDown) { 2202 notifyAll(); 2203 } 2204 } 2205 2206 if (prev != null) { 2207 prev.resumeKeyDispatchingLocked(); 2208 } 2209 2210 if (prev.app != null && prev.cpuTimeAtResume > 0 && mBatteryStatsService.isOnBattery()) { 2211 long diff = 0; 2212 synchronized (mProcessStatsThread) { 2213 diff = mProcessStats.getCpuTimeForPid(prev.app.pid) - prev.cpuTimeAtResume; 2214 } 2215 if (diff > 0) { 2216 BatteryStatsImpl bsi = mBatteryStatsService.getActiveStatistics(); 2217 synchronized (bsi) { 2218 BatteryStatsImpl.Uid.Proc ps = 2219 bsi.getProcessStatsLocked(prev.info.applicationInfo.uid, 2220 prev.info.packageName); 2221 if (ps != null) { 2222 ps.addForegroundTimeLocked(diff); 2223 } 2224 } 2225 } 2226 } 2227 prev.cpuTimeAtResume = 0; // reset it 2228 } 2229 2230 /** 2231 * Once we know that we have asked an application to put an activity in 2232 * the resumed state (either by launching it or explicitly telling it), 2233 * this function updates the rest of our state to match that fact. 2234 */ 2235 private final void completeResumeLocked(HistoryRecord next) { 2236 next.idle = false; 2237 next.results = null; 2238 next.newIntents = null; 2239 2240 // schedule an idle timeout in case the app doesn't do it for us. 2241 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 2242 msg.obj = next; 2243 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 2244 2245 if (false) { 2246 // The activity was never told to pause, so just keep 2247 // things going as-is. To maintain our own state, 2248 // we need to emulate it coming back and saying it is 2249 // idle. 2250 msg = mHandler.obtainMessage(IDLE_NOW_MSG); 2251 msg.obj = next; 2252 mHandler.sendMessage(msg); 2253 } 2254 2255 reportResumedActivity(next); 2256 2257 next.thumbnail = null; 2258 setFocusedActivityLocked(next); 2259 next.resumeKeyDispatchingLocked(); 2260 ensureActivitiesVisibleLocked(null, 0); 2261 mWindowManager.executeAppTransition(); 2262 mNoAnimActivities.clear(); 2263 2264 // Mark the point when the activity is resuming 2265 // TODO: To be more accurate, the mark should be before the onCreate, 2266 // not after the onResume. But for subsequent starts, onResume is fine. 2267 if (next.app != null) { 2268 synchronized (mProcessStatsThread) { 2269 next.cpuTimeAtResume = mProcessStats.getCpuTimeForPid(next.app.pid); 2270 } 2271 } else { 2272 next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process 2273 } 2274 } 2275 2276 /** 2277 * Make sure that all activities that need to be visible (that is, they 2278 * currently can be seen by the user) actually are. 2279 */ 2280 private final void ensureActivitiesVisibleLocked(HistoryRecord top, 2281 HistoryRecord starting, String onlyThisProcess, int configChanges) { 2282 if (DEBUG_VISBILITY) Log.v( 2283 TAG, "ensureActivitiesVisible behind " + top 2284 + " configChanges=0x" + Integer.toHexString(configChanges)); 2285 2286 // If the top activity is not fullscreen, then we need to 2287 // make sure any activities under it are now visible. 2288 final int count = mHistory.size(); 2289 int i = count-1; 2290 while (mHistory.get(i) != top) { 2291 i--; 2292 } 2293 HistoryRecord r; 2294 boolean behindFullscreen = false; 2295 for (; i>=0; i--) { 2296 r = (HistoryRecord)mHistory.get(i); 2297 if (DEBUG_VISBILITY) Log.v( 2298 TAG, "Make visible? " + r + " finishing=" + r.finishing 2299 + " state=" + r.state); 2300 if (r.finishing) { 2301 continue; 2302 } 2303 2304 final boolean doThisProcess = onlyThisProcess == null 2305 || onlyThisProcess.equals(r.processName); 2306 2307 // First: if this is not the current activity being started, make 2308 // sure it matches the current configuration. 2309 if (r != starting && doThisProcess) { 2310 ensureActivityConfigurationLocked(r, 0); 2311 } 2312 2313 if (r.app == null || r.app.thread == null) { 2314 if (onlyThisProcess == null 2315 || onlyThisProcess.equals(r.processName)) { 2316 // This activity needs to be visible, but isn't even 2317 // running... get it started, but don't resume it 2318 // at this point. 2319 if (DEBUG_VISBILITY) Log.v( 2320 TAG, "Start and freeze screen for " + r); 2321 if (r != starting) { 2322 r.startFreezingScreenLocked(r.app, configChanges); 2323 } 2324 if (!r.visible) { 2325 if (DEBUG_VISBILITY) Log.v( 2326 TAG, "Starting and making visible: " + r); 2327 mWindowManager.setAppVisibility(r, true); 2328 } 2329 if (r != starting) { 2330 startSpecificActivityLocked(r, false, false); 2331 } 2332 } 2333 2334 } else if (r.visible) { 2335 // If this activity is already visible, then there is nothing 2336 // else to do here. 2337 if (DEBUG_VISBILITY) Log.v( 2338 TAG, "Skipping: already visible at " + r); 2339 r.stopFreezingScreenLocked(false); 2340 2341 } else if (onlyThisProcess == null) { 2342 // This activity is not currently visible, but is running. 2343 // Tell it to become visible. 2344 r.visible = true; 2345 if (r.state != ActivityState.RESUMED && r != starting) { 2346 // If this activity is paused, tell it 2347 // to now show its window. 2348 if (DEBUG_VISBILITY) Log.v( 2349 TAG, "Making visible and scheduling visibility: " + r); 2350 try { 2351 mWindowManager.setAppVisibility(r, true); 2352 r.app.thread.scheduleWindowVisibility(r, true); 2353 r.stopFreezingScreenLocked(false); 2354 } catch (Exception e) { 2355 // Just skip on any failure; we'll make it 2356 // visible when it next restarts. 2357 Log.w(TAG, "Exception thrown making visibile: " 2358 + r.intent.getComponent(), e); 2359 } 2360 } 2361 } 2362 2363 // Aggregate current change flags. 2364 configChanges |= r.configChangeFlags; 2365 2366 if (r.fullscreen) { 2367 // At this point, nothing else needs to be shown 2368 if (DEBUG_VISBILITY) Log.v( 2369 TAG, "Stopping: fullscreen at " + r); 2370 behindFullscreen = true; 2371 i--; 2372 break; 2373 } 2374 } 2375 2376 // Now for any activities that aren't visible to the user, make 2377 // sure they no longer are keeping the screen frozen. 2378 while (i >= 0) { 2379 r = (HistoryRecord)mHistory.get(i); 2380 if (DEBUG_VISBILITY) Log.v( 2381 TAG, "Make invisible? " + r + " finishing=" + r.finishing 2382 + " state=" + r.state 2383 + " behindFullscreen=" + behindFullscreen); 2384 if (!r.finishing) { 2385 if (behindFullscreen) { 2386 if (r.visible) { 2387 if (DEBUG_VISBILITY) Log.v( 2388 TAG, "Making invisible: " + r); 2389 r.visible = false; 2390 try { 2391 mWindowManager.setAppVisibility(r, false); 2392 if ((r.state == ActivityState.STOPPING 2393 || r.state == ActivityState.STOPPED) 2394 && r.app != null && r.app.thread != null) { 2395 if (DEBUG_VISBILITY) Log.v( 2396 TAG, "Scheduling invisibility: " + r); 2397 r.app.thread.scheduleWindowVisibility(r, false); 2398 } 2399 } catch (Exception e) { 2400 // Just skip on any failure; we'll make it 2401 // visible when it next restarts. 2402 Log.w(TAG, "Exception thrown making hidden: " 2403 + r.intent.getComponent(), e); 2404 } 2405 } else { 2406 if (DEBUG_VISBILITY) Log.v( 2407 TAG, "Already invisible: " + r); 2408 } 2409 } else if (r.fullscreen) { 2410 if (DEBUG_VISBILITY) Log.v( 2411 TAG, "Now behindFullscreen: " + r); 2412 behindFullscreen = true; 2413 } 2414 } 2415 i--; 2416 } 2417 } 2418 2419 /** 2420 * Version of ensureActivitiesVisible that can easily be called anywhere. 2421 */ 2422 private final void ensureActivitiesVisibleLocked(HistoryRecord starting, 2423 int configChanges) { 2424 HistoryRecord r = topRunningActivityLocked(null); 2425 if (r != null) { 2426 ensureActivitiesVisibleLocked(r, starting, null, configChanges); 2427 } 2428 } 2429 2430 private void updateUsageStats(HistoryRecord resumedComponent, boolean resumed) { 2431 if (resumed) { 2432 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2433 } else { 2434 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2435 } 2436 } 2437 2438 private boolean startHomeActivityLocked() { 2439 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2440 && mTopAction == null) { 2441 // We are running in factory test mode, but unable to find 2442 // the factory test app, so just sit around displaying the 2443 // error message and don't try to start anything. 2444 return false; 2445 } 2446 Intent intent = new Intent( 2447 mTopAction, 2448 mTopData != null ? Uri.parse(mTopData) : null); 2449 intent.setComponent(mTopComponent); 2450 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2451 intent.addCategory(Intent.CATEGORY_HOME); 2452 } 2453 ActivityInfo aInfo = 2454 intent.resolveActivityInfo(mContext.getPackageManager(), 2455 STOCK_PM_FLAGS); 2456 if (aInfo != null) { 2457 intent.setComponent(new ComponentName( 2458 aInfo.applicationInfo.packageName, aInfo.name)); 2459 // Don't do this if the home app is currently being 2460 // instrumented. 2461 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2462 aInfo.applicationInfo.uid); 2463 if (app == null || app.instrumentationClass == null) { 2464 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2465 startActivityLocked(null, intent, null, null, 0, aInfo, 2466 null, null, 0, 0, 0, false, false); 2467 } 2468 } 2469 2470 2471 return true; 2472 } 2473 2474 /** 2475 * Starts the "new version setup screen" if appropriate. 2476 */ 2477 private void startSetupActivityLocked() { 2478 // Only do this once per boot. 2479 if (mCheckedForSetup) { 2480 return; 2481 } 2482 2483 // We will show this screen if the current one is a different 2484 // version than the last one shown, and we are not running in 2485 // low-level factory test mode. 2486 final ContentResolver resolver = mContext.getContentResolver(); 2487 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2488 Settings.Secure.getInt(resolver, 2489 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2490 mCheckedForSetup = true; 2491 2492 // See if we should be showing the platform update setup UI. 2493 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2494 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2495 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2496 2497 // We don't allow third party apps to replace this. 2498 ResolveInfo ri = null; 2499 for (int i=0; ris != null && i<ris.size(); i++) { 2500 if ((ris.get(i).activityInfo.applicationInfo.flags 2501 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2502 ri = ris.get(i); 2503 break; 2504 } 2505 } 2506 2507 if (ri != null) { 2508 String vers = ri.activityInfo.metaData != null 2509 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2510 : null; 2511 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2512 vers = ri.activityInfo.applicationInfo.metaData.getString( 2513 Intent.METADATA_SETUP_VERSION); 2514 } 2515 String lastVers = Settings.Secure.getString( 2516 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2517 if (vers != null && !vers.equals(lastVers)) { 2518 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2519 intent.setComponent(new ComponentName( 2520 ri.activityInfo.packageName, ri.activityInfo.name)); 2521 startActivityLocked(null, intent, null, null, 0, ri.activityInfo, 2522 null, null, 0, 0, 0, false, false); 2523 } 2524 } 2525 } 2526 } 2527 2528 private void reportResumedActivity(HistoryRecord r) { 2529 //Log.i(TAG, "**** REPORT RESUME: " + r); 2530 2531 final int identHash = System.identityHashCode(r); 2532 updateUsageStats(r, true); 2533 2534 int i = mWatchers.beginBroadcast(); 2535 while (i > 0) { 2536 i--; 2537 IActivityWatcher w = mWatchers.getBroadcastItem(i); 2538 if (w != null) { 2539 try { 2540 w.activityResuming(identHash); 2541 } catch (RemoteException e) { 2542 } 2543 } 2544 } 2545 mWatchers.finishBroadcast(); 2546 } 2547 2548 /** 2549 * Ensure that the top activity in the stack is resumed. 2550 * 2551 * @param prev The previously resumed activity, for when in the process 2552 * of pausing; can be null to call from elsewhere. 2553 * 2554 * @return Returns true if something is being resumed, or false if 2555 * nothing happened. 2556 */ 2557 private final boolean resumeTopActivityLocked(HistoryRecord prev) { 2558 // Find the first activity that is not finishing. 2559 HistoryRecord next = topRunningActivityLocked(null); 2560 2561 // Remember how we'll process this pause/resume situation, and ensure 2562 // that the state is reset however we wind up proceeding. 2563 final boolean userLeaving = mUserLeaving; 2564 mUserLeaving = false; 2565 2566 if (next == null) { 2567 // There are no more activities! Let's just start up the 2568 // Launcher... 2569 return startHomeActivityLocked(); 2570 } 2571 2572 next.delayedResume = false; 2573 2574 // If the top activity is the resumed one, nothing to do. 2575 if (mResumedActivity == next && next.state == ActivityState.RESUMED) { 2576 // Make sure we have executed any pending transitions, since there 2577 // should be nothing left to do at this point. 2578 mWindowManager.executeAppTransition(); 2579 mNoAnimActivities.clear(); 2580 return false; 2581 } 2582 2583 // If we are sleeping, and there is no resumed activity, and the top 2584 // activity is paused, well that is the state we want. 2585 if ((mSleeping || mShuttingDown) 2586 && mLastPausedActivity == next && next.state == ActivityState.PAUSED) { 2587 // Make sure we have executed any pending transitions, since there 2588 // should be nothing left to do at this point. 2589 mWindowManager.executeAppTransition(); 2590 mNoAnimActivities.clear(); 2591 return false; 2592 } 2593 2594 // The activity may be waiting for stop, but that is no longer 2595 // appropriate for it. 2596 mStoppingActivities.remove(next); 2597 mWaitingVisibleActivities.remove(next); 2598 2599 if (DEBUG_SWITCH) Log.v(TAG, "Resuming " + next); 2600 2601 // If we are currently pausing an activity, then don't do anything 2602 // until that is done. 2603 if (mPausingActivity != null) { 2604 if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: pausing=" + mPausingActivity); 2605 return false; 2606 } 2607 2608 // We need to start pausing the current activity so the top one 2609 // can be resumed... 2610 if (mResumedActivity != null) { 2611 if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: need to start pausing"); 2612 startPausingLocked(userLeaving, false); 2613 return true; 2614 } 2615 2616 if (prev != null && prev != next) { 2617 if (!prev.waitingVisible && next != null && !next.nowVisible) { 2618 prev.waitingVisible = true; 2619 mWaitingVisibleActivities.add(prev); 2620 if (DEBUG_SWITCH) Log.v( 2621 TAG, "Resuming top, waiting visible to hide: " + prev); 2622 } else { 2623 // The next activity is already visible, so hide the previous 2624 // activity's windows right now so we can show the new one ASAP. 2625 // We only do this if the previous is finishing, which should mean 2626 // it is on top of the one being resumed so hiding it quickly 2627 // is good. Otherwise, we want to do the normal route of allowing 2628 // the resumed activity to be shown so we can decide if the 2629 // previous should actually be hidden depending on whether the 2630 // new one is found to be full-screen or not. 2631 if (prev.finishing) { 2632 mWindowManager.setAppVisibility(prev, false); 2633 if (DEBUG_SWITCH) Log.v(TAG, "Not waiting for visible to hide: " 2634 + prev + ", waitingVisible=" 2635 + (prev != null ? prev.waitingVisible : null) 2636 + ", nowVisible=" + next.nowVisible); 2637 } else { 2638 if (DEBUG_SWITCH) Log.v(TAG, "Previous already visible but still waiting to hide: " 2639 + prev + ", waitingVisible=" 2640 + (prev != null ? prev.waitingVisible : null) 2641 + ", nowVisible=" + next.nowVisible); 2642 } 2643 } 2644 } 2645 2646 // We are starting up the next activity, so tell the window manager 2647 // that the previous one will be hidden soon. This way it can know 2648 // to ignore it when computing the desired screen orientation. 2649 if (prev != null) { 2650 if (prev.finishing) { 2651 if (DEBUG_TRANSITION) Log.v(TAG, 2652 "Prepare close transition: prev=" + prev); 2653 if (mNoAnimActivities.contains(prev)) { 2654 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 2655 } else { 2656 mWindowManager.prepareAppTransition(prev.task == next.task 2657 ? WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE 2658 : WindowManagerPolicy.TRANSIT_TASK_CLOSE); 2659 } 2660 mWindowManager.setAppWillBeHidden(prev); 2661 mWindowManager.setAppVisibility(prev, false); 2662 } else { 2663 if (DEBUG_TRANSITION) Log.v(TAG, 2664 "Prepare open transition: prev=" + prev); 2665 if (mNoAnimActivities.contains(next)) { 2666 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 2667 } else { 2668 mWindowManager.prepareAppTransition(prev.task == next.task 2669 ? WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 2670 : WindowManagerPolicy.TRANSIT_TASK_OPEN); 2671 } 2672 } 2673 if (false) { 2674 mWindowManager.setAppWillBeHidden(prev); 2675 mWindowManager.setAppVisibility(prev, false); 2676 } 2677 } else if (mHistory.size() > 1) { 2678 if (DEBUG_TRANSITION) Log.v(TAG, 2679 "Prepare open transition: no previous"); 2680 if (mNoAnimActivities.contains(next)) { 2681 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 2682 } else { 2683 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN); 2684 } 2685 } 2686 2687 if (next.app != null && next.app.thread != null) { 2688 if (DEBUG_SWITCH) Log.v(TAG, "Resume running: " + next); 2689 2690 // This activity is now becoming visible. 2691 mWindowManager.setAppVisibility(next, true); 2692 2693 HistoryRecord lastResumedActivity = mResumedActivity; 2694 ActivityState lastState = next.state; 2695 2696 updateCpuStats(); 2697 2698 next.state = ActivityState.RESUMED; 2699 mResumedActivity = next; 2700 next.task.touchActiveTime(); 2701 updateLRUListLocked(next.app, true); 2702 updateLRUListLocked(next); 2703 2704 // Have the window manager re-evaluate the orientation of 2705 // the screen based on the new activity order. 2706 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2707 mConfiguration, 2708 next.mayFreezeScreenLocked(next.app) ? next : null); 2709 if (config != null) { 2710 next.frozenBeforeDestroy = true; 2711 } 2712 if (!updateConfigurationLocked(config, next)) { 2713 // The configuration update wasn't able to keep the existing 2714 // instance of the activity, and instead started a new one. 2715 // We should be all done, but let's just make sure our activity 2716 // is still at the top and schedule another run if something 2717 // weird happened. 2718 HistoryRecord nextNext = topRunningActivityLocked(null); 2719 if (DEBUG_SWITCH) Log.i(TAG, 2720 "Activity config changed during resume: " + next 2721 + ", new next: " + nextNext); 2722 if (nextNext != next) { 2723 // Do over! 2724 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 2725 } 2726 setFocusedActivityLocked(next); 2727 ensureActivitiesVisibleLocked(null, 0); 2728 mWindowManager.executeAppTransition(); 2729 mNoAnimActivities.clear(); 2730 return true; 2731 } 2732 2733 try { 2734 // Deliver all pending results. 2735 ArrayList a = next.results; 2736 if (a != null) { 2737 final int N = a.size(); 2738 if (!next.finishing && N > 0) { 2739 if (DEBUG_RESULTS) Log.v( 2740 TAG, "Delivering results to " + next 2741 + ": " + a); 2742 next.app.thread.scheduleSendResult(next, a); 2743 } 2744 } 2745 2746 if (next.newIntents != null) { 2747 next.app.thread.scheduleNewIntent(next.newIntents, next); 2748 } 2749 2750 EventLog.writeEvent(LOG_AM_RESUME_ACTIVITY, 2751 System.identityHashCode(next), 2752 next.task.taskId, next.shortComponentName); 2753 2754 next.app.thread.scheduleResumeActivity(next, 2755 isNextTransitionForward()); 2756 2757 pauseIfSleepingLocked(); 2758 2759 } catch (Exception e) { 2760 // Whoops, need to restart this activity! 2761 next.state = lastState; 2762 mResumedActivity = lastResumedActivity; 2763 if (Config.LOGD) Log.d(TAG, 2764 "Restarting because process died: " + next); 2765 if (!next.hasBeenLaunched) { 2766 next.hasBeenLaunched = true; 2767 } else { 2768 if (SHOW_APP_STARTING_ICON) { 2769 mWindowManager.setAppStartingWindow( 2770 next, next.packageName, next.theme, 2771 next.nonLocalizedLabel, 2772 next.labelRes, next.icon, null, true); 2773 } 2774 } 2775 startSpecificActivityLocked(next, true, false); 2776 return true; 2777 } 2778 2779 // From this point on, if something goes wrong there is no way 2780 // to recover the activity. 2781 try { 2782 next.visible = true; 2783 completeResumeLocked(next); 2784 } catch (Exception e) { 2785 // If any exception gets thrown, toss away this 2786 // activity and try the next one. 2787 Log.w(TAG, "Exception thrown during resume of " + next, e); 2788 requestFinishActivityLocked(next, Activity.RESULT_CANCELED, null, 2789 "resume-exception"); 2790 return true; 2791 } 2792 2793 // Didn't need to use the icicle, and it is now out of date. 2794 next.icicle = null; 2795 next.haveState = false; 2796 next.stopped = false; 2797 2798 } else { 2799 // Whoops, need to restart this activity! 2800 if (!next.hasBeenLaunched) { 2801 next.hasBeenLaunched = true; 2802 } else { 2803 if (SHOW_APP_STARTING_ICON) { 2804 mWindowManager.setAppStartingWindow( 2805 next, next.packageName, next.theme, 2806 next.nonLocalizedLabel, 2807 next.labelRes, next.icon, null, true); 2808 } 2809 if (DEBUG_SWITCH) Log.v(TAG, "Restarting: " + next); 2810 } 2811 startSpecificActivityLocked(next, true, true); 2812 } 2813 2814 return true; 2815 } 2816 2817 private final void startActivityLocked(HistoryRecord r, boolean newTask, 2818 boolean doResume) { 2819 final int NH = mHistory.size(); 2820 2821 int addPos = -1; 2822 2823 if (!newTask) { 2824 // If starting in an existing task, find where that is... 2825 HistoryRecord next = null; 2826 boolean startIt = true; 2827 for (int i = NH-1; i >= 0; i--) { 2828 HistoryRecord p = (HistoryRecord)mHistory.get(i); 2829 if (p.finishing) { 2830 continue; 2831 } 2832 if (p.task == r.task) { 2833 // Here it is! Now, if this is not yet visible to the 2834 // user, then just add it without starting; it will 2835 // get started when the user navigates back to it. 2836 addPos = i+1; 2837 if (!startIt) { 2838 mHistory.add(addPos, r); 2839 r.inHistory = true; 2840 r.task.numActivities++; 2841 mWindowManager.addAppToken(addPos, r, r.task.taskId, 2842 r.info.screenOrientation, r.fullscreen); 2843 if (VALIDATE_TOKENS) { 2844 mWindowManager.validateAppTokens(mHistory); 2845 } 2846 return; 2847 } 2848 break; 2849 } 2850 if (p.fullscreen) { 2851 startIt = false; 2852 } 2853 next = p; 2854 } 2855 } 2856 2857 // Place a new activity at top of stack, so it is next to interact 2858 // with the user. 2859 if (addPos < 0) { 2860 addPos = mHistory.size(); 2861 } 2862 2863 // If we are not placing the new activity frontmost, we do not want 2864 // to deliver the onUserLeaving callback to the actual frontmost 2865 // activity 2866 if (addPos < NH) { 2867 mUserLeaving = false; 2868 if (DEBUG_USER_LEAVING) Log.v(TAG, "startActivity() behind front, mUserLeaving=false"); 2869 } 2870 2871 // Slot the activity into the history stack and proceed 2872 mHistory.add(addPos, r); 2873 r.inHistory = true; 2874 r.frontOfTask = newTask; 2875 r.task.numActivities++; 2876 if (NH > 0) { 2877 // We want to show the starting preview window if we are 2878 // switching to a new task, or the next activity's process is 2879 // not currently running. 2880 boolean showStartingIcon = newTask; 2881 ProcessRecord proc = r.app; 2882 if (proc == null) { 2883 proc = mProcessNames.get(r.processName, r.info.applicationInfo.uid); 2884 } 2885 if (proc == null || proc.thread == null) { 2886 showStartingIcon = true; 2887 } 2888 if (DEBUG_TRANSITION) Log.v(TAG, 2889 "Prepare open transition: starting " + r); 2890 if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { 2891 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 2892 mNoAnimActivities.add(r); 2893 } else if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) { 2894 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_OPEN); 2895 mNoAnimActivities.remove(r); 2896 } else { 2897 mWindowManager.prepareAppTransition(newTask 2898 ? WindowManagerPolicy.TRANSIT_TASK_OPEN 2899 : WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN); 2900 mNoAnimActivities.remove(r); 2901 } 2902 mWindowManager.addAppToken( 2903 addPos, r, r.task.taskId, r.info.screenOrientation, r.fullscreen); 2904 boolean doShow = true; 2905 if (newTask) { 2906 // Even though this activity is starting fresh, we still need 2907 // to reset it to make sure we apply affinities to move any 2908 // existing activities from other tasks in to it. 2909 // If the caller has requested that the target task be 2910 // reset, then do so. 2911 if ((r.intent.getFlags() 2912 &Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 2913 resetTaskIfNeededLocked(r, r); 2914 doShow = topRunningNonDelayedActivityLocked(null) == r; 2915 } 2916 } 2917 if (SHOW_APP_STARTING_ICON && doShow) { 2918 // Figure out if we are transitioning from another activity that is 2919 // "has the same starting icon" as the next one. This allows the 2920 // window manager to keep the previous window it had previously 2921 // created, if it still had one. 2922 HistoryRecord prev = mResumedActivity; 2923 if (prev != null) { 2924 // We don't want to reuse the previous starting preview if: 2925 // (1) The current activity is in a different task. 2926 if (prev.task != r.task) prev = null; 2927 // (2) The current activity is already displayed. 2928 else if (prev.nowVisible) prev = null; 2929 } 2930 mWindowManager.setAppStartingWindow( 2931 r, r.packageName, r.theme, r.nonLocalizedLabel, 2932 r.labelRes, r.icon, prev, showStartingIcon); 2933 } 2934 } else { 2935 // If this is the first activity, don't do any fancy animations, 2936 // because there is nothing for it to animate on top of. 2937 mWindowManager.addAppToken(addPos, r, r.task.taskId, 2938 r.info.screenOrientation, r.fullscreen); 2939 } 2940 if (VALIDATE_TOKENS) { 2941 mWindowManager.validateAppTokens(mHistory); 2942 } 2943 2944 if (doResume) { 2945 resumeTopActivityLocked(null); 2946 } 2947 } 2948 2949 /** 2950 * Perform clear operation as requested by 2951 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the 2952 * stack to the given task, then look for 2953 * an instance of that activity in the stack and, if found, finish all 2954 * activities on top of it and return the instance. 2955 * 2956 * @param newR Description of the new activity being started. 2957 * @return Returns the old activity that should be continue to be used, 2958 * or null if none was found. 2959 */ 2960 private final HistoryRecord performClearTaskLocked(int taskId, 2961 HistoryRecord newR, int launchFlags, boolean doClear) { 2962 int i = mHistory.size(); 2963 2964 // First find the requested task. 2965 while (i > 0) { 2966 i--; 2967 HistoryRecord r = (HistoryRecord)mHistory.get(i); 2968 if (r.task.taskId == taskId) { 2969 i++; 2970 break; 2971 } 2972 } 2973 2974 // Now clear it. 2975 while (i > 0) { 2976 i--; 2977 HistoryRecord r = (HistoryRecord)mHistory.get(i); 2978 if (r.finishing) { 2979 continue; 2980 } 2981 if (r.task.taskId != taskId) { 2982 return null; 2983 } 2984 if (r.realActivity.equals(newR.realActivity)) { 2985 // Here it is! Now finish everything in front... 2986 HistoryRecord ret = r; 2987 if (doClear) { 2988 while (i < (mHistory.size()-1)) { 2989 i++; 2990 r = (HistoryRecord)mHistory.get(i); 2991 if (r.finishing) { 2992 continue; 2993 } 2994 if (finishActivityLocked(r, i, Activity.RESULT_CANCELED, 2995 null, "clear")) { 2996 i--; 2997 } 2998 } 2999 } 3000 3001 // Finally, if this is a normal launch mode (that is, not 3002 // expecting onNewIntent()), then we will finish the current 3003 // instance of the activity so a new fresh one can be started. 3004 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE 3005 && (launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) { 3006 if (!ret.finishing) { 3007 int index = indexOfTokenLocked(ret); 3008 if (index >= 0) { 3009 finishActivityLocked(ret, 0, Activity.RESULT_CANCELED, 3010 null, "clear"); 3011 } 3012 return null; 3013 } 3014 } 3015 3016 return ret; 3017 } 3018 } 3019 3020 return null; 3021 } 3022 3023 /** 3024 * Find the activity in the history stack within the given task. Returns 3025 * the index within the history at which it's found, or < 0 if not found. 3026 */ 3027 private final int findActivityInHistoryLocked(HistoryRecord r, int task) { 3028 int i = mHistory.size(); 3029 while (i > 0) { 3030 i--; 3031 HistoryRecord candidate = (HistoryRecord)mHistory.get(i); 3032 if (candidate.task.taskId != task) { 3033 break; 3034 } 3035 if (candidate.realActivity.equals(r.realActivity)) { 3036 return i; 3037 } 3038 } 3039 3040 return -1; 3041 } 3042 3043 /** 3044 * Reorder the history stack so that the activity at the given index is 3045 * brought to the front. 3046 */ 3047 private final HistoryRecord moveActivityToFrontLocked(int where) { 3048 HistoryRecord newTop = (HistoryRecord)mHistory.remove(where); 3049 int top = mHistory.size(); 3050 HistoryRecord oldTop = (HistoryRecord)mHistory.get(top-1); 3051 mHistory.add(top, newTop); 3052 oldTop.frontOfTask = false; 3053 newTop.frontOfTask = true; 3054 return newTop; 3055 } 3056 3057 /** 3058 * Deliver a new Intent to an existing activity, so that its onNewIntent() 3059 * method will be called at the proper time. 3060 */ 3061 private final void deliverNewIntentLocked(HistoryRecord r, Intent intent) { 3062 boolean sent = false; 3063 if (r.state == ActivityState.RESUMED 3064 && r.app != null && r.app.thread != null) { 3065 try { 3066 ArrayList<Intent> ar = new ArrayList<Intent>(); 3067 ar.add(new Intent(intent)); 3068 r.app.thread.scheduleNewIntent(ar, r); 3069 sent = true; 3070 } catch (Exception e) { 3071 Log.w(TAG, "Exception thrown sending new intent to " + r, e); 3072 } 3073 } 3074 if (!sent) { 3075 r.addNewIntentLocked(new Intent(intent)); 3076 } 3077 } 3078 3079 private final void logStartActivity(int tag, HistoryRecord r, 3080 TaskRecord task) { 3081 EventLog.writeEvent(tag, 3082 System.identityHashCode(r), task.taskId, 3083 r.shortComponentName, r.intent.getAction(), 3084 r.intent.getType(), r.intent.getDataString(), 3085 r.intent.getFlags()); 3086 } 3087 3088 private final int startActivityLocked(IApplicationThread caller, 3089 Intent intent, String resolvedType, 3090 Uri[] grantedUriPermissions, 3091 int grantedMode, ActivityInfo aInfo, IBinder resultTo, 3092 String resultWho, int requestCode, 3093 int callingPid, int callingUid, boolean onlyIfNeeded, 3094 boolean componentSpecified) { 3095 Log.i(TAG, "Starting activity: " + intent); 3096 3097 HistoryRecord sourceRecord = null; 3098 HistoryRecord resultRecord = null; 3099 if (resultTo != null) { 3100 int index = indexOfTokenLocked(resultTo); 3101 if (DEBUG_RESULTS) Log.v( 3102 TAG, "Sending result to " + resultTo + " (index " + index + ")"); 3103 if (index >= 0) { 3104 sourceRecord = (HistoryRecord)mHistory.get(index); 3105 if (requestCode >= 0 && !sourceRecord.finishing) { 3106 resultRecord = sourceRecord; 3107 } 3108 } 3109 } 3110 3111 int launchFlags = intent.getFlags(); 3112 3113 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 3114 && sourceRecord != null) { 3115 // Transfer the result target from the source activity to the new 3116 // one being started, including any failures. 3117 if (requestCode >= 0) { 3118 return START_FORWARD_AND_REQUEST_CONFLICT; 3119 } 3120 resultRecord = sourceRecord.resultTo; 3121 resultWho = sourceRecord.resultWho; 3122 requestCode = sourceRecord.requestCode; 3123 sourceRecord.resultTo = null; 3124 if (resultRecord != null) { 3125 resultRecord.removeResultsLocked( 3126 sourceRecord, resultWho, requestCode); 3127 } 3128 } 3129 3130 int err = START_SUCCESS; 3131 3132 if (intent.getComponent() == null) { 3133 // We couldn't find a class that can handle the given Intent. 3134 // That's the end of that! 3135 err = START_INTENT_NOT_RESOLVED; 3136 } 3137 3138 if (err == START_SUCCESS && aInfo == null) { 3139 // We couldn't find the specific class specified in the Intent. 3140 // Also the end of the line. 3141 err = START_CLASS_NOT_FOUND; 3142 } 3143 3144 ProcessRecord callerApp = null; 3145 if (err == START_SUCCESS && caller != null) { 3146 callerApp = getRecordForAppLocked(caller); 3147 if (callerApp != null) { 3148 callingPid = callerApp.pid; 3149 callingUid = callerApp.info.uid; 3150 } else { 3151 Log.w(TAG, "Unable to find app for caller " + caller 3152 + " (pid=" + callingPid + ") when starting: " 3153 + intent.toString()); 3154 err = START_PERMISSION_DENIED; 3155 } 3156 } 3157 3158 if (err != START_SUCCESS) { 3159 if (resultRecord != null) { 3160 sendActivityResultLocked(-1, 3161 resultRecord, resultWho, requestCode, 3162 Activity.RESULT_CANCELED, null); 3163 } 3164 return err; 3165 } 3166 3167 final int perm = checkComponentPermission(aInfo.permission, callingPid, 3168 callingUid, aInfo.exported ? -1 : aInfo.applicationInfo.uid); 3169 if (perm != PackageManager.PERMISSION_GRANTED) { 3170 if (resultRecord != null) { 3171 sendActivityResultLocked(-1, 3172 resultRecord, resultWho, requestCode, 3173 Activity.RESULT_CANCELED, null); 3174 } 3175 String msg = "Permission Denial: starting " + intent.toString() 3176 + " from " + callerApp + " (pid=" + callingPid 3177 + ", uid=" + callingUid + ")" 3178 + " requires " + aInfo.permission; 3179 Log.w(TAG, msg); 3180 throw new SecurityException(msg); 3181 } 3182 3183 if (mController != null) { 3184 boolean abort = false; 3185 try { 3186 // The Intent we give to the watcher has the extra data 3187 // stripped off, since it can contain private information. 3188 Intent watchIntent = intent.cloneFilter(); 3189 abort = !mController.activityStarting(watchIntent, 3190 aInfo.applicationInfo.packageName); 3191 } catch (RemoteException e) { 3192 mController = null; 3193 } 3194 3195 if (abort) { 3196 if (resultRecord != null) { 3197 sendActivityResultLocked(-1, 3198 resultRecord, resultWho, requestCode, 3199 Activity.RESULT_CANCELED, null); 3200 } 3201 // We pretend to the caller that it was really started, but 3202 // they will just get a cancel result. 3203 return START_SUCCESS; 3204 } 3205 } 3206 3207 HistoryRecord r = new HistoryRecord(this, callerApp, callingUid, 3208 intent, resolvedType, aInfo, mConfiguration, 3209 resultRecord, resultWho, requestCode, componentSpecified); 3210 3211 if (mResumedActivity == null 3212 || mResumedActivity.info.applicationInfo.uid != callingUid) { 3213 if (!checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) { 3214 PendingActivityLaunch pal = new PendingActivityLaunch(); 3215 pal.r = r; 3216 pal.sourceRecord = sourceRecord; 3217 pal.grantedUriPermissions = grantedUriPermissions; 3218 pal.grantedMode = grantedMode; 3219 pal.onlyIfNeeded = onlyIfNeeded; 3220 mPendingActivityLaunches.add(pal); 3221 return START_SWITCHES_CANCELED; 3222 } 3223 } 3224 3225 if (mDidAppSwitch) { 3226 // This is the second allowed switch since we stopped switches, 3227 // so now just generally allow switches. Use case: user presses 3228 // home (switches disabled, switch to home, mDidAppSwitch now true); 3229 // user taps a home icon (coming from home so allowed, we hit here 3230 // and now allow anyone to switch again). 3231 mAppSwitchesAllowedTime = 0; 3232 } else { 3233 mDidAppSwitch = true; 3234 } 3235 3236 doPendingActivityLaunchesLocked(false); 3237 3238 return startActivityUncheckedLocked(r, sourceRecord, 3239 grantedUriPermissions, grantedMode, onlyIfNeeded, true); 3240 } 3241 3242 private final void doPendingActivityLaunchesLocked(boolean doResume) { 3243 final int N = mPendingActivityLaunches.size(); 3244 if (N <= 0) { 3245 return; 3246 } 3247 for (int i=0; i<N; i++) { 3248 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3249 startActivityUncheckedLocked(pal.r, pal.sourceRecord, 3250 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded, 3251 doResume && i == (N-1)); 3252 } 3253 mPendingActivityLaunches.clear(); 3254 } 3255 3256 private final int startActivityUncheckedLocked(HistoryRecord r, 3257 HistoryRecord sourceRecord, Uri[] grantedUriPermissions, 3258 int grantedMode, boolean onlyIfNeeded, boolean doResume) { 3259 final Intent intent = r.intent; 3260 final int callingUid = r.launchedFromUid; 3261 3262 int launchFlags = intent.getFlags(); 3263 3264 // We'll invoke onUserLeaving before onPause only if the launching 3265 // activity did not explicitly state that this is an automated launch. 3266 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0; 3267 if (DEBUG_USER_LEAVING) Log.v(TAG, 3268 "startActivity() => mUserLeaving=" + mUserLeaving); 3269 3270 // If the caller has asked not to resume at this point, we make note 3271 // of this in the record so that we can skip it when trying to find 3272 // the top running activity. 3273 if (!doResume) { 3274 r.delayedResume = true; 3275 } 3276 3277 HistoryRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) 3278 != 0 ? r : null; 3279 3280 // If the onlyIfNeeded flag is set, then we can do this if the activity 3281 // being launched is the same as the one making the call... or, as 3282 // a special case, if we do not know the caller then we count the 3283 // current top activity as the caller. 3284 if (onlyIfNeeded) { 3285 HistoryRecord checkedCaller = sourceRecord; 3286 if (checkedCaller == null) { 3287 checkedCaller = topRunningNonDelayedActivityLocked(notTop); 3288 } 3289 if (!checkedCaller.realActivity.equals(r.realActivity)) { 3290 // Caller is not the same as launcher, so always needed. 3291 onlyIfNeeded = false; 3292 } 3293 } 3294 3295 if (grantedUriPermissions != null && callingUid > 0) { 3296 for (int i=0; i<grantedUriPermissions.length; i++) { 3297 grantUriPermissionLocked(callingUid, r.packageName, 3298 grantedUriPermissions[i], grantedMode, r); 3299 } 3300 } 3301 3302 grantUriPermissionFromIntentLocked(callingUid, r.packageName, 3303 intent, r); 3304 3305 if (sourceRecord == null) { 3306 // This activity is not being started from another... in this 3307 // case we -always- start a new task. 3308 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 3309 Log.w(TAG, "startActivity called from non-Activity context; forcing Intent.FLAG_ACTIVITY_NEW_TASK for: " 3310 + intent); 3311 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 3312 } 3313 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 3314 // The original activity who is starting us is running as a single 3315 // instance... this new activity it is starting must go on its 3316 // own task. 3317 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 3318 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE 3319 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 3320 // The activity being started is a single instance... it always 3321 // gets launched into its own task. 3322 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 3323 } 3324 3325 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 3326 // For whatever reason this activity is being launched into a new 3327 // task... yet the caller has requested a result back. Well, that 3328 // is pretty messed up, so instead immediately send back a cancel 3329 // and let the new task continue launched as normal without a 3330 // dependency on its originator. 3331 Log.w(TAG, "Activity is launching as a new task, so cancelling activity result."); 3332 sendActivityResultLocked(-1, 3333 r.resultTo, r.resultWho, r.requestCode, 3334 Activity.RESULT_CANCELED, null); 3335 r.resultTo = null; 3336 } 3337 3338 boolean addingToTask = false; 3339 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && 3340 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) 3341 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 3342 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 3343 // If bring to front is requested, and no result is requested, and 3344 // we can find a task that was started with this same 3345 // component, then instead of launching bring that one to the front. 3346 if (r.resultTo == null) { 3347 // See if there is a task to bring to the front. If this is 3348 // a SINGLE_INSTANCE activity, there can be one and only one 3349 // instance of it in the history, and it is always in its own 3350 // unique task, so we do a special search. 3351 HistoryRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE 3352 ? findTaskLocked(intent, r.info) 3353 : findActivityLocked(intent, r.info); 3354 if (taskTop != null) { 3355 if (taskTop.task.intent == null) { 3356 // This task was started because of movement of 3357 // the activity based on affinity... now that we 3358 // are actually launching it, we can assign the 3359 // base intent. 3360 taskTop.task.setIntent(intent, r.info); 3361 } 3362 // If the target task is not in the front, then we need 3363 // to bring it to the front... except... well, with 3364 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like 3365 // to have the same behavior as if a new instance was 3366 // being started, which means not bringing it to the front 3367 // if the caller is not itself in the front. 3368 HistoryRecord curTop = topRunningNonDelayedActivityLocked(notTop); 3369 if (curTop.task != taskTop.task) { 3370 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); 3371 boolean callerAtFront = sourceRecord == null 3372 || curTop.task == sourceRecord.task; 3373 if (callerAtFront) { 3374 // We really do want to push this one into the 3375 // user's face, right now. 3376 moveTaskToFrontLocked(taskTop.task, r); 3377 } 3378 } 3379 // If the caller has requested that the target task be 3380 // reset, then do so. 3381 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 3382 taskTop = resetTaskIfNeededLocked(taskTop, r); 3383 } 3384 if (onlyIfNeeded) { 3385 // We don't need to start a new activity, and 3386 // the client said not to do anything if that 3387 // is the case, so this is it! And for paranoia, make 3388 // sure we have correctly resumed the top activity. 3389 if (doResume) { 3390 resumeTopActivityLocked(null); 3391 } 3392 return START_RETURN_INTENT_TO_CALLER; 3393 } 3394 if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0 3395 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 3396 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 3397 // In this situation we want to remove all activities 3398 // from the task up to the one being started. In most 3399 // cases this means we are resetting the task to its 3400 // initial state. 3401 HistoryRecord top = performClearTaskLocked( 3402 taskTop.task.taskId, r, launchFlags, true); 3403 if (top != null) { 3404 if (top.frontOfTask) { 3405 // Activity aliases may mean we use different 3406 // intents for the top activity, so make sure 3407 // the task now has the identity of the new 3408 // intent. 3409 top.task.setIntent(r.intent, r.info); 3410 } 3411 logStartActivity(LOG_AM_NEW_INTENT, r, top.task); 3412 deliverNewIntentLocked(top, r.intent); 3413 } else { 3414 // A special case: we need to 3415 // start the activity because it is not currently 3416 // running, and the caller has asked to clear the 3417 // current task to have this activity at the top. 3418 addingToTask = true; 3419 // Now pretend like this activity is being started 3420 // by the top of its task, so it is put in the 3421 // right place. 3422 sourceRecord = taskTop; 3423 } 3424 } else if (r.realActivity.equals(taskTop.task.realActivity)) { 3425 // In this case the top activity on the task is the 3426 // same as the one being launched, so we take that 3427 // as a request to bring the task to the foreground. 3428 // If the top activity in the task is the root 3429 // activity, deliver this new intent to it if it 3430 // desires. 3431 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 3432 && taskTop.realActivity.equals(r.realActivity)) { 3433 logStartActivity(LOG_AM_NEW_INTENT, r, taskTop.task); 3434 if (taskTop.frontOfTask) { 3435 taskTop.task.setIntent(r.intent, r.info); 3436 } 3437 deliverNewIntentLocked(taskTop, r.intent); 3438 } else if (!r.intent.filterEquals(taskTop.task.intent)) { 3439 // In this case we are launching the root activity 3440 // of the task, but with a different intent. We 3441 // should start a new instance on top. 3442 addingToTask = true; 3443 sourceRecord = taskTop; 3444 } 3445 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) { 3446 // In this case an activity is being launched in to an 3447 // existing task, without resetting that task. This 3448 // is typically the situation of launching an activity 3449 // from a notification or shortcut. We want to place 3450 // the new activity on top of the current task. 3451 addingToTask = true; 3452 sourceRecord = taskTop; 3453 } else if (!taskTop.task.rootWasReset) { 3454 // In this case we are launching in to an existing task 3455 // that has not yet been started from its front door. 3456 // The current task has been brought to the front. 3457 // Ideally, we'd probably like to place this new task 3458 // at the bottom of its stack, but that's a little hard 3459 // to do with the current organization of the code so 3460 // for now we'll just drop it. 3461 taskTop.task.setIntent(r.intent, r.info); 3462 } 3463 if (!addingToTask) { 3464 // We didn't do anything... but it was needed (a.k.a., client 3465 // don't use that intent!) And for paranoia, make 3466 // sure we have correctly resumed the top activity. 3467 if (doResume) { 3468 resumeTopActivityLocked(null); 3469 } 3470 return START_TASK_TO_FRONT; 3471 } 3472 } 3473 } 3474 } 3475 3476 //String uri = r.intent.toURI(); 3477 //Intent intent2 = new Intent(uri); 3478 //Log.i(TAG, "Given intent: " + r.intent); 3479 //Log.i(TAG, "URI is: " + uri); 3480 //Log.i(TAG, "To intent: " + intent2); 3481 3482 if (r.packageName != null) { 3483 // If the activity being launched is the same as the one currently 3484 // at the top, then we need to check if it should only be launched 3485 // once. 3486 HistoryRecord top = topRunningNonDelayedActivityLocked(notTop); 3487 if (top != null && r.resultTo == null) { 3488 if (top.realActivity.equals(r.realActivity)) { 3489 if (top.app != null && top.app.thread != null) { 3490 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 3491 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP 3492 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 3493 logStartActivity(LOG_AM_NEW_INTENT, top, top.task); 3494 // For paranoia, make sure we have correctly 3495 // resumed the top activity. 3496 if (doResume) { 3497 resumeTopActivityLocked(null); 3498 } 3499 if (onlyIfNeeded) { 3500 // We don't need to start a new activity, and 3501 // the client said not to do anything if that 3502 // is the case, so this is it! 3503 return START_RETURN_INTENT_TO_CALLER; 3504 } 3505 deliverNewIntentLocked(top, r.intent); 3506 return START_DELIVERED_TO_TOP; 3507 } 3508 } 3509 } 3510 } 3511 3512 } else { 3513 if (r.resultTo != null) { 3514 sendActivityResultLocked(-1, 3515 r.resultTo, r.resultWho, r.requestCode, 3516 Activity.RESULT_CANCELED, null); 3517 } 3518 return START_CLASS_NOT_FOUND; 3519 } 3520 3521 boolean newTask = false; 3522 3523 // Should this be considered a new task? 3524 if (r.resultTo == null && !addingToTask 3525 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 3526 // todo: should do better management of integers. 3527 mCurTask++; 3528 if (mCurTask <= 0) { 3529 mCurTask = 1; 3530 } 3531 r.task = new TaskRecord(mCurTask, r.info, intent, 3532 (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0); 3533 if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r 3534 + " in new task " + r.task); 3535 newTask = true; 3536 addRecentTask(r.task); 3537 3538 } else if (sourceRecord != null) { 3539 if (!addingToTask && 3540 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 3541 // In this case, we are adding the activity to an existing 3542 // task, but the caller has asked to clear that task if the 3543 // activity is already running. 3544 HistoryRecord top = performClearTaskLocked( 3545 sourceRecord.task.taskId, r, launchFlags, true); 3546 if (top != null) { 3547 logStartActivity(LOG_AM_NEW_INTENT, r, top.task); 3548 deliverNewIntentLocked(top, r.intent); 3549 // For paranoia, make sure we have correctly 3550 // resumed the top activity. 3551 if (doResume) { 3552 resumeTopActivityLocked(null); 3553 } 3554 return START_DELIVERED_TO_TOP; 3555 } 3556 } else if (!addingToTask && 3557 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { 3558 // In this case, we are launching an activity in our own task 3559 // that may already be running somewhere in the history, and 3560 // we want to shuffle it to the front of the stack if so. 3561 int where = findActivityInHistoryLocked(r, sourceRecord.task.taskId); 3562 if (where >= 0) { 3563 HistoryRecord top = moveActivityToFrontLocked(where); 3564 logStartActivity(LOG_AM_NEW_INTENT, r, top.task); 3565 deliverNewIntentLocked(top, r.intent); 3566 if (doResume) { 3567 resumeTopActivityLocked(null); 3568 } 3569 return START_DELIVERED_TO_TOP; 3570 } 3571 } 3572 // An existing activity is starting this new activity, so we want 3573 // to keep the new one in the same task as the one that is starting 3574 // it. 3575 r.task = sourceRecord.task; 3576 if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r 3577 + " in existing task " + r.task); 3578 3579 } else { 3580 // This not being started from an existing activity, and not part 3581 // of a new task... just put it in the top task, though these days 3582 // this case should never happen. 3583 final int N = mHistory.size(); 3584 HistoryRecord prev = 3585 N > 0 ? (HistoryRecord)mHistory.get(N-1) : null; 3586 r.task = prev != null 3587 ? prev.task 3588 : new TaskRecord(mCurTask, r.info, intent, 3589 (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0); 3590 if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r 3591 + " in new guessed " + r.task); 3592 } 3593 if (newTask) { 3594 EventLog.writeEvent(LOG_AM_CREATE_TASK, r.task.taskId); 3595 } 3596 logStartActivity(LOG_AM_CREATE_ACTIVITY, r, r.task); 3597 startActivityLocked(r, newTask, doResume); 3598 return START_SUCCESS; 3599 } 3600 3601 public final int startActivity(IApplicationThread caller, 3602 Intent intent, String resolvedType, Uri[] grantedUriPermissions, 3603 int grantedMode, IBinder resultTo, 3604 String resultWho, int requestCode, boolean onlyIfNeeded, 3605 boolean debug) { 3606 // Refuse possible leaked file descriptors 3607 if (intent != null && intent.hasFileDescriptors()) { 3608 throw new IllegalArgumentException("File descriptors passed in Intent"); 3609 } 3610 3611 final boolean componentSpecified = intent.getComponent() != null; 3612 3613 // Don't modify the client's object! 3614 intent = new Intent(intent); 3615 3616 // Collect information about the target of the Intent. 3617 ActivityInfo aInfo; 3618 try { 3619 ResolveInfo rInfo = 3620 ActivityThread.getPackageManager().resolveIntent( 3621 intent, resolvedType, 3622 PackageManager.MATCH_DEFAULT_ONLY 3623 | STOCK_PM_FLAGS); 3624 aInfo = rInfo != null ? rInfo.activityInfo : null; 3625 } catch (RemoteException e) { 3626 aInfo = null; 3627 } 3628 3629 if (aInfo != null) { 3630 // Store the found target back into the intent, because now that 3631 // we have it we never want to do this again. For example, if the 3632 // user navigates back to this point in the history, we should 3633 // always restart the exact same activity. 3634 intent.setComponent(new ComponentName( 3635 aInfo.applicationInfo.packageName, aInfo.name)); 3636 3637 // Don't debug things in the system process 3638 if (debug) { 3639 if (!aInfo.processName.equals("system")) { 3640 setDebugApp(aInfo.processName, true, false); 3641 } 3642 } 3643 } 3644 3645 synchronized(this) { 3646 final long origId = Binder.clearCallingIdentity(); 3647 int res = startActivityLocked(caller, intent, resolvedType, 3648 grantedUriPermissions, grantedMode, aInfo, 3649 resultTo, resultWho, requestCode, -1, -1, 3650 onlyIfNeeded, componentSpecified); 3651 Binder.restoreCallingIdentity(origId); 3652 return res; 3653 } 3654 } 3655 3656 public int startActivityIntentSender(IApplicationThread caller, 3657 IntentSender intent, Intent fillInIntent, String resolvedType, 3658 IBinder resultTo, String resultWho, int requestCode, 3659 int flagsMask, int flagsValues) { 3660 // Refuse possible leaked file descriptors 3661 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3662 throw new IllegalArgumentException("File descriptors passed in Intent"); 3663 } 3664 3665 IIntentSender sender = intent.getTarget(); 3666 if (!(sender instanceof PendingIntentRecord)) { 3667 throw new IllegalArgumentException("Bad PendingIntent object"); 3668 } 3669 3670 PendingIntentRecord pir = (PendingIntentRecord)sender; 3671 3672 synchronized (this) { 3673 // If this is coming from the currently resumed activity, it is 3674 // effectively saying that app switches are allowed at this point. 3675 if (mResumedActivity != null 3676 && mResumedActivity.info.applicationInfo.uid == 3677 Binder.getCallingUid()) { 3678 mAppSwitchesAllowedTime = 0; 3679 } 3680 } 3681 3682 return pir.sendInner(0, fillInIntent, resolvedType, 3683 null, resultTo, resultWho, requestCode, flagsMask, flagsValues); 3684 } 3685 3686 public boolean startNextMatchingActivity(IBinder callingActivity, 3687 Intent intent) { 3688 // Refuse possible leaked file descriptors 3689 if (intent != null && intent.hasFileDescriptors() == true) { 3690 throw new IllegalArgumentException("File descriptors passed in Intent"); 3691 } 3692 3693 synchronized (this) { 3694 int index = indexOfTokenLocked(callingActivity); 3695 if (index < 0) { 3696 return false; 3697 } 3698 HistoryRecord r = (HistoryRecord)mHistory.get(index); 3699 if (r.app == null || r.app.thread == null) { 3700 // The caller is not running... d'oh! 3701 return false; 3702 } 3703 intent = new Intent(intent); 3704 // The caller is not allowed to change the data. 3705 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3706 // And we are resetting to find the next component... 3707 intent.setComponent(null); 3708 3709 ActivityInfo aInfo = null; 3710 try { 3711 List<ResolveInfo> resolves = 3712 ActivityThread.getPackageManager().queryIntentActivities( 3713 intent, r.resolvedType, 3714 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS); 3715 3716 // Look for the original activity in the list... 3717 final int N = resolves != null ? resolves.size() : 0; 3718 for (int i=0; i<N; i++) { 3719 ResolveInfo rInfo = resolves.get(i); 3720 if (rInfo.activityInfo.packageName.equals(r.packageName) 3721 && rInfo.activityInfo.name.equals(r.info.name)) { 3722 // We found the current one... the next matching is 3723 // after it. 3724 i++; 3725 if (i<N) { 3726 aInfo = resolves.get(i).activityInfo; 3727 } 3728 break; 3729 } 3730 } 3731 } catch (RemoteException e) { 3732 } 3733 3734 if (aInfo == null) { 3735 // Nobody who is next! 3736 return false; 3737 } 3738 3739 intent.setComponent(new ComponentName( 3740 aInfo.applicationInfo.packageName, aInfo.name)); 3741 intent.setFlags(intent.getFlags()&~( 3742 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3743 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3744 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3745 Intent.FLAG_ACTIVITY_NEW_TASK)); 3746 3747 // Okay now we need to start the new activity, replacing the 3748 // currently running activity. This is a little tricky because 3749 // we want to start the new one as if the current one is finished, 3750 // but not finish the current one first so that there is no flicker. 3751 // And thus... 3752 final boolean wasFinishing = r.finishing; 3753 r.finishing = true; 3754 3755 // Propagate reply information over to the new activity. 3756 final HistoryRecord resultTo = r.resultTo; 3757 final String resultWho = r.resultWho; 3758 final int requestCode = r.requestCode; 3759 r.resultTo = null; 3760 if (resultTo != null) { 3761 resultTo.removeResultsLocked(r, resultWho, requestCode); 3762 } 3763 3764 final long origId = Binder.clearCallingIdentity(); 3765 // XXX we are not dealing with propagating grantedUriPermissions... 3766 // those are not yet exposed to user code, so there is no need. 3767 int res = startActivityLocked(r.app.thread, intent, 3768 r.resolvedType, null, 0, aInfo, resultTo, resultWho, 3769 requestCode, -1, r.launchedFromUid, false, false); 3770 Binder.restoreCallingIdentity(origId); 3771 3772 r.finishing = wasFinishing; 3773 if (res != START_SUCCESS) { 3774 return false; 3775 } 3776 return true; 3777 } 3778 } 3779 3780 public final int startActivityInPackage(int uid, 3781 Intent intent, String resolvedType, IBinder resultTo, 3782 String resultWho, int requestCode, boolean onlyIfNeeded) { 3783 3784 // This is so super not safe, that only the system (or okay root) 3785 // can do it. 3786 final int callingUid = Binder.getCallingUid(); 3787 if (callingUid != 0 && callingUid != Process.myUid()) { 3788 throw new SecurityException( 3789 "startActivityInPackage only available to the system"); 3790 } 3791 3792 final boolean componentSpecified = intent.getComponent() != null; 3793 3794 // Don't modify the client's object! 3795 intent = new Intent(intent); 3796 3797 // Collect information about the target of the Intent. 3798 ActivityInfo aInfo; 3799 try { 3800 ResolveInfo rInfo = 3801 ActivityThread.getPackageManager().resolveIntent( 3802 intent, resolvedType, 3803 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS); 3804 aInfo = rInfo != null ? rInfo.activityInfo : null; 3805 } catch (RemoteException e) { 3806 aInfo = null; 3807 } 3808 3809 if (aInfo != null) { 3810 // Store the found target back into the intent, because now that 3811 // we have it we never want to do this again. For example, if the 3812 // user navigates back to this point in the history, we should 3813 // always restart the exact same activity. 3814 intent.setComponent(new ComponentName( 3815 aInfo.applicationInfo.packageName, aInfo.name)); 3816 } 3817 3818 synchronized(this) { 3819 return startActivityLocked(null, intent, resolvedType, 3820 null, 0, aInfo, resultTo, resultWho, requestCode, -1, uid, 3821 onlyIfNeeded, componentSpecified); 3822 } 3823 } 3824 3825 private final void addRecentTask(TaskRecord task) { 3826 // Remove any existing entries that are the same kind of task. 3827 int N = mRecentTasks.size(); 3828 for (int i=0; i<N; i++) { 3829 TaskRecord tr = mRecentTasks.get(i); 3830 if ((task.affinity != null && task.affinity.equals(tr.affinity)) 3831 || (task.intent != null && task.intent.filterEquals(tr.intent))) { 3832 mRecentTasks.remove(i); 3833 i--; 3834 N--; 3835 if (task.intent == null) { 3836 // If the new recent task we are adding is not fully 3837 // specified, then replace it with the existing recent task. 3838 task = tr; 3839 } 3840 } 3841 } 3842 if (N >= MAX_RECENT_TASKS) { 3843 mRecentTasks.remove(N-1); 3844 } 3845 mRecentTasks.add(0, task); 3846 } 3847 3848 public void setRequestedOrientation(IBinder token, 3849 int requestedOrientation) { 3850 synchronized (this) { 3851 int index = indexOfTokenLocked(token); 3852 if (index < 0) { 3853 return; 3854 } 3855 HistoryRecord r = (HistoryRecord)mHistory.get(index); 3856 final long origId = Binder.clearCallingIdentity(); 3857 mWindowManager.setAppOrientation(r, requestedOrientation); 3858 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3859 mConfiguration, 3860 r.mayFreezeScreenLocked(r.app) ? r : null); 3861 if (config != null) { 3862 r.frozenBeforeDestroy = true; 3863 if (!updateConfigurationLocked(config, r)) { 3864 resumeTopActivityLocked(null); 3865 } 3866 } 3867 Binder.restoreCallingIdentity(origId); 3868 } 3869 } 3870 3871 public int getRequestedOrientation(IBinder token) { 3872 synchronized (this) { 3873 int index = indexOfTokenLocked(token); 3874 if (index < 0) { 3875 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3876 } 3877 HistoryRecord r = (HistoryRecord)mHistory.get(index); 3878 return mWindowManager.getAppOrientation(r); 3879 } 3880 } 3881 3882 private final void stopActivityLocked(HistoryRecord r) { 3883 if (DEBUG_SWITCH) Log.d(TAG, "Stopping: " + r); 3884 if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0 3885 || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) { 3886 if (!r.finishing) { 3887 requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null, 3888 "no-history"); 3889 } 3890 } else if (r.app != null && r.app.thread != null) { 3891 if (mFocusedActivity == r) { 3892 setFocusedActivityLocked(topRunningActivityLocked(null)); 3893 } 3894 r.resumeKeyDispatchingLocked(); 3895 try { 3896 r.stopped = false; 3897 r.state = ActivityState.STOPPING; 3898 if (DEBUG_VISBILITY) Log.v( 3899 TAG, "Stopping visible=" + r.visible + " for " + r); 3900 if (!r.visible) { 3901 mWindowManager.setAppVisibility(r, false); 3902 } 3903 r.app.thread.scheduleStopActivity(r, r.visible, r.configChangeFlags); 3904 } catch (Exception e) { 3905 // Maybe just ignore exceptions here... if the process 3906 // has crashed, our death notification will clean things 3907 // up. 3908 Log.w(TAG, "Exception thrown during pause", e); 3909 // Just in case, assume it to be stopped. 3910 r.stopped = true; 3911 r.state = ActivityState.STOPPED; 3912 if (r.configDestroy) { 3913 destroyActivityLocked(r, true); 3914 } 3915 } 3916 } 3917 } 3918 3919 /** 3920 * @return Returns true if the activity is being finished, false if for 3921 * some reason it is being left as-is. 3922 */ 3923 private final boolean requestFinishActivityLocked(IBinder token, int resultCode, 3924 Intent resultData, String reason) { 3925 if (DEBUG_RESULTS) Log.v( 3926 TAG, "Finishing activity: token=" + token 3927 + ", result=" + resultCode + ", data=" + resultData); 3928 3929 int index = indexOfTokenLocked(token); 3930 if (index < 0) { 3931 return false; 3932 } 3933 HistoryRecord r = (HistoryRecord)mHistory.get(index); 3934 3935 // Is this the last activity left? 3936 boolean lastActivity = true; 3937 for (int i=mHistory.size()-1; i>=0; i--) { 3938 HistoryRecord p = (HistoryRecord)mHistory.get(i); 3939 if (!p.finishing && p != r) { 3940 lastActivity = false; 3941 break; 3942 } 3943 } 3944 3945 // If this is the last activity, but it is the home activity, then 3946 // just don't finish it. 3947 if (lastActivity) { 3948 if (r.intent.hasCategory(Intent.CATEGORY_HOME)) { 3949 return false; 3950 } 3951 } 3952 3953 finishActivityLocked(r, index, resultCode, resultData, reason); 3954 return true; 3955 } 3956 3957 /** 3958 * @return Returns true if this activity has been removed from the history 3959 * list, or false if it is still in the list and will be removed later. 3960 */ 3961 private final boolean finishActivityLocked(HistoryRecord r, int index, 3962 int resultCode, Intent resultData, String reason) { 3963 if (r.finishing) { 3964 Log.w(TAG, "Duplicate finish request for " + r); 3965 return false; 3966 } 3967 3968 r.finishing = true; 3969 EventLog.writeEvent(LOG_AM_FINISH_ACTIVITY, 3970 System.identityHashCode(r), 3971 r.task.taskId, r.shortComponentName, reason); 3972 r.task.numActivities--; 3973 if (r.frontOfTask && index < (mHistory.size()-1)) { 3974 HistoryRecord next = (HistoryRecord)mHistory.get(index+1); 3975 if (next.task == r.task) { 3976 next.frontOfTask = true; 3977 } 3978 } 3979 3980 r.pauseKeyDispatchingLocked(); 3981 if (mFocusedActivity == r) { 3982 setFocusedActivityLocked(topRunningActivityLocked(null)); 3983 } 3984 3985 // send the result 3986 HistoryRecord resultTo = r.resultTo; 3987 if (resultTo != null) { 3988 if (DEBUG_RESULTS) Log.v(TAG, "Adding result to " + resultTo 3989 + " who=" + r.resultWho + " req=" + r.requestCode 3990 + " res=" + resultCode + " data=" + resultData); 3991 if (r.info.applicationInfo.uid > 0) { 3992 grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid, 3993 r.packageName, resultData, r); 3994 } 3995 resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode, 3996 resultData); 3997 r.resultTo = null; 3998 } 3999 else if (DEBUG_RESULTS) Log.v(TAG, "No result destination from " + r); 4000 4001 // Make sure this HistoryRecord is not holding on to other resources, 4002 // because clients have remote IPC references to this object so we 4003 // can't assume that will go away and want to avoid circular IPC refs. 4004 r.results = null; 4005 r.pendingResults = null; 4006 r.newIntents = null; 4007 r.icicle = null; 4008 4009 if (mPendingThumbnails.size() > 0) { 4010 // There are clients waiting to receive thumbnails so, in case 4011 // this is an activity that someone is waiting for, add it 4012 // to the pending list so we can correctly update the clients. 4013 mCancelledThumbnails.add(r); 4014 } 4015 4016 if (mResumedActivity == r) { 4017 boolean endTask = index <= 0 4018 || ((HistoryRecord)mHistory.get(index-1)).task != r.task; 4019 if (DEBUG_TRANSITION) Log.v(TAG, 4020 "Prepare close transition: finishing " + r); 4021 mWindowManager.prepareAppTransition(endTask 4022 ? WindowManagerPolicy.TRANSIT_TASK_CLOSE 4023 : WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE); 4024 4025 // Tell window manager to prepare for this one to be removed. 4026 mWindowManager.setAppVisibility(r, false); 4027 4028 if (mPausingActivity == null) { 4029 if (DEBUG_PAUSE) Log.v(TAG, "Finish needs to pause: " + r); 4030 if (DEBUG_USER_LEAVING) Log.v(TAG, "finish() => pause with userLeaving=false"); 4031 startPausingLocked(false, false); 4032 } 4033 4034 } else if (r.state != ActivityState.PAUSING) { 4035 // If the activity is PAUSING, we will complete the finish once 4036 // it is done pausing; else we can just directly finish it here. 4037 if (DEBUG_PAUSE) Log.v(TAG, "Finish not pausing: " + r); 4038 return finishCurrentActivityLocked(r, index, 4039 FINISH_AFTER_PAUSE) == null; 4040 } else { 4041 if (DEBUG_PAUSE) Log.v(TAG, "Finish waiting for pause of: " + r); 4042 } 4043 4044 return false; 4045 } 4046 4047 private static final int FINISH_IMMEDIATELY = 0; 4048 private static final int FINISH_AFTER_PAUSE = 1; 4049 private static final int FINISH_AFTER_VISIBLE = 2; 4050 4051 private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r, 4052 int mode) { 4053 final int index = indexOfTokenLocked(r); 4054 if (index < 0) { 4055 return null; 4056 } 4057 4058 return finishCurrentActivityLocked(r, index, mode); 4059 } 4060 4061 private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r, 4062 int index, int mode) { 4063 // First things first: if this activity is currently visible, 4064 // and the resumed activity is not yet visible, then hold off on 4065 // finishing until the resumed one becomes visible. 4066 if (mode == FINISH_AFTER_VISIBLE && r.nowVisible) { 4067 if (!mStoppingActivities.contains(r)) { 4068 mStoppingActivities.add(r); 4069 if (mStoppingActivities.size() > 3) { 4070 // If we already have a few activities waiting to stop, 4071 // then give up on things going idle and start clearing 4072 // them out. 4073 Message msg = Message.obtain(); 4074 msg.what = ActivityManagerService.IDLE_NOW_MSG; 4075 mHandler.sendMessage(msg); 4076 } 4077 } 4078 r.state = ActivityState.STOPPING; 4079 updateOomAdjLocked(); 4080 return r; 4081 } 4082 4083 // make sure the record is cleaned out of other places. 4084 mStoppingActivities.remove(r); 4085 mWaitingVisibleActivities.remove(r); 4086 if (mResumedActivity == r) { 4087 mResumedActivity = null; 4088 } 4089 final ActivityState prevState = r.state; 4090 r.state = ActivityState.FINISHING; 4091 4092 if (mode == FINISH_IMMEDIATELY 4093 || prevState == ActivityState.STOPPED 4094 || prevState == ActivityState.INITIALIZING) { 4095 // If this activity is already stopped, we can just finish 4096 // it right now. 4097 return destroyActivityLocked(r, true) ? null : r; 4098 } else { 4099 // Need to go through the full pause cycle to get this 4100 // activity into the stopped state and then finish it. 4101 if (localLOGV) Log.v(TAG, "Enqueueing pending finish: " + r); 4102 mFinishingActivities.add(r); 4103 resumeTopActivityLocked(null); 4104 } 4105 return r; 4106 } 4107 4108 /** 4109 * This is the internal entry point for handling Activity.finish(). 4110 * 4111 * @param token The Binder token referencing the Activity we want to finish. 4112 * @param resultCode Result code, if any, from this Activity. 4113 * @param resultData Result data (Intent), if any, from this Activity. 4114 * 4115 * @result Returns true if the activity successfully finished, or false if it is still running. 4116 */ 4117 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 4118 // Refuse possible leaked file descriptors 4119 if (resultData != null && resultData.hasFileDescriptors() == true) { 4120 throw new IllegalArgumentException("File descriptors passed in Intent"); 4121 } 4122 4123 synchronized(this) { 4124 if (mController != null) { 4125 // Find the first activity that is not finishing. 4126 HistoryRecord next = topRunningActivityLocked(token, 0); 4127 if (next != null) { 4128 // ask watcher if this is allowed 4129 boolean resumeOK = true; 4130 try { 4131 resumeOK = mController.activityResuming(next.packageName); 4132 } catch (RemoteException e) { 4133 mController = null; 4134 } 4135 4136 if (!resumeOK) { 4137 return false; 4138 } 4139 } 4140 } 4141 final long origId = Binder.clearCallingIdentity(); 4142 boolean res = requestFinishActivityLocked(token, resultCode, 4143 resultData, "app-request"); 4144 Binder.restoreCallingIdentity(origId); 4145 return res; 4146 } 4147 } 4148 4149 void sendActivityResultLocked(int callingUid, HistoryRecord r, 4150 String resultWho, int requestCode, int resultCode, Intent data) { 4151 4152 if (callingUid > 0) { 4153 grantUriPermissionFromIntentLocked(callingUid, r.packageName, 4154 data, r); 4155 } 4156 4157 if (DEBUG_RESULTS) Log.v(TAG, "Send activity result to " + r 4158 + " : who=" + resultWho + " req=" + requestCode 4159 + " res=" + resultCode + " data=" + data); 4160 if (mResumedActivity == r && r.app != null && r.app.thread != null) { 4161 try { 4162 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>(); 4163 list.add(new ResultInfo(resultWho, requestCode, 4164 resultCode, data)); 4165 r.app.thread.scheduleSendResult(r, list); 4166 return; 4167 } catch (Exception e) { 4168 Log.w(TAG, "Exception thrown sending result to " + r, e); 4169 } 4170 } 4171 4172 r.addResultLocked(null, resultWho, requestCode, resultCode, data); 4173 } 4174 4175 public final void finishSubActivity(IBinder token, String resultWho, 4176 int requestCode) { 4177 synchronized(this) { 4178 int index = indexOfTokenLocked(token); 4179 if (index < 0) { 4180 return; 4181 } 4182 HistoryRecord self = (HistoryRecord)mHistory.get(index); 4183 4184 final long origId = Binder.clearCallingIdentity(); 4185 4186 int i; 4187 for (i=mHistory.size()-1; i>=0; i--) { 4188 HistoryRecord r = (HistoryRecord)mHistory.get(i); 4189 if (r.resultTo == self && r.requestCode == requestCode) { 4190 if ((r.resultWho == null && resultWho == null) || 4191 (r.resultWho != null && r.resultWho.equals(resultWho))) { 4192 finishActivityLocked(r, i, 4193 Activity.RESULT_CANCELED, null, "request-sub"); 4194 } 4195 } 4196 } 4197 4198 Binder.restoreCallingIdentity(origId); 4199 } 4200 } 4201 4202 public void overridePendingTransition(IBinder token, String packageName, 4203 int enterAnim, int exitAnim) { 4204 synchronized(this) { 4205 int index = indexOfTokenLocked(token); 4206 if (index < 0) { 4207 return; 4208 } 4209 HistoryRecord self = (HistoryRecord)mHistory.get(index); 4210 4211 final long origId = Binder.clearCallingIdentity(); 4212 4213 if (self.state == ActivityState.RESUMED 4214 || self.state == ActivityState.PAUSING) { 4215 mWindowManager.overridePendingAppTransition(packageName, 4216 enterAnim, exitAnim); 4217 } 4218 4219 Binder.restoreCallingIdentity(origId); 4220 } 4221 } 4222 4223 /** 4224 * Perform clean-up of service connections in an activity record. 4225 */ 4226 private final void cleanUpActivityServicesLocked(HistoryRecord r) { 4227 // Throw away any services that have been bound by this activity. 4228 if (r.connections != null) { 4229 Iterator<ConnectionRecord> it = r.connections.iterator(); 4230 while (it.hasNext()) { 4231 ConnectionRecord c = it.next(); 4232 removeConnectionLocked(c, null, r); 4233 } 4234 r.connections = null; 4235 } 4236 } 4237 4238 /** 4239 * Perform the common clean-up of an activity record. This is called both 4240 * as part of destroyActivityLocked() (when destroying the client-side 4241 * representation) and cleaning things up as a result of its hosting 4242 * processing going away, in which case there is no remaining client-side 4243 * state to destroy so only the cleanup here is needed. 4244 */ 4245 private final void cleanUpActivityLocked(HistoryRecord r, boolean cleanServices) { 4246 if (mResumedActivity == r) { 4247 mResumedActivity = null; 4248 } 4249 if (mFocusedActivity == r) { 4250 mFocusedActivity = null; 4251 } 4252 4253 r.configDestroy = false; 4254 r.frozenBeforeDestroy = false; 4255 4256 // Make sure this record is no longer in the pending finishes list. 4257 // This could happen, for example, if we are trimming activities 4258 // down to the max limit while they are still waiting to finish. 4259 mFinishingActivities.remove(r); 4260 mWaitingVisibleActivities.remove(r); 4261 4262 // Remove any pending results. 4263 if (r.finishing && r.pendingResults != null) { 4264 for (WeakReference<PendingIntentRecord> apr : r.pendingResults) { 4265 PendingIntentRecord rec = apr.get(); 4266 if (rec != null) { 4267 cancelIntentSenderLocked(rec, false); 4268 } 4269 } 4270 r.pendingResults = null; 4271 } 4272 4273 if (cleanServices) { 4274 cleanUpActivityServicesLocked(r); 4275 } 4276 4277 if (mPendingThumbnails.size() > 0) { 4278 // There are clients waiting to receive thumbnails so, in case 4279 // this is an activity that someone is waiting for, add it 4280 // to the pending list so we can correctly update the clients. 4281 mCancelledThumbnails.add(r); 4282 } 4283 4284 // Get rid of any pending idle timeouts. 4285 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); 4286 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 4287 } 4288 4289 private final void removeActivityFromHistoryLocked(HistoryRecord r) { 4290 if (r.state != ActivityState.DESTROYED) { 4291 mHistory.remove(r); 4292 r.inHistory = false; 4293 r.state = ActivityState.DESTROYED; 4294 mWindowManager.removeAppToken(r); 4295 if (VALIDATE_TOKENS) { 4296 mWindowManager.validateAppTokens(mHistory); 4297 } 4298 cleanUpActivityServicesLocked(r); 4299 removeActivityUriPermissionsLocked(r); 4300 } 4301 } 4302 4303 /** 4304 * Destroy the current CLIENT SIDE instance of an activity. This may be 4305 * called both when actually finishing an activity, or when performing 4306 * a configuration switch where we destroy the current client-side object 4307 * but then create a new client-side object for this same HistoryRecord. 4308 */ 4309 private final boolean destroyActivityLocked(HistoryRecord r, 4310 boolean removeFromApp) { 4311 if (DEBUG_SWITCH) Log.v( 4312 TAG, "Removing activity: token=" + r 4313 + ", app=" + (r.app != null ? r.app.processName : "(null)")); 4314 EventLog.writeEvent(LOG_AM_DESTROY_ACTIVITY, 4315 System.identityHashCode(r), 4316 r.task.taskId, r.shortComponentName); 4317 4318 boolean removedFromHistory = false; 4319 4320 cleanUpActivityLocked(r, false); 4321 4322 if (r.app != null) { 4323 if (removeFromApp) { 4324 int idx = r.app.activities.indexOf(r); 4325 if (idx >= 0) { 4326 r.app.activities.remove(idx); 4327 } 4328 if (r.persistent) { 4329 decPersistentCountLocked(r.app); 4330 } 4331 } 4332 4333 boolean skipDestroy = false; 4334 4335 try { 4336 if (DEBUG_SWITCH) Log.i(TAG, "Destroying: " + r); 4337 r.app.thread.scheduleDestroyActivity(r, r.finishing, 4338 r.configChangeFlags); 4339 } catch (Exception e) { 4340 // We can just ignore exceptions here... if the process 4341 // has crashed, our death notification will clean things 4342 // up. 4343 //Log.w(TAG, "Exception thrown during finish", e); 4344 if (r.finishing) { 4345 removeActivityFromHistoryLocked(r); 4346 removedFromHistory = true; 4347 skipDestroy = true; 4348 } 4349 } 4350 4351 r.app = null; 4352 r.nowVisible = false; 4353 4354 if (r.finishing && !skipDestroy) { 4355 r.state = ActivityState.DESTROYING; 4356 Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG); 4357 msg.obj = r; 4358 mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT); 4359 } else { 4360 r.state = ActivityState.DESTROYED; 4361 } 4362 } else { 4363 // remove this record from the history. 4364 if (r.finishing) { 4365 removeActivityFromHistoryLocked(r); 4366 removedFromHistory = true; 4367 } else { 4368 r.state = ActivityState.DESTROYED; 4369 } 4370 } 4371 4372 r.configChangeFlags = 0; 4373 4374 if (!mLRUActivities.remove(r)) { 4375 Log.w(TAG, "Activity " + r + " being finished, but not in LRU list"); 4376 } 4377 4378 return removedFromHistory; 4379 } 4380 4381 private static void removeHistoryRecordsForAppLocked(ArrayList list, 4382 ProcessRecord app) 4383 { 4384 int i = list.size(); 4385 if (localLOGV) Log.v( 4386 TAG, "Removing app " + app + " from list " + list 4387 + " with " + i + " entries"); 4388 while (i > 0) { 4389 i--; 4390 HistoryRecord r = (HistoryRecord)list.get(i); 4391 if (localLOGV) Log.v( 4392 TAG, "Record #" + i + " " + r + ": app=" + r.app); 4393 if (r.app == app) { 4394 if (localLOGV) Log.v(TAG, "Removing this entry!"); 4395 list.remove(i); 4396 } 4397 } 4398 } 4399 4400 /** 4401 * Main function for removing an existing process from the activity manager 4402 * as a result of that process going away. Clears out all connections 4403 * to the process. 4404 */ 4405 private final void handleAppDiedLocked(ProcessRecord app, 4406 boolean restarting) { 4407 cleanUpApplicationRecordLocked(app, restarting, -1); 4408 if (!restarting) { 4409 mLRUProcesses.remove(app); 4410 } 4411 4412 // Just in case... 4413 if (mPausingActivity != null && mPausingActivity.app == app) { 4414 if (DEBUG_PAUSE) Log.v(TAG, "App died while pausing: " + mPausingActivity); 4415 mPausingActivity = null; 4416 } 4417 if (mLastPausedActivity != null && mLastPausedActivity.app == app) { 4418 mLastPausedActivity = null; 4419 } 4420 4421 // Remove this application's activities from active lists. 4422 removeHistoryRecordsForAppLocked(mLRUActivities, app); 4423 removeHistoryRecordsForAppLocked(mStoppingActivities, app); 4424 removeHistoryRecordsForAppLocked(mWaitingVisibleActivities, app); 4425 removeHistoryRecordsForAppLocked(mFinishingActivities, app); 4426 4427 boolean atTop = true; 4428 boolean hasVisibleActivities = false; 4429 4430 // Clean out the history list. 4431 int i = mHistory.size(); 4432 if (localLOGV) Log.v( 4433 TAG, "Removing app " + app + " from history with " + i + " entries"); 4434 while (i > 0) { 4435 i--; 4436 HistoryRecord r = (HistoryRecord)mHistory.get(i); 4437 if (localLOGV) Log.v( 4438 TAG, "Record #" + i + " " + r + ": app=" + r.app); 4439 if (r.app == app) { 4440 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 4441 if (localLOGV) Log.v( 4442 TAG, "Removing this entry! frozen=" + r.haveState 4443 + " finishing=" + r.finishing); 4444 mHistory.remove(i); 4445 4446 r.inHistory = false; 4447 mWindowManager.removeAppToken(r); 4448 if (VALIDATE_TOKENS) { 4449 mWindowManager.validateAppTokens(mHistory); 4450 } 4451 removeActivityUriPermissionsLocked(r); 4452 4453 } else { 4454 // We have the current state for this activity, so 4455 // it can be restarted later when needed. 4456 if (localLOGV) Log.v( 4457 TAG, "Keeping entry, setting app to null"); 4458 if (r.visible) { 4459 hasVisibleActivities = true; 4460 } 4461 r.app = null; 4462 r.nowVisible = false; 4463 if (!r.haveState) { 4464 r.icicle = null; 4465 } 4466 } 4467 4468 cleanUpActivityLocked(r, true); 4469 r.state = ActivityState.STOPPED; 4470 } 4471 atTop = false; 4472 } 4473 4474 app.activities.clear(); 4475 4476 if (app.instrumentationClass != null) { 4477 Log.w(TAG, "Crash of app " + app.processName 4478 + " running instrumentation " + app.instrumentationClass); 4479 Bundle info = new Bundle(); 4480 info.putString("shortMsg", "Process crashed."); 4481 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4482 } 4483 4484 if (!restarting) { 4485 if (!resumeTopActivityLocked(null)) { 4486 // If there was nothing to resume, and we are not already 4487 // restarting this process, but there is a visible activity that 4488 // is hosted by the process... then make sure all visible 4489 // activities are running, taking care of restarting this 4490 // process. 4491 if (hasVisibleActivities) { 4492 ensureActivitiesVisibleLocked(null, 0); 4493 } 4494 } 4495 } 4496 } 4497 4498 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4499 IBinder threadBinder = thread.asBinder(); 4500 4501 // Find the application record. 4502 int count = mLRUProcesses.size(); 4503 int i; 4504 for (i=0; i<count; i++) { 4505 ProcessRecord rec = mLRUProcesses.get(i); 4506 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4507 return i; 4508 } 4509 } 4510 return -1; 4511 } 4512 4513 private final ProcessRecord getRecordForAppLocked( 4514 IApplicationThread thread) { 4515 if (thread == null) { 4516 return null; 4517 } 4518 4519 int appIndex = getLRURecordIndexForAppLocked(thread); 4520 return appIndex >= 0 ? mLRUProcesses.get(appIndex) : null; 4521 } 4522 4523 private final void appDiedLocked(ProcessRecord app, int pid, 4524 IApplicationThread thread) { 4525 4526 mProcDeaths[0]++; 4527 4528 if (app.thread != null && app.thread.asBinder() == thread.asBinder()) { 4529 Log.i(TAG, "Process " + app.processName + " (pid " + pid 4530 + ") has died."); 4531 EventLog.writeEvent(LOG_AM_PROCESS_DIED, app.pid, app.processName); 4532 if (localLOGV) Log.v( 4533 TAG, "Dying app: " + app + ", pid: " + pid 4534 + ", thread: " + thread.asBinder()); 4535 boolean doLowMem = app.instrumentationClass == null; 4536 handleAppDiedLocked(app, false); 4537 4538 if (doLowMem) { 4539 // If there are no longer any background processes running, 4540 // and the app that died was not running instrumentation, 4541 // then tell everyone we are now low on memory. 4542 boolean haveBg = false; 4543 int count = mLRUProcesses.size(); 4544 int i; 4545 for (i=0; i<count; i++) { 4546 ProcessRecord rec = mLRUProcesses.get(i); 4547 if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) { 4548 haveBg = true; 4549 break; 4550 } 4551 } 4552 4553 if (!haveBg) { 4554 Log.i(TAG, "Low Memory: No more background processes."); 4555 EventLog.writeEvent(LOG_AM_LOW_MEMORY, mLRUProcesses.size()); 4556 long now = SystemClock.uptimeMillis(); 4557 for (i=0; i<count; i++) { 4558 ProcessRecord rec = mLRUProcesses.get(i); 4559 if (rec.thread != null && 4560 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4561 // The low memory report is overriding any current 4562 // state for a GC request. Make sure to do 4563 // visible/foreground processes first. 4564 if (rec.setAdj <= VISIBLE_APP_ADJ) { 4565 rec.lastRequestedGc = 0; 4566 } else { 4567 rec.lastRequestedGc = rec.lastLowMemory; 4568 } 4569 rec.reportLowMemory = true; 4570 rec.lastLowMemory = now; 4571 mProcessesToGc.remove(rec); 4572 addProcessToGcListLocked(rec); 4573 } 4574 } 4575 scheduleAppGcsLocked(); 4576 } 4577 } 4578 } else if (Config.LOGD) { 4579 Log.d(TAG, "Received spurious death notification for thread " 4580 + thread.asBinder()); 4581 } 4582 } 4583 4584 final String readFile(String filename) { 4585 try { 4586 FileInputStream fs = new FileInputStream(filename); 4587 byte[] inp = new byte[8192]; 4588 int size = fs.read(inp); 4589 fs.close(); 4590 return new String(inp, 0, 0, size); 4591 } catch (java.io.IOException e) { 4592 } 4593 return ""; 4594 } 4595 4596 final void appNotRespondingLocked(ProcessRecord app, HistoryRecord activity, 4597 HistoryRecord reportedActivity, final String annotation) { 4598 if (app.notResponding || app.crashing) { 4599 return; 4600 } 4601 4602 // Log the ANR to the event log. 4603 EventLog.writeEvent(LOG_ANR, app.pid, app.processName, annotation); 4604 4605 // If we are on a secure build and the application is not interesting to the user (it is 4606 // not visible or in the background), just kill it instead of displaying a dialog. 4607 boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0")); 4608 if (isSecure && !app.isInterestingToUserLocked() && Process.myPid() != app.pid) { 4609 Process.killProcess(app.pid); 4610 return; 4611 } 4612 4613 // DeviceMonitor.start(); 4614 4615 String processInfo = null; 4616 if (MONITOR_CPU_USAGE) { 4617 updateCpuStatsNow(); 4618 synchronized (mProcessStatsThread) { 4619 processInfo = mProcessStats.printCurrentState(); 4620 } 4621 } 4622 4623 StringBuilder info = mStringBuilder; 4624 info.setLength(0); 4625 info.append("ANR in process: "); 4626 info.append(app.processName); 4627 if (reportedActivity != null && reportedActivity.app != null) { 4628 info.append(" (last in "); 4629 info.append(reportedActivity.app.processName); 4630 info.append(")"); 4631 } 4632 if (annotation != null) { 4633 info.append("\nAnnotation: "); 4634 info.append(annotation); 4635 } 4636 if (MONITOR_CPU_USAGE) { 4637 info.append("\nCPU usage:\n"); 4638 info.append(processInfo); 4639 } 4640 Log.i(TAG, info.toString()); 4641 4642 // The application is not responding. Dump as many thread traces as we can. 4643 boolean fileDump = prepareTraceFile(true); 4644 if (!fileDump) { 4645 // Dumping traces to the log, just dump the process that isn't responding so 4646 // we don't overflow the log 4647 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4648 } else { 4649 // Dumping traces to a file so dump all active processes we know about 4650 synchronized (this) { 4651 // First, these are the most important processes. 4652 final int[] imppids = new int[3]; 4653 int i=0; 4654 imppids[0] = app.pid; 4655 i++; 4656 if (reportedActivity != null && reportedActivity.app != null 4657 && reportedActivity.app.thread != null 4658 && reportedActivity.app.pid != app.pid) { 4659 imppids[i] = reportedActivity.app.pid; 4660 i++; 4661 } 4662 imppids[i] = Process.myPid(); 4663 for (i=0; i<imppids.length && imppids[i] != 0; i++) { 4664 Process.sendSignal(imppids[i], Process.SIGNAL_QUIT); 4665 synchronized (this) { 4666 try { 4667 wait(200); 4668 } catch (InterruptedException e) { 4669 } 4670 } 4671 } 4672 for (i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) { 4673 ProcessRecord r = mLRUProcesses.get(i); 4674 boolean done = false; 4675 for (int j=0; j<imppids.length && imppids[j] != 0; j++) { 4676 if (imppids[j] == r.pid) { 4677 done = true; 4678 break; 4679 } 4680 } 4681 if (!done && r.thread != null) { 4682 Process.sendSignal(r.pid, Process.SIGNAL_QUIT); 4683 synchronized (this) { 4684 try { 4685 wait(200); 4686 } catch (InterruptedException e) { 4687 } 4688 } 4689 } 4690 } 4691 } 4692 } 4693 4694 if (mController != null) { 4695 try { 4696 int res = mController.appNotResponding(app.processName, 4697 app.pid, info.toString()); 4698 if (res != 0) { 4699 if (res < 0) { 4700 // wait until the SIGQUIT has had a chance to process before killing the 4701 // process. 4702 try { 4703 wait(2000); 4704 } catch (InterruptedException e) { 4705 } 4706 4707 Process.killProcess(app.pid); 4708 return; 4709 } 4710 } 4711 } catch (RemoteException e) { 4712 mController = null; 4713 } 4714 } 4715 4716 makeAppNotRespondingLocked(app, 4717 activity != null ? activity.shortComponentName : null, 4718 annotation != null ? "ANR " + annotation : "ANR", 4719 info.toString(), null); 4720 Message msg = Message.obtain(); 4721 HashMap map = new HashMap(); 4722 msg.what = SHOW_NOT_RESPONDING_MSG; 4723 msg.obj = map; 4724 map.put("app", app); 4725 if (activity != null) { 4726 map.put("activity", activity); 4727 } 4728 4729 mHandler.sendMessage(msg); 4730 return; 4731 } 4732 4733 /** 4734 * If a stack trace file has been configured, prepare the filesystem 4735 * by creating the directory if it doesn't exist and optionally 4736 * removing the old trace file. 4737 * 4738 * @param removeExisting If set, the existing trace file will be removed. 4739 * @return Returns true if the trace file preparations succeeded 4740 */ 4741 public static boolean prepareTraceFile(boolean removeExisting) { 4742 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4743 boolean fileReady = false; 4744 if (!TextUtils.isEmpty(tracesPath)) { 4745 File f = new File(tracesPath); 4746 if (!f.exists()) { 4747 // Ensure the enclosing directory exists 4748 File dir = f.getParentFile(); 4749 if (!dir.exists()) { 4750 fileReady = dir.mkdirs(); 4751 FileUtils.setPermissions(dir.getAbsolutePath(), 4752 FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IXOTH, -1, -1); 4753 } else if (dir.isDirectory()) { 4754 fileReady = true; 4755 } 4756 } else if (removeExisting) { 4757 // Remove the previous traces file, so we don't fill the disk. 4758 // The VM will recreate it 4759 Log.i(TAG, "Removing old ANR trace file from " + tracesPath); 4760 fileReady = f.delete(); 4761 } 4762 4763 if (removeExisting) { 4764 try { 4765 f.createNewFile(); 4766 FileUtils.setPermissions(f.getAbsolutePath(), 4767 FileUtils.S_IRWXU | FileUtils.S_IRWXG 4768 | FileUtils.S_IWOTH | FileUtils.S_IROTH, -1, -1); 4769 fileReady = true; 4770 } catch (IOException e) { 4771 Log.w(TAG, "Unable to make ANR traces file", e); 4772 } 4773 } 4774 } 4775 4776 return fileReady; 4777 } 4778 4779 4780 private final void decPersistentCountLocked(ProcessRecord app) 4781 { 4782 app.persistentActivities--; 4783 if (app.persistentActivities > 0) { 4784 // Still more of 'em... 4785 return; 4786 } 4787 if (app.persistent) { 4788 // Ah, but the application itself is persistent. Whatever! 4789 return; 4790 } 4791 4792 // App is no longer persistent... make sure it and the ones 4793 // following it in the LRU list have the correc oom_adj. 4794 updateOomAdjLocked(); 4795 } 4796 4797 public void setPersistent(IBinder token, boolean isPersistent) { 4798 if (checkCallingPermission(android.Manifest.permission.PERSISTENT_ACTIVITY) 4799 != PackageManager.PERMISSION_GRANTED) { 4800 String msg = "Permission Denial: setPersistent() from pid=" 4801 + Binder.getCallingPid() 4802 + ", uid=" + Binder.getCallingUid() 4803 + " requires " + android.Manifest.permission.PERSISTENT_ACTIVITY; 4804 Log.w(TAG, msg); 4805 throw new SecurityException(msg); 4806 } 4807 4808 synchronized(this) { 4809 int index = indexOfTokenLocked(token); 4810 if (index < 0) { 4811 return; 4812 } 4813 HistoryRecord r = (HistoryRecord)mHistory.get(index); 4814 ProcessRecord app = r.app; 4815 4816 if (localLOGV) Log.v( 4817 TAG, "Setting persistence " + isPersistent + ": " + r); 4818 4819 if (isPersistent) { 4820 if (r.persistent) { 4821 // Okay okay, I heard you already! 4822 if (localLOGV) Log.v(TAG, "Already persistent!"); 4823 return; 4824 } 4825 r.persistent = true; 4826 app.persistentActivities++; 4827 if (localLOGV) Log.v(TAG, "Num persistent now: " + app.persistentActivities); 4828 if (app.persistentActivities > 1) { 4829 // We aren't the first... 4830 if (localLOGV) Log.v(TAG, "Not the first!"); 4831 return; 4832 } 4833 if (app.persistent) { 4834 // This would be redundant. 4835 if (localLOGV) Log.v(TAG, "App is persistent!"); 4836 return; 4837 } 4838 4839 // App is now persistent... make sure it and the ones 4840 // following it now have the correct oom_adj. 4841 final long origId = Binder.clearCallingIdentity(); 4842 updateOomAdjLocked(); 4843 Binder.restoreCallingIdentity(origId); 4844 4845 } else { 4846 if (!r.persistent) { 4847 // Okay okay, I heard you already! 4848 return; 4849 } 4850 r.persistent = false; 4851 final long origId = Binder.clearCallingIdentity(); 4852 decPersistentCountLocked(app); 4853 Binder.restoreCallingIdentity(origId); 4854 4855 } 4856 } 4857 } 4858 4859 public boolean clearApplicationUserData(final String packageName, 4860 final IPackageDataObserver observer) { 4861 int uid = Binder.getCallingUid(); 4862 int pid = Binder.getCallingPid(); 4863 long callingId = Binder.clearCallingIdentity(); 4864 try { 4865 IPackageManager pm = ActivityThread.getPackageManager(); 4866 int pkgUid = -1; 4867 synchronized(this) { 4868 try { 4869 pkgUid = pm.getPackageUid(packageName); 4870 } catch (RemoteException e) { 4871 } 4872 if (pkgUid == -1) { 4873 Log.w(TAG, "Invalid packageName:" + packageName); 4874 return false; 4875 } 4876 if (uid == pkgUid || checkComponentPermission( 4877 android.Manifest.permission.CLEAR_APP_USER_DATA, 4878 pid, uid, -1) 4879 == PackageManager.PERMISSION_GRANTED) { 4880 restartPackageLocked(packageName, pkgUid); 4881 } else { 4882 throw new SecurityException(pid+" does not have permission:"+ 4883 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 4884 "for process:"+packageName); 4885 } 4886 } 4887 4888 try { 4889 //clear application user data 4890 pm.clearApplicationUserData(packageName, observer); 4891 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4892 Uri.fromParts("package", packageName, null)); 4893 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4894 broadcastIntentLocked(null, null, intent, 4895 null, null, 0, null, null, null, 4896 false, false, MY_PID, Process.SYSTEM_UID); 4897 } catch (RemoteException e) { 4898 } 4899 } finally { 4900 Binder.restoreCallingIdentity(callingId); 4901 } 4902 return true; 4903 } 4904 4905 public void restartPackage(final String packageName) { 4906 if (checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4907 != PackageManager.PERMISSION_GRANTED) { 4908 String msg = "Permission Denial: restartPackage() from pid=" 4909 + Binder.getCallingPid() 4910 + ", uid=" + Binder.getCallingUid() 4911 + " requires " + android.Manifest.permission.RESTART_PACKAGES; 4912 Log.w(TAG, msg); 4913 throw new SecurityException(msg); 4914 } 4915 4916 long callingId = Binder.clearCallingIdentity(); 4917 try { 4918 IPackageManager pm = ActivityThread.getPackageManager(); 4919 int pkgUid = -1; 4920 synchronized(this) { 4921 try { 4922 pkgUid = pm.getPackageUid(packageName); 4923 } catch (RemoteException e) { 4924 } 4925 if (pkgUid == -1) { 4926 Log.w(TAG, "Invalid packageName: " + packageName); 4927 return; 4928 } 4929 restartPackageLocked(packageName, pkgUid); 4930 } 4931 } finally { 4932 Binder.restoreCallingIdentity(callingId); 4933 } 4934 } 4935 4936 /* 4937 * The pkg name and uid have to be specified. 4938 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 4939 */ 4940 public void killApplicationWithUid(String pkg, int uid) { 4941 if (pkg == null) { 4942 return; 4943 } 4944 // Make sure the uid is valid. 4945 if (uid < 0) { 4946 Log.w(TAG, "Invalid uid specified for pkg : " + pkg); 4947 return; 4948 } 4949 int callerUid = Binder.getCallingUid(); 4950 // Only the system server can kill an application 4951 if (callerUid == Process.SYSTEM_UID) { 4952 // Post an aysnc message to kill the application 4953 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4954 msg.arg1 = uid; 4955 msg.arg2 = 0; 4956 msg.obj = pkg; 4957 mHandler.sendMessage(msg); 4958 } else { 4959 throw new SecurityException(callerUid + " cannot kill pkg: " + 4960 pkg); 4961 } 4962 } 4963 4964 public void closeSystemDialogs(String reason) { 4965 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4966 if (reason != null) { 4967 intent.putExtra("reason", reason); 4968 } 4969 4970 final int uid = Binder.getCallingUid(); 4971 final long origId = Binder.clearCallingIdentity(); 4972 synchronized (this) { 4973 int i = mWatchers.beginBroadcast(); 4974 while (i > 0) { 4975 i--; 4976 IActivityWatcher w = mWatchers.getBroadcastItem(i); 4977 if (w != null) { 4978 try { 4979 w.closingSystemDialogs(reason); 4980 } catch (RemoteException e) { 4981 } 4982 } 4983 } 4984 mWatchers.finishBroadcast(); 4985 4986 mWindowManager.closeSystemDialogs(reason); 4987 4988 for (i=mHistory.size()-1; i>=0; i--) { 4989 HistoryRecord r = (HistoryRecord)mHistory.get(i); 4990 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 4991 finishActivityLocked(r, i, 4992 Activity.RESULT_CANCELED, null, "close-sys"); 4993 } 4994 } 4995 4996 broadcastIntentLocked(null, null, intent, null, 4997 null, 0, null, null, null, false, false, -1, uid); 4998 } 4999 Binder.restoreCallingIdentity(origId); 5000 } 5001 5002 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 5003 throws RemoteException { 5004 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5005 for (int i=pids.length-1; i>=0; i--) { 5006 infos[i] = new Debug.MemoryInfo(); 5007 Debug.getMemoryInfo(pids[i], infos[i]); 5008 } 5009 return infos; 5010 } 5011 5012 public void killApplicationProcess(String processName, int uid) { 5013 if (processName == null) { 5014 return; 5015 } 5016 5017 int callerUid = Binder.getCallingUid(); 5018 // Only the system server can kill an application 5019 if (callerUid == Process.SYSTEM_UID) { 5020 synchronized (this) { 5021 ProcessRecord app = getProcessRecordLocked(processName, uid); 5022 if (app != null) { 5023 try { 5024 app.thread.scheduleSuicide(); 5025 } catch (RemoteException e) { 5026 // If the other end already died, then our work here is done. 5027 } 5028 } else { 5029 Log.w(TAG, "Process/uid not found attempting kill of " 5030 + processName + " / " + uid); 5031 } 5032 } 5033 } else { 5034 throw new SecurityException(callerUid + " cannot kill app process: " + 5035 processName); 5036 } 5037 } 5038 5039 private void restartPackageLocked(final String packageName, int uid) { 5040 uninstallPackageLocked(packageName, uid, false); 5041 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5042 Uri.fromParts("package", packageName, null)); 5043 intent.putExtra(Intent.EXTRA_UID, uid); 5044 broadcastIntentLocked(null, null, intent, 5045 null, null, 0, null, null, null, 5046 false, false, MY_PID, Process.SYSTEM_UID); 5047 } 5048 5049 private final void uninstallPackageLocked(String name, int uid, 5050 boolean callerWillRestart) { 5051 if (Config.LOGD) Log.d(TAG, "Uninstalling process " + name); 5052 5053 int i, N; 5054 5055 final String procNamePrefix = name + ":"; 5056 if (uid < 0) { 5057 try { 5058 uid = ActivityThread.getPackageManager().getPackageUid(name); 5059 } catch (RemoteException e) { 5060 } 5061 } 5062 5063 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 5064 while (badApps.hasNext()) { 5065 SparseArray<Long> ba = badApps.next(); 5066 if (ba.get(uid) != null) { 5067 badApps.remove(); 5068 } 5069 } 5070 5071 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5072 5073 // Remove all processes this package may have touched: all with the 5074 // same UID (except for the system or root user), and all whose name 5075 // matches the package name. 5076 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 5077 final int NA = apps.size(); 5078 for (int ia=0; ia<NA; ia++) { 5079 ProcessRecord app = apps.valueAt(ia); 5080 if (app.removed) { 5081 procs.add(app); 5082 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 5083 || app.processName.equals(name) 5084 || app.processName.startsWith(procNamePrefix)) { 5085 app.removed = true; 5086 procs.add(app); 5087 } 5088 } 5089 } 5090 5091 N = procs.size(); 5092 for (i=0; i<N; i++) { 5093 removeProcessLocked(procs.get(i), callerWillRestart); 5094 } 5095 5096 for (i=mHistory.size()-1; i>=0; i--) { 5097 HistoryRecord r = (HistoryRecord)mHistory.get(i); 5098 if (r.packageName.equals(name)) { 5099 if (Config.LOGD) Log.d( 5100 TAG, " Force finishing activity " 5101 + r.intent.getComponent().flattenToShortString()); 5102 if (r.app != null) { 5103 r.app.removed = true; 5104 } 5105 r.app = null; 5106 finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall"); 5107 } 5108 } 5109 5110 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 5111 for (ServiceRecord service : mServices.values()) { 5112 if (service.packageName.equals(name)) { 5113 if (service.app != null) { 5114 service.app.removed = true; 5115 } 5116 service.app = null; 5117 services.add(service); 5118 } 5119 } 5120 5121 N = services.size(); 5122 for (i=0; i<N; i++) { 5123 bringDownServiceLocked(services.get(i), true); 5124 } 5125 5126 resumeTopActivityLocked(null); 5127 } 5128 5129 private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) { 5130 final String name = app.processName; 5131 final int uid = app.info.uid; 5132 if (Config.LOGD) Log.d( 5133 TAG, "Force removing process " + app + " (" + name 5134 + "/" + uid + ")"); 5135 5136 mProcessNames.remove(name, uid); 5137 boolean needRestart = false; 5138 if (app.pid > 0 && app.pid != MY_PID) { 5139 int pid = app.pid; 5140 synchronized (mPidsSelfLocked) { 5141 mPidsSelfLocked.remove(pid); 5142 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5143 } 5144 handleAppDiedLocked(app, true); 5145 mLRUProcesses.remove(app); 5146 Process.killProcess(pid); 5147 5148 if (app.persistent) { 5149 if (!callerWillRestart) { 5150 addAppLocked(app.info); 5151 } else { 5152 needRestart = true; 5153 } 5154 } 5155 } else { 5156 mRemovedProcesses.add(app); 5157 } 5158 5159 return needRestart; 5160 } 5161 5162 private final void processStartTimedOutLocked(ProcessRecord app) { 5163 final int pid = app.pid; 5164 boolean gone = false; 5165 synchronized (mPidsSelfLocked) { 5166 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5167 if (knownApp != null && knownApp.thread == null) { 5168 mPidsSelfLocked.remove(pid); 5169 gone = true; 5170 } 5171 } 5172 5173 if (gone) { 5174 Log.w(TAG, "Process " + app + " failed to attach"); 5175 mProcessNames.remove(app.processName, app.info.uid); 5176 Process.killProcess(pid); 5177 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) { 5178 Log.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5179 mPendingBroadcast = null; 5180 scheduleBroadcastsLocked(); 5181 } 5182 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5183 Log.w(TAG, "Unattached app died before backup, skipping"); 5184 try { 5185 IBackupManager bm = IBackupManager.Stub.asInterface( 5186 ServiceManager.getService(Context.BACKUP_SERVICE)); 5187 bm.agentDisconnected(app.info.packageName); 5188 } catch (RemoteException e) { 5189 // Can't happen; the backup manager is local 5190 } 5191 } 5192 } else { 5193 Log.w(TAG, "Spurious process start timeout - pid not known for " + app); 5194 } 5195 } 5196 5197 private final boolean attachApplicationLocked(IApplicationThread thread, 5198 int pid) { 5199 5200 // Find the application record that is being attached... either via 5201 // the pid if we are running in multiple processes, or just pull the 5202 // next app record if we are emulating process with anonymous threads. 5203 ProcessRecord app; 5204 if (pid != MY_PID && pid >= 0) { 5205 synchronized (mPidsSelfLocked) { 5206 app = mPidsSelfLocked.get(pid); 5207 } 5208 } else if (mStartingProcesses.size() > 0) { 5209 app = mStartingProcesses.remove(0); 5210 app.setPid(pid); 5211 } else { 5212 app = null; 5213 } 5214 5215 if (app == null) { 5216 Log.w(TAG, "No pending application record for pid " + pid 5217 + " (IApplicationThread " + thread + "); dropping process"); 5218 EventLog.writeEvent(LOG_AM_DROP_PROCESS, pid); 5219 if (pid > 0 && pid != MY_PID) { 5220 Process.killProcess(pid); 5221 } else { 5222 try { 5223 thread.scheduleExit(); 5224 } catch (Exception e) { 5225 // Ignore exceptions. 5226 } 5227 } 5228 return false; 5229 } 5230 5231 // If this application record is still attached to a previous 5232 // process, clean it up now. 5233 if (app.thread != null) { 5234 handleAppDiedLocked(app, true); 5235 } 5236 5237 // Tell the process all about itself. 5238 5239 if (localLOGV) Log.v( 5240 TAG, "Binding process pid " + pid + " to record " + app); 5241 5242 String processName = app.processName; 5243 try { 5244 thread.asBinder().linkToDeath(new AppDeathRecipient( 5245 app, pid, thread), 0); 5246 } catch (RemoteException e) { 5247 app.resetPackageList(); 5248 startProcessLocked(app, "link fail", processName); 5249 return false; 5250 } 5251 5252 EventLog.writeEvent(LOG_AM_PROCESS_BOUND, app.pid, app.processName); 5253 5254 app.thread = thread; 5255 app.curAdj = app.setAdj = -100; 5256 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5257 app.forcingToForeground = null; 5258 app.foregroundServices = false; 5259 app.debugging = false; 5260 5261 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5262 5263 boolean normalMode = mSystemReady || isAllowedWhileBooting(app.info); 5264 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5265 5266 if (!normalMode) { 5267 Log.i(TAG, "Launching preboot mode app: " + app); 5268 } 5269 5270 if (localLOGV) Log.v( 5271 TAG, "New app record " + app 5272 + " thread=" + thread.asBinder() + " pid=" + pid); 5273 try { 5274 int testMode = IApplicationThread.DEBUG_OFF; 5275 if (mDebugApp != null && mDebugApp.equals(processName)) { 5276 testMode = mWaitForDebugger 5277 ? IApplicationThread.DEBUG_WAIT 5278 : IApplicationThread.DEBUG_ON; 5279 app.debugging = true; 5280 if (mDebugTransient) { 5281 mDebugApp = mOrigDebugApp; 5282 mWaitForDebugger = mOrigWaitForDebugger; 5283 } 5284 } 5285 5286 // If the app is being launched for restore or full backup, set it up specially 5287 boolean isRestrictedBackupMode = false; 5288 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5289 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5290 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5291 } 5292 5293 ensurePackageDexOpt(app.instrumentationInfo != null 5294 ? app.instrumentationInfo.packageName 5295 : app.info.packageName); 5296 if (app.instrumentationClass != null) { 5297 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5298 } 5299 if (DEBUG_CONFIGURATION) Log.v(TAG, "Binding proc " 5300 + processName + " with config " + mConfiguration); 5301 thread.bindApplication(processName, app.instrumentationInfo != null 5302 ? app.instrumentationInfo : app.info, providers, 5303 app.instrumentationClass, app.instrumentationProfileFile, 5304 app.instrumentationArguments, app.instrumentationWatcher, testMode, 5305 isRestrictedBackupMode || !normalMode, 5306 mConfiguration, getCommonServicesLocked()); 5307 updateLRUListLocked(app, false); 5308 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5309 } catch (Exception e) { 5310 // todo: Yikes! What should we do? For now we will try to 5311 // start another process, but that could easily get us in 5312 // an infinite loop of restarting processes... 5313 Log.w(TAG, "Exception thrown during bind!", e); 5314 5315 app.resetPackageList(); 5316 startProcessLocked(app, "bind fail", processName); 5317 return false; 5318 } 5319 5320 // Remove this record from the list of starting applications. 5321 mPersistentStartingProcesses.remove(app); 5322 mProcessesOnHold.remove(app); 5323 5324 boolean badApp = false; 5325 boolean didSomething = false; 5326 5327 // See if the top visible activity is waiting to run in this process... 5328 HistoryRecord hr = topRunningActivityLocked(null); 5329 if (hr != null) { 5330 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid 5331 && processName.equals(hr.processName)) { 5332 try { 5333 if (realStartActivityLocked(hr, app, true, true)) { 5334 didSomething = true; 5335 } 5336 } catch (Exception e) { 5337 Log.w(TAG, "Exception in new application when starting activity " 5338 + hr.intent.getComponent().flattenToShortString(), e); 5339 badApp = true; 5340 } 5341 } else { 5342 ensureActivitiesVisibleLocked(hr, null, processName, 0); 5343 } 5344 } 5345 5346 // Find any services that should be running in this process... 5347 if (!badApp && mPendingServices.size() > 0) { 5348 ServiceRecord sr = null; 5349 try { 5350 for (int i=0; i<mPendingServices.size(); i++) { 5351 sr = mPendingServices.get(i); 5352 if (app.info.uid != sr.appInfo.uid 5353 || !processName.equals(sr.processName)) { 5354 continue; 5355 } 5356 5357 mPendingServices.remove(i); 5358 i--; 5359 realStartServiceLocked(sr, app); 5360 didSomething = true; 5361 } 5362 } catch (Exception e) { 5363 Log.w(TAG, "Exception in new application when starting service " 5364 + sr.shortName, e); 5365 badApp = true; 5366 } 5367 } 5368 5369 // Check if the next broadcast receiver is in this process... 5370 BroadcastRecord br = mPendingBroadcast; 5371 if (!badApp && br != null && br.curApp == app) { 5372 try { 5373 mPendingBroadcast = null; 5374 processCurBroadcastLocked(br, app); 5375 didSomething = true; 5376 } catch (Exception e) { 5377 Log.w(TAG, "Exception in new application when starting receiver " 5378 + br.curComponent.flattenToShortString(), e); 5379 badApp = true; 5380 logBroadcastReceiverDiscard(br); 5381 finishReceiverLocked(br.receiver, br.resultCode, br.resultData, 5382 br.resultExtras, br.resultAbort, true); 5383 scheduleBroadcastsLocked(); 5384 } 5385 } 5386 5387 // Check whether the next backup agent is in this process... 5388 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) { 5389 if (DEBUG_BACKUP) Log.v(TAG, "New app is backup target, launching agent for " + app); 5390 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5391 try { 5392 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, mBackupTarget.backupMode); 5393 } catch (Exception e) { 5394 Log.w(TAG, "Exception scheduling backup agent creation: "); 5395 e.printStackTrace(); 5396 } 5397 } 5398 5399 if (badApp) { 5400 // todo: Also need to kill application to deal with all 5401 // kinds of exceptions. 5402 handleAppDiedLocked(app, false); 5403 return false; 5404 } 5405 5406 if (!didSomething) { 5407 updateOomAdjLocked(); 5408 } 5409 5410 return true; 5411 } 5412 5413 public final void attachApplication(IApplicationThread thread) { 5414 synchronized (this) { 5415 int callingPid = Binder.getCallingPid(); 5416 final long origId = Binder.clearCallingIdentity(); 5417 attachApplicationLocked(thread, callingPid); 5418 Binder.restoreCallingIdentity(origId); 5419 } 5420 } 5421 5422 public final void activityIdle(IBinder token) { 5423 final long origId = Binder.clearCallingIdentity(); 5424 activityIdleInternal(token, false); 5425 Binder.restoreCallingIdentity(origId); 5426 } 5427 5428 final ArrayList<HistoryRecord> processStoppingActivitiesLocked( 5429 boolean remove) { 5430 int N = mStoppingActivities.size(); 5431 if (N <= 0) return null; 5432 5433 ArrayList<HistoryRecord> stops = null; 5434 5435 final boolean nowVisible = mResumedActivity != null 5436 && mResumedActivity.nowVisible 5437 && !mResumedActivity.waitingVisible; 5438 for (int i=0; i<N; i++) { 5439 HistoryRecord s = mStoppingActivities.get(i); 5440 if (localLOGV) Log.v(TAG, "Stopping " + s + ": nowVisible=" 5441 + nowVisible + " waitingVisible=" + s.waitingVisible 5442 + " finishing=" + s.finishing); 5443 if (s.waitingVisible && nowVisible) { 5444 mWaitingVisibleActivities.remove(s); 5445 s.waitingVisible = false; 5446 if (s.finishing) { 5447 // If this activity is finishing, it is sitting on top of 5448 // everyone else but we now know it is no longer needed... 5449 // so get rid of it. Otherwise, we need to go through the 5450 // normal flow and hide it once we determine that it is 5451 // hidden by the activities in front of it. 5452 if (localLOGV) Log.v(TAG, "Before stopping, can hide: " + s); 5453 mWindowManager.setAppVisibility(s, false); 5454 } 5455 } 5456 if (!s.waitingVisible && remove) { 5457 if (localLOGV) Log.v(TAG, "Ready to stop: " + s); 5458 if (stops == null) { 5459 stops = new ArrayList<HistoryRecord>(); 5460 } 5461 stops.add(s); 5462 mStoppingActivities.remove(i); 5463 N--; 5464 i--; 5465 } 5466 } 5467 5468 return stops; 5469 } 5470 5471 void enableScreenAfterBoot() { 5472 EventLog.writeEvent(LOG_BOOT_PROGRESS_ENABLE_SCREEN, 5473 SystemClock.uptimeMillis()); 5474 mWindowManager.enableScreenAfterBoot(); 5475 } 5476 5477 final void activityIdleInternal(IBinder token, boolean fromTimeout) { 5478 if (localLOGV) Log.v(TAG, "Activity idle: " + token); 5479 5480 ArrayList<HistoryRecord> stops = null; 5481 ArrayList<HistoryRecord> finishes = null; 5482 ArrayList<HistoryRecord> thumbnails = null; 5483 int NS = 0; 5484 int NF = 0; 5485 int NT = 0; 5486 IApplicationThread sendThumbnail = null; 5487 boolean booting = false; 5488 boolean enableScreen = false; 5489 5490 synchronized (this) { 5491 if (token != null) { 5492 mHandler.removeMessages(IDLE_TIMEOUT_MSG, token); 5493 } 5494 5495 // Get the activity record. 5496 int index = indexOfTokenLocked(token); 5497 if (index >= 0) { 5498 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5499 5500 // No longer need to keep the device awake. 5501 if (mResumedActivity == r && mLaunchingActivity.isHeld()) { 5502 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 5503 mLaunchingActivity.release(); 5504 } 5505 5506 // We are now idle. If someone is waiting for a thumbnail from 5507 // us, we can now deliver. 5508 r.idle = true; 5509 scheduleAppGcsLocked(); 5510 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) { 5511 sendThumbnail = r.app.thread; 5512 r.thumbnailNeeded = false; 5513 } 5514 5515 // If this activity is fullscreen, set up to hide those under it. 5516 5517 if (DEBUG_VISBILITY) Log.v(TAG, "Idle activity for " + r); 5518 ensureActivitiesVisibleLocked(null, 0); 5519 5520 //Log.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); 5521 if (!mBooted && !fromTimeout) { 5522 mBooted = true; 5523 enableScreen = true; 5524 } 5525 } 5526 5527 // Atomically retrieve all of the other things to do. 5528 stops = processStoppingActivitiesLocked(true); 5529 NS = stops != null ? stops.size() : 0; 5530 if ((NF=mFinishingActivities.size()) > 0) { 5531 finishes = new ArrayList<HistoryRecord>(mFinishingActivities); 5532 mFinishingActivities.clear(); 5533 } 5534 if ((NT=mCancelledThumbnails.size()) > 0) { 5535 thumbnails = new ArrayList<HistoryRecord>(mCancelledThumbnails); 5536 mCancelledThumbnails.clear(); 5537 } 5538 5539 booting = mBooting; 5540 mBooting = false; 5541 } 5542 5543 int i; 5544 5545 // Send thumbnail if requested. 5546 if (sendThumbnail != null) { 5547 try { 5548 sendThumbnail.requestThumbnail(token); 5549 } catch (Exception e) { 5550 Log.w(TAG, "Exception thrown when requesting thumbnail", e); 5551 sendPendingThumbnail(null, token, null, null, true); 5552 } 5553 } 5554 5555 // Stop any activities that are scheduled to do so but have been 5556 // waiting for the next one to start. 5557 for (i=0; i<NS; i++) { 5558 HistoryRecord r = (HistoryRecord)stops.get(i); 5559 synchronized (this) { 5560 if (r.finishing) { 5561 finishCurrentActivityLocked(r, FINISH_IMMEDIATELY); 5562 } else { 5563 stopActivityLocked(r); 5564 } 5565 } 5566 } 5567 5568 // Finish any activities that are scheduled to do so but have been 5569 // waiting for the next one to start. 5570 for (i=0; i<NF; i++) { 5571 HistoryRecord r = (HistoryRecord)finishes.get(i); 5572 synchronized (this) { 5573 destroyActivityLocked(r, true); 5574 } 5575 } 5576 5577 // Report back to any thumbnail receivers. 5578 for (i=0; i<NT; i++) { 5579 HistoryRecord r = (HistoryRecord)thumbnails.get(i); 5580 sendPendingThumbnail(r, null, null, null, true); 5581 } 5582 5583 if (booting) { 5584 finishBooting(); 5585 } 5586 5587 trimApplications(); 5588 //dump(); 5589 //mWindowManager.dump(); 5590 5591 if (enableScreen) { 5592 enableScreenAfterBoot(); 5593 } 5594 } 5595 5596 final void finishBooting() { 5597 // Ensure that any processes we had put on hold are now started 5598 // up. 5599 final int NP = mProcessesOnHold.size(); 5600 if (NP > 0) { 5601 ArrayList<ProcessRecord> procs = 5602 new ArrayList<ProcessRecord>(mProcessesOnHold); 5603 for (int ip=0; ip<NP; ip++) { 5604 this.startProcessLocked(procs.get(ip), "on-hold", null); 5605 } 5606 } 5607 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 5608 // Tell anyone interested that we are done booting! 5609 synchronized (this) { 5610 broadcastIntentLocked(null, null, 5611 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 5612 null, null, 0, null, null, 5613 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5614 false, false, MY_PID, Process.SYSTEM_UID); 5615 } 5616 } 5617 } 5618 5619 final void ensureBootCompleted() { 5620 boolean booting; 5621 boolean enableScreen; 5622 synchronized (this) { 5623 booting = mBooting; 5624 mBooting = false; 5625 enableScreen = !mBooted; 5626 mBooted = true; 5627 } 5628 5629 if (booting) { 5630 finishBooting(); 5631 } 5632 5633 if (enableScreen) { 5634 enableScreenAfterBoot(); 5635 } 5636 } 5637 5638 public final void activityPaused(IBinder token, Bundle icicle) { 5639 // Refuse possible leaked file descriptors 5640 if (icicle != null && icicle.hasFileDescriptors()) { 5641 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5642 } 5643 5644 final long origId = Binder.clearCallingIdentity(); 5645 activityPaused(token, icicle, false); 5646 Binder.restoreCallingIdentity(origId); 5647 } 5648 5649 final void activityPaused(IBinder token, Bundle icicle, boolean timeout) { 5650 if (DEBUG_PAUSE) Log.v( 5651 TAG, "Activity paused: token=" + token + ", icicle=" + icicle 5652 + ", timeout=" + timeout); 5653 5654 HistoryRecord r = null; 5655 5656 synchronized (this) { 5657 int index = indexOfTokenLocked(token); 5658 if (index >= 0) { 5659 r = (HistoryRecord)mHistory.get(index); 5660 if (!timeout) { 5661 r.icicle = icicle; 5662 r.haveState = true; 5663 } 5664 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); 5665 if (mPausingActivity == r) { 5666 r.state = ActivityState.PAUSED; 5667 completePauseLocked(); 5668 } else { 5669 EventLog.writeEvent(LOG_AM_FAILED_TO_PAUSE_ACTIVITY, 5670 System.identityHashCode(r), r.shortComponentName, 5671 mPausingActivity != null 5672 ? mPausingActivity.shortComponentName : "(none)"); 5673 } 5674 } 5675 } 5676 } 5677 5678 public final void activityStopped(IBinder token, Bitmap thumbnail, 5679 CharSequence description) { 5680 if (localLOGV) Log.v( 5681 TAG, "Activity stopped: token=" + token); 5682 5683 HistoryRecord r = null; 5684 5685 final long origId = Binder.clearCallingIdentity(); 5686 5687 synchronized (this) { 5688 int index = indexOfTokenLocked(token); 5689 if (index >= 0) { 5690 r = (HistoryRecord)mHistory.get(index); 5691 r.thumbnail = thumbnail; 5692 r.description = description; 5693 r.stopped = true; 5694 r.state = ActivityState.STOPPED; 5695 if (!r.finishing) { 5696 if (r.configDestroy) { 5697 destroyActivityLocked(r, true); 5698 resumeTopActivityLocked(null); 5699 } 5700 } 5701 } 5702 } 5703 5704 if (r != null) { 5705 sendPendingThumbnail(r, null, null, null, false); 5706 } 5707 5708 trimApplications(); 5709 5710 Binder.restoreCallingIdentity(origId); 5711 } 5712 5713 public final void activityDestroyed(IBinder token) { 5714 if (DEBUG_SWITCH) Log.v(TAG, "ACTIVITY DESTROYED: " + token); 5715 synchronized (this) { 5716 mHandler.removeMessages(DESTROY_TIMEOUT_MSG, token); 5717 5718 int index = indexOfTokenLocked(token); 5719 if (index >= 0) { 5720 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5721 if (r.state == ActivityState.DESTROYING) { 5722 final long origId = Binder.clearCallingIdentity(); 5723 removeActivityFromHistoryLocked(r); 5724 Binder.restoreCallingIdentity(origId); 5725 } 5726 } 5727 } 5728 } 5729 5730 public String getCallingPackage(IBinder token) { 5731 synchronized (this) { 5732 HistoryRecord r = getCallingRecordLocked(token); 5733 return r != null && r.app != null ? r.app.processName : null; 5734 } 5735 } 5736 5737 public ComponentName getCallingActivity(IBinder token) { 5738 synchronized (this) { 5739 HistoryRecord r = getCallingRecordLocked(token); 5740 return r != null ? r.intent.getComponent() : null; 5741 } 5742 } 5743 5744 private HistoryRecord getCallingRecordLocked(IBinder token) { 5745 int index = indexOfTokenLocked(token); 5746 if (index >= 0) { 5747 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5748 if (r != null) { 5749 return r.resultTo; 5750 } 5751 } 5752 return null; 5753 } 5754 5755 public ComponentName getActivityClassForToken(IBinder token) { 5756 synchronized(this) { 5757 int index = indexOfTokenLocked(token); 5758 if (index >= 0) { 5759 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5760 return r.intent.getComponent(); 5761 } 5762 return null; 5763 } 5764 } 5765 5766 public String getPackageForToken(IBinder token) { 5767 synchronized(this) { 5768 int index = indexOfTokenLocked(token); 5769 if (index >= 0) { 5770 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5771 return r.packageName; 5772 } 5773 return null; 5774 } 5775 } 5776 5777 public IIntentSender getIntentSender(int type, 5778 String packageName, IBinder token, String resultWho, 5779 int requestCode, Intent intent, String resolvedType, int flags) { 5780 // Refuse possible leaked file descriptors 5781 if (intent != null && intent.hasFileDescriptors() == true) { 5782 throw new IllegalArgumentException("File descriptors passed in Intent"); 5783 } 5784 5785 if (type == INTENT_SENDER_BROADCAST) { 5786 if ((intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5787 throw new IllegalArgumentException( 5788 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5789 } 5790 } 5791 5792 synchronized(this) { 5793 int callingUid = Binder.getCallingUid(); 5794 try { 5795 if (callingUid != 0 && callingUid != Process.SYSTEM_UID && 5796 Process.supportsProcesses()) { 5797 int uid = ActivityThread.getPackageManager() 5798 .getPackageUid(packageName); 5799 if (uid != Binder.getCallingUid()) { 5800 String msg = "Permission Denial: getIntentSender() from pid=" 5801 + Binder.getCallingPid() 5802 + ", uid=" + Binder.getCallingUid() 5803 + ", (need uid=" + uid + ")" 5804 + " is not allowed to send as package " + packageName; 5805 Log.w(TAG, msg); 5806 throw new SecurityException(msg); 5807 } 5808 } 5809 } catch (RemoteException e) { 5810 throw new SecurityException(e); 5811 } 5812 HistoryRecord activity = null; 5813 if (type == INTENT_SENDER_ACTIVITY_RESULT) { 5814 int index = indexOfTokenLocked(token); 5815 if (index < 0) { 5816 return null; 5817 } 5818 activity = (HistoryRecord)mHistory.get(index); 5819 if (activity.finishing) { 5820 return null; 5821 } 5822 } 5823 5824 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5825 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5826 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5827 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5828 |PendingIntent.FLAG_UPDATE_CURRENT); 5829 5830 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5831 type, packageName, activity, resultWho, 5832 requestCode, intent, resolvedType, flags); 5833 WeakReference<PendingIntentRecord> ref; 5834 ref = mIntentSenderRecords.get(key); 5835 PendingIntentRecord rec = ref != null ? ref.get() : null; 5836 if (rec != null) { 5837 if (!cancelCurrent) { 5838 if (updateCurrent) { 5839 rec.key.requestIntent.replaceExtras(intent); 5840 } 5841 return rec; 5842 } 5843 rec.canceled = true; 5844 mIntentSenderRecords.remove(key); 5845 } 5846 if (noCreate) { 5847 return rec; 5848 } 5849 rec = new PendingIntentRecord(this, key, callingUid); 5850 mIntentSenderRecords.put(key, rec.ref); 5851 if (type == INTENT_SENDER_ACTIVITY_RESULT) { 5852 if (activity.pendingResults == null) { 5853 activity.pendingResults 5854 = new HashSet<WeakReference<PendingIntentRecord>>(); 5855 } 5856 activity.pendingResults.add(rec.ref); 5857 } 5858 return rec; 5859 } 5860 } 5861 5862 public void cancelIntentSender(IIntentSender sender) { 5863 if (!(sender instanceof PendingIntentRecord)) { 5864 return; 5865 } 5866 synchronized(this) { 5867 PendingIntentRecord rec = (PendingIntentRecord)sender; 5868 try { 5869 int uid = ActivityThread.getPackageManager() 5870 .getPackageUid(rec.key.packageName); 5871 if (uid != Binder.getCallingUid()) { 5872 String msg = "Permission Denial: cancelIntentSender() from pid=" 5873 + Binder.getCallingPid() 5874 + ", uid=" + Binder.getCallingUid() 5875 + " is not allowed to cancel packges " 5876 + rec.key.packageName; 5877 Log.w(TAG, msg); 5878 throw new SecurityException(msg); 5879 } 5880 } catch (RemoteException e) { 5881 throw new SecurityException(e); 5882 } 5883 cancelIntentSenderLocked(rec, true); 5884 } 5885 } 5886 5887 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5888 rec.canceled = true; 5889 mIntentSenderRecords.remove(rec.key); 5890 if (cleanActivity && rec.key.activity != null) { 5891 rec.key.activity.pendingResults.remove(rec.ref); 5892 } 5893 } 5894 5895 public String getPackageForIntentSender(IIntentSender pendingResult) { 5896 if (!(pendingResult instanceof PendingIntentRecord)) { 5897 return null; 5898 } 5899 synchronized(this) { 5900 try { 5901 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5902 return res.key.packageName; 5903 } catch (ClassCastException e) { 5904 } 5905 } 5906 return null; 5907 } 5908 5909 public void setProcessLimit(int max) { 5910 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5911 "setProcessLimit()"); 5912 mProcessLimit = max; 5913 } 5914 5915 public int getProcessLimit() { 5916 return mProcessLimit; 5917 } 5918 5919 void foregroundTokenDied(ForegroundToken token) { 5920 synchronized (ActivityManagerService.this) { 5921 synchronized (mPidsSelfLocked) { 5922 ForegroundToken cur 5923 = mForegroundProcesses.get(token.pid); 5924 if (cur != token) { 5925 return; 5926 } 5927 mForegroundProcesses.remove(token.pid); 5928 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5929 if (pr == null) { 5930 return; 5931 } 5932 pr.forcingToForeground = null; 5933 pr.foregroundServices = false; 5934 } 5935 updateOomAdjLocked(); 5936 } 5937 } 5938 5939 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5940 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5941 "setProcessForeground()"); 5942 synchronized(this) { 5943 boolean changed = false; 5944 5945 synchronized (mPidsSelfLocked) { 5946 ProcessRecord pr = mPidsSelfLocked.get(pid); 5947 if (pr == null) { 5948 Log.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5949 return; 5950 } 5951 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5952 if (oldToken != null) { 5953 oldToken.token.unlinkToDeath(oldToken, 0); 5954 mForegroundProcesses.remove(pid); 5955 pr.forcingToForeground = null; 5956 changed = true; 5957 } 5958 if (isForeground && token != null) { 5959 ForegroundToken newToken = new ForegroundToken() { 5960 public void binderDied() { 5961 foregroundTokenDied(this); 5962 } 5963 }; 5964 newToken.pid = pid; 5965 newToken.token = token; 5966 try { 5967 token.linkToDeath(newToken, 0); 5968 mForegroundProcesses.put(pid, newToken); 5969 pr.forcingToForeground = token; 5970 changed = true; 5971 } catch (RemoteException e) { 5972 // If the process died while doing this, we will later 5973 // do the cleanup with the process death link. 5974 } 5975 } 5976 } 5977 5978 if (changed) { 5979 updateOomAdjLocked(); 5980 } 5981 } 5982 } 5983 5984 // ========================================================= 5985 // PERMISSIONS 5986 // ========================================================= 5987 5988 static class PermissionController extends IPermissionController.Stub { 5989 ActivityManagerService mActivityManagerService; 5990 PermissionController(ActivityManagerService activityManagerService) { 5991 mActivityManagerService = activityManagerService; 5992 } 5993 5994 public boolean checkPermission(String permission, int pid, int uid) { 5995 return mActivityManagerService.checkPermission(permission, pid, 5996 uid) == PackageManager.PERMISSION_GRANTED; 5997 } 5998 } 5999 6000 /** 6001 * This can be called with or without the global lock held. 6002 */ 6003 int checkComponentPermission(String permission, int pid, int uid, 6004 int reqUid) { 6005 // We might be performing an operation on behalf of an indirect binder 6006 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6007 // client identity accordingly before proceeding. 6008 Identity tlsIdentity = sCallerIdentity.get(); 6009 if (tlsIdentity != null) { 6010 Log.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6011 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6012 uid = tlsIdentity.uid; 6013 pid = tlsIdentity.pid; 6014 } 6015 6016 // Root, system server and our own process get to do everything. 6017 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID || 6018 !Process.supportsProcesses()) { 6019 return PackageManager.PERMISSION_GRANTED; 6020 } 6021 // If the target requires a specific UID, always fail for others. 6022 if (reqUid >= 0 && uid != reqUid) { 6023 return PackageManager.PERMISSION_DENIED; 6024 } 6025 if (permission == null) { 6026 return PackageManager.PERMISSION_GRANTED; 6027 } 6028 try { 6029 return ActivityThread.getPackageManager() 6030 .checkUidPermission(permission, uid); 6031 } catch (RemoteException e) { 6032 // Should never happen, but if it does... deny! 6033 Log.e(TAG, "PackageManager is dead?!?", e); 6034 } 6035 return PackageManager.PERMISSION_DENIED; 6036 } 6037 6038 /** 6039 * As the only public entry point for permissions checking, this method 6040 * can enforce the semantic that requesting a check on a null global 6041 * permission is automatically denied. (Internally a null permission 6042 * string is used when calling {@link #checkComponentPermission} in cases 6043 * when only uid-based security is needed.) 6044 * 6045 * This can be called with or without the global lock held. 6046 */ 6047 public int checkPermission(String permission, int pid, int uid) { 6048 if (permission == null) { 6049 return PackageManager.PERMISSION_DENIED; 6050 } 6051 return checkComponentPermission(permission, pid, uid, -1); 6052 } 6053 6054 /** 6055 * Binder IPC calls go through the public entry point. 6056 * This can be called with or without the global lock held. 6057 */ 6058 int checkCallingPermission(String permission) { 6059 return checkPermission(permission, 6060 Binder.getCallingPid(), 6061 Binder.getCallingUid()); 6062 } 6063 6064 /** 6065 * This can be called with or without the global lock held. 6066 */ 6067 void enforceCallingPermission(String permission, String func) { 6068 if (checkCallingPermission(permission) 6069 == PackageManager.PERMISSION_GRANTED) { 6070 return; 6071 } 6072 6073 String msg = "Permission Denial: " + func + " from pid=" 6074 + Binder.getCallingPid() 6075 + ", uid=" + Binder.getCallingUid() 6076 + " requires " + permission; 6077 Log.w(TAG, msg); 6078 throw new SecurityException(msg); 6079 } 6080 6081 private final boolean checkHoldingPermissionsLocked(IPackageManager pm, 6082 ProviderInfo pi, int uid, int modeFlags) { 6083 try { 6084 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6085 if ((pi.readPermission != null) && 6086 (pm.checkUidPermission(pi.readPermission, uid) 6087 != PackageManager.PERMISSION_GRANTED)) { 6088 return false; 6089 } 6090 } 6091 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6092 if ((pi.writePermission != null) && 6093 (pm.checkUidPermission(pi.writePermission, uid) 6094 != PackageManager.PERMISSION_GRANTED)) { 6095 return false; 6096 } 6097 } 6098 return true; 6099 } catch (RemoteException e) { 6100 return false; 6101 } 6102 } 6103 6104 private final boolean checkUriPermissionLocked(Uri uri, int uid, 6105 int modeFlags) { 6106 // Root gets to do everything. 6107 if (uid == 0 || !Process.supportsProcesses()) { 6108 return true; 6109 } 6110 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6111 if (perms == null) return false; 6112 UriPermission perm = perms.get(uri); 6113 if (perm == null) return false; 6114 return (modeFlags&perm.modeFlags) == modeFlags; 6115 } 6116 6117 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 6118 // Another redirected-binder-call permissions check as in 6119 // {@link checkComponentPermission}. 6120 Identity tlsIdentity = sCallerIdentity.get(); 6121 if (tlsIdentity != null) { 6122 uid = tlsIdentity.uid; 6123 pid = tlsIdentity.pid; 6124 } 6125 6126 // Our own process gets to do everything. 6127 if (pid == MY_PID) { 6128 return PackageManager.PERMISSION_GRANTED; 6129 } 6130 synchronized(this) { 6131 return checkUriPermissionLocked(uri, uid, modeFlags) 6132 ? PackageManager.PERMISSION_GRANTED 6133 : PackageManager.PERMISSION_DENIED; 6134 } 6135 } 6136 6137 private void grantUriPermissionLocked(int callingUid, 6138 String targetPkg, Uri uri, int modeFlags, HistoryRecord activity) { 6139 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6140 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6141 if (modeFlags == 0) { 6142 return; 6143 } 6144 6145 final IPackageManager pm = ActivityThread.getPackageManager(); 6146 6147 // If this is not a content: uri, we can't do anything with it. 6148 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 6149 return; 6150 } 6151 6152 String name = uri.getAuthority(); 6153 ProviderInfo pi = null; 6154 ContentProviderRecord cpr 6155 = (ContentProviderRecord)mProvidersByName.get(name); 6156 if (cpr != null) { 6157 pi = cpr.info; 6158 } else { 6159 try { 6160 pi = pm.resolveContentProvider(name, 6161 PackageManager.GET_URI_PERMISSION_PATTERNS); 6162 } catch (RemoteException ex) { 6163 } 6164 } 6165 if (pi == null) { 6166 Log.w(TAG, "No content provider found for: " + name); 6167 return; 6168 } 6169 6170 int targetUid; 6171 try { 6172 targetUid = pm.getPackageUid(targetPkg); 6173 if (targetUid < 0) { 6174 return; 6175 } 6176 } catch (RemoteException ex) { 6177 return; 6178 } 6179 6180 // First... does the target actually need this permission? 6181 if (checkHoldingPermissionsLocked(pm, pi, targetUid, modeFlags)) { 6182 // No need to grant the target this permission. 6183 return; 6184 } 6185 6186 // Second... maybe someone else has already granted the 6187 // permission? 6188 if (checkUriPermissionLocked(uri, targetUid, modeFlags)) { 6189 // No need to grant the target this permission. 6190 return; 6191 } 6192 6193 // Third... is the provider allowing granting of URI permissions? 6194 if (!pi.grantUriPermissions) { 6195 throw new SecurityException("Provider " + pi.packageName 6196 + "/" + pi.name 6197 + " does not allow granting of Uri permissions (uri " 6198 + uri + ")"); 6199 } 6200 if (pi.uriPermissionPatterns != null) { 6201 final int N = pi.uriPermissionPatterns.length; 6202 boolean allowed = false; 6203 for (int i=0; i<N; i++) { 6204 if (pi.uriPermissionPatterns[i] != null 6205 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6206 allowed = true; 6207 break; 6208 } 6209 } 6210 if (!allowed) { 6211 throw new SecurityException("Provider " + pi.packageName 6212 + "/" + pi.name 6213 + " does not allow granting of permission to path of Uri " 6214 + uri); 6215 } 6216 } 6217 6218 // Fourth... does the caller itself have permission to access 6219 // this uri? 6220 if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) { 6221 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6222 throw new SecurityException("Uid " + callingUid 6223 + " does not have permission to uri " + uri); 6224 } 6225 } 6226 6227 // Okay! So here we are: the caller has the assumed permission 6228 // to the uri, and the target doesn't. Let's now give this to 6229 // the target. 6230 6231 HashMap<Uri, UriPermission> targetUris 6232 = mGrantedUriPermissions.get(targetUid); 6233 if (targetUris == null) { 6234 targetUris = new HashMap<Uri, UriPermission>(); 6235 mGrantedUriPermissions.put(targetUid, targetUris); 6236 } 6237 6238 UriPermission perm = targetUris.get(uri); 6239 if (perm == null) { 6240 perm = new UriPermission(targetUid, uri); 6241 targetUris.put(uri, perm); 6242 6243 } 6244 perm.modeFlags |= modeFlags; 6245 if (activity == null) { 6246 perm.globalModeFlags |= modeFlags; 6247 } else if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6248 perm.readActivities.add(activity); 6249 if (activity.readUriPermissions == null) { 6250 activity.readUriPermissions = new HashSet<UriPermission>(); 6251 } 6252 activity.readUriPermissions.add(perm); 6253 } else if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6254 perm.writeActivities.add(activity); 6255 if (activity.writeUriPermissions == null) { 6256 activity.writeUriPermissions = new HashSet<UriPermission>(); 6257 } 6258 activity.writeUriPermissions.add(perm); 6259 } 6260 } 6261 6262 private void grantUriPermissionFromIntentLocked(int callingUid, 6263 String targetPkg, Intent intent, HistoryRecord activity) { 6264 if (intent == null) { 6265 return; 6266 } 6267 Uri data = intent.getData(); 6268 if (data == null) { 6269 return; 6270 } 6271 grantUriPermissionLocked(callingUid, targetPkg, data, 6272 intent.getFlags(), activity); 6273 } 6274 6275 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6276 Uri uri, int modeFlags) { 6277 synchronized(this) { 6278 final ProcessRecord r = getRecordForAppLocked(caller); 6279 if (r == null) { 6280 throw new SecurityException("Unable to find app for caller " 6281 + caller 6282 + " when granting permission to uri " + uri); 6283 } 6284 if (targetPkg == null) { 6285 Log.w(TAG, "grantUriPermission: null target"); 6286 return; 6287 } 6288 if (uri == null) { 6289 Log.w(TAG, "grantUriPermission: null uri"); 6290 return; 6291 } 6292 6293 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags, 6294 null); 6295 } 6296 } 6297 6298 private void removeUriPermissionIfNeededLocked(UriPermission perm) { 6299 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6300 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6301 HashMap<Uri, UriPermission> perms 6302 = mGrantedUriPermissions.get(perm.uid); 6303 if (perms != null) { 6304 perms.remove(perm.uri); 6305 if (perms.size() == 0) { 6306 mGrantedUriPermissions.remove(perm.uid); 6307 } 6308 } 6309 } 6310 } 6311 6312 private void removeActivityUriPermissionsLocked(HistoryRecord activity) { 6313 if (activity.readUriPermissions != null) { 6314 for (UriPermission perm : activity.readUriPermissions) { 6315 perm.readActivities.remove(activity); 6316 if (perm.readActivities.size() == 0 && (perm.globalModeFlags 6317 &Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0) { 6318 perm.modeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION; 6319 removeUriPermissionIfNeededLocked(perm); 6320 } 6321 } 6322 } 6323 if (activity.writeUriPermissions != null) { 6324 for (UriPermission perm : activity.writeUriPermissions) { 6325 perm.writeActivities.remove(activity); 6326 if (perm.writeActivities.size() == 0 && (perm.globalModeFlags 6327 &Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0) { 6328 perm.modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION; 6329 removeUriPermissionIfNeededLocked(perm); 6330 } 6331 } 6332 } 6333 } 6334 6335 private void revokeUriPermissionLocked(int callingUid, Uri uri, 6336 int modeFlags) { 6337 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6338 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6339 if (modeFlags == 0) { 6340 return; 6341 } 6342 6343 final IPackageManager pm = ActivityThread.getPackageManager(); 6344 6345 final String authority = uri.getAuthority(); 6346 ProviderInfo pi = null; 6347 ContentProviderRecord cpr 6348 = (ContentProviderRecord)mProvidersByName.get(authority); 6349 if (cpr != null) { 6350 pi = cpr.info; 6351 } else { 6352 try { 6353 pi = pm.resolveContentProvider(authority, 6354 PackageManager.GET_URI_PERMISSION_PATTERNS); 6355 } catch (RemoteException ex) { 6356 } 6357 } 6358 if (pi == null) { 6359 Log.w(TAG, "No content provider found for: " + authority); 6360 return; 6361 } 6362 6363 // Does the caller have this permission on the URI? 6364 if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) { 6365 // Right now, if you are not the original owner of the permission, 6366 // you are not allowed to revoke it. 6367 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6368 throw new SecurityException("Uid " + callingUid 6369 + " does not have permission to uri " + uri); 6370 //} 6371 } 6372 6373 // Go through all of the permissions and remove any that match. 6374 final List<String> SEGMENTS = uri.getPathSegments(); 6375 if (SEGMENTS != null) { 6376 final int NS = SEGMENTS.size(); 6377 int N = mGrantedUriPermissions.size(); 6378 for (int i=0; i<N; i++) { 6379 HashMap<Uri, UriPermission> perms 6380 = mGrantedUriPermissions.valueAt(i); 6381 Iterator<UriPermission> it = perms.values().iterator(); 6382 toploop: 6383 while (it.hasNext()) { 6384 UriPermission perm = it.next(); 6385 Uri targetUri = perm.uri; 6386 if (!authority.equals(targetUri.getAuthority())) { 6387 continue; 6388 } 6389 List<String> targetSegments = targetUri.getPathSegments(); 6390 if (targetSegments == null) { 6391 continue; 6392 } 6393 if (targetSegments.size() < NS) { 6394 continue; 6395 } 6396 for (int j=0; j<NS; j++) { 6397 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6398 continue toploop; 6399 } 6400 } 6401 perm.clearModes(modeFlags); 6402 if (perm.modeFlags == 0) { 6403 it.remove(); 6404 } 6405 } 6406 if (perms.size() == 0) { 6407 mGrantedUriPermissions.remove( 6408 mGrantedUriPermissions.keyAt(i)); 6409 N--; 6410 i--; 6411 } 6412 } 6413 } 6414 } 6415 6416 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6417 int modeFlags) { 6418 synchronized(this) { 6419 final ProcessRecord r = getRecordForAppLocked(caller); 6420 if (r == null) { 6421 throw new SecurityException("Unable to find app for caller " 6422 + caller 6423 + " when revoking permission to uri " + uri); 6424 } 6425 if (uri == null) { 6426 Log.w(TAG, "revokeUriPermission: null uri"); 6427 return; 6428 } 6429 6430 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6431 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6432 if (modeFlags == 0) { 6433 return; 6434 } 6435 6436 final IPackageManager pm = ActivityThread.getPackageManager(); 6437 6438 final String authority = uri.getAuthority(); 6439 ProviderInfo pi = null; 6440 ContentProviderRecord cpr 6441 = (ContentProviderRecord)mProvidersByName.get(authority); 6442 if (cpr != null) { 6443 pi = cpr.info; 6444 } else { 6445 try { 6446 pi = pm.resolveContentProvider(authority, 6447 PackageManager.GET_URI_PERMISSION_PATTERNS); 6448 } catch (RemoteException ex) { 6449 } 6450 } 6451 if (pi == null) { 6452 Log.w(TAG, "No content provider found for: " + authority); 6453 return; 6454 } 6455 6456 revokeUriPermissionLocked(r.info.uid, uri, modeFlags); 6457 } 6458 } 6459 6460 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6461 synchronized (this) { 6462 ProcessRecord app = 6463 who != null ? getRecordForAppLocked(who) : null; 6464 if (app == null) return; 6465 6466 Message msg = Message.obtain(); 6467 msg.what = WAIT_FOR_DEBUGGER_MSG; 6468 msg.obj = app; 6469 msg.arg1 = waiting ? 1 : 0; 6470 mHandler.sendMessage(msg); 6471 } 6472 } 6473 6474 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6475 outInfo.availMem = Process.getFreeMemory(); 6476 outInfo.threshold = HOME_APP_MEM; 6477 outInfo.lowMemory = outInfo.availMem < 6478 (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2)); 6479 } 6480 6481 // ========================================================= 6482 // TASK MANAGEMENT 6483 // ========================================================= 6484 6485 public List getTasks(int maxNum, int flags, 6486 IThumbnailReceiver receiver) { 6487 ArrayList list = new ArrayList(); 6488 6489 PendingThumbnailsRecord pending = null; 6490 IApplicationThread topThumbnail = null; 6491 HistoryRecord topRecord = null; 6492 6493 synchronized(this) { 6494 if (localLOGV) Log.v( 6495 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6496 + ", receiver=" + receiver); 6497 6498 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6499 != PackageManager.PERMISSION_GRANTED) { 6500 if (receiver != null) { 6501 // If the caller wants to wait for pending thumbnails, 6502 // it ain't gonna get them. 6503 try { 6504 receiver.finished(); 6505 } catch (RemoteException ex) { 6506 } 6507 } 6508 String msg = "Permission Denial: getTasks() from pid=" 6509 + Binder.getCallingPid() 6510 + ", uid=" + Binder.getCallingUid() 6511 + " requires " + android.Manifest.permission.GET_TASKS; 6512 Log.w(TAG, msg); 6513 throw new SecurityException(msg); 6514 } 6515 6516 int pos = mHistory.size()-1; 6517 HistoryRecord next = 6518 pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null; 6519 HistoryRecord top = null; 6520 CharSequence topDescription = null; 6521 TaskRecord curTask = null; 6522 int numActivities = 0; 6523 int numRunning = 0; 6524 while (pos >= 0 && maxNum > 0) { 6525 final HistoryRecord r = next; 6526 pos--; 6527 next = pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null; 6528 6529 // Initialize state for next task if needed. 6530 if (top == null || 6531 (top.state == ActivityState.INITIALIZING 6532 && top.task == r.task)) { 6533 top = r; 6534 topDescription = r.description; 6535 curTask = r.task; 6536 numActivities = numRunning = 0; 6537 } 6538 6539 // Add 'r' into the current task. 6540 numActivities++; 6541 if (r.app != null && r.app.thread != null) { 6542 numRunning++; 6543 } 6544 if (topDescription == null) { 6545 topDescription = r.description; 6546 } 6547 6548 if (localLOGV) Log.v( 6549 TAG, r.intent.getComponent().flattenToShortString() 6550 + ": task=" + r.task); 6551 6552 // If the next one is a different task, generate a new 6553 // TaskInfo entry for what we have. 6554 if (next == null || next.task != curTask) { 6555 ActivityManager.RunningTaskInfo ci 6556 = new ActivityManager.RunningTaskInfo(); 6557 ci.id = curTask.taskId; 6558 ci.baseActivity = r.intent.getComponent(); 6559 ci.topActivity = top.intent.getComponent(); 6560 ci.thumbnail = top.thumbnail; 6561 ci.description = topDescription; 6562 ci.numActivities = numActivities; 6563 ci.numRunning = numRunning; 6564 //System.out.println( 6565 // "#" + maxNum + ": " + " descr=" + ci.description); 6566 if (ci.thumbnail == null && receiver != null) { 6567 if (localLOGV) Log.v( 6568 TAG, "State=" + top.state + "Idle=" + top.idle 6569 + " app=" + top.app 6570 + " thr=" + (top.app != null ? top.app.thread : null)); 6571 if (top.state == ActivityState.RESUMED 6572 || top.state == ActivityState.PAUSING) { 6573 if (top.idle && top.app != null 6574 && top.app.thread != null) { 6575 topRecord = top; 6576 topThumbnail = top.app.thread; 6577 } else { 6578 top.thumbnailNeeded = true; 6579 } 6580 } 6581 if (pending == null) { 6582 pending = new PendingThumbnailsRecord(receiver); 6583 } 6584 pending.pendingRecords.add(top); 6585 } 6586 list.add(ci); 6587 maxNum--; 6588 top = null; 6589 } 6590 } 6591 6592 if (pending != null) { 6593 mPendingThumbnails.add(pending); 6594 } 6595 } 6596 6597 if (localLOGV) Log.v(TAG, "We have pending thumbnails: " + pending); 6598 6599 if (topThumbnail != null) { 6600 if (localLOGV) Log.v(TAG, "Requesting top thumbnail"); 6601 try { 6602 topThumbnail.requestThumbnail(topRecord); 6603 } catch (Exception e) { 6604 Log.w(TAG, "Exception thrown when requesting thumbnail", e); 6605 sendPendingThumbnail(null, topRecord, null, null, true); 6606 } 6607 } 6608 6609 if (pending == null && receiver != null) { 6610 // In this case all thumbnails were available and the client 6611 // is being asked to be told when the remaining ones come in... 6612 // which is unusually, since the top-most currently running 6613 // activity should never have a canned thumbnail! Oh well. 6614 try { 6615 receiver.finished(); 6616 } catch (RemoteException ex) { 6617 } 6618 } 6619 6620 return list; 6621 } 6622 6623 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6624 int flags) { 6625 synchronized (this) { 6626 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6627 "getRecentTasks()"); 6628 6629 final int N = mRecentTasks.size(); 6630 ArrayList<ActivityManager.RecentTaskInfo> res 6631 = new ArrayList<ActivityManager.RecentTaskInfo>( 6632 maxNum < N ? maxNum : N); 6633 for (int i=0; i<N && maxNum > 0; i++) { 6634 TaskRecord tr = mRecentTasks.get(i); 6635 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6636 || (tr.intent == null) 6637 || ((tr.intent.getFlags() 6638 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6639 ActivityManager.RecentTaskInfo rti 6640 = new ActivityManager.RecentTaskInfo(); 6641 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6642 rti.baseIntent = new Intent( 6643 tr.intent != null ? tr.intent : tr.affinityIntent); 6644 rti.origActivity = tr.origActivity; 6645 res.add(rti); 6646 maxNum--; 6647 } 6648 } 6649 return res; 6650 } 6651 } 6652 6653 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 6654 int j; 6655 TaskRecord startTask = ((HistoryRecord)mHistory.get(startIndex)).task; 6656 TaskRecord jt = startTask; 6657 6658 // First look backwards 6659 for (j=startIndex-1; j>=0; j--) { 6660 HistoryRecord r = (HistoryRecord)mHistory.get(j); 6661 if (r.task != jt) { 6662 jt = r.task; 6663 if (affinity.equals(jt.affinity)) { 6664 return j; 6665 } 6666 } 6667 } 6668 6669 // Now look forwards 6670 final int N = mHistory.size(); 6671 jt = startTask; 6672 for (j=startIndex+1; j<N; j++) { 6673 HistoryRecord r = (HistoryRecord)mHistory.get(j); 6674 if (r.task != jt) { 6675 if (affinity.equals(jt.affinity)) { 6676 return j; 6677 } 6678 jt = r.task; 6679 } 6680 } 6681 6682 // Might it be at the top? 6683 if (affinity.equals(((HistoryRecord)mHistory.get(N-1)).task.affinity)) { 6684 return N-1; 6685 } 6686 6687 return -1; 6688 } 6689 6690 /** 6691 * Perform a reset of the given task, if needed as part of launching it. 6692 * Returns the new HistoryRecord at the top of the task. 6693 */ 6694 private final HistoryRecord resetTaskIfNeededLocked(HistoryRecord taskTop, 6695 HistoryRecord newActivity) { 6696 boolean forceReset = (newActivity.info.flags 6697 &ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0; 6698 if (taskTop.task.getInactiveDuration() > ACTIVITY_INACTIVE_RESET_TIME) { 6699 if ((newActivity.info.flags 6700 &ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE) == 0) { 6701 forceReset = true; 6702 } 6703 } 6704 6705 final TaskRecord task = taskTop.task; 6706 6707 // We are going to move through the history list so that we can look 6708 // at each activity 'target' with 'below' either the interesting 6709 // activity immediately below it in the stack or null. 6710 HistoryRecord target = null; 6711 int targetI = 0; 6712 int taskTopI = -1; 6713 int replyChainEnd = -1; 6714 int lastReparentPos = -1; 6715 for (int i=mHistory.size()-1; i>=-1; i--) { 6716 HistoryRecord below = i >= 0 ? (HistoryRecord)mHistory.get(i) : null; 6717 6718 if (below != null && below.finishing) { 6719 continue; 6720 } 6721 if (target == null) { 6722 target = below; 6723 targetI = i; 6724 // If we were in the middle of a reply chain before this 6725 // task, it doesn't appear like the root of the chain wants 6726 // anything interesting, so drop it. 6727 replyChainEnd = -1; 6728 continue; 6729 } 6730 6731 final int flags = target.info.flags; 6732 6733 final boolean finishOnTaskLaunch = 6734 (flags&ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0; 6735 final boolean allowTaskReparenting = 6736 (flags&ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0; 6737 6738 if (target.task == task) { 6739 // We are inside of the task being reset... we'll either 6740 // finish this activity, push it out for another task, 6741 // or leave it as-is. We only do this 6742 // for activities that are not the root of the task (since 6743 // if we finish the root, we may no longer have the task!). 6744 if (taskTopI < 0) { 6745 taskTopI = targetI; 6746 } 6747 if (below != null && below.task == task) { 6748 final boolean clearWhenTaskReset = 6749 (target.intent.getFlags() 6750 &Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0; 6751 if (!finishOnTaskLaunch && !clearWhenTaskReset && target.resultTo != null) { 6752 // If this activity is sending a reply to a previous 6753 // activity, we can't do anything with it now until 6754 // we reach the start of the reply chain. 6755 // XXX note that we are assuming the result is always 6756 // to the previous activity, which is almost always 6757 // the case but we really shouldn't count on. 6758 if (replyChainEnd < 0) { 6759 replyChainEnd = targetI; 6760 } 6761 } else if (!finishOnTaskLaunch && !clearWhenTaskReset && allowTaskReparenting 6762 && target.taskAffinity != null 6763 && !target.taskAffinity.equals(task.affinity)) { 6764 // If this activity has an affinity for another 6765 // task, then we need to move it out of here. We will 6766 // move it as far out of the way as possible, to the 6767 // bottom of the activity stack. This also keeps it 6768 // correctly ordered with any activities we previously 6769 // moved. 6770 HistoryRecord p = (HistoryRecord)mHistory.get(0); 6771 if (target.taskAffinity != null 6772 && target.taskAffinity.equals(p.task.affinity)) { 6773 // If the activity currently at the bottom has the 6774 // same task affinity as the one we are moving, 6775 // then merge it into the same task. 6776 target.task = p.task; 6777 if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target 6778 + " out to bottom task " + p.task); 6779 } else { 6780 mCurTask++; 6781 if (mCurTask <= 0) { 6782 mCurTask = 1; 6783 } 6784 target.task = new TaskRecord(mCurTask, target.info, null, 6785 (target.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0); 6786 target.task.affinityIntent = target.intent; 6787 if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target 6788 + " out to new task " + target.task); 6789 } 6790 mWindowManager.setAppGroupId(target, task.taskId); 6791 if (replyChainEnd < 0) { 6792 replyChainEnd = targetI; 6793 } 6794 int dstPos = 0; 6795 for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) { 6796 p = (HistoryRecord)mHistory.get(srcPos); 6797 if (p.finishing) { 6798 continue; 6799 } 6800 if (DEBUG_TASKS) Log.v(TAG, "Pushing next activity " + p 6801 + " out to target's task " + target.task); 6802 task.numActivities--; 6803 p.task = target.task; 6804 target.task.numActivities++; 6805 mHistory.remove(srcPos); 6806 mHistory.add(dstPos, p); 6807 mWindowManager.moveAppToken(dstPos, p); 6808 mWindowManager.setAppGroupId(p, p.task.taskId); 6809 dstPos++; 6810 if (VALIDATE_TOKENS) { 6811 mWindowManager.validateAppTokens(mHistory); 6812 } 6813 i++; 6814 } 6815 if (taskTop == p) { 6816 taskTop = below; 6817 } 6818 if (taskTopI == replyChainEnd) { 6819 taskTopI = -1; 6820 } 6821 replyChainEnd = -1; 6822 addRecentTask(target.task); 6823 } else if (forceReset || finishOnTaskLaunch 6824 || clearWhenTaskReset) { 6825 // If the activity should just be removed -- either 6826 // because it asks for it, or the task should be 6827 // cleared -- then finish it and anything that is 6828 // part of its reply chain. 6829 if (clearWhenTaskReset) { 6830 // In this case, we want to finish this activity 6831 // and everything above it, so be sneaky and pretend 6832 // like these are all in the reply chain. 6833 replyChainEnd = targetI+1; 6834 while (replyChainEnd < mHistory.size() && 6835 ((HistoryRecord)mHistory.get( 6836 replyChainEnd)).task == task) { 6837 replyChainEnd++; 6838 } 6839 replyChainEnd--; 6840 } else if (replyChainEnd < 0) { 6841 replyChainEnd = targetI; 6842 } 6843 HistoryRecord p = null; 6844 for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) { 6845 p = (HistoryRecord)mHistory.get(srcPos); 6846 if (p.finishing) { 6847 continue; 6848 } 6849 if (finishActivityLocked(p, srcPos, 6850 Activity.RESULT_CANCELED, null, "reset")) { 6851 replyChainEnd--; 6852 srcPos--; 6853 } 6854 } 6855 if (taskTop == p) { 6856 taskTop = below; 6857 } 6858 if (taskTopI == replyChainEnd) { 6859 taskTopI = -1; 6860 } 6861 replyChainEnd = -1; 6862 } else { 6863 // If we were in the middle of a chain, well the 6864 // activity that started it all doesn't want anything 6865 // special, so leave it all as-is. 6866 replyChainEnd = -1; 6867 } 6868 } else { 6869 // Reached the bottom of the task -- any reply chain 6870 // should be left as-is. 6871 replyChainEnd = -1; 6872 } 6873 6874 } else if (target.resultTo != null) { 6875 // If this activity is sending a reply to a previous 6876 // activity, we can't do anything with it now until 6877 // we reach the start of the reply chain. 6878 // XXX note that we are assuming the result is always 6879 // to the previous activity, which is almost always 6880 // the case but we really shouldn't count on. 6881 if (replyChainEnd < 0) { 6882 replyChainEnd = targetI; 6883 } 6884 6885 } else if (taskTopI >= 0 && allowTaskReparenting 6886 && task.affinity != null 6887 && task.affinity.equals(target.taskAffinity)) { 6888 // We are inside of another task... if this activity has 6889 // an affinity for our task, then either remove it if we are 6890 // clearing or move it over to our task. Note that 6891 // we currently punt on the case where we are resetting a 6892 // task that is not at the top but who has activities above 6893 // with an affinity to it... this is really not a normal 6894 // case, and we will need to later pull that task to the front 6895 // and usually at that point we will do the reset and pick 6896 // up those remaining activities. (This only happens if 6897 // someone starts an activity in a new task from an activity 6898 // in a task that is not currently on top.) 6899 if (forceReset || finishOnTaskLaunch) { 6900 if (replyChainEnd < 0) { 6901 replyChainEnd = targetI; 6902 } 6903 HistoryRecord p = null; 6904 for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) { 6905 p = (HistoryRecord)mHistory.get(srcPos); 6906 if (p.finishing) { 6907 continue; 6908 } 6909 if (finishActivityLocked(p, srcPos, 6910 Activity.RESULT_CANCELED, null, "reset")) { 6911 taskTopI--; 6912 lastReparentPos--; 6913 replyChainEnd--; 6914 srcPos--; 6915 } 6916 } 6917 replyChainEnd = -1; 6918 } else { 6919 if (replyChainEnd < 0) { 6920 replyChainEnd = targetI; 6921 } 6922 for (int srcPos=replyChainEnd; srcPos>=targetI; srcPos--) { 6923 HistoryRecord p = (HistoryRecord)mHistory.get(srcPos); 6924 if (p.finishing) { 6925 continue; 6926 } 6927 if (lastReparentPos < 0) { 6928 lastReparentPos = taskTopI; 6929 taskTop = p; 6930 } else { 6931 lastReparentPos--; 6932 } 6933 mHistory.remove(srcPos); 6934 p.task.numActivities--; 6935 p.task = task; 6936 mHistory.add(lastReparentPos, p); 6937 if (DEBUG_TASKS) Log.v(TAG, "Pulling activity " + p 6938 + " in to resetting task " + task); 6939 task.numActivities++; 6940 mWindowManager.moveAppToken(lastReparentPos, p); 6941 mWindowManager.setAppGroupId(p, p.task.taskId); 6942 if (VALIDATE_TOKENS) { 6943 mWindowManager.validateAppTokens(mHistory); 6944 } 6945 } 6946 replyChainEnd = -1; 6947 6948 // Now we've moved it in to place... but what if this is 6949 // a singleTop activity and we have put it on top of another 6950 // instance of the same activity? Then we drop the instance 6951 // below so it remains singleTop. 6952 if (target.info.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) { 6953 for (int j=lastReparentPos-1; j>=0; j--) { 6954 HistoryRecord p = (HistoryRecord)mHistory.get(j); 6955 if (p.finishing) { 6956 continue; 6957 } 6958 if (p.intent.getComponent().equals(target.intent.getComponent())) { 6959 if (finishActivityLocked(p, j, 6960 Activity.RESULT_CANCELED, null, "replace")) { 6961 taskTopI--; 6962 lastReparentPos--; 6963 } 6964 } 6965 } 6966 } 6967 } 6968 } 6969 6970 target = below; 6971 targetI = i; 6972 } 6973 6974 return taskTop; 6975 } 6976 6977 /** 6978 * TODO: Add mController hook 6979 */ 6980 public void moveTaskToFront(int task) { 6981 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 6982 "moveTaskToFront()"); 6983 6984 synchronized(this) { 6985 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 6986 Binder.getCallingUid(), "Task to front")) { 6987 return; 6988 } 6989 final long origId = Binder.clearCallingIdentity(); 6990 try { 6991 int N = mRecentTasks.size(); 6992 for (int i=0; i<N; i++) { 6993 TaskRecord tr = mRecentTasks.get(i); 6994 if (tr.taskId == task) { 6995 moveTaskToFrontLocked(tr, null); 6996 return; 6997 } 6998 } 6999 for (int i=mHistory.size()-1; i>=0; i--) { 7000 HistoryRecord hr = (HistoryRecord)mHistory.get(i); 7001 if (hr.task.taskId == task) { 7002 moveTaskToFrontLocked(hr.task, null); 7003 return; 7004 } 7005 } 7006 } finally { 7007 Binder.restoreCallingIdentity(origId); 7008 } 7009 } 7010 } 7011 7012 private final void moveTaskToFrontLocked(TaskRecord tr, HistoryRecord reason) { 7013 if (DEBUG_SWITCH) Log.v(TAG, "moveTaskToFront: " + tr); 7014 7015 final int task = tr.taskId; 7016 int top = mHistory.size()-1; 7017 7018 if (top < 0 || ((HistoryRecord)mHistory.get(top)).task.taskId == task) { 7019 // nothing to do! 7020 return; 7021 } 7022 7023 ArrayList moved = new ArrayList(); 7024 7025 // Applying the affinities may have removed entries from the history, 7026 // so get the size again. 7027 top = mHistory.size()-1; 7028 int pos = top; 7029 7030 // Shift all activities with this task up to the top 7031 // of the stack, keeping them in the same internal order. 7032 while (pos >= 0) { 7033 HistoryRecord r = (HistoryRecord)mHistory.get(pos); 7034 if (localLOGV) Log.v( 7035 TAG, "At " + pos + " ckp " + r.task + ": " + r); 7036 boolean first = true; 7037 if (r.task.taskId == task) { 7038 if (localLOGV) Log.v(TAG, "Removing and adding at " + top); 7039 mHistory.remove(pos); 7040 mHistory.add(top, r); 7041 moved.add(0, r); 7042 top--; 7043 if (first) { 7044 addRecentTask(r.task); 7045 first = false; 7046 } 7047 } 7048 pos--; 7049 } 7050 7051 if (DEBUG_TRANSITION) Log.v(TAG, 7052 "Prepare to front transition: task=" + tr); 7053 if (reason != null && 7054 (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { 7055 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 7056 HistoryRecord r = topRunningActivityLocked(null); 7057 if (r != null) { 7058 mNoAnimActivities.add(r); 7059 } 7060 } else { 7061 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT); 7062 } 7063 7064 mWindowManager.moveAppTokensToTop(moved); 7065 if (VALIDATE_TOKENS) { 7066 mWindowManager.validateAppTokens(mHistory); 7067 } 7068 7069 finishTaskMove(task); 7070 EventLog.writeEvent(LOG_TASK_TO_FRONT, task); 7071 } 7072 7073 private final void finishTaskMove(int task) { 7074 resumeTopActivityLocked(null); 7075 } 7076 7077 public void moveTaskToBack(int task) { 7078 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7079 "moveTaskToBack()"); 7080 7081 synchronized(this) { 7082 if (mResumedActivity != null && mResumedActivity.task.taskId == task) { 7083 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7084 Binder.getCallingUid(), "Task to back")) { 7085 return; 7086 } 7087 } 7088 final long origId = Binder.clearCallingIdentity(); 7089 moveTaskToBackLocked(task, null); 7090 Binder.restoreCallingIdentity(origId); 7091 } 7092 } 7093 7094 /** 7095 * Moves an activity, and all of the other activities within the same task, to the bottom 7096 * of the history stack. The activity's order within the task is unchanged. 7097 * 7098 * @param token A reference to the activity we wish to move 7099 * @param nonRoot If false then this only works if the activity is the root 7100 * of a task; if true it will work for any activity in a task. 7101 * @return Returns true if the move completed, false if not. 7102 */ 7103 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7104 synchronized(this) { 7105 final long origId = Binder.clearCallingIdentity(); 7106 int taskId = getTaskForActivityLocked(token, !nonRoot); 7107 if (taskId >= 0) { 7108 return moveTaskToBackLocked(taskId, null); 7109 } 7110 Binder.restoreCallingIdentity(origId); 7111 } 7112 return false; 7113 } 7114 7115 /** 7116 * Worker method for rearranging history stack. Implements the function of moving all 7117 * activities for a specific task (gathering them if disjoint) into a single group at the 7118 * bottom of the stack. 7119 * 7120 * If a watcher is installed, the action is preflighted and the watcher has an opportunity 7121 * to premeptively cancel the move. 7122 * 7123 * @param task The taskId to collect and move to the bottom. 7124 * @return Returns true if the move completed, false if not. 7125 */ 7126 private final boolean moveTaskToBackLocked(int task, HistoryRecord reason) { 7127 Log.i(TAG, "moveTaskToBack: " + task); 7128 7129 // If we have a watcher, preflight the move before committing to it. First check 7130 // for *other* available tasks, but if none are available, then try again allowing the 7131 // current task to be selected. 7132 if (mController != null) { 7133 HistoryRecord next = topRunningActivityLocked(null, task); 7134 if (next == null) { 7135 next = topRunningActivityLocked(null, 0); 7136 } 7137 if (next != null) { 7138 // ask watcher if this is allowed 7139 boolean moveOK = true; 7140 try { 7141 moveOK = mController.activityResuming(next.packageName); 7142 } catch (RemoteException e) { 7143 mController = null; 7144 } 7145 if (!moveOK) { 7146 return false; 7147 } 7148 } 7149 } 7150 7151 ArrayList moved = new ArrayList(); 7152 7153 if (DEBUG_TRANSITION) Log.v(TAG, 7154 "Prepare to back transition: task=" + task); 7155 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_BACK); 7156 7157 final int N = mHistory.size(); 7158 int bottom = 0; 7159 int pos = 0; 7160 7161 // Shift all activities with this task down to the bottom 7162 // of the stack, keeping them in the same internal order. 7163 while (pos < N) { 7164 HistoryRecord r = (HistoryRecord)mHistory.get(pos); 7165 if (localLOGV) Log.v( 7166 TAG, "At " + pos + " ckp " + r.task + ": " + r); 7167 if (r.task.taskId == task) { 7168 if (localLOGV) Log.v(TAG, "Removing and adding at " + (N-1)); 7169 mHistory.remove(pos); 7170 mHistory.add(bottom, r); 7171 moved.add(r); 7172 bottom++; 7173 } 7174 pos++; 7175 } 7176 7177 if (reason != null && 7178 (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { 7179 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 7180 HistoryRecord r = topRunningActivityLocked(null); 7181 if (r != null) { 7182 mNoAnimActivities.add(r); 7183 } 7184 } else { 7185 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT); 7186 } 7187 mWindowManager.moveAppTokensToBottom(moved); 7188 if (VALIDATE_TOKENS) { 7189 mWindowManager.validateAppTokens(mHistory); 7190 } 7191 7192 finishTaskMove(task); 7193 return true; 7194 } 7195 7196 public void moveTaskBackwards(int task) { 7197 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7198 "moveTaskBackwards()"); 7199 7200 synchronized(this) { 7201 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7202 Binder.getCallingUid(), "Task backwards")) { 7203 return; 7204 } 7205 final long origId = Binder.clearCallingIdentity(); 7206 moveTaskBackwardsLocked(task); 7207 Binder.restoreCallingIdentity(origId); 7208 } 7209 } 7210 7211 private final void moveTaskBackwardsLocked(int task) { 7212 Log.e(TAG, "moveTaskBackwards not yet implemented!"); 7213 } 7214 7215 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7216 synchronized(this) { 7217 return getTaskForActivityLocked(token, onlyRoot); 7218 } 7219 } 7220 7221 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 7222 final int N = mHistory.size(); 7223 TaskRecord lastTask = null; 7224 for (int i=0; i<N; i++) { 7225 HistoryRecord r = (HistoryRecord)mHistory.get(i); 7226 if (r == token) { 7227 if (!onlyRoot || lastTask != r.task) { 7228 return r.task.taskId; 7229 } 7230 return -1; 7231 } 7232 lastTask = r.task; 7233 } 7234 7235 return -1; 7236 } 7237 7238 /** 7239 * Returns the top activity in any existing task matching the given 7240 * Intent. Returns null if no such task is found. 7241 */ 7242 private HistoryRecord findTaskLocked(Intent intent, ActivityInfo info) { 7243 ComponentName cls = intent.getComponent(); 7244 if (info.targetActivity != null) { 7245 cls = new ComponentName(info.packageName, info.targetActivity); 7246 } 7247 7248 TaskRecord cp = null; 7249 7250 final int N = mHistory.size(); 7251 for (int i=(N-1); i>=0; i--) { 7252 HistoryRecord r = (HistoryRecord)mHistory.get(i); 7253 if (!r.finishing && r.task != cp 7254 && r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 7255 cp = r.task; 7256 //Log.i(TAG, "Comparing existing cls=" + r.task.intent.getComponent().flattenToShortString() 7257 // + "/aff=" + r.task.affinity + " to new cls=" 7258 // + intent.getComponent().flattenToShortString() + "/aff=" + taskAffinity); 7259 if (r.task.affinity != null) { 7260 if (r.task.affinity.equals(info.taskAffinity)) { 7261 //Log.i(TAG, "Found matching affinity!"); 7262 return r; 7263 } 7264 } else if (r.task.intent != null 7265 && r.task.intent.getComponent().equals(cls)) { 7266 //Log.i(TAG, "Found matching class!"); 7267 //dump(); 7268 //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent); 7269 return r; 7270 } else if (r.task.affinityIntent != null 7271 && r.task.affinityIntent.getComponent().equals(cls)) { 7272 //Log.i(TAG, "Found matching class!"); 7273 //dump(); 7274 //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent); 7275 return r; 7276 } 7277 } 7278 } 7279 7280 return null; 7281 } 7282 7283 /** 7284 * Returns the first activity (starting from the top of the stack) that 7285 * is the same as the given activity. Returns null if no such activity 7286 * is found. 7287 */ 7288 private HistoryRecord findActivityLocked(Intent intent, ActivityInfo info) { 7289 ComponentName cls = intent.getComponent(); 7290 if (info.targetActivity != null) { 7291 cls = new ComponentName(info.packageName, info.targetActivity); 7292 } 7293 7294 final int N = mHistory.size(); 7295 for (int i=(N-1); i>=0; i--) { 7296 HistoryRecord r = (HistoryRecord)mHistory.get(i); 7297 if (!r.finishing) { 7298 if (r.intent.getComponent().equals(cls)) { 7299 //Log.i(TAG, "Found matching class!"); 7300 //dump(); 7301 //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent); 7302 return r; 7303 } 7304 } 7305 } 7306 7307 return null; 7308 } 7309 7310 public void finishOtherInstances(IBinder token, ComponentName className) { 7311 synchronized(this) { 7312 final long origId = Binder.clearCallingIdentity(); 7313 7314 int N = mHistory.size(); 7315 TaskRecord lastTask = null; 7316 for (int i=0; i<N; i++) { 7317 HistoryRecord r = (HistoryRecord)mHistory.get(i); 7318 if (r.realActivity.equals(className) 7319 && r != token && lastTask != r.task) { 7320 if (finishActivityLocked(r, i, Activity.RESULT_CANCELED, 7321 null, "others")) { 7322 i--; 7323 N--; 7324 } 7325 } 7326 lastTask = r.task; 7327 } 7328 7329 Binder.restoreCallingIdentity(origId); 7330 } 7331 } 7332 7333 // ========================================================= 7334 // THUMBNAILS 7335 // ========================================================= 7336 7337 public void reportThumbnail(IBinder token, 7338 Bitmap thumbnail, CharSequence description) { 7339 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7340 final long origId = Binder.clearCallingIdentity(); 7341 sendPendingThumbnail(null, token, thumbnail, description, true); 7342 Binder.restoreCallingIdentity(origId); 7343 } 7344 7345 final void sendPendingThumbnail(HistoryRecord r, IBinder token, 7346 Bitmap thumbnail, CharSequence description, boolean always) { 7347 TaskRecord task = null; 7348 ArrayList receivers = null; 7349 7350 //System.out.println("Send pending thumbnail: " + r); 7351 7352 synchronized(this) { 7353 if (r == null) { 7354 int index = indexOfTokenLocked(token); 7355 if (index < 0) { 7356 return; 7357 } 7358 r = (HistoryRecord)mHistory.get(index); 7359 } 7360 if (thumbnail == null) { 7361 thumbnail = r.thumbnail; 7362 description = r.description; 7363 } 7364 if (thumbnail == null && !always) { 7365 // If there is no thumbnail, and this entry is not actually 7366 // going away, then abort for now and pick up the next 7367 // thumbnail we get. 7368 return; 7369 } 7370 task = r.task; 7371 7372 int N = mPendingThumbnails.size(); 7373 int i=0; 7374 while (i<N) { 7375 PendingThumbnailsRecord pr = 7376 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 7377 //System.out.println("Looking in " + pr.pendingRecords); 7378 if (pr.pendingRecords.remove(r)) { 7379 if (receivers == null) { 7380 receivers = new ArrayList(); 7381 } 7382 receivers.add(pr); 7383 if (pr.pendingRecords.size() == 0) { 7384 pr.finished = true; 7385 mPendingThumbnails.remove(i); 7386 N--; 7387 continue; 7388 } 7389 } 7390 i++; 7391 } 7392 } 7393 7394 if (receivers != null) { 7395 final int N = receivers.size(); 7396 for (int i=0; i<N; i++) { 7397 try { 7398 PendingThumbnailsRecord pr = 7399 (PendingThumbnailsRecord)receivers.get(i); 7400 pr.receiver.newThumbnail( 7401 task != null ? task.taskId : -1, thumbnail, description); 7402 if (pr.finished) { 7403 pr.receiver.finished(); 7404 } 7405 } catch (Exception e) { 7406 Log.w(TAG, "Exception thrown when sending thumbnail", e); 7407 } 7408 } 7409 } 7410 } 7411 7412 // ========================================================= 7413 // CONTENT PROVIDERS 7414 // ========================================================= 7415 7416 private final List generateApplicationProvidersLocked(ProcessRecord app) { 7417 List providers = null; 7418 try { 7419 providers = ActivityThread.getPackageManager(). 7420 queryContentProviders(app.processName, app.info.uid, 7421 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7422 } catch (RemoteException ex) { 7423 } 7424 if (providers != null) { 7425 final int N = providers.size(); 7426 for (int i=0; i<N; i++) { 7427 ProviderInfo cpi = 7428 (ProviderInfo)providers.get(i); 7429 ContentProviderRecord cpr = 7430 (ContentProviderRecord)mProvidersByClass.get(cpi.name); 7431 if (cpr == null) { 7432 cpr = new ContentProviderRecord(cpi, app.info); 7433 mProvidersByClass.put(cpi.name, cpr); 7434 } 7435 app.pubProviders.put(cpi.name, cpr); 7436 app.addPackage(cpi.applicationInfo.packageName); 7437 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7438 } 7439 } 7440 return providers; 7441 } 7442 7443 private final String checkContentProviderPermissionLocked( 7444 ProviderInfo cpi, ProcessRecord r, int mode) { 7445 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7446 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid(); 7447 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7448 cpi.exported ? -1 : cpi.applicationInfo.uid) 7449 == PackageManager.PERMISSION_GRANTED 7450 && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) { 7451 return null; 7452 } 7453 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7454 cpi.exported ? -1 : cpi.applicationInfo.uid) 7455 == PackageManager.PERMISSION_GRANTED) { 7456 return null; 7457 } 7458 7459 PathPermission[] pps = cpi.pathPermissions; 7460 if (pps != null) { 7461 int i = pps.length; 7462 while (i > 0) { 7463 i--; 7464 PathPermission pp = pps[i]; 7465 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7466 cpi.exported ? -1 : cpi.applicationInfo.uid) 7467 == PackageManager.PERMISSION_GRANTED 7468 && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) { 7469 return null; 7470 } 7471 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7472 cpi.exported ? -1 : cpi.applicationInfo.uid) 7473 == PackageManager.PERMISSION_GRANTED) { 7474 return null; 7475 } 7476 } 7477 } 7478 7479 String msg = "Permission Denial: opening provider " + cpi.name 7480 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7481 + ", uid=" + callingUid + ") requires " 7482 + cpi.readPermission + " or " + cpi.writePermission; 7483 Log.w(TAG, msg); 7484 return msg; 7485 } 7486 7487 private final ContentProviderHolder getContentProviderImpl( 7488 IApplicationThread caller, String name) { 7489 ContentProviderRecord cpr; 7490 ProviderInfo cpi = null; 7491 7492 synchronized(this) { 7493 ProcessRecord r = null; 7494 if (caller != null) { 7495 r = getRecordForAppLocked(caller); 7496 if (r == null) { 7497 throw new SecurityException( 7498 "Unable to find app for caller " + caller 7499 + " (pid=" + Binder.getCallingPid() 7500 + ") when getting content provider " + name); 7501 } 7502 } 7503 7504 // First check if this content provider has been published... 7505 cpr = (ContentProviderRecord)mProvidersByName.get(name); 7506 if (cpr != null) { 7507 cpi = cpr.info; 7508 if (checkContentProviderPermissionLocked(cpi, r, -1) != null) { 7509 return new ContentProviderHolder(cpi, 7510 cpi.readPermission != null 7511 ? cpi.readPermission : cpi.writePermission); 7512 } 7513 7514 if (r != null && cpr.canRunHere(r)) { 7515 // This provider has been published or is in the process 7516 // of being published... but it is also allowed to run 7517 // in the caller's process, so don't make a connection 7518 // and just let the caller instantiate its own instance. 7519 if (cpr.provider != null) { 7520 // don't give caller the provider object, it needs 7521 // to make its own. 7522 cpr = new ContentProviderRecord(cpr); 7523 } 7524 return cpr; 7525 } 7526 7527 final long origId = Binder.clearCallingIdentity(); 7528 7529 // In this case the provider instance already exists, so we can 7530 // return it right away. 7531 if (r != null) { 7532 if (DEBUG_PROVIDER) Log.v(TAG, 7533 "Adding provider requested by " 7534 + r.processName + " from process " 7535 + cpr.info.processName); 7536 r.conProviders.add(cpr); 7537 cpr.clients.add(r); 7538 } else { 7539 cpr.externals++; 7540 } 7541 7542 if (cpr.app != null) { 7543 updateOomAdjLocked(cpr.app); 7544 } 7545 7546 Binder.restoreCallingIdentity(origId); 7547 7548 } else { 7549 try { 7550 cpi = ActivityThread.getPackageManager(). 7551 resolveContentProvider(name, 7552 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7553 } catch (RemoteException ex) { 7554 } 7555 if (cpi == null) { 7556 return null; 7557 } 7558 7559 if (checkContentProviderPermissionLocked(cpi, r, -1) != null) { 7560 return new ContentProviderHolder(cpi, 7561 cpi.readPermission != null 7562 ? cpi.readPermission : cpi.writePermission); 7563 } 7564 7565 cpr = (ContentProviderRecord)mProvidersByClass.get(cpi.name); 7566 final boolean firstClass = cpr == null; 7567 if (firstClass) { 7568 try { 7569 ApplicationInfo ai = 7570 ActivityThread.getPackageManager(). 7571 getApplicationInfo( 7572 cpi.applicationInfo.packageName, 7573 STOCK_PM_FLAGS); 7574 if (ai == null) { 7575 Log.w(TAG, "No package info for content provider " 7576 + cpi.name); 7577 return null; 7578 } 7579 cpr = new ContentProviderRecord(cpi, ai); 7580 } catch (RemoteException ex) { 7581 // pm is in same process, this will never happen. 7582 } 7583 } 7584 7585 if (r != null && cpr.canRunHere(r)) { 7586 // If this is a multiprocess provider, then just return its 7587 // info and allow the caller to instantiate it. Only do 7588 // this if the provider is the same user as the caller's 7589 // process, or can run as root (so can be in any process). 7590 return cpr; 7591 } 7592 7593 if (DEBUG_PROVIDER) { 7594 RuntimeException e = new RuntimeException("here"); 7595 Log.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid 7596 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7597 } 7598 7599 // This is single process, and our app is now connecting to it. 7600 // See if we are already in the process of launching this 7601 // provider. 7602 final int N = mLaunchingProviders.size(); 7603 int i; 7604 for (i=0; i<N; i++) { 7605 if (mLaunchingProviders.get(i) == cpr) { 7606 break; 7607 } 7608 } 7609 7610 // If the provider is not already being launched, then get it 7611 // started. 7612 if (i >= N) { 7613 final long origId = Binder.clearCallingIdentity(); 7614 ProcessRecord proc = startProcessLocked(cpi.processName, 7615 cpr.appInfo, false, 0, "content provider", 7616 new ComponentName(cpi.applicationInfo.packageName, 7617 cpi.name), false); 7618 if (proc == null) { 7619 Log.w(TAG, "Unable to launch app " 7620 + cpi.applicationInfo.packageName + "/" 7621 + cpi.applicationInfo.uid + " for provider " 7622 + name + ": process is bad"); 7623 return null; 7624 } 7625 cpr.launchingApp = proc; 7626 mLaunchingProviders.add(cpr); 7627 Binder.restoreCallingIdentity(origId); 7628 } 7629 7630 // Make sure the provider is published (the same provider class 7631 // may be published under multiple names). 7632 if (firstClass) { 7633 mProvidersByClass.put(cpi.name, cpr); 7634 } 7635 mProvidersByName.put(name, cpr); 7636 7637 if (r != null) { 7638 if (DEBUG_PROVIDER) Log.v(TAG, 7639 "Adding provider requested by " 7640 + r.processName + " from process " 7641 + cpr.info.processName); 7642 r.conProviders.add(cpr); 7643 cpr.clients.add(r); 7644 } else { 7645 cpr.externals++; 7646 } 7647 } 7648 } 7649 7650 // Wait for the provider to be published... 7651 synchronized (cpr) { 7652 while (cpr.provider == null) { 7653 if (cpr.launchingApp == null) { 7654 Log.w(TAG, "Unable to launch app " 7655 + cpi.applicationInfo.packageName + "/" 7656 + cpi.applicationInfo.uid + " for provider " 7657 + name + ": launching app became null"); 7658 EventLog.writeEvent(LOG_AM_PROVIDER_LOST_PROCESS, 7659 cpi.applicationInfo.packageName, 7660 cpi.applicationInfo.uid, name); 7661 return null; 7662 } 7663 try { 7664 cpr.wait(); 7665 } catch (InterruptedException ex) { 7666 } 7667 } 7668 } 7669 return cpr; 7670 } 7671 7672 public final ContentProviderHolder getContentProvider( 7673 IApplicationThread caller, String name) { 7674 if (caller == null) { 7675 String msg = "null IApplicationThread when getting content provider " 7676 + name; 7677 Log.w(TAG, msg); 7678 throw new SecurityException(msg); 7679 } 7680 7681 return getContentProviderImpl(caller, name); 7682 } 7683 7684 private ContentProviderHolder getContentProviderExternal(String name) { 7685 return getContentProviderImpl(null, name); 7686 } 7687 7688 /** 7689 * Drop a content provider from a ProcessRecord's bookkeeping 7690 * @param cpr 7691 */ 7692 public void removeContentProvider(IApplicationThread caller, String name) { 7693 synchronized (this) { 7694 ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name); 7695 if(cpr == null) { 7696 // remove from mProvidersByClass 7697 if (DEBUG_PROVIDER) Log.v(TAG, name + 7698 " provider not found in providers list"); 7699 return; 7700 } 7701 final ProcessRecord r = getRecordForAppLocked(caller); 7702 if (r == null) { 7703 throw new SecurityException( 7704 "Unable to find app for caller " + caller + 7705 " when removing content provider " + name); 7706 } 7707 //update content provider record entry info 7708 ContentProviderRecord localCpr = (ContentProviderRecord) 7709 mProvidersByClass.get(cpr.info.name); 7710 if (DEBUG_PROVIDER) Log.v(TAG, "Removing provider requested by " 7711 + r.info.processName + " from process " 7712 + localCpr.appInfo.processName); 7713 if (localCpr.app == r) { 7714 //should not happen. taken care of as a local provider 7715 Log.w(TAG, "removeContentProvider called on local provider: " 7716 + cpr.info.name + " in process " + r.processName); 7717 return; 7718 } else { 7719 localCpr.clients.remove(r); 7720 r.conProviders.remove(localCpr); 7721 } 7722 updateOomAdjLocked(); 7723 } 7724 } 7725 7726 private void removeContentProviderExternal(String name) { 7727 synchronized (this) { 7728 ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name); 7729 if(cpr == null) { 7730 //remove from mProvidersByClass 7731 if(localLOGV) Log.v(TAG, name+" content provider not found in providers list"); 7732 return; 7733 } 7734 7735 //update content provider record entry info 7736 ContentProviderRecord localCpr = (ContentProviderRecord) mProvidersByClass.get(cpr.info.name); 7737 localCpr.externals--; 7738 if (localCpr.externals < 0) { 7739 Log.e(TAG, "Externals < 0 for content provider " + localCpr); 7740 } 7741 updateOomAdjLocked(); 7742 } 7743 } 7744 7745 public final void publishContentProviders(IApplicationThread caller, 7746 List<ContentProviderHolder> providers) { 7747 if (providers == null) { 7748 return; 7749 } 7750 7751 synchronized(this) { 7752 final ProcessRecord r = getRecordForAppLocked(caller); 7753 if (r == null) { 7754 throw new SecurityException( 7755 "Unable to find app for caller " + caller 7756 + " (pid=" + Binder.getCallingPid() 7757 + ") when publishing content providers"); 7758 } 7759 7760 final long origId = Binder.clearCallingIdentity(); 7761 7762 final int N = providers.size(); 7763 for (int i=0; i<N; i++) { 7764 ContentProviderHolder src = providers.get(i); 7765 if (src == null || src.info == null || src.provider == null) { 7766 continue; 7767 } 7768 ContentProviderRecord dst = 7769 (ContentProviderRecord)r.pubProviders.get(src.info.name); 7770 if (dst != null) { 7771 mProvidersByClass.put(dst.info.name, dst); 7772 String names[] = dst.info.authority.split(";"); 7773 for (int j = 0; j < names.length; j++) { 7774 mProvidersByName.put(names[j], dst); 7775 } 7776 7777 int NL = mLaunchingProviders.size(); 7778 int j; 7779 for (j=0; j<NL; j++) { 7780 if (mLaunchingProviders.get(j) == dst) { 7781 mLaunchingProviders.remove(j); 7782 j--; 7783 NL--; 7784 } 7785 } 7786 synchronized (dst) { 7787 dst.provider = src.provider; 7788 dst.app = r; 7789 dst.notifyAll(); 7790 } 7791 updateOomAdjLocked(r); 7792 } 7793 } 7794 7795 Binder.restoreCallingIdentity(origId); 7796 } 7797 } 7798 7799 public static final void installSystemProviders() { 7800 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 7801 List providers = mSelf.generateApplicationProvidersLocked(app); 7802 mSystemThread.installSystemProviders(providers); 7803 } 7804 7805 // ========================================================= 7806 // GLOBAL MANAGEMENT 7807 // ========================================================= 7808 7809 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 7810 ApplicationInfo info, String customProcess) { 7811 String proc = customProcess != null ? customProcess : info.processName; 7812 BatteryStatsImpl.Uid.Proc ps = null; 7813 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7814 synchronized (stats) { 7815 ps = stats.getProcessStatsLocked(info.uid, proc); 7816 } 7817 return new ProcessRecord(ps, thread, info, proc); 7818 } 7819 7820 final ProcessRecord addAppLocked(ApplicationInfo info) { 7821 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid); 7822 7823 if (app == null) { 7824 app = newProcessRecordLocked(null, info, null); 7825 mProcessNames.put(info.processName, info.uid, app); 7826 updateLRUListLocked(app, true); 7827 } 7828 7829 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 7830 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 7831 app.persistent = true; 7832 app.maxAdj = CORE_SERVER_ADJ; 7833 } 7834 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 7835 mPersistentStartingProcesses.add(app); 7836 startProcessLocked(app, "added application", app.processName); 7837 } 7838 7839 return app; 7840 } 7841 7842 public void unhandledBack() { 7843 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 7844 "unhandledBack()"); 7845 7846 synchronized(this) { 7847 int count = mHistory.size(); 7848 if (Config.LOGD) Log.d( 7849 TAG, "Performing unhandledBack(): stack size = " + count); 7850 if (count > 1) { 7851 final long origId = Binder.clearCallingIdentity(); 7852 finishActivityLocked((HistoryRecord)mHistory.get(count-1), 7853 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 7854 Binder.restoreCallingIdentity(origId); 7855 } 7856 } 7857 } 7858 7859 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 7860 String name = uri.getAuthority(); 7861 ContentProviderHolder cph = getContentProviderExternal(name); 7862 ParcelFileDescriptor pfd = null; 7863 if (cph != null) { 7864 // We record the binder invoker's uid in thread-local storage before 7865 // going to the content provider to open the file. Later, in the code 7866 // that handles all permissions checks, we look for this uid and use 7867 // that rather than the Activity Manager's own uid. The effect is that 7868 // we do the check against the caller's permissions even though it looks 7869 // to the content provider like the Activity Manager itself is making 7870 // the request. 7871 sCallerIdentity.set(new Identity( 7872 Binder.getCallingPid(), Binder.getCallingUid())); 7873 try { 7874 pfd = cph.provider.openFile(uri, "r"); 7875 } catch (FileNotFoundException e) { 7876 // do nothing; pfd will be returned null 7877 } finally { 7878 // Ensure that whatever happens, we clean up the identity state 7879 sCallerIdentity.remove(); 7880 } 7881 7882 // We've got the fd now, so we're done with the provider. 7883 removeContentProviderExternal(name); 7884 } else { 7885 Log.d(TAG, "Failed to get provider for authority '" + name + "'"); 7886 } 7887 return pfd; 7888 } 7889 7890 public void goingToSleep() { 7891 synchronized(this) { 7892 mSleeping = true; 7893 mWindowManager.setEventDispatching(false); 7894 7895 if (mResumedActivity != null) { 7896 pauseIfSleepingLocked(); 7897 } else { 7898 Log.w(TAG, "goingToSleep with no resumed activity!"); 7899 } 7900 } 7901 } 7902 7903 public boolean shutdown(int timeout) { 7904 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 7905 != PackageManager.PERMISSION_GRANTED) { 7906 throw new SecurityException("Requires permission " 7907 + android.Manifest.permission.SHUTDOWN); 7908 } 7909 7910 boolean timedout = false; 7911 7912 synchronized(this) { 7913 mShuttingDown = true; 7914 mWindowManager.setEventDispatching(false); 7915 7916 if (mResumedActivity != null) { 7917 pauseIfSleepingLocked(); 7918 final long endTime = System.currentTimeMillis() + timeout; 7919 while (mResumedActivity != null || mPausingActivity != null) { 7920 long delay = endTime - System.currentTimeMillis(); 7921 if (delay <= 0) { 7922 Log.w(TAG, "Activity manager shutdown timed out"); 7923 timedout = true; 7924 break; 7925 } 7926 try { 7927 this.wait(); 7928 } catch (InterruptedException e) { 7929 } 7930 } 7931 } 7932 } 7933 7934 mUsageStatsService.shutdown(); 7935 mBatteryStatsService.shutdown(); 7936 7937 return timedout; 7938 } 7939 7940 void pauseIfSleepingLocked() { 7941 if (mSleeping || mShuttingDown) { 7942 if (!mGoingToSleep.isHeld()) { 7943 mGoingToSleep.acquire(); 7944 if (mLaunchingActivity.isHeld()) { 7945 mLaunchingActivity.release(); 7946 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 7947 } 7948 } 7949 7950 // If we are not currently pausing an activity, get the current 7951 // one to pause. If we are pausing one, we will just let that stuff 7952 // run and release the wake lock when all done. 7953 if (mPausingActivity == null) { 7954 if (DEBUG_PAUSE) Log.v(TAG, "Sleep needs to pause..."); 7955 if (DEBUG_USER_LEAVING) Log.v(TAG, "Sleep => pause with userLeaving=false"); 7956 startPausingLocked(false, true); 7957 } 7958 } 7959 } 7960 7961 public void wakingUp() { 7962 synchronized(this) { 7963 if (mGoingToSleep.isHeld()) { 7964 mGoingToSleep.release(); 7965 } 7966 mWindowManager.setEventDispatching(true); 7967 mSleeping = false; 7968 resumeTopActivityLocked(null); 7969 } 7970 } 7971 7972 public void stopAppSwitches() { 7973 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7974 != PackageManager.PERMISSION_GRANTED) { 7975 throw new SecurityException("Requires permission " 7976 + android.Manifest.permission.STOP_APP_SWITCHES); 7977 } 7978 7979 synchronized(this) { 7980 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 7981 + APP_SWITCH_DELAY_TIME; 7982 mDidAppSwitch = false; 7983 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7984 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 7985 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 7986 } 7987 } 7988 7989 public void resumeAppSwitches() { 7990 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 7991 != PackageManager.PERMISSION_GRANTED) { 7992 throw new SecurityException("Requires permission " 7993 + android.Manifest.permission.STOP_APP_SWITCHES); 7994 } 7995 7996 synchronized(this) { 7997 // Note that we don't execute any pending app switches... we will 7998 // let those wait until either the timeout, or the next start 7999 // activity request. 8000 mAppSwitchesAllowedTime = 0; 8001 } 8002 } 8003 8004 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8005 String name) { 8006 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8007 return true; 8008 } 8009 8010 final int perm = checkComponentPermission( 8011 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8012 callingUid, -1); 8013 if (perm == PackageManager.PERMISSION_GRANTED) { 8014 return true; 8015 } 8016 8017 Log.w(TAG, name + " request from " + callingUid + " stopped"); 8018 return false; 8019 } 8020 8021 public void setDebugApp(String packageName, boolean waitForDebugger, 8022 boolean persistent) { 8023 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8024 "setDebugApp()"); 8025 8026 // Note that this is not really thread safe if there are multiple 8027 // callers into it at the same time, but that's not a situation we 8028 // care about. 8029 if (persistent) { 8030 final ContentResolver resolver = mContext.getContentResolver(); 8031 Settings.System.putString( 8032 resolver, Settings.System.DEBUG_APP, 8033 packageName); 8034 Settings.System.putInt( 8035 resolver, Settings.System.WAIT_FOR_DEBUGGER, 8036 waitForDebugger ? 1 : 0); 8037 } 8038 8039 synchronized (this) { 8040 if (!persistent) { 8041 mOrigDebugApp = mDebugApp; 8042 mOrigWaitForDebugger = mWaitForDebugger; 8043 } 8044 mDebugApp = packageName; 8045 mWaitForDebugger = waitForDebugger; 8046 mDebugTransient = !persistent; 8047 if (packageName != null) { 8048 final long origId = Binder.clearCallingIdentity(); 8049 uninstallPackageLocked(packageName, -1, false); 8050 Binder.restoreCallingIdentity(origId); 8051 } 8052 } 8053 } 8054 8055 public void setAlwaysFinish(boolean enabled) { 8056 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8057 "setAlwaysFinish()"); 8058 8059 Settings.System.putInt( 8060 mContext.getContentResolver(), 8061 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8062 8063 synchronized (this) { 8064 mAlwaysFinishActivities = enabled; 8065 } 8066 } 8067 8068 public void setActivityController(IActivityController controller) { 8069 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8070 "setActivityController()"); 8071 synchronized (this) { 8072 mController = controller; 8073 } 8074 } 8075 8076 public void registerActivityWatcher(IActivityWatcher watcher) { 8077 mWatchers.register(watcher); 8078 } 8079 8080 public void unregisterActivityWatcher(IActivityWatcher watcher) { 8081 mWatchers.unregister(watcher); 8082 } 8083 8084 public final void enterSafeMode() { 8085 synchronized(this) { 8086 // It only makes sense to do this before the system is ready 8087 // and started launching other packages. 8088 if (!mSystemReady) { 8089 try { 8090 ActivityThread.getPackageManager().enterSafeMode(); 8091 } catch (RemoteException e) { 8092 } 8093 8094 View v = LayoutInflater.from(mContext).inflate( 8095 com.android.internal.R.layout.safe_mode, null); 8096 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8097 lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; 8098 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8099 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8100 lp.gravity = Gravity.BOTTOM | Gravity.LEFT; 8101 lp.format = v.getBackground().getOpacity(); 8102 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8103 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8104 ((WindowManager)mContext.getSystemService( 8105 Context.WINDOW_SERVICE)).addView(v, lp); 8106 } 8107 } 8108 } 8109 8110 public void noteWakeupAlarm(IIntentSender sender) { 8111 if (!(sender instanceof PendingIntentRecord)) { 8112 return; 8113 } 8114 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8115 synchronized (stats) { 8116 if (mBatteryStatsService.isOnBattery()) { 8117 mBatteryStatsService.enforceCallingPermission(); 8118 PendingIntentRecord rec = (PendingIntentRecord)sender; 8119 int MY_UID = Binder.getCallingUid(); 8120 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8121 BatteryStatsImpl.Uid.Pkg pkg = 8122 stats.getPackageStatsLocked(uid, rec.key.packageName); 8123 pkg.incWakeupsLocked(); 8124 } 8125 } 8126 } 8127 8128 public boolean killPidsForMemory(int[] pids) { 8129 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8130 throw new SecurityException("killPidsForMemory only available to the system"); 8131 } 8132 8133 // XXX Note: don't acquire main activity lock here, because the window 8134 // manager calls in with its locks held. 8135 8136 boolean killed = false; 8137 synchronized (mPidsSelfLocked) { 8138 int[] types = new int[pids.length]; 8139 int worstType = 0; 8140 for (int i=0; i<pids.length; i++) { 8141 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8142 if (proc != null) { 8143 int type = proc.setAdj; 8144 types[i] = type; 8145 if (type > worstType) { 8146 worstType = type; 8147 } 8148 } 8149 } 8150 8151 // If the worse oom_adj is somewhere in the hidden proc LRU range, 8152 // then constrain it so we will kill all hidden procs. 8153 if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) { 8154 worstType = HIDDEN_APP_MIN_ADJ; 8155 } 8156 Log.w(TAG, "Killing processes for memory at adjustment " + worstType); 8157 for (int i=0; i<pids.length; i++) { 8158 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8159 if (proc == null) { 8160 continue; 8161 } 8162 int adj = proc.setAdj; 8163 if (adj >= worstType) { 8164 Log.w(TAG, "Killing for memory: " + proc + " (adj " 8165 + adj + ")"); 8166 EventLog.writeEvent(LOG_AM_KILL_FOR_MEMORY, proc.pid, 8167 proc.processName, adj); 8168 killed = true; 8169 Process.killProcess(pids[i]); 8170 } 8171 } 8172 } 8173 return killed; 8174 } 8175 8176 public void reportPss(IApplicationThread caller, int pss) { 8177 Watchdog.PssRequestor req; 8178 String name; 8179 ProcessRecord callerApp; 8180 synchronized (this) { 8181 if (caller == null) { 8182 return; 8183 } 8184 callerApp = getRecordForAppLocked(caller); 8185 if (callerApp == null) { 8186 return; 8187 } 8188 callerApp.lastPss = pss; 8189 req = callerApp; 8190 name = callerApp.processName; 8191 } 8192 Watchdog.getInstance().reportPss(req, name, pss); 8193 if (!callerApp.persistent) { 8194 removeRequestedPss(callerApp); 8195 } 8196 } 8197 8198 public void requestPss(Runnable completeCallback) { 8199 ArrayList<ProcessRecord> procs; 8200 synchronized (this) { 8201 mRequestPssCallback = completeCallback; 8202 mRequestPssList.clear(); 8203 for (int i=mLRUProcesses.size()-1; i>=0; i--) { 8204 ProcessRecord proc = mLRUProcesses.get(i); 8205 if (!proc.persistent) { 8206 mRequestPssList.add(proc); 8207 } 8208 } 8209 procs = new ArrayList<ProcessRecord>(mRequestPssList); 8210 } 8211 8212 int oldPri = Process.getThreadPriority(Process.myTid()); 8213 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 8214 for (int i=procs.size()-1; i>=0; i--) { 8215 ProcessRecord proc = procs.get(i); 8216 proc.lastPss = 0; 8217 proc.requestPss(); 8218 } 8219 Process.setThreadPriority(oldPri); 8220 } 8221 8222 void removeRequestedPss(ProcessRecord proc) { 8223 Runnable callback = null; 8224 synchronized (this) { 8225 if (mRequestPssList.remove(proc)) { 8226 if (mRequestPssList.size() == 0) { 8227 callback = mRequestPssCallback; 8228 mRequestPssCallback = null; 8229 } 8230 } 8231 } 8232 8233 if (callback != null) { 8234 callback.run(); 8235 } 8236 } 8237 8238 public void collectPss(Watchdog.PssStats stats) { 8239 stats.mEmptyPss = 0; 8240 stats.mEmptyCount = 0; 8241 stats.mBackgroundPss = 0; 8242 stats.mBackgroundCount = 0; 8243 stats.mServicePss = 0; 8244 stats.mServiceCount = 0; 8245 stats.mVisiblePss = 0; 8246 stats.mVisibleCount = 0; 8247 stats.mForegroundPss = 0; 8248 stats.mForegroundCount = 0; 8249 stats.mNoPssCount = 0; 8250 synchronized (this) { 8251 int i; 8252 int NPD = mProcDeaths.length < stats.mProcDeaths.length 8253 ? mProcDeaths.length : stats.mProcDeaths.length; 8254 int aggr = 0; 8255 for (i=0; i<NPD; i++) { 8256 aggr += mProcDeaths[i]; 8257 stats.mProcDeaths[i] = aggr; 8258 } 8259 while (i<stats.mProcDeaths.length) { 8260 stats.mProcDeaths[i] = 0; 8261 i++; 8262 } 8263 8264 for (i=mLRUProcesses.size()-1; i>=0; i--) { 8265 ProcessRecord proc = mLRUProcesses.get(i); 8266 if (proc.persistent) { 8267 continue; 8268 } 8269 //Log.i(TAG, "Proc " + proc + ": pss=" + proc.lastPss); 8270 if (proc.lastPss == 0) { 8271 stats.mNoPssCount++; 8272 continue; 8273 } 8274 if (proc.setAdj == EMPTY_APP_ADJ) { 8275 stats.mEmptyPss += proc.lastPss; 8276 stats.mEmptyCount++; 8277 } else if (proc.setAdj == CONTENT_PROVIDER_ADJ) { 8278 stats.mEmptyPss += proc.lastPss; 8279 stats.mEmptyCount++; 8280 } else if (proc.setAdj >= HIDDEN_APP_MIN_ADJ) { 8281 stats.mBackgroundPss += proc.lastPss; 8282 stats.mBackgroundCount++; 8283 } else if (proc.setAdj >= VISIBLE_APP_ADJ) { 8284 stats.mVisiblePss += proc.lastPss; 8285 stats.mVisibleCount++; 8286 } else { 8287 stats.mForegroundPss += proc.lastPss; 8288 stats.mForegroundCount++; 8289 } 8290 } 8291 } 8292 } 8293 8294 public final void startRunning(String pkg, String cls, String action, 8295 String data) { 8296 synchronized(this) { 8297 if (mStartRunning) { 8298 return; 8299 } 8300 mStartRunning = true; 8301 mTopComponent = pkg != null && cls != null 8302 ? new ComponentName(pkg, cls) : null; 8303 mTopAction = action != null ? action : Intent.ACTION_MAIN; 8304 mTopData = data; 8305 if (!mSystemReady) { 8306 return; 8307 } 8308 } 8309 8310 systemReady(null); 8311 } 8312 8313 private void retrieveSettings() { 8314 final ContentResolver resolver = mContext.getContentResolver(); 8315 String debugApp = Settings.System.getString( 8316 resolver, Settings.System.DEBUG_APP); 8317 boolean waitForDebugger = Settings.System.getInt( 8318 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 8319 boolean alwaysFinishActivities = Settings.System.getInt( 8320 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 8321 8322 Configuration configuration = new Configuration(); 8323 Settings.System.getConfiguration(resolver, configuration); 8324 8325 synchronized (this) { 8326 mDebugApp = mOrigDebugApp = debugApp; 8327 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 8328 mAlwaysFinishActivities = alwaysFinishActivities; 8329 // This happens before any activities are started, so we can 8330 // change mConfiguration in-place. 8331 mConfiguration.updateFrom(configuration); 8332 if (DEBUG_CONFIGURATION) Log.v(TAG, "Initial config: " + mConfiguration); 8333 } 8334 } 8335 8336 public boolean testIsSystemReady() { 8337 // no need to synchronize(this) just to read & return the value 8338 return mSystemReady; 8339 } 8340 8341 public void systemReady(final Runnable goingCallback) { 8342 // In the simulator, startRunning will never have been called, which 8343 // normally sets a few crucial variables. Do it here instead. 8344 if (!Process.supportsProcesses()) { 8345 mStartRunning = true; 8346 mTopAction = Intent.ACTION_MAIN; 8347 } 8348 8349 synchronized(this) { 8350 if (mSystemReady) { 8351 if (goingCallback != null) goingCallback.run(); 8352 return; 8353 } 8354 8355 // Check to see if there are any update receivers to run. 8356 if (!mDidUpdate) { 8357 if (mWaitingUpdate) { 8358 return; 8359 } 8360 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 8361 List<ResolveInfo> ris = null; 8362 try { 8363 ris = ActivityThread.getPackageManager().queryIntentReceivers( 8364 intent, null, 0); 8365 } catch (RemoteException e) { 8366 } 8367 if (ris != null) { 8368 for (int i=ris.size()-1; i>=0; i--) { 8369 if ((ris.get(i).activityInfo.applicationInfo.flags 8370 &ApplicationInfo.FLAG_SYSTEM) == 0) { 8371 ris.remove(i); 8372 } 8373 } 8374 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 8375 for (int i=0; i<ris.size(); i++) { 8376 ActivityInfo ai = ris.get(i).activityInfo; 8377 intent.setComponent(new ComponentName(ai.packageName, ai.name)); 8378 IIntentReceiver finisher = null; 8379 if (i == 0) { 8380 finisher = new IIntentReceiver.Stub() { 8381 public void performReceive(Intent intent, int resultCode, 8382 String data, Bundle extras, boolean ordered) 8383 throws RemoteException { 8384 synchronized (ActivityManagerService.this) { 8385 mDidUpdate = true; 8386 } 8387 systemReady(goingCallback); 8388 } 8389 }; 8390 } 8391 Log.i(TAG, "Sending system update to: " + intent.getComponent()); 8392 broadcastIntentLocked(null, null, intent, null, finisher, 8393 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID); 8394 if (i == 0) { 8395 mWaitingUpdate = true; 8396 } 8397 } 8398 } 8399 if (mWaitingUpdate) { 8400 return; 8401 } 8402 mDidUpdate = true; 8403 } 8404 8405 mSystemReady = true; 8406 if (!mStartRunning) { 8407 return; 8408 } 8409 } 8410 8411 ArrayList<ProcessRecord> procsToKill = null; 8412 synchronized(mPidsSelfLocked) { 8413 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 8414 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8415 if (!isAllowedWhileBooting(proc.info)){ 8416 if (procsToKill == null) { 8417 procsToKill = new ArrayList<ProcessRecord>(); 8418 } 8419 procsToKill.add(proc); 8420 } 8421 } 8422 } 8423 8424 if (procsToKill != null) { 8425 synchronized(this) { 8426 for (int i=procsToKill.size()-1; i>=0; i--) { 8427 ProcessRecord proc = procsToKill.get(i); 8428 Log.i(TAG, "Removing system update proc: " + proc); 8429 removeProcessLocked(proc, true); 8430 } 8431 } 8432 } 8433 8434 Log.i(TAG, "System now ready"); 8435 EventLog.writeEvent(LOG_BOOT_PROGRESS_AMS_READY, 8436 SystemClock.uptimeMillis()); 8437 8438 synchronized(this) { 8439 // Make sure we have no pre-ready processes sitting around. 8440 8441 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 8442 ResolveInfo ri = mContext.getPackageManager() 8443 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 8444 STOCK_PM_FLAGS); 8445 CharSequence errorMsg = null; 8446 if (ri != null) { 8447 ActivityInfo ai = ri.activityInfo; 8448 ApplicationInfo app = ai.applicationInfo; 8449 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 8450 mTopAction = Intent.ACTION_FACTORY_TEST; 8451 mTopData = null; 8452 mTopComponent = new ComponentName(app.packageName, 8453 ai.name); 8454 } else { 8455 errorMsg = mContext.getResources().getText( 8456 com.android.internal.R.string.factorytest_not_system); 8457 } 8458 } else { 8459 errorMsg = mContext.getResources().getText( 8460 com.android.internal.R.string.factorytest_no_action); 8461 } 8462 if (errorMsg != null) { 8463 mTopAction = null; 8464 mTopData = null; 8465 mTopComponent = null; 8466 Message msg = Message.obtain(); 8467 msg.what = SHOW_FACTORY_ERROR_MSG; 8468 msg.getData().putCharSequence("msg", errorMsg); 8469 mHandler.sendMessage(msg); 8470 } 8471 } 8472 } 8473 8474 retrieveSettings(); 8475 8476 if (goingCallback != null) goingCallback.run(); 8477 8478 synchronized (this) { 8479 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 8480 try { 8481 List apps = ActivityThread.getPackageManager(). 8482 getPersistentApplications(STOCK_PM_FLAGS); 8483 if (apps != null) { 8484 int N = apps.size(); 8485 int i; 8486 for (i=0; i<N; i++) { 8487 ApplicationInfo info 8488 = (ApplicationInfo)apps.get(i); 8489 if (info != null && 8490 !info.packageName.equals("android")) { 8491 addAppLocked(info); 8492 } 8493 } 8494 } 8495 } catch (RemoteException ex) { 8496 // pm is in same process, this will never happen. 8497 } 8498 } 8499 8500 // Start up initial activity. 8501 mBooting = true; 8502 8503 try { 8504 if (ActivityThread.getPackageManager().hasSystemUidErrors()) { 8505 Message msg = Message.obtain(); 8506 msg.what = SHOW_UID_ERROR_MSG; 8507 mHandler.sendMessage(msg); 8508 } 8509 } catch (RemoteException e) { 8510 } 8511 8512 resumeTopActivityLocked(null); 8513 } 8514 } 8515 8516 boolean makeAppCrashingLocked(ProcessRecord app, 8517 String tag, String shortMsg, String longMsg, byte[] crashData) { 8518 app.crashing = true; 8519 app.crashingReport = generateProcessError(app, 8520 ActivityManager.ProcessErrorStateInfo.CRASHED, tag, shortMsg, longMsg, crashData); 8521 startAppProblemLocked(app); 8522 app.stopFreezingAllLocked(); 8523 return handleAppCrashLocked(app); 8524 } 8525 8526 private ComponentName getErrorReportReceiver(ProcessRecord app) { 8527 // check if error reporting is enabled in Gservices 8528 int enabled = Settings.Gservices.getInt(mContext.getContentResolver(), 8529 Settings.Gservices.SEND_ACTION_APP_ERROR, 0); 8530 if (enabled == 0) { 8531 return null; 8532 } 8533 8534 IPackageManager pm = ActivityThread.getPackageManager(); 8535 8536 try { 8537 // look for receiver in the installer package 8538 String candidate = pm.getInstallerPackageName(app.info.packageName); 8539 ComponentName result = getErrorReportReceiver(pm, app.info.packageName, candidate); 8540 if (result != null) { 8541 return result; 8542 } 8543 8544 // if the error app is on the system image, look for system apps 8545 // error receiver 8546 if ((app.info.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 8547 candidate = SystemProperties.get(SYSTEM_APPS_ERROR_RECEIVER_PROPERTY); 8548 result = getErrorReportReceiver(pm, app.info.packageName, candidate); 8549 if (result != null) { 8550 return result; 8551 } 8552 } 8553 8554 // if there is a default receiver, try that 8555 candidate = SystemProperties.get(DEFAULT_ERROR_RECEIVER_PROPERTY); 8556 return getErrorReportReceiver(pm, app.info.packageName, candidate); 8557 } catch (RemoteException e) { 8558 // should not happen 8559 Log.e(TAG, "error talking to PackageManager", e); 8560 return null; 8561 } 8562 } 8563 8564 /** 8565 * Return activity in receiverPackage that handles ACTION_APP_ERROR. 8566 * 8567 * @param pm PackageManager isntance 8568 * @param errorPackage package which caused the error 8569 * @param receiverPackage candidate package to receive the error 8570 * @return activity component within receiverPackage which handles 8571 * ACTION_APP_ERROR, or null if not found 8572 */ 8573 private ComponentName getErrorReportReceiver(IPackageManager pm, String errorPackage, 8574 String receiverPackage) throws RemoteException { 8575 if (receiverPackage == null || receiverPackage.length() == 0) { 8576 return null; 8577 } 8578 8579 // break the loop if it's the error report receiver package that crashed 8580 if (receiverPackage.equals(errorPackage)) { 8581 return null; 8582 } 8583 8584 Intent intent = new Intent(Intent.ACTION_APP_ERROR); 8585 intent.setPackage(receiverPackage); 8586 ResolveInfo info = pm.resolveIntent(intent, null, 0); 8587 if (info == null || info.activityInfo == null) { 8588 return null; 8589 } 8590 return new ComponentName(receiverPackage, info.activityInfo.name); 8591 } 8592 8593 void makeAppNotRespondingLocked(ProcessRecord app, 8594 String tag, String shortMsg, String longMsg, byte[] crashData) { 8595 app.notResponding = true; 8596 app.notRespondingReport = generateProcessError(app, 8597 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, tag, shortMsg, longMsg, 8598 crashData); 8599 startAppProblemLocked(app); 8600 app.stopFreezingAllLocked(); 8601 } 8602 8603 /** 8604 * Generate a process error record, suitable for attachment to a ProcessRecord. 8605 * 8606 * @param app The ProcessRecord in which the error occurred. 8607 * @param condition Crashing, Application Not Responding, etc. Values are defined in 8608 * ActivityManager.AppErrorStateInfo 8609 * @param tag The tag that was passed into handleApplicationError(). Typically the classname. 8610 * @param shortMsg Short message describing the crash. 8611 * @param longMsg Long message describing the crash. 8612 * @param crashData Raw data passed into handleApplicationError(). Typically a stack trace. 8613 * 8614 * @return Returns a fully-formed AppErrorStateInfo record. 8615 */ 8616 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 8617 int condition, String tag, String shortMsg, String longMsg, byte[] crashData) { 8618 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 8619 8620 report.condition = condition; 8621 report.processName = app.processName; 8622 report.pid = app.pid; 8623 report.uid = app.info.uid; 8624 report.tag = tag; 8625 report.shortMsg = shortMsg; 8626 report.longMsg = longMsg; 8627 report.crashData = crashData; 8628 8629 return report; 8630 } 8631 8632 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog, 8633 boolean crashed) { 8634 synchronized (this) { 8635 app.crashing = false; 8636 app.crashingReport = null; 8637 app.notResponding = false; 8638 app.notRespondingReport = null; 8639 if (app.anrDialog == fromDialog) { 8640 app.anrDialog = null; 8641 } 8642 if (app.waitDialog == fromDialog) { 8643 app.waitDialog = null; 8644 } 8645 if (app.pid > 0 && app.pid != MY_PID) { 8646 if (crashed) { 8647 handleAppCrashLocked(app); 8648 } 8649 Log.i(ActivityManagerService.TAG, "Killing process " 8650 + app.processName 8651 + " (pid=" + app.pid + ") at user's request"); 8652 Process.killProcess(app.pid); 8653 } 8654 8655 } 8656 } 8657 8658 boolean handleAppCrashLocked(ProcessRecord app) { 8659 long now = SystemClock.uptimeMillis(); 8660 8661 Long crashTime = mProcessCrashTimes.get(app.info.processName, 8662 app.info.uid); 8663 if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) { 8664 // This process loses! 8665 Log.w(TAG, "Process " + app.info.processName 8666 + " has crashed too many times: killing!"); 8667 EventLog.writeEvent(LOG_AM_PROCESS_CRASHED_TOO_MUCH, 8668 app.info.processName, app.info.uid); 8669 killServicesLocked(app, false); 8670 for (int i=mHistory.size()-1; i>=0; i--) { 8671 HistoryRecord r = (HistoryRecord)mHistory.get(i); 8672 if (r.app == app) { 8673 if (Config.LOGD) Log.d( 8674 TAG, " Force finishing activity " 8675 + r.intent.getComponent().flattenToShortString()); 8676 finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 8677 } 8678 } 8679 if (!app.persistent) { 8680 // We don't want to start this process again until the user 8681 // explicitly does so... but for persistent process, we really 8682 // need to keep it running. If a persistent process is actually 8683 // repeatedly crashing, then badness for everyone. 8684 EventLog.writeEvent(LOG_AM_PROCESS_BAD, app.info.uid, 8685 app.info.processName); 8686 mBadProcesses.put(app.info.processName, app.info.uid, now); 8687 app.bad = true; 8688 mProcessCrashTimes.remove(app.info.processName, app.info.uid); 8689 app.removed = true; 8690 removeProcessLocked(app, false); 8691 return false; 8692 } 8693 } 8694 8695 // Bump up the crash count of any services currently running in the proc. 8696 if (app.services.size() != 0) { 8697 // Any services running in the application need to be placed 8698 // back in the pending list. 8699 Iterator it = app.services.iterator(); 8700 while (it.hasNext()) { 8701 ServiceRecord sr = (ServiceRecord)it.next(); 8702 sr.crashCount++; 8703 } 8704 } 8705 8706 mProcessCrashTimes.put(app.info.processName, app.info.uid, now); 8707 return true; 8708 } 8709 8710 void startAppProblemLocked(ProcessRecord app) { 8711 app.errorReportReceiver = getErrorReportReceiver(app); 8712 skipCurrentReceiverLocked(app); 8713 } 8714 8715 void skipCurrentReceiverLocked(ProcessRecord app) { 8716 boolean reschedule = false; 8717 BroadcastRecord r = app.curReceiver; 8718 if (r != null) { 8719 // The current broadcast is waiting for this app's receiver 8720 // to be finished. Looks like that's not going to happen, so 8721 // let the broadcast continue. 8722 logBroadcastReceiverDiscard(r); 8723 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 8724 r.resultExtras, r.resultAbort, true); 8725 reschedule = true; 8726 } 8727 r = mPendingBroadcast; 8728 if (r != null && r.curApp == app) { 8729 if (DEBUG_BROADCAST) Log.v(TAG, 8730 "skip & discard pending app " + r); 8731 logBroadcastReceiverDiscard(r); 8732 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 8733 r.resultExtras, r.resultAbort, true); 8734 reschedule = true; 8735 } 8736 if (reschedule) { 8737 scheduleBroadcastsLocked(); 8738 } 8739 } 8740 8741 public int handleApplicationError(IBinder app, int flags, 8742 String tag, String shortMsg, String longMsg, byte[] crashData) { 8743 AppErrorResult result = new AppErrorResult(); 8744 ProcessRecord r = null; 8745 synchronized (this) { 8746 if (app != null) { 8747 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8748 final int NA = apps.size(); 8749 for (int ia=0; ia<NA; ia++) { 8750 ProcessRecord p = apps.valueAt(ia); 8751 if (p.thread != null && p.thread.asBinder() == app) { 8752 r = p; 8753 break; 8754 } 8755 } 8756 } 8757 } 8758 8759 if (r != null) { 8760 // The application has crashed. Send the SIGQUIT to the process so 8761 // that it can dump its state. 8762 Process.sendSignal(r.pid, Process.SIGNAL_QUIT); 8763 //Log.i(TAG, "Current system threads:"); 8764 //Process.sendSignal(MY_PID, Process.SIGNAL_QUIT); 8765 } 8766 8767 if (mController != null) { 8768 try { 8769 String name = r != null ? r.processName : null; 8770 int pid = r != null ? r.pid : Binder.getCallingPid(); 8771 if (!mController.appCrashed(name, pid, 8772 shortMsg, longMsg, crashData)) { 8773 Log.w(TAG, "Force-killing crashed app " + name 8774 + " at watcher's request"); 8775 Process.killProcess(pid); 8776 return 0; 8777 } 8778 } catch (RemoteException e) { 8779 mController = null; 8780 } 8781 } 8782 8783 final long origId = Binder.clearCallingIdentity(); 8784 8785 // If this process is running instrumentation, finish it. 8786 if (r != null && r.instrumentationClass != null) { 8787 Log.w(TAG, "Error in app " + r.processName 8788 + " running instrumentation " + r.instrumentationClass + ":"); 8789 if (shortMsg != null) Log.w(TAG, " " + shortMsg); 8790 if (longMsg != null) Log.w(TAG, " " + longMsg); 8791 Bundle info = new Bundle(); 8792 info.putString("shortMsg", shortMsg); 8793 info.putString("longMsg", longMsg); 8794 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8795 Binder.restoreCallingIdentity(origId); 8796 return 0; 8797 } 8798 8799 if (r != null) { 8800 if (!makeAppCrashingLocked(r, tag, shortMsg, longMsg, crashData)) { 8801 return 0; 8802 } 8803 } else { 8804 Log.w(TAG, "Some application object " + app + " tag " + tag 8805 + " has crashed, but I don't know who it is."); 8806 Log.w(TAG, "ShortMsg:" + shortMsg); 8807 Log.w(TAG, "LongMsg:" + longMsg); 8808 Binder.restoreCallingIdentity(origId); 8809 return 0; 8810 } 8811 8812 Message msg = Message.obtain(); 8813 msg.what = SHOW_ERROR_MSG; 8814 HashMap data = new HashMap(); 8815 data.put("result", result); 8816 data.put("app", r); 8817 data.put("flags", flags); 8818 data.put("shortMsg", shortMsg); 8819 data.put("longMsg", longMsg); 8820 if (r != null && (r.info.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 8821 // For system processes, submit crash data to the server. 8822 data.put("crashData", crashData); 8823 } 8824 msg.obj = data; 8825 mHandler.sendMessage(msg); 8826 8827 Binder.restoreCallingIdentity(origId); 8828 } 8829 8830 int res = result.get(); 8831 8832 Intent appErrorIntent = null; 8833 synchronized (this) { 8834 if (r != null) { 8835 mProcessCrashTimes.put(r.info.processName, r.info.uid, 8836 SystemClock.uptimeMillis()); 8837 } 8838 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8839 appErrorIntent = createAppErrorIntentLocked(r); 8840 res = AppErrorDialog.FORCE_QUIT; 8841 } 8842 } 8843 8844 if (appErrorIntent != null) { 8845 try { 8846 mContext.startActivity(appErrorIntent); 8847 } catch (ActivityNotFoundException e) { 8848 Log.w(TAG, "bug report receiver dissappeared", e); 8849 } 8850 } 8851 8852 return res; 8853 } 8854 8855 Intent createAppErrorIntentLocked(ProcessRecord r) { 8856 ApplicationErrorReport report = createAppErrorReportLocked(r); 8857 if (report == null) { 8858 return null; 8859 } 8860 Intent result = new Intent(Intent.ACTION_APP_ERROR); 8861 result.setComponent(r.errorReportReceiver); 8862 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 8863 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8864 return result; 8865 } 8866 8867 ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r) { 8868 if (r.errorReportReceiver == null) { 8869 return null; 8870 } 8871 8872 if (!r.crashing && !r.notResponding) { 8873 return null; 8874 } 8875 8876 try { 8877 ApplicationErrorReport report = new ApplicationErrorReport(); 8878 report.packageName = r.info.packageName; 8879 report.installerPackageName = r.errorReportReceiver.getPackageName(); 8880 report.processName = r.processName; 8881 8882 if (r.crashing) { 8883 report.type = ApplicationErrorReport.TYPE_CRASH; 8884 report.crashInfo = new ApplicationErrorReport.CrashInfo(); 8885 8886 ByteArrayInputStream byteStream = new ByteArrayInputStream( 8887 r.crashingReport.crashData); 8888 DataInputStream dataStream = new DataInputStream(byteStream); 8889 CrashData crashData = new CrashData(dataStream); 8890 ThrowableData throwData = crashData.getThrowableData(); 8891 8892 report.time = crashData.getTime(); 8893 report.crashInfo.stackTrace = throwData.toString(); 8894 8895 // Extract the source of the exception, useful for report 8896 // clustering. Also extract the "deepest" non-null exception 8897 // message. 8898 String exceptionMessage = throwData.getMessage(); 8899 while (throwData.getCause() != null) { 8900 throwData = throwData.getCause(); 8901 String msg = throwData.getMessage(); 8902 if (msg != null && msg.length() > 0) { 8903 exceptionMessage = msg; 8904 } 8905 } 8906 StackTraceElementData trace = throwData.getStackTrace()[0]; 8907 report.crashInfo.exceptionMessage = exceptionMessage; 8908 report.crashInfo.exceptionClassName = throwData.getType(); 8909 report.crashInfo.throwFileName = trace.getFileName(); 8910 report.crashInfo.throwClassName = trace.getClassName(); 8911 report.crashInfo.throwMethodName = trace.getMethodName(); 8912 report.crashInfo.throwLineNumber = trace.getLineNumber(); 8913 } else if (r.notResponding) { 8914 report.type = ApplicationErrorReport.TYPE_ANR; 8915 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 8916 8917 report.anrInfo.activity = r.notRespondingReport.tag; 8918 report.anrInfo.cause = r.notRespondingReport.shortMsg; 8919 report.anrInfo.info = r.notRespondingReport.longMsg; 8920 } 8921 8922 return report; 8923 } catch (IOException e) { 8924 // we don't send it 8925 } 8926 8927 return null; 8928 } 8929 8930 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 8931 // assume our apps are happy - lazy create the list 8932 List<ActivityManager.ProcessErrorStateInfo> errList = null; 8933 8934 synchronized (this) { 8935 8936 // iterate across all processes 8937 final int N = mLRUProcesses.size(); 8938 for (int i = 0; i < N; i++) { 8939 ProcessRecord app = mLRUProcesses.get(i); 8940 if ((app.thread != null) && (app.crashing || app.notResponding)) { 8941 // This one's in trouble, so we'll generate a report for it 8942 // crashes are higher priority (in case there's a crash *and* an anr) 8943 ActivityManager.ProcessErrorStateInfo report = null; 8944 if (app.crashing) { 8945 report = app.crashingReport; 8946 } else if (app.notResponding) { 8947 report = app.notRespondingReport; 8948 } 8949 8950 if (report != null) { 8951 if (errList == null) { 8952 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 8953 } 8954 errList.add(report); 8955 } else { 8956 Log.w(TAG, "Missing app error report, app = " + app.processName + 8957 " crashing = " + app.crashing + 8958 " notResponding = " + app.notResponding); 8959 } 8960 } 8961 } 8962 } 8963 8964 return errList; 8965 } 8966 8967 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 8968 // Lazy instantiation of list 8969 List<ActivityManager.RunningAppProcessInfo> runList = null; 8970 synchronized (this) { 8971 // Iterate across all processes 8972 final int N = mLRUProcesses.size(); 8973 for (int i = 0; i < N; i++) { 8974 ProcessRecord app = mLRUProcesses.get(i); 8975 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 8976 // Generate process state info for running application 8977 ActivityManager.RunningAppProcessInfo currApp = 8978 new ActivityManager.RunningAppProcessInfo(app.processName, 8979 app.pid, app.getPackageList()); 8980 currApp.uid = app.info.uid; 8981 int adj = app.curAdj; 8982 if (adj >= CONTENT_PROVIDER_ADJ) { 8983 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY; 8984 } else if (adj >= HIDDEN_APP_MIN_ADJ) { 8985 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8986 currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1; 8987 } else if (adj >= HOME_APP_ADJ) { 8988 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 8989 currApp.lru = 0; 8990 } else if (adj >= SECONDARY_SERVER_ADJ) { 8991 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 8992 } else if (adj >= VISIBLE_APP_ADJ) { 8993 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 8994 } else { 8995 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 8996 } 8997 currApp.importanceReasonCode = app.adjTypeCode; 8998 if (app.adjSource instanceof ProcessRecord) { 8999 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 9000 } else if (app.adjSource instanceof HistoryRecord) { 9001 HistoryRecord r = (HistoryRecord)app.adjSource; 9002 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 9003 } 9004 if (app.adjTarget instanceof ComponentName) { 9005 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 9006 } 9007 //Log.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 9008 // + " lru=" + currApp.lru); 9009 if (runList == null) { 9010 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 9011 } 9012 runList.add(currApp); 9013 } 9014 } 9015 } 9016 return runList; 9017 } 9018 9019 @Override 9020 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 9021 synchronized (this) { 9022 if (checkCallingPermission(android.Manifest.permission.DUMP) 9023 != PackageManager.PERMISSION_GRANTED) { 9024 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 9025 + Binder.getCallingPid() 9026 + ", uid=" + Binder.getCallingUid() 9027 + " without permission " 9028 + android.Manifest.permission.DUMP); 9029 return; 9030 } 9031 if (args.length != 0 && "service".equals(args[0])) { 9032 dumpService(fd, pw, args); 9033 return; 9034 } 9035 pw.println("Activities in Current Activity Manager State:"); 9036 dumpHistoryList(pw, mHistory, " ", "Hist", true); 9037 pw.println(" "); 9038 pw.println(" Running activities (most recent first):"); 9039 dumpHistoryList(pw, mLRUActivities, " ", "Run", false); 9040 if (mWaitingVisibleActivities.size() > 0) { 9041 pw.println(" "); 9042 pw.println(" Activities waiting for another to become visible:"); 9043 dumpHistoryList(pw, mWaitingVisibleActivities, " ", "Wait", false); 9044 } 9045 if (mStoppingActivities.size() > 0) { 9046 pw.println(" "); 9047 pw.println(" Activities waiting to stop:"); 9048 dumpHistoryList(pw, mStoppingActivities, " ", "Stop", false); 9049 } 9050 if (mFinishingActivities.size() > 0) { 9051 pw.println(" "); 9052 pw.println(" Activities waiting to finish:"); 9053 dumpHistoryList(pw, mFinishingActivities, " ", "Fin", false); 9054 } 9055 9056 pw.println(" "); 9057 pw.println(" mPausingActivity: " + mPausingActivity); 9058 pw.println(" mResumedActivity: " + mResumedActivity); 9059 pw.println(" mFocusedActivity: " + mFocusedActivity); 9060 pw.println(" mLastPausedActivity: " + mLastPausedActivity); 9061 9062 if (mRecentTasks.size() > 0) { 9063 pw.println(" "); 9064 pw.println("Recent tasks in Current Activity Manager State:"); 9065 9066 final int N = mRecentTasks.size(); 9067 for (int i=0; i<N; i++) { 9068 TaskRecord tr = mRecentTasks.get(i); 9069 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 9070 pw.println(tr); 9071 mRecentTasks.get(i).dump(pw, " "); 9072 } 9073 } 9074 9075 pw.println(" "); 9076 pw.println(" mCurTask: " + mCurTask); 9077 9078 pw.println(" "); 9079 pw.println("Processes in Current Activity Manager State:"); 9080 9081 boolean needSep = false; 9082 int numPers = 0; 9083 9084 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 9085 final int NA = procs.size(); 9086 for (int ia=0; ia<NA; ia++) { 9087 if (!needSep) { 9088 pw.println(" All known processes:"); 9089 needSep = true; 9090 } 9091 ProcessRecord r = procs.valueAt(ia); 9092 pw.print(r.persistent ? " *PERS*" : " *APP*"); 9093 pw.print(" UID "); pw.print(procs.keyAt(ia)); 9094 pw.print(" "); pw.println(r); 9095 r.dump(pw, " "); 9096 if (r.persistent) { 9097 numPers++; 9098 } 9099 } 9100 } 9101 9102 if (mLRUProcesses.size() > 0) { 9103 if (needSep) pw.println(" "); 9104 needSep = true; 9105 pw.println(" Running processes (most recent first):"); 9106 dumpProcessList(pw, mLRUProcesses, " ", 9107 "App ", "PERS", true); 9108 needSep = true; 9109 } 9110 9111 synchronized (mPidsSelfLocked) { 9112 if (mPidsSelfLocked.size() > 0) { 9113 if (needSep) pw.println(" "); 9114 needSep = true; 9115 pw.println(" PID mappings:"); 9116 for (int i=0; i<mPidsSelfLocked.size(); i++) { 9117 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 9118 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 9119 } 9120 } 9121 } 9122 9123 if (mForegroundProcesses.size() > 0) { 9124 if (needSep) pw.println(" "); 9125 needSep = true; 9126 pw.println(" Foreground Processes:"); 9127 for (int i=0; i<mForegroundProcesses.size(); i++) { 9128 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 9129 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 9130 } 9131 } 9132 9133 if (mPersistentStartingProcesses.size() > 0) { 9134 if (needSep) pw.println(" "); 9135 needSep = true; 9136 pw.println(" Persisent processes that are starting:"); 9137 dumpProcessList(pw, mPersistentStartingProcesses, " ", 9138 "Starting Norm", "Restarting PERS", false); 9139 } 9140 9141 if (mStartingProcesses.size() > 0) { 9142 if (needSep) pw.println(" "); 9143 needSep = true; 9144 pw.println(" Processes that are starting:"); 9145 dumpProcessList(pw, mStartingProcesses, " ", 9146 "Starting Norm", "Starting PERS", false); 9147 } 9148 9149 if (mRemovedProcesses.size() > 0) { 9150 if (needSep) pw.println(" "); 9151 needSep = true; 9152 pw.println(" Processes that are being removed:"); 9153 dumpProcessList(pw, mRemovedProcesses, " ", 9154 "Removed Norm", "Removed PERS", false); 9155 } 9156 9157 if (mProcessesOnHold.size() > 0) { 9158 if (needSep) pw.println(" "); 9159 needSep = true; 9160 pw.println(" Processes that are on old until the system is ready:"); 9161 dumpProcessList(pw, mProcessesOnHold, " ", 9162 "OnHold Norm", "OnHold PERS", false); 9163 } 9164 9165 if (mProcessesToGc.size() > 0) { 9166 if (needSep) pw.println(" "); 9167 needSep = true; 9168 pw.println(" Processes that are waiting to GC:"); 9169 long now = SystemClock.uptimeMillis(); 9170 for (int i=0; i<mProcessesToGc.size(); i++) { 9171 ProcessRecord proc = mProcessesToGc.get(i); 9172 pw.print(" Process "); pw.println(proc); 9173 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9174 pw.print(", last gced="); 9175 pw.print(now-proc.lastRequestedGc); 9176 pw.print(" ms ago, last lowMwm="); 9177 pw.print(now-proc.lastLowMemory); 9178 pw.println(" ms ago"); 9179 9180 } 9181 } 9182 9183 if (mProcessCrashTimes.getMap().size() > 0) { 9184 if (needSep) pw.println(" "); 9185 needSep = true; 9186 pw.println(" Time since processes crashed:"); 9187 long now = SystemClock.uptimeMillis(); 9188 for (Map.Entry<String, SparseArray<Long>> procs 9189 : mProcessCrashTimes.getMap().entrySet()) { 9190 SparseArray<Long> uids = procs.getValue(); 9191 final int N = uids.size(); 9192 for (int i=0; i<N; i++) { 9193 pw.print(" Process "); pw.print(procs.getKey()); 9194 pw.print(" uid "); pw.print(uids.keyAt(i)); 9195 pw.print(": last crashed "); 9196 pw.print((now-uids.valueAt(i))); 9197 pw.println(" ms ago"); 9198 } 9199 } 9200 } 9201 9202 if (mBadProcesses.getMap().size() > 0) { 9203 if (needSep) pw.println(" "); 9204 needSep = true; 9205 pw.println(" Bad processes:"); 9206 for (Map.Entry<String, SparseArray<Long>> procs 9207 : mBadProcesses.getMap().entrySet()) { 9208 SparseArray<Long> uids = procs.getValue(); 9209 final int N = uids.size(); 9210 for (int i=0; i<N; i++) { 9211 pw.print(" Bad process "); pw.print(procs.getKey()); 9212 pw.print(" uid "); pw.print(uids.keyAt(i)); 9213 pw.print(": crashed at time "); 9214 pw.println(uids.valueAt(i)); 9215 } 9216 } 9217 } 9218 9219 pw.println(" "); 9220 pw.println(" Total persistent processes: " + numPers); 9221 pw.println(" mHomeProcess: " + mHomeProcess); 9222 pw.println(" mConfiguration: " + mConfiguration); 9223 pw.println(" mStartRunning=" + mStartRunning 9224 + " mSystemReady=" + mSystemReady 9225 + " mBooting=" + mBooting 9226 + " mBooted=" + mBooted 9227 + " mFactoryTest=" + mFactoryTest); 9228 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown); 9229 pw.println(" mGoingToSleep=" + mGoingToSleep); 9230 pw.println(" mLaunchingActivity=" + mLaunchingActivity); 9231 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9232 + " mDebugTransient=" + mDebugTransient 9233 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9234 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9235 + " mController=" + mController); 9236 } 9237 } 9238 9239 /** 9240 * There are three ways to call this: 9241 * - no service specified: dump all the services 9242 * - a flattened component name that matched an existing service was specified as the 9243 * first arg: dump that one service 9244 * - the first arg isn't the flattened component name of an existing service: 9245 * dump all services whose component contains the first arg as a substring 9246 */ 9247 protected void dumpService(FileDescriptor fd, PrintWriter pw, String[] args) { 9248 String[] newArgs; 9249 String componentNameString; 9250 ServiceRecord r; 9251 if (args.length == 1) { 9252 componentNameString = null; 9253 newArgs = EMPTY_STRING_ARRAY; 9254 r = null; 9255 } else { 9256 componentNameString = args[1]; 9257 ComponentName componentName = ComponentName.unflattenFromString(componentNameString); 9258 r = componentName != null ? mServices.get(componentName) : null; 9259 newArgs = new String[args.length - 2]; 9260 if (args.length > 2) System.arraycopy(args, 2, newArgs, 0, args.length - 2); 9261 } 9262 9263 if (r != null) { 9264 dumpService(fd, pw, r, newArgs); 9265 } else { 9266 for (ServiceRecord r1 : mServices.values()) { 9267 if (componentNameString == null 9268 || r1.name.flattenToString().contains(componentNameString)) { 9269 dumpService(fd, pw, r1, newArgs); 9270 } 9271 } 9272 } 9273 } 9274 9275 /** 9276 * Invokes IApplicationThread.dumpService() on the thread of the specified service if 9277 * there is a thread associated with the service. 9278 */ 9279 private void dumpService(FileDescriptor fd, PrintWriter pw, ServiceRecord r, String[] args) { 9280 pw.println(" Service " + r.name.flattenToString()); 9281 if (r.app != null && r.app.thread != null) { 9282 try { 9283 // flush anything that is already in the PrintWriter since the thread is going 9284 // to write to the file descriptor directly 9285 pw.flush(); 9286 r.app.thread.dumpService(fd, r, args); 9287 pw.print("\n"); 9288 } catch (RemoteException e) { 9289 pw.println("got a RemoteException while dumping the service"); 9290 } 9291 } 9292 } 9293 9294 void dumpBroadcasts(PrintWriter pw) { 9295 synchronized (this) { 9296 if (checkCallingPermission(android.Manifest.permission.DUMP) 9297 != PackageManager.PERMISSION_GRANTED) { 9298 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 9299 + Binder.getCallingPid() 9300 + ", uid=" + Binder.getCallingUid() 9301 + " without permission " 9302 + android.Manifest.permission.DUMP); 9303 return; 9304 } 9305 pw.println("Broadcasts in Current Activity Manager State:"); 9306 9307 if (mRegisteredReceivers.size() > 0) { 9308 pw.println(" "); 9309 pw.println(" Registered Receivers:"); 9310 Iterator it = mRegisteredReceivers.values().iterator(); 9311 while (it.hasNext()) { 9312 ReceiverList r = (ReceiverList)it.next(); 9313 pw.print(" * "); pw.println(r); 9314 r.dump(pw, " "); 9315 } 9316 } 9317 9318 pw.println(" "); 9319 pw.println("Receiver Resolver Table:"); 9320 mReceiverResolver.dump(pw, " "); 9321 9322 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0 9323 || mPendingBroadcast != null) { 9324 if (mParallelBroadcasts.size() > 0) { 9325 pw.println(" "); 9326 pw.println(" Active broadcasts:"); 9327 } 9328 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) { 9329 pw.println(" Broadcast #" + i + ":"); 9330 mParallelBroadcasts.get(i).dump(pw, " "); 9331 } 9332 if (mOrderedBroadcasts.size() > 0) { 9333 pw.println(" "); 9334 pw.println(" Active serialized broadcasts:"); 9335 } 9336 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) { 9337 pw.println(" Serialized Broadcast #" + i + ":"); 9338 mOrderedBroadcasts.get(i).dump(pw, " "); 9339 } 9340 pw.println(" "); 9341 pw.println(" Pending broadcast:"); 9342 if (mPendingBroadcast != null) { 9343 mPendingBroadcast.dump(pw, " "); 9344 } else { 9345 pw.println(" (null)"); 9346 } 9347 } 9348 9349 pw.println(" "); 9350 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled); 9351 if (mStickyBroadcasts != null) { 9352 pw.println(" "); 9353 pw.println(" Sticky broadcasts:"); 9354 StringBuilder sb = new StringBuilder(128); 9355 for (Map.Entry<String, ArrayList<Intent>> ent 9356 : mStickyBroadcasts.entrySet()) { 9357 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9358 pw.println(":"); 9359 ArrayList<Intent> intents = ent.getValue(); 9360 final int N = intents.size(); 9361 for (int i=0; i<N; i++) { 9362 sb.setLength(0); 9363 sb.append(" Intent: "); 9364 intents.get(i).toShortString(sb, true, false); 9365 pw.println(sb.toString()); 9366 Bundle bundle = intents.get(i).getExtras(); 9367 if (bundle != null) { 9368 pw.print(" "); 9369 pw.println(bundle.toString()); 9370 } 9371 } 9372 } 9373 } 9374 9375 pw.println(" "); 9376 pw.println(" mHandler:"); 9377 mHandler.dump(new PrintWriterPrinter(pw), " "); 9378 } 9379 } 9380 9381 void dumpServices(PrintWriter pw) { 9382 synchronized (this) { 9383 if (checkCallingPermission(android.Manifest.permission.DUMP) 9384 != PackageManager.PERMISSION_GRANTED) { 9385 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 9386 + Binder.getCallingPid() 9387 + ", uid=" + Binder.getCallingUid() 9388 + " without permission " 9389 + android.Manifest.permission.DUMP); 9390 return; 9391 } 9392 pw.println("Services in Current Activity Manager State:"); 9393 9394 boolean needSep = false; 9395 9396 if (mServices.size() > 0) { 9397 pw.println(" Active services:"); 9398 Iterator<ServiceRecord> it = mServices.values().iterator(); 9399 while (it.hasNext()) { 9400 ServiceRecord r = it.next(); 9401 pw.print(" * "); pw.println(r); 9402 r.dump(pw, " "); 9403 } 9404 needSep = true; 9405 } 9406 9407 if (mPendingServices.size() > 0) { 9408 if (needSep) pw.println(" "); 9409 pw.println(" Pending services:"); 9410 for (int i=0; i<mPendingServices.size(); i++) { 9411 ServiceRecord r = mPendingServices.get(i); 9412 pw.print(" * Pending "); pw.println(r); 9413 r.dump(pw, " "); 9414 } 9415 needSep = true; 9416 } 9417 9418 if (mRestartingServices.size() > 0) { 9419 if (needSep) pw.println(" "); 9420 pw.println(" Restarting services:"); 9421 for (int i=0; i<mRestartingServices.size(); i++) { 9422 ServiceRecord r = mRestartingServices.get(i); 9423 pw.print(" * Restarting "); pw.println(r); 9424 r.dump(pw, " "); 9425 } 9426 needSep = true; 9427 } 9428 9429 if (mStoppingServices.size() > 0) { 9430 if (needSep) pw.println(" "); 9431 pw.println(" Stopping services:"); 9432 for (int i=0; i<mStoppingServices.size(); i++) { 9433 ServiceRecord r = mStoppingServices.get(i); 9434 pw.print(" * Stopping "); pw.println(r); 9435 r.dump(pw, " "); 9436 } 9437 needSep = true; 9438 } 9439 9440 if (mServiceConnections.size() > 0) { 9441 if (needSep) pw.println(" "); 9442 pw.println(" Connection bindings to services:"); 9443 Iterator<ConnectionRecord> it 9444 = mServiceConnections.values().iterator(); 9445 while (it.hasNext()) { 9446 ConnectionRecord r = it.next(); 9447 pw.print(" * "); pw.println(r); 9448 r.dump(pw, " "); 9449 } 9450 } 9451 } 9452 } 9453 9454 void dumpProviders(PrintWriter pw) { 9455 synchronized (this) { 9456 if (checkCallingPermission(android.Manifest.permission.DUMP) 9457 != PackageManager.PERMISSION_GRANTED) { 9458 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 9459 + Binder.getCallingPid() 9460 + ", uid=" + Binder.getCallingUid() 9461 + " without permission " 9462 + android.Manifest.permission.DUMP); 9463 return; 9464 } 9465 9466 pw.println("Content Providers in Current Activity Manager State:"); 9467 9468 boolean needSep = false; 9469 9470 if (mProvidersByClass.size() > 0) { 9471 if (needSep) pw.println(" "); 9472 pw.println(" Published content providers (by class):"); 9473 Iterator it = mProvidersByClass.entrySet().iterator(); 9474 while (it.hasNext()) { 9475 Map.Entry e = (Map.Entry)it.next(); 9476 ContentProviderRecord r = (ContentProviderRecord)e.getValue(); 9477 pw.print(" * "); pw.println(r); 9478 r.dump(pw, " "); 9479 } 9480 needSep = true; 9481 } 9482 9483 if (mProvidersByName.size() > 0) { 9484 pw.println(" "); 9485 pw.println(" Authority to provider mappings:"); 9486 Iterator it = mProvidersByName.entrySet().iterator(); 9487 while (it.hasNext()) { 9488 Map.Entry e = (Map.Entry)it.next(); 9489 ContentProviderRecord r = (ContentProviderRecord)e.getValue(); 9490 pw.print(" "); pw.print(e.getKey()); pw.print(": "); 9491 pw.println(r); 9492 } 9493 needSep = true; 9494 } 9495 9496 if (mLaunchingProviders.size() > 0) { 9497 if (needSep) pw.println(" "); 9498 pw.println(" Launching content providers:"); 9499 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9500 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9501 pw.println(mLaunchingProviders.get(i)); 9502 } 9503 needSep = true; 9504 } 9505 9506 if (mGrantedUriPermissions.size() > 0) { 9507 pw.println(); 9508 pw.println("Granted Uri Permissions:"); 9509 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9510 int uid = mGrantedUriPermissions.keyAt(i); 9511 HashMap<Uri, UriPermission> perms 9512 = mGrantedUriPermissions.valueAt(i); 9513 pw.print(" * UID "); pw.print(uid); 9514 pw.println(" holds:"); 9515 for (UriPermission perm : perms.values()) { 9516 pw.print(" "); pw.println(perm); 9517 perm.dump(pw, " "); 9518 } 9519 } 9520 } 9521 } 9522 } 9523 9524 void dumpSenders(PrintWriter pw) { 9525 synchronized (this) { 9526 if (checkCallingPermission(android.Manifest.permission.DUMP) 9527 != PackageManager.PERMISSION_GRANTED) { 9528 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 9529 + Binder.getCallingPid() 9530 + ", uid=" + Binder.getCallingUid() 9531 + " without permission " 9532 + android.Manifest.permission.DUMP); 9533 return; 9534 } 9535 9536 pw.println("Pending Intents in Current Activity Manager State:"); 9537 9538 if (this.mIntentSenderRecords.size() > 0) { 9539 Iterator<WeakReference<PendingIntentRecord>> it 9540 = mIntentSenderRecords.values().iterator(); 9541 while (it.hasNext()) { 9542 WeakReference<PendingIntentRecord> ref = it.next(); 9543 PendingIntentRecord rec = ref != null ? ref.get(): null; 9544 if (rec != null) { 9545 pw.print(" * "); pw.println(rec); 9546 rec.dump(pw, " "); 9547 } else { 9548 pw.print(" * "); pw.print(ref); 9549 } 9550 } 9551 } 9552 } 9553 } 9554 9555 private static final void dumpHistoryList(PrintWriter pw, List list, 9556 String prefix, String label, boolean complete) { 9557 TaskRecord lastTask = null; 9558 for (int i=list.size()-1; i>=0; i--) { 9559 HistoryRecord r = (HistoryRecord)list.get(i); 9560 final boolean full = complete || !r.inHistory; 9561 if (lastTask != r.task) { 9562 lastTask = r.task; 9563 pw.print(prefix); 9564 pw.print(full ? "* " : " "); 9565 pw.println(lastTask); 9566 if (full) { 9567 lastTask.dump(pw, prefix + " "); 9568 } 9569 } 9570 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9571 pw.print(" #"); pw.print(i); pw.print(": "); 9572 pw.println(r); 9573 if (full) { 9574 r.dump(pw, prefix + " "); 9575 } 9576 } 9577 } 9578 9579 private static final int dumpProcessList(PrintWriter pw, List list, 9580 String prefix, String normalLabel, String persistentLabel, 9581 boolean inclOomAdj) { 9582 int numPers = 0; 9583 for (int i=list.size()-1; i>=0; i--) { 9584 ProcessRecord r = (ProcessRecord)list.get(i); 9585 if (false) { 9586 pw.println(prefix + (r.persistent ? persistentLabel : normalLabel) 9587 + " #" + i + ":"); 9588 r.dump(pw, prefix + " "); 9589 } else if (inclOomAdj) { 9590 pw.println(String.format("%s%s #%2d: adj=%4d/%d %s (%s)", 9591 prefix, (r.persistent ? persistentLabel : normalLabel), 9592 i, r.setAdj, r.setSchedGroup, r.toString(), r.adjType)); 9593 if (r.adjSource != null || r.adjTarget != null) { 9594 pw.println(prefix + " " + r.adjTarget 9595 + " used by " + r.adjSource); 9596 } 9597 } else { 9598 pw.println(String.format("%s%s #%2d: %s", 9599 prefix, (r.persistent ? persistentLabel : normalLabel), 9600 i, r.toString())); 9601 } 9602 if (r.persistent) { 9603 numPers++; 9604 } 9605 } 9606 return numPers; 9607 } 9608 9609 private static final void dumpApplicationMemoryUsage(FileDescriptor fd, 9610 PrintWriter pw, List list, String prefix, String[] args) { 9611 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 9612 long uptime = SystemClock.uptimeMillis(); 9613 long realtime = SystemClock.elapsedRealtime(); 9614 9615 if (isCheckinRequest) { 9616 // short checkin version 9617 pw.println(uptime + "," + realtime); 9618 pw.flush(); 9619 } else { 9620 pw.println("Applications Memory Usage (kB):"); 9621 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9622 } 9623 for (int i = list.size() - 1 ; i >= 0 ; i--) { 9624 ProcessRecord r = (ProcessRecord)list.get(i); 9625 if (r.thread != null) { 9626 if (!isCheckinRequest) { 9627 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 9628 pw.flush(); 9629 } 9630 try { 9631 r.thread.asBinder().dump(fd, args); 9632 } catch (RemoteException e) { 9633 if (!isCheckinRequest) { 9634 pw.println("Got RemoteException!"); 9635 pw.flush(); 9636 } 9637 } 9638 } 9639 } 9640 } 9641 9642 /** 9643 * Searches array of arguments for the specified string 9644 * @param args array of argument strings 9645 * @param value value to search for 9646 * @return true if the value is contained in the array 9647 */ 9648 private static boolean scanArgs(String[] args, String value) { 9649 if (args != null) { 9650 for (String arg : args) { 9651 if (value.equals(arg)) { 9652 return true; 9653 } 9654 } 9655 } 9656 return false; 9657 } 9658 9659 private final int indexOfTokenLocked(IBinder token) { 9660 int count = mHistory.size(); 9661 9662 // convert the token to an entry in the history. 9663 HistoryRecord r = null; 9664 int index = -1; 9665 for (int i=count-1; i>=0; i--) { 9666 Object o = mHistory.get(i); 9667 if (o == token) { 9668 r = (HistoryRecord)o; 9669 index = i; 9670 break; 9671 } 9672 } 9673 9674 return index; 9675 } 9676 9677 private final void killServicesLocked(ProcessRecord app, 9678 boolean allowRestart) { 9679 // Report disconnected services. 9680 if (false) { 9681 // XXX we are letting the client link to the service for 9682 // death notifications. 9683 if (app.services.size() > 0) { 9684 Iterator it = app.services.iterator(); 9685 while (it.hasNext()) { 9686 ServiceRecord r = (ServiceRecord)it.next(); 9687 if (r.connections.size() > 0) { 9688 Iterator<ConnectionRecord> jt 9689 = r.connections.values().iterator(); 9690 while (jt.hasNext()) { 9691 ConnectionRecord c = jt.next(); 9692 if (c.binding.client != app) { 9693 try { 9694 //c.conn.connected(r.className, null); 9695 } catch (Exception e) { 9696 // todo: this should be asynchronous! 9697 Log.w(TAG, "Exception thrown disconnected servce " 9698 + r.shortName 9699 + " from app " + app.processName, e); 9700 } 9701 } 9702 } 9703 } 9704 } 9705 } 9706 } 9707 9708 // Clean up any connections this application has to other services. 9709 if (app.connections.size() > 0) { 9710 Iterator<ConnectionRecord> it = app.connections.iterator(); 9711 while (it.hasNext()) { 9712 ConnectionRecord r = it.next(); 9713 removeConnectionLocked(r, app, null); 9714 } 9715 } 9716 app.connections.clear(); 9717 9718 if (app.services.size() != 0) { 9719 // Any services running in the application need to be placed 9720 // back in the pending list. 9721 Iterator it = app.services.iterator(); 9722 while (it.hasNext()) { 9723 ServiceRecord sr = (ServiceRecord)it.next(); 9724 synchronized (sr.stats.getBatteryStats()) { 9725 sr.stats.stopLaunchedLocked(); 9726 } 9727 sr.app = null; 9728 sr.executeNesting = 0; 9729 mStoppingServices.remove(sr); 9730 9731 boolean hasClients = sr.bindings.size() > 0; 9732 if (hasClients) { 9733 Iterator<IntentBindRecord> bindings 9734 = sr.bindings.values().iterator(); 9735 while (bindings.hasNext()) { 9736 IntentBindRecord b = bindings.next(); 9737 if (DEBUG_SERVICE) Log.v(TAG, "Killing binding " + b 9738 + ": shouldUnbind=" + b.hasBound); 9739 b.binder = null; 9740 b.requested = b.received = b.hasBound = false; 9741 } 9742 } 9743 9744 if (sr.crashCount >= 2) { 9745 Log.w(TAG, "Service crashed " + sr.crashCount 9746 + " times, stopping: " + sr); 9747 EventLog.writeEvent(LOG_AM_SERVICE_CRASHED_TOO_MUCH, 9748 sr.crashCount, sr.shortName, app.pid); 9749 bringDownServiceLocked(sr, true); 9750 } else if (!allowRestart) { 9751 bringDownServiceLocked(sr, true); 9752 } else { 9753 boolean canceled = scheduleServiceRestartLocked(sr, true); 9754 9755 // Should the service remain running? Note that in the 9756 // extreme case of so many attempts to deliver a command 9757 // that it failed, that we also will stop it here. 9758 if (sr.startRequested && (sr.stopIfKilled || canceled)) { 9759 if (sr.pendingStarts.size() == 0) { 9760 sr.startRequested = false; 9761 if (!hasClients) { 9762 // Whoops, no reason to restart! 9763 bringDownServiceLocked(sr, true); 9764 } 9765 } 9766 } 9767 } 9768 } 9769 9770 if (!allowRestart) { 9771 app.services.clear(); 9772 } 9773 } 9774 9775 // Make sure we have no more records on the stopping list. 9776 int i = mStoppingServices.size(); 9777 while (i > 0) { 9778 i--; 9779 ServiceRecord sr = mStoppingServices.get(i); 9780 if (sr.app == app) { 9781 mStoppingServices.remove(i); 9782 } 9783 } 9784 9785 app.executingServices.clear(); 9786 } 9787 9788 private final void removeDyingProviderLocked(ProcessRecord proc, 9789 ContentProviderRecord cpr) { 9790 synchronized (cpr) { 9791 cpr.launchingApp = null; 9792 cpr.notifyAll(); 9793 } 9794 9795 mProvidersByClass.remove(cpr.info.name); 9796 String names[] = cpr.info.authority.split(";"); 9797 for (int j = 0; j < names.length; j++) { 9798 mProvidersByName.remove(names[j]); 9799 } 9800 9801 Iterator<ProcessRecord> cit = cpr.clients.iterator(); 9802 while (cit.hasNext()) { 9803 ProcessRecord capp = cit.next(); 9804 if (!capp.persistent && capp.thread != null 9805 && capp.pid != 0 9806 && capp.pid != MY_PID) { 9807 Log.i(TAG, "Killing app " + capp.processName 9808 + " (pid " + capp.pid 9809 + ") because provider " + cpr.info.name 9810 + " is in dying process " + proc.processName); 9811 Process.killProcess(capp.pid); 9812 } 9813 } 9814 9815 mLaunchingProviders.remove(cpr); 9816 } 9817 9818 /** 9819 * Main code for cleaning up a process when it has gone away. This is 9820 * called both as a result of the process dying, or directly when stopping 9821 * a process when running in single process mode. 9822 */ 9823 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 9824 boolean restarting, int index) { 9825 if (index >= 0) { 9826 mLRUProcesses.remove(index); 9827 } 9828 9829 // Dismiss any open dialogs. 9830 if (app.crashDialog != null) { 9831 app.crashDialog.dismiss(); 9832 app.crashDialog = null; 9833 } 9834 if (app.anrDialog != null) { 9835 app.anrDialog.dismiss(); 9836 app.anrDialog = null; 9837 } 9838 if (app.waitDialog != null) { 9839 app.waitDialog.dismiss(); 9840 app.waitDialog = null; 9841 } 9842 9843 app.crashing = false; 9844 app.notResponding = false; 9845 9846 app.resetPackageList(); 9847 app.thread = null; 9848 app.forcingToForeground = null; 9849 app.foregroundServices = false; 9850 9851 killServicesLocked(app, true); 9852 9853 boolean restart = false; 9854 9855 int NL = mLaunchingProviders.size(); 9856 9857 // Remove published content providers. 9858 if (!app.pubProviders.isEmpty()) { 9859 Iterator it = app.pubProviders.values().iterator(); 9860 while (it.hasNext()) { 9861 ContentProviderRecord cpr = (ContentProviderRecord)it.next(); 9862 cpr.provider = null; 9863 cpr.app = null; 9864 9865 // See if someone is waiting for this provider... in which 9866 // case we don't remove it, but just let it restart. 9867 int i = 0; 9868 if (!app.bad) { 9869 for (; i<NL; i++) { 9870 if (mLaunchingProviders.get(i) == cpr) { 9871 restart = true; 9872 break; 9873 } 9874 } 9875 } else { 9876 i = NL; 9877 } 9878 9879 if (i >= NL) { 9880 removeDyingProviderLocked(app, cpr); 9881 NL = mLaunchingProviders.size(); 9882 } 9883 } 9884 app.pubProviders.clear(); 9885 } 9886 9887 // Look through the content providers we are waiting to have launched, 9888 // and if any run in this process then either schedule a restart of 9889 // the process or kill the client waiting for it if this process has 9890 // gone bad. 9891 for (int i=0; i<NL; i++) { 9892 ContentProviderRecord cpr = (ContentProviderRecord) 9893 mLaunchingProviders.get(i); 9894 if (cpr.launchingApp == app) { 9895 if (!app.bad) { 9896 restart = true; 9897 } else { 9898 removeDyingProviderLocked(app, cpr); 9899 NL = mLaunchingProviders.size(); 9900 } 9901 } 9902 } 9903 9904 // Unregister from connected content providers. 9905 if (!app.conProviders.isEmpty()) { 9906 Iterator it = app.conProviders.iterator(); 9907 while (it.hasNext()) { 9908 ContentProviderRecord cpr = (ContentProviderRecord)it.next(); 9909 cpr.clients.remove(app); 9910 } 9911 app.conProviders.clear(); 9912 } 9913 9914 // At this point there may be remaining entries in mLaunchingProviders 9915 // where we were the only one waiting, so they are no longer of use. 9916 // Look for these and clean up if found. 9917 // XXX Commented out for now. Trying to figure out a way to reproduce 9918 // the actual situation to identify what is actually going on. 9919 if (false) { 9920 for (int i=0; i<NL; i++) { 9921 ContentProviderRecord cpr = (ContentProviderRecord) 9922 mLaunchingProviders.get(i); 9923 if (cpr.clients.size() <= 0 && cpr.externals <= 0) { 9924 synchronized (cpr) { 9925 cpr.launchingApp = null; 9926 cpr.notifyAll(); 9927 } 9928 } 9929 } 9930 } 9931 9932 skipCurrentReceiverLocked(app); 9933 9934 // Unregister any receivers. 9935 if (app.receivers.size() > 0) { 9936 Iterator<ReceiverList> it = app.receivers.iterator(); 9937 while (it.hasNext()) { 9938 removeReceiverLocked(it.next()); 9939 } 9940 app.receivers.clear(); 9941 } 9942 9943 // If the app is undergoing backup, tell the backup manager about it 9944 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 9945 if (DEBUG_BACKUP) Log.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 9946 try { 9947 IBackupManager bm = IBackupManager.Stub.asInterface( 9948 ServiceManager.getService(Context.BACKUP_SERVICE)); 9949 bm.agentDisconnected(app.info.packageName); 9950 } catch (RemoteException e) { 9951 // can't happen; backup manager is local 9952 } 9953 } 9954 9955 // If the caller is restarting this app, then leave it in its 9956 // current lists and let the caller take care of it. 9957 if (restarting) { 9958 return; 9959 } 9960 9961 if (!app.persistent) { 9962 if (DEBUG_PROCESSES) Log.v(TAG, 9963 "Removing non-persistent process during cleanup: " + app); 9964 mProcessNames.remove(app.processName, app.info.uid); 9965 } else if (!app.removed) { 9966 // This app is persistent, so we need to keep its record around. 9967 // If it is not already on the pending app list, add it there 9968 // and start a new process for it. 9969 app.thread = null; 9970 app.forcingToForeground = null; 9971 app.foregroundServices = false; 9972 if (mPersistentStartingProcesses.indexOf(app) < 0) { 9973 mPersistentStartingProcesses.add(app); 9974 restart = true; 9975 } 9976 } 9977 mProcessesOnHold.remove(app); 9978 9979 if (app == mHomeProcess) { 9980 mHomeProcess = null; 9981 } 9982 9983 if (restart) { 9984 // We have components that still need to be running in the 9985 // process, so re-launch it. 9986 mProcessNames.put(app.processName, app.info.uid, app); 9987 startProcessLocked(app, "restart", app.processName); 9988 } else if (app.pid > 0 && app.pid != MY_PID) { 9989 // Goodbye! 9990 synchronized (mPidsSelfLocked) { 9991 mPidsSelfLocked.remove(app.pid); 9992 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 9993 } 9994 app.setPid(0); 9995 } 9996 } 9997 9998 // ========================================================= 9999 // SERVICES 10000 // ========================================================= 10001 10002 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) { 10003 ActivityManager.RunningServiceInfo info = 10004 new ActivityManager.RunningServiceInfo(); 10005 info.service = r.name; 10006 if (r.app != null) { 10007 info.pid = r.app.pid; 10008 } 10009 info.uid = r.appInfo.uid; 10010 info.process = r.processName; 10011 info.foreground = r.isForeground; 10012 info.activeSince = r.createTime; 10013 info.started = r.startRequested; 10014 info.clientCount = r.connections.size(); 10015 info.crashCount = r.crashCount; 10016 info.lastActivityTime = r.lastActivity; 10017 if (r.isForeground) { 10018 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND; 10019 } 10020 if (r.startRequested) { 10021 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED; 10022 } 10023 if (r.app != null && r.app.pid == Process.myPid()) { 10024 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS; 10025 } 10026 if (r.app != null && r.app.persistent) { 10027 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS; 10028 } 10029 for (ConnectionRecord conn : r.connections.values()) { 10030 if (conn.clientLabel != 0) { 10031 info.clientPackage = conn.binding.client.info.packageName; 10032 info.clientLabel = conn.clientLabel; 10033 break; 10034 } 10035 } 10036 return info; 10037 } 10038 10039 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10040 int flags) { 10041 synchronized (this) { 10042 ArrayList<ActivityManager.RunningServiceInfo> res 10043 = new ArrayList<ActivityManager.RunningServiceInfo>(); 10044 10045 if (mServices.size() > 0) { 10046 Iterator<ServiceRecord> it = mServices.values().iterator(); 10047 while (it.hasNext() && res.size() < maxNum) { 10048 res.add(makeRunningServiceInfoLocked(it.next())); 10049 } 10050 } 10051 10052 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) { 10053 ServiceRecord r = mRestartingServices.get(i); 10054 ActivityManager.RunningServiceInfo info = 10055 makeRunningServiceInfoLocked(r); 10056 info.restarting = r.nextRestartTime; 10057 res.add(info); 10058 } 10059 10060 return res; 10061 } 10062 } 10063 10064 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10065 synchronized (this) { 10066 ServiceRecord r = mServices.get(name); 10067 if (r != null) { 10068 for (ConnectionRecord conn : r.connections.values()) { 10069 if (conn.clientIntent != null) { 10070 return conn.clientIntent; 10071 } 10072 } 10073 } 10074 } 10075 return null; 10076 } 10077 10078 private final ServiceRecord findServiceLocked(ComponentName name, 10079 IBinder token) { 10080 ServiceRecord r = mServices.get(name); 10081 return r == token ? r : null; 10082 } 10083 10084 private final class ServiceLookupResult { 10085 final ServiceRecord record; 10086 final String permission; 10087 10088 ServiceLookupResult(ServiceRecord _record, String _permission) { 10089 record = _record; 10090 permission = _permission; 10091 } 10092 }; 10093 10094 private ServiceLookupResult findServiceLocked(Intent service, 10095 String resolvedType) { 10096 ServiceRecord r = null; 10097 if (service.getComponent() != null) { 10098 r = mServices.get(service.getComponent()); 10099 } 10100 if (r == null) { 10101 Intent.FilterComparison filter = new Intent.FilterComparison(service); 10102 r = mServicesByIntent.get(filter); 10103 } 10104 10105 if (r == null) { 10106 try { 10107 ResolveInfo rInfo = 10108 ActivityThread.getPackageManager().resolveService( 10109 service, resolvedType, 0); 10110 ServiceInfo sInfo = 10111 rInfo != null ? rInfo.serviceInfo : null; 10112 if (sInfo == null) { 10113 return null; 10114 } 10115 10116 ComponentName name = new ComponentName( 10117 sInfo.applicationInfo.packageName, sInfo.name); 10118 r = mServices.get(name); 10119 } catch (RemoteException ex) { 10120 // pm is in same process, this will never happen. 10121 } 10122 } 10123 if (r != null) { 10124 int callingPid = Binder.getCallingPid(); 10125 int callingUid = Binder.getCallingUid(); 10126 if (checkComponentPermission(r.permission, 10127 callingPid, callingUid, r.exported ? -1 : r.appInfo.uid) 10128 != PackageManager.PERMISSION_GRANTED) { 10129 Log.w(TAG, "Permission Denial: Accessing service " + r.name 10130 + " from pid=" + callingPid 10131 + ", uid=" + callingUid 10132 + " requires " + r.permission); 10133 return new ServiceLookupResult(null, r.permission); 10134 } 10135 return new ServiceLookupResult(r, null); 10136 } 10137 return null; 10138 } 10139 10140 private class ServiceRestarter implements Runnable { 10141 private ServiceRecord mService; 10142 10143 void setService(ServiceRecord service) { 10144 mService = service; 10145 } 10146 10147 public void run() { 10148 synchronized(ActivityManagerService.this) { 10149 performServiceRestartLocked(mService); 10150 } 10151 } 10152 } 10153 10154 private ServiceLookupResult retrieveServiceLocked(Intent service, 10155 String resolvedType, int callingPid, int callingUid) { 10156 ServiceRecord r = null; 10157 if (service.getComponent() != null) { 10158 r = mServices.get(service.getComponent()); 10159 } 10160 Intent.FilterComparison filter = new Intent.FilterComparison(service); 10161 r = mServicesByIntent.get(filter); 10162 if (r == null) { 10163 try { 10164 ResolveInfo rInfo = 10165 ActivityThread.getPackageManager().resolveService( 10166 service, resolvedType, STOCK_PM_FLAGS); 10167 ServiceInfo sInfo = 10168 rInfo != null ? rInfo.serviceInfo : null; 10169 if (sInfo == null) { 10170 Log.w(TAG, "Unable to start service " + service + 10171 ": not found"); 10172 return null; 10173 } 10174 10175 ComponentName name = new ComponentName( 10176 sInfo.applicationInfo.packageName, sInfo.name); 10177 r = mServices.get(name); 10178 if (r == null) { 10179 filter = new Intent.FilterComparison(service.cloneFilter()); 10180 ServiceRestarter res = new ServiceRestarter(); 10181 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10182 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10183 synchronized (stats) { 10184 ss = stats.getServiceStatsLocked( 10185 sInfo.applicationInfo.uid, sInfo.packageName, 10186 sInfo.name); 10187 } 10188 r = new ServiceRecord(ss, name, filter, sInfo, res); 10189 res.setService(r); 10190 mServices.put(name, r); 10191 mServicesByIntent.put(filter, r); 10192 10193 // Make sure this component isn't in the pending list. 10194 int N = mPendingServices.size(); 10195 for (int i=0; i<N; i++) { 10196 ServiceRecord pr = mPendingServices.get(i); 10197 if (pr.name.equals(name)) { 10198 mPendingServices.remove(i); 10199 i--; 10200 N--; 10201 } 10202 } 10203 } 10204 } catch (RemoteException ex) { 10205 // pm is in same process, this will never happen. 10206 } 10207 } 10208 if (r != null) { 10209 if (checkComponentPermission(r.permission, 10210 callingPid, callingUid, r.exported ? -1 : r.appInfo.uid) 10211 != PackageManager.PERMISSION_GRANTED) { 10212 Log.w(TAG, "Permission Denial: Accessing service " + r.name 10213 + " from pid=" + Binder.getCallingPid() 10214 + ", uid=" + Binder.getCallingUid() 10215 + " requires " + r.permission); 10216 return new ServiceLookupResult(null, r.permission); 10217 } 10218 return new ServiceLookupResult(r, null); 10219 } 10220 return null; 10221 } 10222 10223 private final void bumpServiceExecutingLocked(ServiceRecord r) { 10224 long now = SystemClock.uptimeMillis(); 10225 if (r.executeNesting == 0 && r.app != null) { 10226 if (r.app.executingServices.size() == 0) { 10227 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 10228 msg.obj = r.app; 10229 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT); 10230 } 10231 r.app.executingServices.add(r); 10232 } 10233 r.executeNesting++; 10234 r.executingStart = now; 10235 } 10236 10237 private final void sendServiceArgsLocked(ServiceRecord r, 10238 boolean oomAdjusted) { 10239 final int N = r.pendingStarts.size(); 10240 if (N == 0) { 10241 return; 10242 } 10243 10244 int i = 0; 10245 while (i < N) { 10246 try { 10247 ServiceRecord.StartItem si = r.pendingStarts.get(i); 10248 if (DEBUG_SERVICE) Log.v(TAG, "Sending arguments to service: " 10249 + r.name + " " + r.intent + " args=" + si.intent); 10250 if (si.intent == null && N > 1) { 10251 // If somehow we got a dummy start at the front, then 10252 // just drop it here. 10253 i++; 10254 continue; 10255 } 10256 bumpServiceExecutingLocked(r); 10257 if (!oomAdjusted) { 10258 oomAdjusted = true; 10259 updateOomAdjLocked(r.app); 10260 } 10261 int flags = 0; 10262 if (si.deliveryCount > 0) { 10263 flags |= Service.START_FLAG_RETRY; 10264 } 10265 if (si.doneExecutingCount > 0) { 10266 flags |= Service.START_FLAG_REDELIVERY; 10267 } 10268 r.app.thread.scheduleServiceArgs(r, si.id, flags, si.intent); 10269 si.deliveredTime = SystemClock.uptimeMillis(); 10270 r.deliveredStarts.add(si); 10271 si.deliveryCount++; 10272 i++; 10273 } catch (RemoteException e) { 10274 // Remote process gone... we'll let the normal cleanup take 10275 // care of this. 10276 break; 10277 } catch (Exception e) { 10278 Log.w(TAG, "Unexpected exception", e); 10279 break; 10280 } 10281 } 10282 if (i == N) { 10283 r.pendingStarts.clear(); 10284 } else { 10285 while (i > 0) { 10286 i--; 10287 r.pendingStarts.remove(i); 10288 } 10289 } 10290 } 10291 10292 private final boolean requestServiceBindingLocked(ServiceRecord r, 10293 IntentBindRecord i, boolean rebind) { 10294 if (r.app == null || r.app.thread == null) { 10295 // If service is not currently running, can't yet bind. 10296 return false; 10297 } 10298 if ((!i.requested || rebind) && i.apps.size() > 0) { 10299 try { 10300 bumpServiceExecutingLocked(r); 10301 if (DEBUG_SERVICE) Log.v(TAG, "Connecting binding " + i 10302 + ": shouldUnbind=" + i.hasBound); 10303 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind); 10304 if (!rebind) { 10305 i.requested = true; 10306 } 10307 i.hasBound = true; 10308 i.doRebind = false; 10309 } catch (RemoteException e) { 10310 return false; 10311 } 10312 } 10313 return true; 10314 } 10315 10316 private final void requestServiceBindingsLocked(ServiceRecord r) { 10317 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator(); 10318 while (bindings.hasNext()) { 10319 IntentBindRecord i = bindings.next(); 10320 if (!requestServiceBindingLocked(r, i, false)) { 10321 break; 10322 } 10323 } 10324 } 10325 10326 private final void realStartServiceLocked(ServiceRecord r, 10327 ProcessRecord app) throws RemoteException { 10328 if (app.thread == null) { 10329 throw new RemoteException(); 10330 } 10331 10332 r.app = app; 10333 r.restartTime = r.lastActivity = SystemClock.uptimeMillis(); 10334 10335 app.services.add(r); 10336 bumpServiceExecutingLocked(r); 10337 updateLRUListLocked(app, true); 10338 10339 boolean created = false; 10340 try { 10341 if (DEBUG_SERVICE) Log.v(TAG, "Scheduling start service: " 10342 + r.name + " " + r.intent); 10343 EventLog.writeEvent(LOG_AM_CREATE_SERVICE, 10344 System.identityHashCode(r), r.shortName, 10345 r.intent.getIntent().toString(), r.app.pid); 10346 synchronized (r.stats.getBatteryStats()) { 10347 r.stats.startLaunchedLocked(); 10348 } 10349 ensurePackageDexOpt(r.serviceInfo.packageName); 10350 app.thread.scheduleCreateService(r, r.serviceInfo); 10351 r.postNotification(); 10352 created = true; 10353 } finally { 10354 if (!created) { 10355 app.services.remove(r); 10356 scheduleServiceRestartLocked(r, false); 10357 } 10358 } 10359 10360 requestServiceBindingsLocked(r); 10361 10362 // If the service is in the started state, and there are no 10363 // pending arguments, then fake up one so its onStartCommand() will 10364 // be called. 10365 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) { 10366 r.lastStartId++; 10367 if (r.lastStartId < 1) { 10368 r.lastStartId = 1; 10369 } 10370 r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, null)); 10371 } 10372 10373 sendServiceArgsLocked(r, true); 10374 } 10375 10376 private final boolean scheduleServiceRestartLocked(ServiceRecord r, 10377 boolean allowCancel) { 10378 boolean canceled = false; 10379 10380 final long now = SystemClock.uptimeMillis(); 10381 long minDuration = SERVICE_RESTART_DURATION; 10382 long resetTime = SERVICE_RESET_RUN_DURATION; 10383 10384 // Any delivered but not yet finished starts should be put back 10385 // on the pending list. 10386 final int N = r.deliveredStarts.size(); 10387 if (N > 0) { 10388 for (int i=N-1; i>=0; i--) { 10389 ServiceRecord.StartItem si = r.deliveredStarts.get(i); 10390 if (si.intent == null) { 10391 // We'll generate this again if needed. 10392 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT 10393 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) { 10394 r.pendingStarts.add(0, si); 10395 long dur = SystemClock.uptimeMillis() - si.deliveredTime; 10396 dur *= 2; 10397 if (minDuration < dur) minDuration = dur; 10398 if (resetTime < dur) resetTime = dur; 10399 } else { 10400 Log.w(TAG, "Canceling start item " + si.intent + " in service " 10401 + r.name); 10402 canceled = true; 10403 } 10404 } 10405 r.deliveredStarts.clear(); 10406 } 10407 10408 r.totalRestartCount++; 10409 if (r.restartDelay == 0) { 10410 r.restartCount++; 10411 r.restartDelay = minDuration; 10412 } else { 10413 // If it has been a "reasonably long time" since the service 10414 // was started, then reset our restart duration back to 10415 // the beginning, so we don't infinitely increase the duration 10416 // on a service that just occasionally gets killed (which is 10417 // a normal case, due to process being killed to reclaim memory). 10418 if (now > (r.restartTime+resetTime)) { 10419 r.restartCount = 1; 10420 r.restartDelay = minDuration; 10421 } else { 10422 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR; 10423 if (r.restartDelay < minDuration) { 10424 r.restartDelay = minDuration; 10425 } 10426 } 10427 } 10428 10429 r.nextRestartTime = now + r.restartDelay; 10430 10431 // Make sure that we don't end up restarting a bunch of services 10432 // all at the same time. 10433 boolean repeat; 10434 do { 10435 repeat = false; 10436 for (int i=mRestartingServices.size()-1; i>=0; i--) { 10437 ServiceRecord r2 = mRestartingServices.get(i); 10438 if (r2 != r && r.nextRestartTime 10439 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN) 10440 && r.nextRestartTime 10441 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) { 10442 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN; 10443 r.restartDelay = r.nextRestartTime - now; 10444 repeat = true; 10445 break; 10446 } 10447 } 10448 } while (repeat); 10449 10450 if (!mRestartingServices.contains(r)) { 10451 mRestartingServices.add(r); 10452 } 10453 10454 r.cancelNotification(); 10455 10456 mHandler.removeCallbacks(r.restarter); 10457 mHandler.postAtTime(r.restarter, r.nextRestartTime); 10458 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay; 10459 Log.w(TAG, "Scheduling restart of crashed service " 10460 + r.shortName + " in " + r.restartDelay + "ms"); 10461 EventLog.writeEvent(LOG_AM_SCHEDULE_SERVICE_RESTART, 10462 r.shortName, r.restartDelay); 10463 10464 Message msg = Message.obtain(); 10465 msg.what = SERVICE_ERROR_MSG; 10466 msg.obj = r; 10467 mHandler.sendMessage(msg); 10468 10469 return canceled; 10470 } 10471 10472 final void performServiceRestartLocked(ServiceRecord r) { 10473 if (!mRestartingServices.contains(r)) { 10474 return; 10475 } 10476 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true); 10477 } 10478 10479 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) { 10480 if (r.restartDelay == 0) { 10481 return false; 10482 } 10483 r.resetRestartCounter(); 10484 mRestartingServices.remove(r); 10485 mHandler.removeCallbacks(r.restarter); 10486 return true; 10487 } 10488 10489 private final boolean bringUpServiceLocked(ServiceRecord r, 10490 int intentFlags, boolean whileRestarting) { 10491 //Log.i(TAG, "Bring up service:"); 10492 //r.dump(" "); 10493 10494 if (r.app != null) { 10495 sendServiceArgsLocked(r, false); 10496 return true; 10497 } 10498 10499 if (!whileRestarting && r.restartDelay > 0) { 10500 // If waiting for a restart, then do nothing. 10501 return true; 10502 } 10503 10504 if (DEBUG_SERVICE) Log.v(TAG, "Bringing up service " + r.name 10505 + " " + r.intent); 10506 10507 // We are now bringing the service up, so no longer in the 10508 // restarting state. 10509 mRestartingServices.remove(r); 10510 10511 final String appName = r.processName; 10512 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid); 10513 if (app != null && app.thread != null) { 10514 try { 10515 realStartServiceLocked(r, app); 10516 return true; 10517 } catch (RemoteException e) { 10518 Log.w(TAG, "Exception when starting service " + r.shortName, e); 10519 } 10520 10521 // If a dead object exception was thrown -- fall through to 10522 // restart the application. 10523 } 10524 10525 if (!mPendingServices.contains(r)) { 10526 // Not running -- get it started, and enqueue this service record 10527 // to be executed when the app comes up. 10528 if (startProcessLocked(appName, r.appInfo, true, intentFlags, 10529 "service", r.name, false) == null) { 10530 Log.w(TAG, "Unable to launch app " 10531 + r.appInfo.packageName + "/" 10532 + r.appInfo.uid + " for service " 10533 + r.intent.getIntent() + ": process is bad"); 10534 bringDownServiceLocked(r, true); 10535 return false; 10536 } 10537 mPendingServices.add(r); 10538 } 10539 return true; 10540 } 10541 10542 private final void bringDownServiceLocked(ServiceRecord r, boolean force) { 10543 //Log.i(TAG, "Bring down service:"); 10544 //r.dump(" "); 10545 10546 // Does it still need to run? 10547 if (!force && r.startRequested) { 10548 return; 10549 } 10550 if (r.connections.size() > 0) { 10551 if (!force) { 10552 // XXX should probably keep a count of the number of auto-create 10553 // connections directly in the service. 10554 Iterator<ConnectionRecord> it = r.connections.values().iterator(); 10555 while (it.hasNext()) { 10556 ConnectionRecord cr = it.next(); 10557 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) { 10558 return; 10559 } 10560 } 10561 } 10562 10563 // Report to all of the connections that the service is no longer 10564 // available. 10565 Iterator<ConnectionRecord> it = r.connections.values().iterator(); 10566 while (it.hasNext()) { 10567 ConnectionRecord c = it.next(); 10568 try { 10569 // todo: shouldn't be a synchronous call! 10570 c.conn.connected(r.name, null); 10571 } catch (Exception e) { 10572 Log.w(TAG, "Failure disconnecting service " + r.name + 10573 " to connection " + c.conn.asBinder() + 10574 " (in " + c.binding.client.processName + ")", e); 10575 } 10576 } 10577 } 10578 10579 // Tell the service that it has been unbound. 10580 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) { 10581 Iterator<IntentBindRecord> it = r.bindings.values().iterator(); 10582 while (it.hasNext()) { 10583 IntentBindRecord ibr = it.next(); 10584 if (DEBUG_SERVICE) Log.v(TAG, "Bringing down binding " + ibr 10585 + ": hasBound=" + ibr.hasBound); 10586 if (r.app != null && r.app.thread != null && ibr.hasBound) { 10587 try { 10588 bumpServiceExecutingLocked(r); 10589 updateOomAdjLocked(r.app); 10590 ibr.hasBound = false; 10591 r.app.thread.scheduleUnbindService(r, 10592 ibr.intent.getIntent()); 10593 } catch (Exception e) { 10594 Log.w(TAG, "Exception when unbinding service " 10595 + r.shortName, e); 10596 serviceDoneExecutingLocked(r, true); 10597 } 10598 } 10599 } 10600 } 10601 10602 if (DEBUG_SERVICE) Log.v(TAG, "Bringing down service " + r.name 10603 + " " + r.intent); 10604 EventLog.writeEvent(LOG_AM_DESTROY_SERVICE, 10605 System.identityHashCode(r), r.shortName, 10606 (r.app != null) ? r.app.pid : -1); 10607 10608 mServices.remove(r.name); 10609 mServicesByIntent.remove(r.intent); 10610 if (localLOGV) Log.v(TAG, "BRING DOWN SERVICE: " + r.shortName); 10611 r.totalRestartCount = 0; 10612 unscheduleServiceRestartLocked(r); 10613 10614 // Also make sure it is not on the pending list. 10615 int N = mPendingServices.size(); 10616 for (int i=0; i<N; i++) { 10617 if (mPendingServices.get(i) == r) { 10618 mPendingServices.remove(i); 10619 if (DEBUG_SERVICE) Log.v( 10620 TAG, "Removed pending service: " + r.shortName); 10621 i--; 10622 N--; 10623 } 10624 } 10625 10626 r.cancelNotification(); 10627 r.isForeground = false; 10628 r.foregroundId = 0; 10629 r.foregroundNoti = null; 10630 10631 // Clear start entries. 10632 r.deliveredStarts.clear(); 10633 r.pendingStarts.clear(); 10634 10635 if (r.app != null) { 10636 synchronized (r.stats.getBatteryStats()) { 10637 r.stats.stopLaunchedLocked(); 10638 } 10639 r.app.services.remove(r); 10640 if (r.app.thread != null) { 10641 try { 10642 if (DEBUG_SERVICE) Log.v(TAG, 10643 "Stopping service: " + r.shortName); 10644 bumpServiceExecutingLocked(r); 10645 mStoppingServices.add(r); 10646 updateOomAdjLocked(r.app); 10647 r.app.thread.scheduleStopService(r); 10648 } catch (Exception e) { 10649 Log.w(TAG, "Exception when stopping service " 10650 + r.shortName, e); 10651 serviceDoneExecutingLocked(r, true); 10652 } 10653 updateServiceForegroundLocked(r.app, false); 10654 } else { 10655 if (DEBUG_SERVICE) Log.v( 10656 TAG, "Removed service that has no process: " + r.shortName); 10657 } 10658 } else { 10659 if (DEBUG_SERVICE) Log.v( 10660 TAG, "Removed service that is not running: " + r.shortName); 10661 } 10662 } 10663 10664 ComponentName startServiceLocked(IApplicationThread caller, 10665 Intent service, String resolvedType, 10666 int callingPid, int callingUid) { 10667 synchronized(this) { 10668 if (DEBUG_SERVICE) Log.v(TAG, "startService: " + service 10669 + " type=" + resolvedType + " args=" + service.getExtras()); 10670 10671 if (caller != null) { 10672 final ProcessRecord callerApp = getRecordForAppLocked(caller); 10673 if (callerApp == null) { 10674 throw new SecurityException( 10675 "Unable to find app for caller " + caller 10676 + " (pid=" + Binder.getCallingPid() 10677 + ") when starting service " + service); 10678 } 10679 } 10680 10681 ServiceLookupResult res = 10682 retrieveServiceLocked(service, resolvedType, 10683 callingPid, callingUid); 10684 if (res == null) { 10685 return null; 10686 } 10687 if (res.record == null) { 10688 return new ComponentName("!", res.permission != null 10689 ? res.permission : "private to package"); 10690 } 10691 ServiceRecord r = res.record; 10692 if (unscheduleServiceRestartLocked(r)) { 10693 if (DEBUG_SERVICE) Log.v(TAG, "START SERVICE WHILE RESTART PENDING: " 10694 + r.shortName); 10695 } 10696 r.startRequested = true; 10697 r.callStart = false; 10698 r.lastStartId++; 10699 if (r.lastStartId < 1) { 10700 r.lastStartId = 1; 10701 } 10702 r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, service)); 10703 r.lastActivity = SystemClock.uptimeMillis(); 10704 synchronized (r.stats.getBatteryStats()) { 10705 r.stats.startRunningLocked(); 10706 } 10707 if (!bringUpServiceLocked(r, service.getFlags(), false)) { 10708 return new ComponentName("!", "Service process is bad"); 10709 } 10710 return r.name; 10711 } 10712 } 10713 10714 public ComponentName startService(IApplicationThread caller, Intent service, 10715 String resolvedType) { 10716 // Refuse possible leaked file descriptors 10717 if (service != null && service.hasFileDescriptors() == true) { 10718 throw new IllegalArgumentException("File descriptors passed in Intent"); 10719 } 10720 10721 synchronized(this) { 10722 final int callingPid = Binder.getCallingPid(); 10723 final int callingUid = Binder.getCallingUid(); 10724 final long origId = Binder.clearCallingIdentity(); 10725 ComponentName res = startServiceLocked(caller, service, 10726 resolvedType, callingPid, callingUid); 10727 Binder.restoreCallingIdentity(origId); 10728 return res; 10729 } 10730 } 10731 10732 ComponentName startServiceInPackage(int uid, 10733 Intent service, String resolvedType) { 10734 synchronized(this) { 10735 final long origId = Binder.clearCallingIdentity(); 10736 ComponentName res = startServiceLocked(null, service, 10737 resolvedType, -1, uid); 10738 Binder.restoreCallingIdentity(origId); 10739 return res; 10740 } 10741 } 10742 10743 public int stopService(IApplicationThread caller, Intent service, 10744 String resolvedType) { 10745 // Refuse possible leaked file descriptors 10746 if (service != null && service.hasFileDescriptors() == true) { 10747 throw new IllegalArgumentException("File descriptors passed in Intent"); 10748 } 10749 10750 synchronized(this) { 10751 if (DEBUG_SERVICE) Log.v(TAG, "stopService: " + service 10752 + " type=" + resolvedType); 10753 10754 final ProcessRecord callerApp = getRecordForAppLocked(caller); 10755 if (caller != null && callerApp == null) { 10756 throw new SecurityException( 10757 "Unable to find app for caller " + caller 10758 + " (pid=" + Binder.getCallingPid() 10759 + ") when stopping service " + service); 10760 } 10761 10762 // If this service is active, make sure it is stopped. 10763 ServiceLookupResult r = findServiceLocked(service, resolvedType); 10764 if (r != null) { 10765 if (r.record != null) { 10766 synchronized (r.record.stats.getBatteryStats()) { 10767 r.record.stats.stopRunningLocked(); 10768 } 10769 r.record.startRequested = false; 10770 r.record.callStart = false; 10771 final long origId = Binder.clearCallingIdentity(); 10772 bringDownServiceLocked(r.record, false); 10773 Binder.restoreCallingIdentity(origId); 10774 return 1; 10775 } 10776 return -1; 10777 } 10778 } 10779 10780 return 0; 10781 } 10782 10783 public IBinder peekService(Intent service, String resolvedType) { 10784 // Refuse possible leaked file descriptors 10785 if (service != null && service.hasFileDescriptors() == true) { 10786 throw new IllegalArgumentException("File descriptors passed in Intent"); 10787 } 10788 10789 IBinder ret = null; 10790 10791 synchronized(this) { 10792 ServiceLookupResult r = findServiceLocked(service, resolvedType); 10793 10794 if (r != null) { 10795 // r.record is null if findServiceLocked() failed the caller permission check 10796 if (r.record == null) { 10797 throw new SecurityException( 10798 "Permission Denial: Accessing service " + r.record.name 10799 + " from pid=" + Binder.getCallingPid() 10800 + ", uid=" + Binder.getCallingUid() 10801 + " requires " + r.permission); 10802 } 10803 IntentBindRecord ib = r.record.bindings.get(r.record.intent); 10804 if (ib != null) { 10805 ret = ib.binder; 10806 } 10807 } 10808 } 10809 10810 return ret; 10811 } 10812 10813 public boolean stopServiceToken(ComponentName className, IBinder token, 10814 int startId) { 10815 synchronized(this) { 10816 if (DEBUG_SERVICE) Log.v(TAG, "stopServiceToken: " + className 10817 + " " + token + " startId=" + startId); 10818 ServiceRecord r = findServiceLocked(className, token); 10819 if (r != null) { 10820 if (startId >= 0) { 10821 // Asked to only stop if done with all work. Note that 10822 // to avoid leaks, we will take this as dropping all 10823 // start items up to and including this one. 10824 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 10825 if (si != null) { 10826 while (r.deliveredStarts.size() > 0) { 10827 if (r.deliveredStarts.remove(0) == si) { 10828 break; 10829 } 10830 } 10831 } 10832 10833 if (r.lastStartId != startId) { 10834 return false; 10835 } 10836 10837 if (r.deliveredStarts.size() > 0) { 10838 Log.w(TAG, "stopServiceToken startId " + startId 10839 + " is last, but have " + r.deliveredStarts.size() 10840 + " remaining args"); 10841 } 10842 } 10843 10844 synchronized (r.stats.getBatteryStats()) { 10845 r.stats.stopRunningLocked(); 10846 r.startRequested = false; 10847 r.callStart = false; 10848 } 10849 final long origId = Binder.clearCallingIdentity(); 10850 bringDownServiceLocked(r, false); 10851 Binder.restoreCallingIdentity(origId); 10852 return true; 10853 } 10854 } 10855 return false; 10856 } 10857 10858 public void setServiceForeground(ComponentName className, IBinder token, 10859 int id, Notification notification, boolean removeNotification) { 10860 final long origId = Binder.clearCallingIdentity(); 10861 try { 10862 synchronized(this) { 10863 ServiceRecord r = findServiceLocked(className, token); 10864 if (r != null) { 10865 if (id != 0) { 10866 if (notification == null) { 10867 throw new IllegalArgumentException("null notification"); 10868 } 10869 if (r.foregroundId != id) { 10870 r.cancelNotification(); 10871 r.foregroundId = id; 10872 } 10873 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE; 10874 r.foregroundNoti = notification; 10875 r.isForeground = true; 10876 r.postNotification(); 10877 if (r.app != null) { 10878 updateServiceForegroundLocked(r.app, true); 10879 } 10880 } else { 10881 if (r.isForeground) { 10882 r.isForeground = false; 10883 if (r.app != null) { 10884 updateServiceForegroundLocked(r.app, true); 10885 } 10886 } 10887 if (removeNotification) { 10888 r.cancelNotification(); 10889 r.foregroundId = 0; 10890 r.foregroundNoti = null; 10891 } 10892 } 10893 } 10894 } 10895 } finally { 10896 Binder.restoreCallingIdentity(origId); 10897 } 10898 } 10899 10900 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) { 10901 boolean anyForeground = false; 10902 for (ServiceRecord sr : (HashSet<ServiceRecord>)proc.services) { 10903 if (sr.isForeground) { 10904 anyForeground = true; 10905 break; 10906 } 10907 } 10908 if (anyForeground != proc.foregroundServices) { 10909 proc.foregroundServices = anyForeground; 10910 if (oomAdj) { 10911 updateOomAdjLocked(); 10912 } 10913 } 10914 } 10915 10916 public int bindService(IApplicationThread caller, IBinder token, 10917 Intent service, String resolvedType, 10918 IServiceConnection connection, int flags) { 10919 // Refuse possible leaked file descriptors 10920 if (service != null && service.hasFileDescriptors() == true) { 10921 throw new IllegalArgumentException("File descriptors passed in Intent"); 10922 } 10923 10924 synchronized(this) { 10925 if (DEBUG_SERVICE) Log.v(TAG, "bindService: " + service 10926 + " type=" + resolvedType + " conn=" + connection.asBinder() 10927 + " flags=0x" + Integer.toHexString(flags)); 10928 final ProcessRecord callerApp = getRecordForAppLocked(caller); 10929 if (callerApp == null) { 10930 throw new SecurityException( 10931 "Unable to find app for caller " + caller 10932 + " (pid=" + Binder.getCallingPid() 10933 + ") when binding service " + service); 10934 } 10935 10936 HistoryRecord activity = null; 10937 if (token != null) { 10938 int aindex = indexOfTokenLocked(token); 10939 if (aindex < 0) { 10940 Log.w(TAG, "Binding with unknown activity: " + token); 10941 return 0; 10942 } 10943 activity = (HistoryRecord)mHistory.get(aindex); 10944 } 10945 10946 int clientLabel = 0; 10947 PendingIntent clientIntent = null; 10948 10949 if (callerApp.info.uid == Process.SYSTEM_UID) { 10950 // Hacky kind of thing -- allow system stuff to tell us 10951 // what they are, so we can report this elsewhere for 10952 // others to know why certain services are running. 10953 try { 10954 clientIntent = (PendingIntent)service.getParcelableExtra( 10955 Intent.EXTRA_CLIENT_INTENT); 10956 } catch (RuntimeException e) { 10957 } 10958 if (clientIntent != null) { 10959 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0); 10960 if (clientLabel != 0) { 10961 // There are no useful extras in the intent, trash them. 10962 // System code calling with this stuff just needs to know 10963 // this will happen. 10964 service = service.cloneFilter(); 10965 } 10966 } 10967 } 10968 10969 ServiceLookupResult res = 10970 retrieveServiceLocked(service, resolvedType, 10971 Binder.getCallingPid(), Binder.getCallingUid()); 10972 if (res == null) { 10973 return 0; 10974 } 10975 if (res.record == null) { 10976 return -1; 10977 } 10978 ServiceRecord s = res.record; 10979 10980 final long origId = Binder.clearCallingIdentity(); 10981 10982 if (unscheduleServiceRestartLocked(s)) { 10983 if (DEBUG_SERVICE) Log.v(TAG, "BIND SERVICE WHILE RESTART PENDING: " 10984 + s.shortName); 10985 } 10986 10987 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp); 10988 ConnectionRecord c = new ConnectionRecord(b, activity, 10989 connection, flags, clientLabel, clientIntent); 10990 10991 IBinder binder = connection.asBinder(); 10992 s.connections.put(binder, c); 10993 b.connections.add(c); 10994 if (activity != null) { 10995 if (activity.connections == null) { 10996 activity.connections = new HashSet<ConnectionRecord>(); 10997 } 10998 activity.connections.add(c); 10999 } 11000 b.client.connections.add(c); 11001 mServiceConnections.put(binder, c); 11002 11003 if ((flags&Context.BIND_AUTO_CREATE) != 0) { 11004 s.lastActivity = SystemClock.uptimeMillis(); 11005 if (!bringUpServiceLocked(s, service.getFlags(), false)) { 11006 return 0; 11007 } 11008 } 11009 11010 if (s.app != null) { 11011 // This could have made the service more important. 11012 updateOomAdjLocked(s.app); 11013 } 11014 11015 if (DEBUG_SERVICE) Log.v(TAG, "Bind " + s + " with " + b 11016 + ": received=" + b.intent.received 11017 + " apps=" + b.intent.apps.size() 11018 + " doRebind=" + b.intent.doRebind); 11019 11020 if (s.app != null && b.intent.received) { 11021 // Service is already running, so we can immediately 11022 // publish the connection. 11023 try { 11024 c.conn.connected(s.name, b.intent.binder); 11025 } catch (Exception e) { 11026 Log.w(TAG, "Failure sending service " + s.shortName 11027 + " to connection " + c.conn.asBinder() 11028 + " (in " + c.binding.client.processName + ")", e); 11029 } 11030 11031 // If this is the first app connected back to this binding, 11032 // and the service had previously asked to be told when 11033 // rebound, then do so. 11034 if (b.intent.apps.size() == 1 && b.intent.doRebind) { 11035 requestServiceBindingLocked(s, b.intent, true); 11036 } 11037 } else if (!b.intent.requested) { 11038 requestServiceBindingLocked(s, b.intent, false); 11039 } 11040 11041 Binder.restoreCallingIdentity(origId); 11042 } 11043 11044 return 1; 11045 } 11046 11047 private void removeConnectionLocked( 11048 ConnectionRecord c, ProcessRecord skipApp, HistoryRecord skipAct) { 11049 IBinder binder = c.conn.asBinder(); 11050 AppBindRecord b = c.binding; 11051 ServiceRecord s = b.service; 11052 s.connections.remove(binder); 11053 b.connections.remove(c); 11054 if (c.activity != null && c.activity != skipAct) { 11055 if (c.activity.connections != null) { 11056 c.activity.connections.remove(c); 11057 } 11058 } 11059 if (b.client != skipApp) { 11060 b.client.connections.remove(c); 11061 } 11062 mServiceConnections.remove(binder); 11063 11064 if (b.connections.size() == 0) { 11065 b.intent.apps.remove(b.client); 11066 } 11067 11068 if (DEBUG_SERVICE) Log.v(TAG, "Disconnecting binding " + b.intent 11069 + ": shouldUnbind=" + b.intent.hasBound); 11070 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0 11071 && b.intent.hasBound) { 11072 try { 11073 bumpServiceExecutingLocked(s); 11074 updateOomAdjLocked(s.app); 11075 b.intent.hasBound = false; 11076 // Assume the client doesn't want to know about a rebind; 11077 // we will deal with that later if it asks for one. 11078 b.intent.doRebind = false; 11079 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent()); 11080 } catch (Exception e) { 11081 Log.w(TAG, "Exception when unbinding service " + s.shortName, e); 11082 serviceDoneExecutingLocked(s, true); 11083 } 11084 } 11085 11086 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) { 11087 bringDownServiceLocked(s, false); 11088 } 11089 } 11090 11091 public boolean unbindService(IServiceConnection connection) { 11092 synchronized (this) { 11093 IBinder binder = connection.asBinder(); 11094 if (DEBUG_SERVICE) Log.v(TAG, "unbindService: conn=" + binder); 11095 ConnectionRecord r = mServiceConnections.get(binder); 11096 if (r == null) { 11097 Log.w(TAG, "Unbind failed: could not find connection for " 11098 + connection.asBinder()); 11099 return false; 11100 } 11101 11102 final long origId = Binder.clearCallingIdentity(); 11103 11104 removeConnectionLocked(r, null, null); 11105 11106 if (r.binding.service.app != null) { 11107 // This could have made the service less important. 11108 updateOomAdjLocked(r.binding.service.app); 11109 } 11110 11111 Binder.restoreCallingIdentity(origId); 11112 } 11113 11114 return true; 11115 } 11116 11117 public void publishService(IBinder token, Intent intent, IBinder service) { 11118 // Refuse possible leaked file descriptors 11119 if (intent != null && intent.hasFileDescriptors() == true) { 11120 throw new IllegalArgumentException("File descriptors passed in Intent"); 11121 } 11122 11123 synchronized(this) { 11124 if (!(token instanceof ServiceRecord)) { 11125 throw new IllegalArgumentException("Invalid service token"); 11126 } 11127 ServiceRecord r = (ServiceRecord)token; 11128 11129 final long origId = Binder.clearCallingIdentity(); 11130 11131 if (DEBUG_SERVICE) Log.v(TAG, "PUBLISHING SERVICE " + r.name 11132 + " " + intent + ": " + service); 11133 if (r != null) { 11134 Intent.FilterComparison filter 11135 = new Intent.FilterComparison(intent); 11136 IntentBindRecord b = r.bindings.get(filter); 11137 if (b != null && !b.received) { 11138 b.binder = service; 11139 b.requested = true; 11140 b.received = true; 11141 if (r.connections.size() > 0) { 11142 Iterator<ConnectionRecord> it 11143 = r.connections.values().iterator(); 11144 while (it.hasNext()) { 11145 ConnectionRecord c = it.next(); 11146 if (!filter.equals(c.binding.intent.intent)) { 11147 if (DEBUG_SERVICE) Log.v( 11148 TAG, "Not publishing to: " + c); 11149 if (DEBUG_SERVICE) Log.v( 11150 TAG, "Bound intent: " + c.binding.intent.intent); 11151 if (DEBUG_SERVICE) Log.v( 11152 TAG, "Published intent: " + intent); 11153 continue; 11154 } 11155 if (DEBUG_SERVICE) Log.v(TAG, "Publishing to: " + c); 11156 try { 11157 c.conn.connected(r.name, service); 11158 } catch (Exception e) { 11159 Log.w(TAG, "Failure sending service " + r.name + 11160 " to connection " + c.conn.asBinder() + 11161 " (in " + c.binding.client.processName + ")", e); 11162 } 11163 } 11164 } 11165 } 11166 11167 serviceDoneExecutingLocked(r, mStoppingServices.contains(r)); 11168 11169 Binder.restoreCallingIdentity(origId); 11170 } 11171 } 11172 } 11173 11174 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 11175 // Refuse possible leaked file descriptors 11176 if (intent != null && intent.hasFileDescriptors() == true) { 11177 throw new IllegalArgumentException("File descriptors passed in Intent"); 11178 } 11179 11180 synchronized(this) { 11181 if (!(token instanceof ServiceRecord)) { 11182 throw new IllegalArgumentException("Invalid service token"); 11183 } 11184 ServiceRecord r = (ServiceRecord)token; 11185 11186 final long origId = Binder.clearCallingIdentity(); 11187 11188 if (r != null) { 11189 Intent.FilterComparison filter 11190 = new Intent.FilterComparison(intent); 11191 IntentBindRecord b = r.bindings.get(filter); 11192 if (DEBUG_SERVICE) Log.v(TAG, "unbindFinished in " + r 11193 + " at " + b + ": apps=" 11194 + (b != null ? b.apps.size() : 0)); 11195 if (b != null) { 11196 if (b.apps.size() > 0) { 11197 // Applications have already bound since the last 11198 // unbind, so just rebind right here. 11199 requestServiceBindingLocked(r, b, true); 11200 } else { 11201 // Note to tell the service the next time there is 11202 // a new client. 11203 b.doRebind = true; 11204 } 11205 } 11206 11207 serviceDoneExecutingLocked(r, mStoppingServices.contains(r)); 11208 11209 Binder.restoreCallingIdentity(origId); 11210 } 11211 } 11212 } 11213 11214 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 11215 synchronized(this) { 11216 if (!(token instanceof ServiceRecord)) { 11217 throw new IllegalArgumentException("Invalid service token"); 11218 } 11219 ServiceRecord r = (ServiceRecord)token; 11220 boolean inStopping = mStoppingServices.contains(token); 11221 if (r != null) { 11222 if (DEBUG_SERVICE) Log.v(TAG, "DONE EXECUTING SERVICE " + r.name 11223 + ": nesting=" + r.executeNesting 11224 + ", inStopping=" + inStopping); 11225 if (r != token) { 11226 Log.w(TAG, "Done executing service " + r.name 11227 + " with incorrect token: given " + token 11228 + ", expected " + r); 11229 return; 11230 } 11231 11232 if (type == 1) { 11233 // This is a call from a service start... take care of 11234 // book-keeping. 11235 r.callStart = true; 11236 switch (res) { 11237 case Service.START_STICKY_COMPATIBILITY: 11238 case Service.START_STICKY: { 11239 // We are done with the associated start arguments. 11240 r.findDeliveredStart(startId, true); 11241 // Don't stop if killed. 11242 r.stopIfKilled = false; 11243 break; 11244 } 11245 case Service.START_NOT_STICKY: { 11246 // We are done with the associated start arguments. 11247 r.findDeliveredStart(startId, true); 11248 if (r.lastStartId == startId) { 11249 // There is no more work, and this service 11250 // doesn't want to hang around if killed. 11251 r.stopIfKilled = true; 11252 } 11253 break; 11254 } 11255 case Service.START_REDELIVER_INTENT: { 11256 // We'll keep this item until they explicitly 11257 // call stop for it, but keep track of the fact 11258 // that it was delivered. 11259 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 11260 if (si != null) { 11261 si.deliveryCount = 0; 11262 si.doneExecutingCount++; 11263 // Don't stop if killed. 11264 r.stopIfKilled = true; 11265 } 11266 break; 11267 } 11268 default: 11269 throw new IllegalArgumentException( 11270 "Unknown service start result: " + res); 11271 } 11272 if (res == Service.START_STICKY_COMPATIBILITY) { 11273 r.callStart = false; 11274 } 11275 } 11276 11277 final long origId = Binder.clearCallingIdentity(); 11278 serviceDoneExecutingLocked(r, inStopping); 11279 Binder.restoreCallingIdentity(origId); 11280 } else { 11281 Log.w(TAG, "Done executing unknown service " + r.name 11282 + " with token " + token); 11283 } 11284 } 11285 } 11286 11287 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) { 11288 r.executeNesting--; 11289 if (r.executeNesting <= 0 && r.app != null) { 11290 r.app.executingServices.remove(r); 11291 if (r.app.executingServices.size() == 0) { 11292 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app); 11293 } 11294 if (inStopping) { 11295 mStoppingServices.remove(r); 11296 } 11297 updateOomAdjLocked(r.app); 11298 } 11299 } 11300 11301 void serviceTimeout(ProcessRecord proc) { 11302 synchronized(this) { 11303 if (proc.executingServices.size() == 0 || proc.thread == null) { 11304 return; 11305 } 11306 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT; 11307 Iterator<ServiceRecord> it = proc.executingServices.iterator(); 11308 ServiceRecord timeout = null; 11309 long nextTime = 0; 11310 while (it.hasNext()) { 11311 ServiceRecord sr = it.next(); 11312 if (sr.executingStart < maxTime) { 11313 timeout = sr; 11314 break; 11315 } 11316 if (sr.executingStart > nextTime) { 11317 nextTime = sr.executingStart; 11318 } 11319 } 11320 if (timeout != null && mLRUProcesses.contains(proc)) { 11321 Log.w(TAG, "Timeout executing service: " + timeout); 11322 appNotRespondingLocked(proc, null, null, "Executing service " 11323 + timeout.name); 11324 } else { 11325 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 11326 msg.obj = proc; 11327 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT); 11328 } 11329 } 11330 } 11331 11332 // ========================================================= 11333 // BACKUP AND RESTORE 11334 // ========================================================= 11335 11336 // Cause the target app to be launched if necessary and its backup agent 11337 // instantiated. The backup agent will invoke backupAgentCreated() on the 11338 // activity manager to announce its creation. 11339 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 11340 if (DEBUG_BACKUP) Log.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 11341 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 11342 11343 synchronized(this) { 11344 // !!! TODO: currently no check here that we're already bound 11345 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 11346 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 11347 synchronized (stats) { 11348 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 11349 } 11350 11351 BackupRecord r = new BackupRecord(ss, app, backupMode); 11352 ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName); 11353 // startProcessLocked() returns existing proc's record if it's already running 11354 ProcessRecord proc = startProcessLocked(app.processName, app, 11355 false, 0, "backup", hostingName, false); 11356 if (proc == null) { 11357 Log.e(TAG, "Unable to start backup agent process " + r); 11358 return false; 11359 } 11360 11361 r.app = proc; 11362 mBackupTarget = r; 11363 mBackupAppName = app.packageName; 11364 11365 // Try not to kill the process during backup 11366 updateOomAdjLocked(proc); 11367 11368 // If the process is already attached, schedule the creation of the backup agent now. 11369 // If it is not yet live, this will be done when it attaches to the framework. 11370 if (proc.thread != null) { 11371 if (DEBUG_BACKUP) Log.v(TAG, "Agent proc already running: " + proc); 11372 try { 11373 proc.thread.scheduleCreateBackupAgent(app, backupMode); 11374 } catch (RemoteException e) { 11375 // !!! TODO: notify the backup manager that we crashed, or rely on 11376 // death notices, or...? 11377 } 11378 } else { 11379 if (DEBUG_BACKUP) Log.v(TAG, "Agent proc not running, waiting for attach"); 11380 } 11381 // Invariants: at this point, the target app process exists and the application 11382 // is either already running or in the process of coming up. mBackupTarget and 11383 // mBackupAppName describe the app, so that when it binds back to the AM we 11384 // know that it's scheduled for a backup-agent operation. 11385 } 11386 11387 return true; 11388 } 11389 11390 // A backup agent has just come up 11391 public void backupAgentCreated(String agentPackageName, IBinder agent) { 11392 if (DEBUG_BACKUP) Log.v(TAG, "backupAgentCreated: " + agentPackageName 11393 + " = " + agent); 11394 11395 synchronized(this) { 11396 if (!agentPackageName.equals(mBackupAppName)) { 11397 Log.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 11398 return; 11399 } 11400 11401 long oldIdent = Binder.clearCallingIdentity(); 11402 try { 11403 IBackupManager bm = IBackupManager.Stub.asInterface( 11404 ServiceManager.getService(Context.BACKUP_SERVICE)); 11405 bm.agentConnected(agentPackageName, agent); 11406 } catch (RemoteException e) { 11407 // can't happen; the backup manager service is local 11408 } catch (Exception e) { 11409 Log.w(TAG, "Exception trying to deliver BackupAgent binding: "); 11410 e.printStackTrace(); 11411 } finally { 11412 Binder.restoreCallingIdentity(oldIdent); 11413 } 11414 } 11415 } 11416 11417 // done with this agent 11418 public void unbindBackupAgent(ApplicationInfo appInfo) { 11419 if (DEBUG_BACKUP) Log.v(TAG, "unbindBackupAgent: " + appInfo); 11420 if (appInfo == null) { 11421 Log.w(TAG, "unbind backup agent for null app"); 11422 return; 11423 } 11424 11425 synchronized(this) { 11426 if (mBackupAppName == null) { 11427 Log.w(TAG, "Unbinding backup agent with no active backup"); 11428 return; 11429 } 11430 11431 if (!mBackupAppName.equals(appInfo.packageName)) { 11432 Log.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 11433 return; 11434 } 11435 11436 ProcessRecord proc = mBackupTarget.app; 11437 mBackupTarget = null; 11438 mBackupAppName = null; 11439 11440 // Not backing this app up any more; reset its OOM adjustment 11441 updateOomAdjLocked(proc); 11442 11443 // If the app crashed during backup, 'thread' will be null here 11444 if (proc.thread != null) { 11445 try { 11446 proc.thread.scheduleDestroyBackupAgent(appInfo); 11447 } catch (Exception e) { 11448 Log.e(TAG, "Exception when unbinding backup agent:"); 11449 e.printStackTrace(); 11450 } 11451 } 11452 } 11453 } 11454 // ========================================================= 11455 // BROADCASTS 11456 // ========================================================= 11457 11458 private final List getStickies(String action, IntentFilter filter, 11459 List cur) { 11460 final ContentResolver resolver = mContext.getContentResolver(); 11461 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 11462 if (list == null) { 11463 return cur; 11464 } 11465 int N = list.size(); 11466 for (int i=0; i<N; i++) { 11467 Intent intent = list.get(i); 11468 if (filter.match(resolver, intent, true, TAG) >= 0) { 11469 if (cur == null) { 11470 cur = new ArrayList<Intent>(); 11471 } 11472 cur.add(intent); 11473 } 11474 } 11475 return cur; 11476 } 11477 11478 private final void scheduleBroadcastsLocked() { 11479 if (DEBUG_BROADCAST) Log.v(TAG, "Schedule broadcasts: current=" 11480 + mBroadcastsScheduled); 11481 11482 if (mBroadcastsScheduled) { 11483 return; 11484 } 11485 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG); 11486 mBroadcastsScheduled = true; 11487 } 11488 11489 public Intent registerReceiver(IApplicationThread caller, 11490 IIntentReceiver receiver, IntentFilter filter, String permission) { 11491 synchronized(this) { 11492 ProcessRecord callerApp = null; 11493 if (caller != null) { 11494 callerApp = getRecordForAppLocked(caller); 11495 if (callerApp == null) { 11496 throw new SecurityException( 11497 "Unable to find app for caller " + caller 11498 + " (pid=" + Binder.getCallingPid() 11499 + ") when registering receiver " + receiver); 11500 } 11501 } 11502 11503 List allSticky = null; 11504 11505 // Look for any matching sticky broadcasts... 11506 Iterator actions = filter.actionsIterator(); 11507 if (actions != null) { 11508 while (actions.hasNext()) { 11509 String action = (String)actions.next(); 11510 allSticky = getStickies(action, filter, allSticky); 11511 } 11512 } else { 11513 allSticky = getStickies(null, filter, allSticky); 11514 } 11515 11516 // The first sticky in the list is returned directly back to 11517 // the client. 11518 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11519 11520 if (DEBUG_BROADCAST) Log.v(TAG, "Register receiver " + filter 11521 + ": " + sticky); 11522 11523 if (receiver == null) { 11524 return sticky; 11525 } 11526 11527 ReceiverList rl 11528 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11529 if (rl == null) { 11530 rl = new ReceiverList(this, callerApp, 11531 Binder.getCallingPid(), 11532 Binder.getCallingUid(), receiver); 11533 if (rl.app != null) { 11534 rl.app.receivers.add(rl); 11535 } else { 11536 try { 11537 receiver.asBinder().linkToDeath(rl, 0); 11538 } catch (RemoteException e) { 11539 return sticky; 11540 } 11541 rl.linkedToDeath = true; 11542 } 11543 mRegisteredReceivers.put(receiver.asBinder(), rl); 11544 } 11545 BroadcastFilter bf = new BroadcastFilter(filter, rl, permission); 11546 rl.add(bf); 11547 if (!bf.debugCheck()) { 11548 Log.w(TAG, "==> For Dynamic broadast"); 11549 } 11550 mReceiverResolver.addFilter(bf); 11551 11552 // Enqueue broadcasts for all existing stickies that match 11553 // this filter. 11554 if (allSticky != null) { 11555 ArrayList receivers = new ArrayList(); 11556 receivers.add(bf); 11557 11558 int N = allSticky.size(); 11559 for (int i=0; i<N; i++) { 11560 Intent intent = (Intent)allSticky.get(i); 11561 BroadcastRecord r = new BroadcastRecord(intent, null, 11562 null, -1, -1, null, receivers, null, 0, null, null, 11563 false); 11564 if (mParallelBroadcasts.size() == 0) { 11565 scheduleBroadcastsLocked(); 11566 } 11567 mParallelBroadcasts.add(r); 11568 } 11569 } 11570 11571 return sticky; 11572 } 11573 } 11574 11575 public void unregisterReceiver(IIntentReceiver receiver) { 11576 if (DEBUG_BROADCAST) Log.v(TAG, "Unregister receiver: " + receiver); 11577 11578 boolean doNext = false; 11579 11580 synchronized(this) { 11581 ReceiverList rl 11582 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11583 if (rl != null) { 11584 if (rl.curBroadcast != null) { 11585 BroadcastRecord r = rl.curBroadcast; 11586 doNext = finishReceiverLocked( 11587 receiver.asBinder(), r.resultCode, r.resultData, 11588 r.resultExtras, r.resultAbort, true); 11589 } 11590 11591 if (rl.app != null) { 11592 rl.app.receivers.remove(rl); 11593 } 11594 removeReceiverLocked(rl); 11595 if (rl.linkedToDeath) { 11596 rl.linkedToDeath = false; 11597 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11598 } 11599 } 11600 } 11601 11602 if (!doNext) { 11603 return; 11604 } 11605 11606 final long origId = Binder.clearCallingIdentity(); 11607 processNextBroadcast(false); 11608 trimApplications(); 11609 Binder.restoreCallingIdentity(origId); 11610 } 11611 11612 void removeReceiverLocked(ReceiverList rl) { 11613 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11614 int N = rl.size(); 11615 for (int i=0; i<N; i++) { 11616 mReceiverResolver.removeFilter(rl.get(i)); 11617 } 11618 } 11619 11620 private final int broadcastIntentLocked(ProcessRecord callerApp, 11621 String callerPackage, Intent intent, String resolvedType, 11622 IIntentReceiver resultTo, int resultCode, String resultData, 11623 Bundle map, String requiredPermission, 11624 boolean ordered, boolean sticky, int callingPid, int callingUid) { 11625 intent = new Intent(intent); 11626 11627 if (DEBUG_BROADCAST_LIGHT) Log.v( 11628 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11629 + " ordered=" + ordered); 11630 if ((resultTo != null) && !ordered) { 11631 Log.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11632 } 11633 11634 // Handle special intents: if this broadcast is from the package 11635 // manager about a package being removed, we need to remove all of 11636 // its activities from the history stack. 11637 final boolean uidRemoved = intent.ACTION_UID_REMOVED.equals( 11638 intent.getAction()); 11639 if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11640 || intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11641 || uidRemoved) { 11642 if (checkComponentPermission( 11643 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11644 callingPid, callingUid, -1) 11645 == PackageManager.PERMISSION_GRANTED) { 11646 if (uidRemoved) { 11647 final Bundle intentExtras = intent.getExtras(); 11648 final int uid = intentExtras != null 11649 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11650 if (uid >= 0) { 11651 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11652 synchronized (bs) { 11653 bs.removeUidStatsLocked(uid); 11654 } 11655 } 11656 } else { 11657 Uri data = intent.getData(); 11658 String ssp; 11659 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11660 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11661 uninstallPackageLocked(ssp, 11662 intent.getIntExtra(Intent.EXTRA_UID, -1), false); 11663 AttributeCache ac = AttributeCache.instance(); 11664 if (ac != null) { 11665 ac.removePackage(ssp); 11666 } 11667 } 11668 } 11669 } 11670 } else { 11671 String msg = "Permission Denial: " + intent.getAction() 11672 + " broadcast from " + callerPackage + " (pid=" + callingPid 11673 + ", uid=" + callingUid + ")" 11674 + " requires " 11675 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11676 Log.w(TAG, msg); 11677 throw new SecurityException(msg); 11678 } 11679 } 11680 11681 /* 11682 * If this is the time zone changed action, queue up a message that will reset the timezone 11683 * of all currently running processes. This message will get queued up before the broadcast 11684 * happens. 11685 */ 11686 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11687 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11688 } 11689 11690 /* 11691 * Prevent non-system code (defined here to be non-persistent 11692 * processes) from sending protected broadcasts. 11693 */ 11694 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11695 || callingUid == Process.SHELL_UID || callingUid == 0) { 11696 // Always okay. 11697 } else if (callerApp == null || !callerApp.persistent) { 11698 try { 11699 if (ActivityThread.getPackageManager().isProtectedBroadcast( 11700 intent.getAction())) { 11701 String msg = "Permission Denial: not allowed to send broadcast " 11702 + intent.getAction() + " from pid=" 11703 + callingPid + ", uid=" + callingUid; 11704 Log.w(TAG, msg); 11705 throw new SecurityException(msg); 11706 } 11707 } catch (RemoteException e) { 11708 Log.w(TAG, "Remote exception", e); 11709 return BROADCAST_SUCCESS; 11710 } 11711 } 11712 11713 // Add to the sticky list if requested. 11714 if (sticky) { 11715 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 11716 callingPid, callingUid) 11717 != PackageManager.PERMISSION_GRANTED) { 11718 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 11719 + callingPid + ", uid=" + callingUid 11720 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11721 Log.w(TAG, msg); 11722 throw new SecurityException(msg); 11723 } 11724 if (requiredPermission != null) { 11725 Log.w(TAG, "Can't broadcast sticky intent " + intent 11726 + " and enforce permission " + requiredPermission); 11727 return BROADCAST_STICKY_CANT_HAVE_PERMISSION; 11728 } 11729 if (intent.getComponent() != null) { 11730 throw new SecurityException( 11731 "Sticky broadcasts can't target a specific component"); 11732 } 11733 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11734 if (list == null) { 11735 list = new ArrayList<Intent>(); 11736 mStickyBroadcasts.put(intent.getAction(), list); 11737 } 11738 int N = list.size(); 11739 int i; 11740 for (i=0; i<N; i++) { 11741 if (intent.filterEquals(list.get(i))) { 11742 // This sticky already exists, replace it. 11743 list.set(i, new Intent(intent)); 11744 break; 11745 } 11746 } 11747 if (i >= N) { 11748 list.add(new Intent(intent)); 11749 } 11750 } 11751 11752 // Figure out who all will receive this broadcast. 11753 List receivers = null; 11754 List<BroadcastFilter> registeredReceivers = null; 11755 try { 11756 if (intent.getComponent() != null) { 11757 // Broadcast is going to one specific receiver class... 11758 ActivityInfo ai = ActivityThread.getPackageManager(). 11759 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS); 11760 if (ai != null) { 11761 receivers = new ArrayList(); 11762 ResolveInfo ri = new ResolveInfo(); 11763 ri.activityInfo = ai; 11764 receivers.add(ri); 11765 } 11766 } else { 11767 // Need to resolve the intent to interested receivers... 11768 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 11769 == 0) { 11770 receivers = 11771 ActivityThread.getPackageManager().queryIntentReceivers( 11772 intent, resolvedType, STOCK_PM_FLAGS); 11773 } 11774 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false); 11775 } 11776 } catch (RemoteException ex) { 11777 // pm is in same process, this will never happen. 11778 } 11779 11780 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 11781 if (!ordered && NR > 0) { 11782 // If we are not serializing this broadcast, then send the 11783 // registered receivers separately so they don't wait for the 11784 // components to be launched. 11785 BroadcastRecord r = new BroadcastRecord(intent, callerApp, 11786 callerPackage, callingPid, callingUid, requiredPermission, 11787 registeredReceivers, resultTo, resultCode, resultData, map, 11788 ordered); 11789 if (DEBUG_BROADCAST) Log.v( 11790 TAG, "Enqueueing parallel broadcast " + r 11791 + ": prev had " + mParallelBroadcasts.size()); 11792 mParallelBroadcasts.add(r); 11793 scheduleBroadcastsLocked(); 11794 registeredReceivers = null; 11795 NR = 0; 11796 } 11797 11798 // Merge into one list. 11799 int ir = 0; 11800 if (receivers != null) { 11801 // A special case for PACKAGE_ADDED: do not allow the package 11802 // being added to see this broadcast. This prevents them from 11803 // using this as a back door to get run as soon as they are 11804 // installed. Maybe in the future we want to have a special install 11805 // broadcast or such for apps, but we'd like to deliberately make 11806 // this decision. 11807 boolean skip = false; 11808 if (intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 11809 skip = true; 11810 } else if (intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())) { 11811 skip = true; 11812 } else if (intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 11813 skip = true; 11814 } 11815 String skipPackage = (skip && intent.getData() != null) 11816 ? intent.getData().getSchemeSpecificPart() 11817 : null; 11818 if (skipPackage != null && receivers != null) { 11819 int NT = receivers.size(); 11820 for (int it=0; it<NT; it++) { 11821 ResolveInfo curt = (ResolveInfo)receivers.get(it); 11822 if (curt.activityInfo.packageName.equals(skipPackage)) { 11823 receivers.remove(it); 11824 it--; 11825 NT--; 11826 } 11827 } 11828 } 11829 11830 int NT = receivers != null ? receivers.size() : 0; 11831 int it = 0; 11832 ResolveInfo curt = null; 11833 BroadcastFilter curr = null; 11834 while (it < NT && ir < NR) { 11835 if (curt == null) { 11836 curt = (ResolveInfo)receivers.get(it); 11837 } 11838 if (curr == null) { 11839 curr = registeredReceivers.get(ir); 11840 } 11841 if (curr.getPriority() >= curt.priority) { 11842 // Insert this broadcast record into the final list. 11843 receivers.add(it, curr); 11844 ir++; 11845 curr = null; 11846 it++; 11847 NT++; 11848 } else { 11849 // Skip to the next ResolveInfo in the final list. 11850 it++; 11851 curt = null; 11852 } 11853 } 11854 } 11855 while (ir < NR) { 11856 if (receivers == null) { 11857 receivers = new ArrayList(); 11858 } 11859 receivers.add(registeredReceivers.get(ir)); 11860 ir++; 11861 } 11862 11863 if ((receivers != null && receivers.size() > 0) 11864 || resultTo != null) { 11865 BroadcastRecord r = new BroadcastRecord(intent, callerApp, 11866 callerPackage, callingPid, callingUid, requiredPermission, 11867 receivers, resultTo, resultCode, resultData, map, ordered); 11868 if (DEBUG_BROADCAST) Log.v( 11869 TAG, "Enqueueing ordered broadcast " + r 11870 + ": prev had " + mOrderedBroadcasts.size()); 11871 if (DEBUG_BROADCAST) { 11872 int seq = r.intent.getIntExtra("seq", -1); 11873 Log.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 11874 } 11875 mOrderedBroadcasts.add(r); 11876 scheduleBroadcastsLocked(); 11877 } 11878 11879 return BROADCAST_SUCCESS; 11880 } 11881 11882 public final int broadcastIntent(IApplicationThread caller, 11883 Intent intent, String resolvedType, IIntentReceiver resultTo, 11884 int resultCode, String resultData, Bundle map, 11885 String requiredPermission, boolean serialized, boolean sticky) { 11886 // Refuse possible leaked file descriptors 11887 if (intent != null && intent.hasFileDescriptors() == true) { 11888 throw new IllegalArgumentException("File descriptors passed in Intent"); 11889 } 11890 11891 synchronized(this) { 11892 int flags = intent.getFlags(); 11893 11894 if (!mSystemReady) { 11895 // if the caller really truly claims to know what they're doing, go 11896 // ahead and allow the broadcast without launching any receivers 11897 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 11898 intent = new Intent(intent); 11899 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11900 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0){ 11901 Log.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 11902 + " before boot completion"); 11903 throw new IllegalStateException("Cannot broadcast before boot completed"); 11904 } 11905 } 11906 11907 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 11908 throw new IllegalArgumentException( 11909 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 11910 } 11911 11912 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11913 final int callingPid = Binder.getCallingPid(); 11914 final int callingUid = Binder.getCallingUid(); 11915 final long origId = Binder.clearCallingIdentity(); 11916 int res = broadcastIntentLocked(callerApp, 11917 callerApp != null ? callerApp.info.packageName : null, 11918 intent, resolvedType, resultTo, 11919 resultCode, resultData, map, requiredPermission, serialized, 11920 sticky, callingPid, callingUid); 11921 Binder.restoreCallingIdentity(origId); 11922 return res; 11923 } 11924 } 11925 11926 int broadcastIntentInPackage(String packageName, int uid, 11927 Intent intent, String resolvedType, IIntentReceiver resultTo, 11928 int resultCode, String resultData, Bundle map, 11929 String requiredPermission, boolean serialized, boolean sticky) { 11930 synchronized(this) { 11931 final long origId = Binder.clearCallingIdentity(); 11932 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 11933 resultTo, resultCode, resultData, map, requiredPermission, 11934 serialized, sticky, -1, uid); 11935 Binder.restoreCallingIdentity(origId); 11936 return res; 11937 } 11938 } 11939 11940 public final void unbroadcastIntent(IApplicationThread caller, 11941 Intent intent) { 11942 // Refuse possible leaked file descriptors 11943 if (intent != null && intent.hasFileDescriptors() == true) { 11944 throw new IllegalArgumentException("File descriptors passed in Intent"); 11945 } 11946 11947 synchronized(this) { 11948 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 11949 != PackageManager.PERMISSION_GRANTED) { 11950 String msg = "Permission Denial: unbroadcastIntent() from pid=" 11951 + Binder.getCallingPid() 11952 + ", uid=" + Binder.getCallingUid() 11953 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 11954 Log.w(TAG, msg); 11955 throw new SecurityException(msg); 11956 } 11957 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 11958 if (list != null) { 11959 int N = list.size(); 11960 int i; 11961 for (i=0; i<N; i++) { 11962 if (intent.filterEquals(list.get(i))) { 11963 list.remove(i); 11964 break; 11965 } 11966 } 11967 } 11968 } 11969 } 11970 11971 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 11972 String resultData, Bundle resultExtras, boolean resultAbort, 11973 boolean explicit) { 11974 if (mOrderedBroadcasts.size() == 0) { 11975 if (explicit) { 11976 Log.w(TAG, "finishReceiver called but no pending broadcasts"); 11977 } 11978 return false; 11979 } 11980 BroadcastRecord r = mOrderedBroadcasts.get(0); 11981 if (r.receiver == null) { 11982 if (explicit) { 11983 Log.w(TAG, "finishReceiver called but none active"); 11984 } 11985 return false; 11986 } 11987 if (r.receiver != receiver) { 11988 Log.w(TAG, "finishReceiver called but active receiver is different"); 11989 return false; 11990 } 11991 int state = r.state; 11992 r.state = r.IDLE; 11993 if (state == r.IDLE) { 11994 if (explicit) { 11995 Log.w(TAG, "finishReceiver called but state is IDLE"); 11996 } 11997 } 11998 r.receiver = null; 11999 r.intent.setComponent(null); 12000 if (r.curApp != null) { 12001 r.curApp.curReceiver = null; 12002 } 12003 if (r.curFilter != null) { 12004 r.curFilter.receiverList.curBroadcast = null; 12005 } 12006 r.curFilter = null; 12007 r.curApp = null; 12008 r.curComponent = null; 12009 r.curReceiver = null; 12010 mPendingBroadcast = null; 12011 12012 r.resultCode = resultCode; 12013 r.resultData = resultData; 12014 r.resultExtras = resultExtras; 12015 r.resultAbort = resultAbort; 12016 12017 // We will process the next receiver right now if this is finishing 12018 // an app receiver (which is always asynchronous) or after we have 12019 // come back from calling a receiver. 12020 return state == BroadcastRecord.APP_RECEIVE 12021 || state == BroadcastRecord.CALL_DONE_RECEIVE; 12022 } 12023 12024 public void finishReceiver(IBinder who, int resultCode, String resultData, 12025 Bundle resultExtras, boolean resultAbort) { 12026 if (DEBUG_BROADCAST) Log.v(TAG, "Finish receiver: " + who); 12027 12028 // Refuse possible leaked file descriptors 12029 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 12030 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12031 } 12032 12033 boolean doNext; 12034 12035 final long origId = Binder.clearCallingIdentity(); 12036 12037 synchronized(this) { 12038 doNext = finishReceiverLocked( 12039 who, resultCode, resultData, resultExtras, resultAbort, true); 12040 } 12041 12042 if (doNext) { 12043 processNextBroadcast(false); 12044 } 12045 trimApplications(); 12046 12047 Binder.restoreCallingIdentity(origId); 12048 } 12049 12050 private final void logBroadcastReceiverDiscard(BroadcastRecord r) { 12051 if (r.nextReceiver > 0) { 12052 Object curReceiver = r.receivers.get(r.nextReceiver-1); 12053 if (curReceiver instanceof BroadcastFilter) { 12054 BroadcastFilter bf = (BroadcastFilter) curReceiver; 12055 EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_FILTER, 12056 System.identityHashCode(r), 12057 r.intent.getAction(), 12058 r.nextReceiver - 1, 12059 System.identityHashCode(bf)); 12060 } else { 12061 EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_APP, 12062 System.identityHashCode(r), 12063 r.intent.getAction(), 12064 r.nextReceiver - 1, 12065 ((ResolveInfo)curReceiver).toString()); 12066 } 12067 } else { 12068 Log.w(TAG, "Discarding broadcast before first receiver is invoked: " 12069 + r); 12070 EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_APP, 12071 System.identityHashCode(r), 12072 r.intent.getAction(), 12073 r.nextReceiver, 12074 "NONE"); 12075 } 12076 } 12077 12078 private final void broadcastTimeout() { 12079 synchronized (this) { 12080 if (mOrderedBroadcasts.size() == 0) { 12081 return; 12082 } 12083 long now = SystemClock.uptimeMillis(); 12084 BroadcastRecord r = mOrderedBroadcasts.get(0); 12085 if ((r.startTime+BROADCAST_TIMEOUT) > now) { 12086 if (DEBUG_BROADCAST) Log.v(TAG, 12087 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for " 12088 + (r.startTime + BROADCAST_TIMEOUT)); 12089 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG); 12090 mHandler.sendMessageAtTime(msg, r.startTime+BROADCAST_TIMEOUT); 12091 return; 12092 } 12093 12094 Log.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver); 12095 r.startTime = now; 12096 r.anrCount++; 12097 12098 // Current receiver has passed its expiration date. 12099 if (r.nextReceiver <= 0) { 12100 Log.w(TAG, "Timeout on receiver with nextReceiver <= 0"); 12101 return; 12102 } 12103 12104 ProcessRecord app = null; 12105 12106 Object curReceiver = r.receivers.get(r.nextReceiver-1); 12107 Log.w(TAG, "Receiver during timeout: " + curReceiver); 12108 logBroadcastReceiverDiscard(r); 12109 if (curReceiver instanceof BroadcastFilter) { 12110 BroadcastFilter bf = (BroadcastFilter)curReceiver; 12111 if (bf.receiverList.pid != 0 12112 && bf.receiverList.pid != MY_PID) { 12113 synchronized (this.mPidsSelfLocked) { 12114 app = this.mPidsSelfLocked.get( 12115 bf.receiverList.pid); 12116 } 12117 } 12118 } else { 12119 app = r.curApp; 12120 } 12121 12122 if (app != null) { 12123 appNotRespondingLocked(app, null, null, 12124 "Broadcast of " + r.intent.toString()); 12125 } 12126 12127 if (mPendingBroadcast == r) { 12128 mPendingBroadcast = null; 12129 } 12130 12131 // Move on to the next receiver. 12132 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 12133 r.resultExtras, r.resultAbort, true); 12134 scheduleBroadcastsLocked(); 12135 } 12136 } 12137 12138 private final void processCurBroadcastLocked(BroadcastRecord r, 12139 ProcessRecord app) throws RemoteException { 12140 if (app.thread == null) { 12141 throw new RemoteException(); 12142 } 12143 r.receiver = app.thread.asBinder(); 12144 r.curApp = app; 12145 app.curReceiver = r; 12146 updateLRUListLocked(app, true); 12147 12148 // Tell the application to launch this receiver. 12149 r.intent.setComponent(r.curComponent); 12150 12151 boolean started = false; 12152 try { 12153 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, 12154 "Delivering to component " + r.curComponent 12155 + ": " + r); 12156 ensurePackageDexOpt(r.intent.getComponent().getPackageName()); 12157 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver, 12158 r.resultCode, r.resultData, r.resultExtras, r.ordered); 12159 started = true; 12160 } finally { 12161 if (!started) { 12162 r.receiver = null; 12163 r.curApp = null; 12164 app.curReceiver = null; 12165 } 12166 } 12167 12168 } 12169 12170 static void performReceive(ProcessRecord app, IIntentReceiver receiver, 12171 Intent intent, int resultCode, String data, 12172 Bundle extras, boolean ordered) throws RemoteException { 12173 if (app != null && app.thread != null) { 12174 // If we have an app thread, do the call through that so it is 12175 // correctly ordered with other one-way calls. 12176 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode, 12177 data, extras, ordered); 12178 } else { 12179 receiver.performReceive(intent, resultCode, data, extras, ordered); 12180 } 12181 } 12182 12183 private final void deliverToRegisteredReceiver(BroadcastRecord r, 12184 BroadcastFilter filter, boolean ordered) { 12185 boolean skip = false; 12186 if (filter.requiredPermission != null) { 12187 int perm = checkComponentPermission(filter.requiredPermission, 12188 r.callingPid, r.callingUid, -1); 12189 if (perm != PackageManager.PERMISSION_GRANTED) { 12190 Log.w(TAG, "Permission Denial: broadcasting " 12191 + r.intent.toString() 12192 + " from " + r.callerPackage + " (pid=" 12193 + r.callingPid + ", uid=" + r.callingUid + ")" 12194 + " requires " + filter.requiredPermission 12195 + " due to registered receiver " + filter); 12196 skip = true; 12197 } 12198 } 12199 if (r.requiredPermission != null) { 12200 int perm = checkComponentPermission(r.requiredPermission, 12201 filter.receiverList.pid, filter.receiverList.uid, -1); 12202 if (perm != PackageManager.PERMISSION_GRANTED) { 12203 Log.w(TAG, "Permission Denial: receiving " 12204 + r.intent.toString() 12205 + " to " + filter.receiverList.app 12206 + " (pid=" + filter.receiverList.pid 12207 + ", uid=" + filter.receiverList.uid + ")" 12208 + " requires " + r.requiredPermission 12209 + " due to sender " + r.callerPackage 12210 + " (uid " + r.callingUid + ")"); 12211 skip = true; 12212 } 12213 } 12214 12215 if (!skip) { 12216 // If this is not being sent as an ordered broadcast, then we 12217 // don't want to touch the fields that keep track of the current 12218 // state of ordered broadcasts. 12219 if (ordered) { 12220 r.receiver = filter.receiverList.receiver.asBinder(); 12221 r.curFilter = filter; 12222 filter.receiverList.curBroadcast = r; 12223 r.state = BroadcastRecord.CALL_IN_RECEIVE; 12224 if (filter.receiverList.app != null) { 12225 // Bump hosting application to no longer be in background 12226 // scheduling class. Note that we can't do that if there 12227 // isn't an app... but we can only be in that case for 12228 // things that directly call the IActivityManager API, which 12229 // are already core system stuff so don't matter for this. 12230 r.curApp = filter.receiverList.app; 12231 filter.receiverList.app.curReceiver = r; 12232 updateOomAdjLocked(); 12233 } 12234 } 12235 try { 12236 if (DEBUG_BROADCAST_LIGHT) { 12237 int seq = r.intent.getIntExtra("seq", -1); 12238 Log.i(TAG, "Delivering to " + filter.receiverList.app 12239 + " (seq=" + seq + "): " + r); 12240 } 12241 performReceive(filter.receiverList.app, filter.receiverList.receiver, 12242 new Intent(r.intent), r.resultCode, 12243 r.resultData, r.resultExtras, r.ordered); 12244 if (ordered) { 12245 r.state = BroadcastRecord.CALL_DONE_RECEIVE; 12246 } 12247 } catch (RemoteException e) { 12248 Log.w(TAG, "Failure sending broadcast " + r.intent, e); 12249 if (ordered) { 12250 r.receiver = null; 12251 r.curFilter = null; 12252 filter.receiverList.curBroadcast = null; 12253 if (filter.receiverList.app != null) { 12254 filter.receiverList.app.curReceiver = null; 12255 } 12256 } 12257 } 12258 } 12259 } 12260 12261 private final void processNextBroadcast(boolean fromMsg) { 12262 synchronized(this) { 12263 BroadcastRecord r; 12264 12265 if (DEBUG_BROADCAST) Log.v(TAG, "processNextBroadcast: " 12266 + mParallelBroadcasts.size() + " broadcasts, " 12267 + mOrderedBroadcasts.size() + " serialized broadcasts"); 12268 12269 updateCpuStats(); 12270 12271 if (fromMsg) { 12272 mBroadcastsScheduled = false; 12273 } 12274 12275 // First, deliver any non-serialized broadcasts right away. 12276 while (mParallelBroadcasts.size() > 0) { 12277 r = mParallelBroadcasts.remove(0); 12278 final int N = r.receivers.size(); 12279 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Processing parallel broadcast " 12280 + r); 12281 for (int i=0; i<N; i++) { 12282 Object target = r.receivers.get(i); 12283 if (DEBUG_BROADCAST) Log.v(TAG, 12284 "Delivering non-serialized to registered " 12285 + target + ": " + r); 12286 deliverToRegisteredReceiver(r, (BroadcastFilter)target, false); 12287 } 12288 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Done with parallel broadcast " 12289 + r); 12290 } 12291 12292 // Now take care of the next serialized one... 12293 12294 // If we are waiting for a process to come up to handle the next 12295 // broadcast, then do nothing at this point. Just in case, we 12296 // check that the process we're waiting for still exists. 12297 if (mPendingBroadcast != null) { 12298 Log.i(TAG, "processNextBroadcast: waiting for " 12299 + mPendingBroadcast.curApp); 12300 12301 boolean isDead; 12302 synchronized (mPidsSelfLocked) { 12303 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null); 12304 } 12305 if (!isDead) { 12306 // It's still alive, so keep waiting 12307 return; 12308 } else { 12309 Log.w(TAG, "pending app " + mPendingBroadcast.curApp 12310 + " died before responding to broadcast"); 12311 mPendingBroadcast = null; 12312 } 12313 } 12314 12315 boolean looped = false; 12316 12317 do { 12318 if (mOrderedBroadcasts.size() == 0) { 12319 // No more broadcasts pending, so all done! 12320 scheduleAppGcsLocked(); 12321 if (looped) { 12322 // If we had finished the last ordered broadcast, then 12323 // make sure all processes have correct oom and sched 12324 // adjustments. 12325 updateOomAdjLocked(); 12326 } 12327 return; 12328 } 12329 r = mOrderedBroadcasts.get(0); 12330 boolean forceReceive = false; 12331 12332 // Ensure that even if something goes awry with the timeout 12333 // detection, we catch "hung" broadcasts here, discard them, 12334 // and continue to make progress. 12335 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0; 12336 long now = SystemClock.uptimeMillis(); 12337 if (r.dispatchTime > 0) { 12338 if ((numReceivers > 0) && 12339 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) { 12340 Log.w(TAG, "Hung broadcast discarded after timeout failure:" 12341 + " now=" + now 12342 + " dispatchTime=" + r.dispatchTime 12343 + " startTime=" + r.startTime 12344 + " intent=" + r.intent 12345 + " numReceivers=" + numReceivers 12346 + " nextReceiver=" + r.nextReceiver 12347 + " state=" + r.state); 12348 broadcastTimeout(); // forcibly finish this broadcast 12349 forceReceive = true; 12350 r.state = BroadcastRecord.IDLE; 12351 } 12352 } 12353 12354 if (r.state != BroadcastRecord.IDLE) { 12355 if (DEBUG_BROADCAST) Log.d(TAG, 12356 "processNextBroadcast() called when not idle (state=" 12357 + r.state + ")"); 12358 return; 12359 } 12360 12361 if (r.receivers == null || r.nextReceiver >= numReceivers 12362 || r.resultAbort || forceReceive) { 12363 // No more receivers for this broadcast! Send the final 12364 // result if requested... 12365 if (r.resultTo != null) { 12366 try { 12367 if (DEBUG_BROADCAST) { 12368 int seq = r.intent.getIntExtra("seq", -1); 12369 Log.i(TAG, "Finishing broadcast " + r.intent.getAction() 12370 + " seq=" + seq + " app=" + r.callerApp); 12371 } 12372 performReceive(r.callerApp, r.resultTo, 12373 new Intent(r.intent), r.resultCode, 12374 r.resultData, r.resultExtras, false); 12375 } catch (RemoteException e) { 12376 Log.w(TAG, "Failure sending broadcast result of " + r.intent, e); 12377 } 12378 } 12379 12380 if (DEBUG_BROADCAST) Log.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG"); 12381 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG); 12382 12383 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Finished with ordered broadcast " 12384 + r); 12385 12386 // ... and on to the next... 12387 mOrderedBroadcasts.remove(0); 12388 r = null; 12389 looped = true; 12390 continue; 12391 } 12392 } while (r == null); 12393 12394 // Get the next receiver... 12395 int recIdx = r.nextReceiver++; 12396 12397 // Keep track of when this receiver started, and make sure there 12398 // is a timeout message pending to kill it if need be. 12399 r.startTime = SystemClock.uptimeMillis(); 12400 if (recIdx == 0) { 12401 r.dispatchTime = r.startTime; 12402 12403 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Processing ordered broadcast " 12404 + r); 12405 if (DEBUG_BROADCAST) Log.v(TAG, 12406 "Submitting BROADCAST_TIMEOUT_MSG for " 12407 + (r.startTime + BROADCAST_TIMEOUT)); 12408 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG); 12409 mHandler.sendMessageAtTime(msg, r.startTime+BROADCAST_TIMEOUT); 12410 } 12411 12412 Object nextReceiver = r.receivers.get(recIdx); 12413 if (nextReceiver instanceof BroadcastFilter) { 12414 // Simple case: this is a registered receiver who gets 12415 // a direct call. 12416 BroadcastFilter filter = (BroadcastFilter)nextReceiver; 12417 if (DEBUG_BROADCAST) Log.v(TAG, 12418 "Delivering serialized to registered " 12419 + filter + ": " + r); 12420 deliverToRegisteredReceiver(r, filter, r.ordered); 12421 if (r.receiver == null || !r.ordered) { 12422 // The receiver has already finished, so schedule to 12423 // process the next one. 12424 r.state = BroadcastRecord.IDLE; 12425 scheduleBroadcastsLocked(); 12426 } 12427 return; 12428 } 12429 12430 // Hard case: need to instantiate the receiver, possibly 12431 // starting its application process to host it. 12432 12433 ResolveInfo info = 12434 (ResolveInfo)nextReceiver; 12435 12436 boolean skip = false; 12437 int perm = checkComponentPermission(info.activityInfo.permission, 12438 r.callingPid, r.callingUid, 12439 info.activityInfo.exported 12440 ? -1 : info.activityInfo.applicationInfo.uid); 12441 if (perm != PackageManager.PERMISSION_GRANTED) { 12442 Log.w(TAG, "Permission Denial: broadcasting " 12443 + r.intent.toString() 12444 + " from " + r.callerPackage + " (pid=" + r.callingPid 12445 + ", uid=" + r.callingUid + ")" 12446 + " requires " + info.activityInfo.permission 12447 + " due to receiver " + info.activityInfo.packageName 12448 + "/" + info.activityInfo.name); 12449 skip = true; 12450 } 12451 if (r.callingUid != Process.SYSTEM_UID && 12452 r.requiredPermission != null) { 12453 try { 12454 perm = ActivityThread.getPackageManager(). 12455 checkPermission(r.requiredPermission, 12456 info.activityInfo.applicationInfo.packageName); 12457 } catch (RemoteException e) { 12458 perm = PackageManager.PERMISSION_DENIED; 12459 } 12460 if (perm != PackageManager.PERMISSION_GRANTED) { 12461 Log.w(TAG, "Permission Denial: receiving " 12462 + r.intent + " to " 12463 + info.activityInfo.applicationInfo.packageName 12464 + " requires " + r.requiredPermission 12465 + " due to sender " + r.callerPackage 12466 + " (uid " + r.callingUid + ")"); 12467 skip = true; 12468 } 12469 } 12470 if (r.curApp != null && r.curApp.crashing) { 12471 // If the target process is crashing, just skip it. 12472 skip = true; 12473 } 12474 12475 if (skip) { 12476 r.receiver = null; 12477 r.curFilter = null; 12478 r.state = BroadcastRecord.IDLE; 12479 scheduleBroadcastsLocked(); 12480 return; 12481 } 12482 12483 r.state = BroadcastRecord.APP_RECEIVE; 12484 String targetProcess = info.activityInfo.processName; 12485 r.curComponent = new ComponentName( 12486 info.activityInfo.applicationInfo.packageName, 12487 info.activityInfo.name); 12488 r.curReceiver = info.activityInfo; 12489 12490 // Is this receiver's application already running? 12491 ProcessRecord app = getProcessRecordLocked(targetProcess, 12492 info.activityInfo.applicationInfo.uid); 12493 if (app != null && app.thread != null) { 12494 try { 12495 processCurBroadcastLocked(r, app); 12496 return; 12497 } catch (RemoteException e) { 12498 Log.w(TAG, "Exception when sending broadcast to " 12499 + r.curComponent, e); 12500 } 12501 12502 // If a dead object exception was thrown -- fall through to 12503 // restart the application. 12504 } 12505 12506 // Not running -- get it started, to be executed when the app comes up. 12507 if ((r.curApp=startProcessLocked(targetProcess, 12508 info.activityInfo.applicationInfo, true, 12509 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND, 12510 "broadcast", r.curComponent, 12511 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0)) 12512 == null) { 12513 // Ah, this recipient is unavailable. Finish it if necessary, 12514 // and mark the broadcast record as ready for the next. 12515 Log.w(TAG, "Unable to launch app " 12516 + info.activityInfo.applicationInfo.packageName + "/" 12517 + info.activityInfo.applicationInfo.uid + " for broadcast " 12518 + r.intent + ": process is bad"); 12519 logBroadcastReceiverDiscard(r); 12520 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 12521 r.resultExtras, r.resultAbort, true); 12522 scheduleBroadcastsLocked(); 12523 r.state = BroadcastRecord.IDLE; 12524 return; 12525 } 12526 12527 mPendingBroadcast = r; 12528 } 12529 } 12530 12531 // ========================================================= 12532 // INSTRUMENTATION 12533 // ========================================================= 12534 12535 public boolean startInstrumentation(ComponentName className, 12536 String profileFile, int flags, Bundle arguments, 12537 IInstrumentationWatcher watcher) { 12538 // Refuse possible leaked file descriptors 12539 if (arguments != null && arguments.hasFileDescriptors()) { 12540 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12541 } 12542 12543 synchronized(this) { 12544 InstrumentationInfo ii = null; 12545 ApplicationInfo ai = null; 12546 try { 12547 ii = mContext.getPackageManager().getInstrumentationInfo( 12548 className, STOCK_PM_FLAGS); 12549 ai = mContext.getPackageManager().getApplicationInfo( 12550 ii.targetPackage, STOCK_PM_FLAGS); 12551 } catch (PackageManager.NameNotFoundException e) { 12552 } 12553 if (ii == null) { 12554 reportStartInstrumentationFailure(watcher, className, 12555 "Unable to find instrumentation info for: " + className); 12556 return false; 12557 } 12558 if (ai == null) { 12559 reportStartInstrumentationFailure(watcher, className, 12560 "Unable to find instrumentation target package: " + ii.targetPackage); 12561 return false; 12562 } 12563 12564 int match = mContext.getPackageManager().checkSignatures( 12565 ii.targetPackage, ii.packageName); 12566 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 12567 String msg = "Permission Denial: starting instrumentation " 12568 + className + " from pid=" 12569 + Binder.getCallingPid() 12570 + ", uid=" + Binder.getCallingPid() 12571 + " not allowed because package " + ii.packageName 12572 + " does not have a signature matching the target " 12573 + ii.targetPackage; 12574 reportStartInstrumentationFailure(watcher, className, msg); 12575 throw new SecurityException(msg); 12576 } 12577 12578 final long origId = Binder.clearCallingIdentity(); 12579 uninstallPackageLocked(ii.targetPackage, -1, true); 12580 ProcessRecord app = addAppLocked(ai); 12581 app.instrumentationClass = className; 12582 app.instrumentationInfo = ai; 12583 app.instrumentationProfileFile = profileFile; 12584 app.instrumentationArguments = arguments; 12585 app.instrumentationWatcher = watcher; 12586 app.instrumentationResultClass = className; 12587 Binder.restoreCallingIdentity(origId); 12588 } 12589 12590 return true; 12591 } 12592 12593 /** 12594 * Report errors that occur while attempting to start Instrumentation. Always writes the 12595 * error to the logs, but if somebody is watching, send the report there too. This enables 12596 * the "am" command to report errors with more information. 12597 * 12598 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 12599 * @param cn The component name of the instrumentation. 12600 * @param report The error report. 12601 */ 12602 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 12603 ComponentName cn, String report) { 12604 Log.w(TAG, report); 12605 try { 12606 if (watcher != null) { 12607 Bundle results = new Bundle(); 12608 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 12609 results.putString("Error", report); 12610 watcher.instrumentationStatus(cn, -1, results); 12611 } 12612 } catch (RemoteException e) { 12613 Log.w(TAG, e); 12614 } 12615 } 12616 12617 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 12618 if (app.instrumentationWatcher != null) { 12619 try { 12620 // NOTE: IInstrumentationWatcher *must* be oneway here 12621 app.instrumentationWatcher.instrumentationFinished( 12622 app.instrumentationClass, 12623 resultCode, 12624 results); 12625 } catch (RemoteException e) { 12626 } 12627 } 12628 app.instrumentationWatcher = null; 12629 app.instrumentationClass = null; 12630 app.instrumentationInfo = null; 12631 app.instrumentationProfileFile = null; 12632 app.instrumentationArguments = null; 12633 12634 uninstallPackageLocked(app.processName, -1, false); 12635 } 12636 12637 public void finishInstrumentation(IApplicationThread target, 12638 int resultCode, Bundle results) { 12639 // Refuse possible leaked file descriptors 12640 if (results != null && results.hasFileDescriptors()) { 12641 throw new IllegalArgumentException("File descriptors passed in Intent"); 12642 } 12643 12644 synchronized(this) { 12645 ProcessRecord app = getRecordForAppLocked(target); 12646 if (app == null) { 12647 Log.w(TAG, "finishInstrumentation: no app for " + target); 12648 return; 12649 } 12650 final long origId = Binder.clearCallingIdentity(); 12651 finishInstrumentationLocked(app, resultCode, results); 12652 Binder.restoreCallingIdentity(origId); 12653 } 12654 } 12655 12656 // ========================================================= 12657 // CONFIGURATION 12658 // ========================================================= 12659 12660 public ConfigurationInfo getDeviceConfigurationInfo() { 12661 ConfigurationInfo config = new ConfigurationInfo(); 12662 synchronized (this) { 12663 config.reqTouchScreen = mConfiguration.touchscreen; 12664 config.reqKeyboardType = mConfiguration.keyboard; 12665 config.reqNavigation = mConfiguration.navigation; 12666 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 12667 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 12668 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 12669 } 12670 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 12671 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 12672 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 12673 } 12674 config.reqGlEsVersion = GL_ES_VERSION; 12675 } 12676 return config; 12677 } 12678 12679 public Configuration getConfiguration() { 12680 Configuration ci; 12681 synchronized(this) { 12682 ci = new Configuration(mConfiguration); 12683 } 12684 return ci; 12685 } 12686 12687 public void updateConfiguration(Configuration values) { 12688 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 12689 "updateConfiguration()"); 12690 12691 synchronized(this) { 12692 if (values == null && mWindowManager != null) { 12693 // sentinel: fetch the current configuration from the window manager 12694 values = mWindowManager.computeNewConfiguration(); 12695 } 12696 12697 final long origId = Binder.clearCallingIdentity(); 12698 updateConfigurationLocked(values, null); 12699 Binder.restoreCallingIdentity(origId); 12700 } 12701 } 12702 12703 /** 12704 * Do either or both things: (1) change the current configuration, and (2) 12705 * make sure the given activity is running with the (now) current 12706 * configuration. Returns true if the activity has been left running, or 12707 * false if <var>starting</var> is being destroyed to match the new 12708 * configuration. 12709 */ 12710 public boolean updateConfigurationLocked(Configuration values, 12711 HistoryRecord starting) { 12712 int changes = 0; 12713 12714 boolean kept = true; 12715 12716 if (values != null) { 12717 Configuration newConfig = new Configuration(mConfiguration); 12718 changes = newConfig.updateFrom(values); 12719 if (changes != 0) { 12720 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 12721 Log.i(TAG, "Updating configuration to: " + values); 12722 } 12723 12724 EventLog.writeEvent(LOG_CONFIGURATION_CHANGED, changes); 12725 12726 if (values.locale != null) { 12727 saveLocaleLocked(values.locale, 12728 !values.locale.equals(mConfiguration.locale), 12729 values.userSetLocale); 12730 } 12731 12732 mConfiguration = newConfig; 12733 Log.i(TAG, "Config changed: " + newConfig); 12734 12735 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 12736 msg.obj = new Configuration(mConfiguration); 12737 mHandler.sendMessage(msg); 12738 12739 final int N = mLRUProcesses.size(); 12740 for (int i=0; i<N; i++) { 12741 ProcessRecord app = mLRUProcesses.get(i); 12742 try { 12743 if (app.thread != null) { 12744 if (DEBUG_CONFIGURATION) Log.v(TAG, "Sending to proc " 12745 + app.processName + " new config " + mConfiguration); 12746 app.thread.scheduleConfigurationChanged(mConfiguration); 12747 } 12748 } catch (Exception e) { 12749 } 12750 } 12751 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 12752 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 12753 null, false, false, MY_PID, Process.SYSTEM_UID); 12754 12755 AttributeCache ac = AttributeCache.instance(); 12756 if (ac != null) { 12757 ac.updateConfiguration(mConfiguration); 12758 } 12759 } 12760 } 12761 12762 if (changes != 0 && starting == null) { 12763 // If the configuration changed, and the caller is not already 12764 // in the process of starting an activity, then find the top 12765 // activity to check if its configuration needs to change. 12766 starting = topRunningActivityLocked(null); 12767 } 12768 12769 if (starting != null) { 12770 kept = ensureActivityConfigurationLocked(starting, changes); 12771 if (kept) { 12772 // If this didn't result in the starting activity being 12773 // destroyed, then we need to make sure at this point that all 12774 // other activities are made visible. 12775 if (DEBUG_SWITCH) Log.i(TAG, "Config didn't destroy " + starting 12776 + ", ensuring others are correct."); 12777 ensureActivitiesVisibleLocked(starting, changes); 12778 } 12779 } 12780 12781 return kept; 12782 } 12783 12784 private final boolean relaunchActivityLocked(HistoryRecord r, 12785 int changes, boolean andResume) { 12786 List<ResultInfo> results = null; 12787 List<Intent> newIntents = null; 12788 if (andResume) { 12789 results = r.results; 12790 newIntents = r.newIntents; 12791 } 12792 if (DEBUG_SWITCH) Log.v(TAG, "Relaunching: " + r 12793 + " with results=" + results + " newIntents=" + newIntents 12794 + " andResume=" + andResume); 12795 EventLog.writeEvent(andResume ? LOG_AM_RELAUNCH_RESUME_ACTIVITY 12796 : LOG_AM_RELAUNCH_ACTIVITY, System.identityHashCode(r), 12797 r.task.taskId, r.shortComponentName); 12798 12799 r.startFreezingScreenLocked(r.app, 0); 12800 12801 try { 12802 if (DEBUG_SWITCH) Log.i(TAG, "Switch is restarting resumed " + r); 12803 r.app.thread.scheduleRelaunchActivity(r, results, newIntents, 12804 changes, !andResume); 12805 // Note: don't need to call pauseIfSleepingLocked() here, because 12806 // the caller will only pass in 'andResume' if this activity is 12807 // currently resumed, which implies we aren't sleeping. 12808 } catch (RemoteException e) { 12809 return false; 12810 } 12811 12812 if (andResume) { 12813 r.results = null; 12814 r.newIntents = null; 12815 } 12816 12817 return true; 12818 } 12819 12820 /** 12821 * Make sure the given activity matches the current configuration. Returns 12822 * false if the activity had to be destroyed. Returns true if the 12823 * configuration is the same, or the activity will remain running as-is 12824 * for whatever reason. Ensures the HistoryRecord is updated with the 12825 * correct configuration and all other bookkeeping is handled. 12826 */ 12827 private final boolean ensureActivityConfigurationLocked(HistoryRecord r, 12828 int globalChanges) { 12829 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 12830 "Ensuring correct configuration: " + r); 12831 12832 // Short circuit: if the two configurations are the exact same 12833 // object (the common case), then there is nothing to do. 12834 Configuration newConfig = mConfiguration; 12835 if (r.configuration == newConfig) { 12836 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 12837 "Configuration unchanged in " + r); 12838 return true; 12839 } 12840 12841 // We don't worry about activities that are finishing. 12842 if (r.finishing) { 12843 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 12844 "Configuration doesn't matter in finishing " + r); 12845 r.stopFreezingScreenLocked(false); 12846 return true; 12847 } 12848 12849 // Okay we now are going to make this activity have the new config. 12850 // But then we need to figure out how it needs to deal with that. 12851 Configuration oldConfig = r.configuration; 12852 r.configuration = newConfig; 12853 12854 // If the activity isn't currently running, just leave the new 12855 // configuration and it will pick that up next time it starts. 12856 if (r.app == null || r.app.thread == null) { 12857 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 12858 "Configuration doesn't matter not running " + r); 12859 r.stopFreezingScreenLocked(false); 12860 return true; 12861 } 12862 12863 // If the activity isn't persistent, there is a chance we will 12864 // need to restart it. 12865 if (!r.persistent) { 12866 12867 // Figure out what has changed between the two configurations. 12868 int changes = oldConfig.diff(newConfig); 12869 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 12870 Log.v(TAG, "Checking to restart " + r.info.name + ": changed=0x" 12871 + Integer.toHexString(changes) + ", handles=0x" 12872 + Integer.toHexString(r.info.configChanges) 12873 + ", newConfig=" + newConfig); 12874 } 12875 if ((changes&(~r.info.configChanges)) != 0) { 12876 // Aha, the activity isn't handling the change, so DIE DIE DIE. 12877 r.configChangeFlags |= changes; 12878 r.startFreezingScreenLocked(r.app, globalChanges); 12879 if (r.app == null || r.app.thread == null) { 12880 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 12881 "Switch is destroying non-running " + r); 12882 destroyActivityLocked(r, true); 12883 } else if (r.state == ActivityState.PAUSING) { 12884 // A little annoying: we are waiting for this activity to 12885 // finish pausing. Let's not do anything now, but just 12886 // flag that it needs to be restarted when done pausing. 12887 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 12888 "Switch is skipping already pausing " + r); 12889 r.configDestroy = true; 12890 return true; 12891 } else if (r.state == ActivityState.RESUMED) { 12892 // Try to optimize this case: the configuration is changing 12893 // and we need to restart the top, resumed activity. 12894 // Instead of doing the normal handshaking, just say 12895 // "restart!". 12896 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 12897 "Switch is restarting resumed " + r); 12898 relaunchActivityLocked(r, r.configChangeFlags, true); 12899 r.configChangeFlags = 0; 12900 } else { 12901 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 12902 "Switch is restarting non-resumed " + r); 12903 relaunchActivityLocked(r, r.configChangeFlags, false); 12904 r.configChangeFlags = 0; 12905 } 12906 12907 // All done... tell the caller we weren't able to keep this 12908 // activity around. 12909 return false; 12910 } 12911 } 12912 12913 // Default case: the activity can handle this new configuration, so 12914 // hand it over. Note that we don't need to give it the new 12915 // configuration, since we always send configuration changes to all 12916 // process when they happen so it can just use whatever configuration 12917 // it last got. 12918 if (r.app != null && r.app.thread != null) { 12919 try { 12920 if (DEBUG_CONFIGURATION) Log.v(TAG, "Sending new config to " + r); 12921 r.app.thread.scheduleActivityConfigurationChanged(r); 12922 } catch (RemoteException e) { 12923 // If process died, whatever. 12924 } 12925 } 12926 r.stopFreezingScreenLocked(false); 12927 12928 return true; 12929 } 12930 12931 /** 12932 * Save the locale. You must be inside a synchronized (this) block. 12933 */ 12934 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 12935 if(isDiff) { 12936 SystemProperties.set("user.language", l.getLanguage()); 12937 SystemProperties.set("user.region", l.getCountry()); 12938 } 12939 12940 if(isPersist) { 12941 SystemProperties.set("persist.sys.language", l.getLanguage()); 12942 SystemProperties.set("persist.sys.country", l.getCountry()); 12943 SystemProperties.set("persist.sys.localevar", l.getVariant()); 12944 } 12945 } 12946 12947 // ========================================================= 12948 // LIFETIME MANAGEMENT 12949 // ========================================================= 12950 12951 private final int computeOomAdjLocked( 12952 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) { 12953 if (mAdjSeq == app.adjSeq) { 12954 // This adjustment has already been computed. 12955 return app.curAdj; 12956 } 12957 12958 if (app.thread == null) { 12959 app.adjSeq = mAdjSeq; 12960 return (app.curAdj=EMPTY_APP_ADJ); 12961 } 12962 12963 if (app.maxAdj <= FOREGROUND_APP_ADJ) { 12964 // The max adjustment doesn't allow this app to be anything 12965 // below foreground, so it is not worth doing work for it. 12966 app.adjType = "fixed"; 12967 app.adjSeq = mAdjSeq; 12968 app.curRawAdj = app.maxAdj; 12969 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 12970 return (app.curAdj=app.maxAdj); 12971 } 12972 12973 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 12974 app.adjSource = null; 12975 app.adjTarget = null; 12976 12977 // Determine the importance of the process, starting with most 12978 // important to least, and assign an appropriate OOM adjustment. 12979 int adj; 12980 int N; 12981 if (app == TOP_APP) { 12982 // The last app on the list is the foreground app. 12983 adj = FOREGROUND_APP_ADJ; 12984 app.adjType = "top-activity"; 12985 } else if (app.instrumentationClass != null) { 12986 // Don't want to kill running instrumentation. 12987 adj = FOREGROUND_APP_ADJ; 12988 app.adjType = "instrumentation"; 12989 } else if (app.persistentActivities > 0) { 12990 // Special persistent activities... shouldn't be used these days. 12991 adj = FOREGROUND_APP_ADJ; 12992 app.adjType = "persistent"; 12993 } else if (app.curReceiver != null || 12994 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) { 12995 // An app that is currently receiving a broadcast also 12996 // counts as being in the foreground. 12997 adj = FOREGROUND_APP_ADJ; 12998 app.adjType = "broadcast"; 12999 } else if (app.executingServices.size() > 0) { 13000 // An app that is currently executing a service callback also 13001 // counts as being in the foreground. 13002 adj = FOREGROUND_APP_ADJ; 13003 app.adjType = "exec-service"; 13004 } else if (app.foregroundServices) { 13005 // The user is aware of this app, so make it visible. 13006 adj = VISIBLE_APP_ADJ; 13007 app.adjType = "foreground-service"; 13008 } else if (app.forcingToForeground != null) { 13009 // The user is aware of this app, so make it visible. 13010 adj = VISIBLE_APP_ADJ; 13011 app.adjType = "force-foreground"; 13012 app.adjSource = app.forcingToForeground; 13013 } else if (app == mHomeProcess) { 13014 // This process is hosting what we currently consider to be the 13015 // home app, so we don't want to let it go into the background. 13016 adj = HOME_APP_ADJ; 13017 app.adjType = "home"; 13018 } else if ((N=app.activities.size()) != 0) { 13019 // This app is in the background with paused activities. 13020 adj = hiddenAdj; 13021 app.adjType = "bg-activities"; 13022 for (int j=0; j<N; j++) { 13023 if (((HistoryRecord)app.activities.get(j)).visible) { 13024 // This app has a visible activity! 13025 adj = VISIBLE_APP_ADJ; 13026 app.adjType = "visible"; 13027 break; 13028 } 13029 } 13030 } else { 13031 // A very not-needed process. 13032 adj = EMPTY_APP_ADJ; 13033 app.adjType = "empty"; 13034 } 13035 13036 // By default, we use the computed adjustment. It may be changed if 13037 // there are applications dependent on our services or providers, but 13038 // this gives us a baseline and makes sure we don't get into an 13039 // infinite recursion. 13040 app.adjSeq = mAdjSeq; 13041 app.curRawAdj = adj; 13042 app.curAdj = adj <= app.maxAdj ? adj : app.maxAdj; 13043 13044 if (mBackupTarget != null && app == mBackupTarget.app) { 13045 // If possible we want to avoid killing apps while they're being backed up 13046 if (adj > BACKUP_APP_ADJ) { 13047 if (DEBUG_BACKUP) Log.v(TAG, "oom BACKUP_APP_ADJ for " + app); 13048 adj = BACKUP_APP_ADJ; 13049 app.adjType = "backup"; 13050 } 13051 } 13052 13053 if (app.services.size() != 0 && adj > FOREGROUND_APP_ADJ) { 13054 final long now = SystemClock.uptimeMillis(); 13055 // This process is more important if the top activity is 13056 // bound to the service. 13057 Iterator jt = app.services.iterator(); 13058 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) { 13059 ServiceRecord s = (ServiceRecord)jt.next(); 13060 if (s.startRequested) { 13061 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) { 13062 // This service has seen some activity within 13063 // recent memory, so we will keep its process ahead 13064 // of the background processes. 13065 if (adj > SECONDARY_SERVER_ADJ) { 13066 adj = SECONDARY_SERVER_ADJ; 13067 app.adjType = "started-services"; 13068 } 13069 } 13070 } 13071 if (s.connections.size() > 0 && adj > FOREGROUND_APP_ADJ) { 13072 Iterator<ConnectionRecord> kt 13073 = s.connections.values().iterator(); 13074 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) { 13075 // XXX should compute this based on the max of 13076 // all connected clients. 13077 ConnectionRecord cr = kt.next(); 13078 if (cr.binding.client == app) { 13079 // Binding to ourself is not interesting. 13080 continue; 13081 } 13082 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) { 13083 ProcessRecord client = cr.binding.client; 13084 int myHiddenAdj = hiddenAdj; 13085 if (myHiddenAdj > client.hiddenAdj) { 13086 if (client.hiddenAdj > VISIBLE_APP_ADJ) { 13087 myHiddenAdj = client.hiddenAdj; 13088 } else { 13089 myHiddenAdj = VISIBLE_APP_ADJ; 13090 } 13091 } 13092 int clientAdj = computeOomAdjLocked( 13093 client, myHiddenAdj, TOP_APP); 13094 if (adj > clientAdj) { 13095 adj = clientAdj > VISIBLE_APP_ADJ 13096 ? clientAdj : VISIBLE_APP_ADJ; 13097 app.adjType = "service"; 13098 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13099 .REASON_SERVICE_IN_USE; 13100 app.adjSource = cr.binding.client; 13101 app.adjTarget = s.serviceInfo.name; 13102 } 13103 } 13104 HistoryRecord a = cr.activity; 13105 //if (a != null) { 13106 // Log.i(TAG, "Connection to " + a ": state=" + a.state); 13107 //} 13108 if (a != null && adj > FOREGROUND_APP_ADJ && 13109 (a.state == ActivityState.RESUMED 13110 || a.state == ActivityState.PAUSING)) { 13111 adj = FOREGROUND_APP_ADJ; 13112 app.adjType = "service"; 13113 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13114 .REASON_SERVICE_IN_USE; 13115 app.adjSource = a; 13116 app.adjTarget = s.serviceInfo.name; 13117 } 13118 } 13119 } 13120 } 13121 13122 // Finally, f this process has active services running in it, we 13123 // would like to avoid killing it unless it would prevent the current 13124 // application from running. By default we put the process in 13125 // with the rest of the background processes; as we scan through 13126 // its services we may bump it up from there. 13127 if (adj > hiddenAdj) { 13128 adj = hiddenAdj; 13129 app.adjType = "bg-services"; 13130 } 13131 } 13132 13133 if (app.pubProviders.size() != 0 && adj > FOREGROUND_APP_ADJ) { 13134 Iterator jt = app.pubProviders.values().iterator(); 13135 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) { 13136 ContentProviderRecord cpr = (ContentProviderRecord)jt.next(); 13137 if (cpr.clients.size() != 0) { 13138 Iterator<ProcessRecord> kt = cpr.clients.iterator(); 13139 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) { 13140 ProcessRecord client = kt.next(); 13141 if (client == app) { 13142 // Being our own client is not interesting. 13143 continue; 13144 } 13145 int myHiddenAdj = hiddenAdj; 13146 if (myHiddenAdj > client.hiddenAdj) { 13147 if (client.hiddenAdj > FOREGROUND_APP_ADJ) { 13148 myHiddenAdj = client.hiddenAdj; 13149 } else { 13150 myHiddenAdj = FOREGROUND_APP_ADJ; 13151 } 13152 } 13153 int clientAdj = computeOomAdjLocked( 13154 client, myHiddenAdj, TOP_APP); 13155 if (adj > clientAdj) { 13156 adj = clientAdj > FOREGROUND_APP_ADJ 13157 ? clientAdj : FOREGROUND_APP_ADJ; 13158 app.adjType = "provider"; 13159 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13160 .REASON_PROVIDER_IN_USE; 13161 app.adjSource = client; 13162 app.adjTarget = cpr.info.name; 13163 } 13164 } 13165 } 13166 // If the provider has external (non-framework) process 13167 // dependencies, ensure that its adjustment is at least 13168 // FOREGROUND_APP_ADJ. 13169 if (cpr.externals != 0) { 13170 if (adj > FOREGROUND_APP_ADJ) { 13171 adj = FOREGROUND_APP_ADJ; 13172 app.adjType = "provider"; 13173 app.adjTarget = cpr.info.name; 13174 } 13175 } 13176 } 13177 13178 // Finally, if this process has published any content providers, 13179 // then its adjustment makes it at least as important as any of the 13180 // processes using those providers, and no less important than 13181 // CONTENT_PROVIDER_ADJ, which is just shy of EMPTY. 13182 if (adj > CONTENT_PROVIDER_ADJ) { 13183 adj = CONTENT_PROVIDER_ADJ; 13184 app.adjType = "pub-providers"; 13185 } 13186 } 13187 13188 app.curRawAdj = adj; 13189 13190 //Log.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 13191 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 13192 if (adj > app.maxAdj) { 13193 adj = app.maxAdj; 13194 } 13195 13196 app.curAdj = adj; 13197 app.curSchedGroup = adj > VISIBLE_APP_ADJ 13198 ? Process.THREAD_GROUP_BG_NONINTERACTIVE 13199 : Process.THREAD_GROUP_DEFAULT; 13200 13201 return adj; 13202 } 13203 13204 /** 13205 * Ask a given process to GC right now. 13206 */ 13207 final void performAppGcLocked(ProcessRecord app) { 13208 try { 13209 app.lastRequestedGc = SystemClock.uptimeMillis(); 13210 if (app.thread != null) { 13211 if (app.reportLowMemory) { 13212 app.reportLowMemory = false; 13213 app.thread.scheduleLowMemory(); 13214 } else { 13215 app.thread.processInBackground(); 13216 } 13217 } 13218 } catch (Exception e) { 13219 // whatever. 13220 } 13221 } 13222 13223 /** 13224 * Returns true if things are idle enough to perform GCs. 13225 */ 13226 private final boolean canGcNow() { 13227 return mParallelBroadcasts.size() == 0 13228 && mOrderedBroadcasts.size() == 0 13229 && (mSleeping || (mResumedActivity != null && 13230 mResumedActivity.idle)); 13231 } 13232 13233 /** 13234 * Perform GCs on all processes that are waiting for it, but only 13235 * if things are idle. 13236 */ 13237 final void performAppGcsLocked() { 13238 final int N = mProcessesToGc.size(); 13239 if (N <= 0) { 13240 return; 13241 } 13242 if (canGcNow()) { 13243 while (mProcessesToGc.size() > 0) { 13244 ProcessRecord proc = mProcessesToGc.remove(0); 13245 if (proc.curRawAdj > VISIBLE_APP_ADJ || proc.reportLowMemory) { 13246 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 13247 <= SystemClock.uptimeMillis()) { 13248 // To avoid spamming the system, we will GC processes one 13249 // at a time, waiting a few seconds between each. 13250 performAppGcLocked(proc); 13251 scheduleAppGcsLocked(); 13252 return; 13253 } else { 13254 // It hasn't been long enough since we last GCed this 13255 // process... put it in the list to wait for its time. 13256 addProcessToGcListLocked(proc); 13257 break; 13258 } 13259 } 13260 } 13261 13262 scheduleAppGcsLocked(); 13263 } 13264 } 13265 13266 /** 13267 * If all looks good, perform GCs on all processes waiting for them. 13268 */ 13269 final void performAppGcsIfAppropriateLocked() { 13270 if (canGcNow()) { 13271 performAppGcsLocked(); 13272 return; 13273 } 13274 // Still not idle, wait some more. 13275 scheduleAppGcsLocked(); 13276 } 13277 13278 /** 13279 * Schedule the execution of all pending app GCs. 13280 */ 13281 final void scheduleAppGcsLocked() { 13282 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 13283 13284 if (mProcessesToGc.size() > 0) { 13285 // Schedule a GC for the time to the next process. 13286 ProcessRecord proc = mProcessesToGc.get(0); 13287 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 13288 13289 long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL; 13290 long now = SystemClock.uptimeMillis(); 13291 if (when < (now+GC_TIMEOUT)) { 13292 when = now + GC_TIMEOUT; 13293 } 13294 mHandler.sendMessageAtTime(msg, when); 13295 } 13296 } 13297 13298 /** 13299 * Add a process to the array of processes waiting to be GCed. Keeps the 13300 * list in sorted order by the last GC time. The process can't already be 13301 * on the list. 13302 */ 13303 final void addProcessToGcListLocked(ProcessRecord proc) { 13304 boolean added = false; 13305 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 13306 if (mProcessesToGc.get(i).lastRequestedGc < 13307 proc.lastRequestedGc) { 13308 added = true; 13309 mProcessesToGc.add(i+1, proc); 13310 break; 13311 } 13312 } 13313 if (!added) { 13314 mProcessesToGc.add(0, proc); 13315 } 13316 } 13317 13318 /** 13319 * Set up to ask a process to GC itself. This will either do it 13320 * immediately, or put it on the list of processes to gc the next 13321 * time things are idle. 13322 */ 13323 final void scheduleAppGcLocked(ProcessRecord app) { 13324 long now = SystemClock.uptimeMillis(); 13325 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 13326 return; 13327 } 13328 if (!mProcessesToGc.contains(app)) { 13329 addProcessToGcListLocked(app); 13330 scheduleAppGcsLocked(); 13331 } 13332 } 13333 13334 private final boolean updateOomAdjLocked( 13335 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) { 13336 app.hiddenAdj = hiddenAdj; 13337 13338 if (app.thread == null) { 13339 return true; 13340 } 13341 13342 int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP); 13343 13344 if (app.pid != 0 && app.pid != MY_PID) { 13345 if (app.curRawAdj != app.setRawAdj) { 13346 if (app.curRawAdj > FOREGROUND_APP_ADJ 13347 && app.setRawAdj <= FOREGROUND_APP_ADJ) { 13348 // If this app is transitioning from foreground to 13349 // non-foreground, have it do a gc. 13350 scheduleAppGcLocked(app); 13351 } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ 13352 && app.setRawAdj < HIDDEN_APP_MIN_ADJ) { 13353 // Likewise do a gc when an app is moving in to the 13354 // background (such as a service stopping). 13355 scheduleAppGcLocked(app); 13356 } 13357 app.setRawAdj = app.curRawAdj; 13358 } 13359 if (adj != app.setAdj) { 13360 if (Process.setOomAdj(app.pid, adj)) { 13361 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v( 13362 TAG, "Set app " + app.processName + 13363 " oom adj to " + adj); 13364 app.setAdj = adj; 13365 } else { 13366 return false; 13367 } 13368 } 13369 if (app.setSchedGroup != app.curSchedGroup) { 13370 app.setSchedGroup = app.curSchedGroup; 13371 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v(TAG, 13372 "Setting process group of " + app.processName 13373 + " to " + app.curSchedGroup); 13374 if (true) { 13375 long oldId = Binder.clearCallingIdentity(); 13376 try { 13377 Process.setProcessGroup(app.pid, app.curSchedGroup); 13378 } catch (Exception e) { 13379 Log.w(TAG, "Failed setting process group of " + app.pid 13380 + " to " + app.curSchedGroup); 13381 e.printStackTrace(); 13382 } finally { 13383 Binder.restoreCallingIdentity(oldId); 13384 } 13385 } 13386 if (false) { 13387 if (app.thread != null) { 13388 try { 13389 app.thread.setSchedulingGroup(app.curSchedGroup); 13390 } catch (RemoteException e) { 13391 } 13392 } 13393 } 13394 } 13395 } 13396 13397 return true; 13398 } 13399 13400 private final HistoryRecord resumedAppLocked() { 13401 HistoryRecord resumedActivity = mResumedActivity; 13402 if (resumedActivity == null || resumedActivity.app == null) { 13403 resumedActivity = mPausingActivity; 13404 if (resumedActivity == null || resumedActivity.app == null) { 13405 resumedActivity = topRunningActivityLocked(null); 13406 } 13407 } 13408 return resumedActivity; 13409 } 13410 13411 private final boolean updateOomAdjLocked(ProcessRecord app) { 13412 final HistoryRecord TOP_ACT = resumedAppLocked(); 13413 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13414 int curAdj = app.curAdj; 13415 final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ 13416 && app.curAdj <= HIDDEN_APP_MAX_ADJ; 13417 13418 mAdjSeq++; 13419 13420 final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP); 13421 if (res) { 13422 final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ 13423 && app.curAdj <= HIDDEN_APP_MAX_ADJ; 13424 if (nowHidden != wasHidden) { 13425 // Changed to/from hidden state, so apps after it in the LRU 13426 // list may also be changed. 13427 updateOomAdjLocked(); 13428 } 13429 } 13430 return res; 13431 } 13432 13433 private final boolean updateOomAdjLocked() { 13434 boolean didOomAdj = true; 13435 final HistoryRecord TOP_ACT = resumedAppLocked(); 13436 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13437 13438 if (false) { 13439 RuntimeException e = new RuntimeException(); 13440 e.fillInStackTrace(); 13441 Log.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13442 } 13443 13444 mAdjSeq++; 13445 13446 // First try updating the OOM adjustment for each of the 13447 // application processes based on their current state. 13448 int i = mLRUProcesses.size(); 13449 int curHiddenAdj = HIDDEN_APP_MIN_ADJ; 13450 while (i > 0) { 13451 i--; 13452 ProcessRecord app = mLRUProcesses.get(i); 13453 if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) { 13454 if (curHiddenAdj < HIDDEN_APP_MAX_ADJ 13455 && app.curAdj == curHiddenAdj) { 13456 curHiddenAdj++; 13457 } 13458 } else { 13459 didOomAdj = false; 13460 } 13461 } 13462 13463 // todo: for now pretend like OOM ADJ didn't work, because things 13464 // aren't behaving as expected on Linux -- it's not killing processes. 13465 return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj; 13466 } 13467 13468 private final void trimApplications() { 13469 synchronized (this) { 13470 int i; 13471 13472 // First remove any unused application processes whose package 13473 // has been removed. 13474 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13475 final ProcessRecord app = mRemovedProcesses.get(i); 13476 if (app.activities.size() == 0 13477 && app.curReceiver == null && app.services.size() == 0) { 13478 Log.i( 13479 TAG, "Exiting empty application process " 13480 + app.processName + " (" 13481 + (app.thread != null ? app.thread.asBinder() : null) 13482 + ")\n"); 13483 if (app.pid > 0 && app.pid != MY_PID) { 13484 Process.killProcess(app.pid); 13485 } else { 13486 try { 13487 app.thread.scheduleExit(); 13488 } catch (Exception e) { 13489 // Ignore exceptions. 13490 } 13491 } 13492 cleanUpApplicationRecordLocked(app, false, -1); 13493 mRemovedProcesses.remove(i); 13494 13495 if (app.persistent) { 13496 if (app.persistent) { 13497 addAppLocked(app.info); 13498 } 13499 } 13500 } 13501 } 13502 13503 // Now try updating the OOM adjustment for each of the 13504 // application processes based on their current state. 13505 // If the setOomAdj() API is not supported, then go with our 13506 // back-up plan... 13507 if (!updateOomAdjLocked()) { 13508 13509 // Count how many processes are running services. 13510 int numServiceProcs = 0; 13511 for (i=mLRUProcesses.size()-1; i>=0; i--) { 13512 final ProcessRecord app = mLRUProcesses.get(i); 13513 13514 if (app.persistent || app.services.size() != 0 13515 || app.curReceiver != null 13516 || app.persistentActivities > 0) { 13517 // Don't count processes holding services against our 13518 // maximum process count. 13519 if (localLOGV) Log.v( 13520 TAG, "Not trimming app " + app + " with services: " 13521 + app.services); 13522 numServiceProcs++; 13523 } 13524 } 13525 13526 int curMaxProcs = mProcessLimit; 13527 if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES; 13528 if (mAlwaysFinishActivities) { 13529 curMaxProcs = 1; 13530 } 13531 curMaxProcs += numServiceProcs; 13532 13533 // Quit as many processes as we can to get down to the desired 13534 // process count. First remove any processes that no longer 13535 // have activites running in them. 13536 for ( i=0; 13537 i<mLRUProcesses.size() 13538 && mLRUProcesses.size() > curMaxProcs; 13539 i++) { 13540 final ProcessRecord app = mLRUProcesses.get(i); 13541 // Quit an application only if it is not currently 13542 // running any activities. 13543 if (!app.persistent && app.activities.size() == 0 13544 && app.curReceiver == null && app.services.size() == 0) { 13545 Log.i( 13546 TAG, "Exiting empty application process " 13547 + app.processName + " (" 13548 + (app.thread != null ? app.thread.asBinder() : null) 13549 + ")\n"); 13550 if (app.pid > 0 && app.pid != MY_PID) { 13551 Process.killProcess(app.pid); 13552 } else { 13553 try { 13554 app.thread.scheduleExit(); 13555 } catch (Exception e) { 13556 // Ignore exceptions. 13557 } 13558 } 13559 // todo: For now we assume the application is not buggy 13560 // or evil, and will quit as a result of our request. 13561 // Eventually we need to drive this off of the death 13562 // notification, and kill the process if it takes too long. 13563 cleanUpApplicationRecordLocked(app, false, i); 13564 i--; 13565 } 13566 } 13567 13568 // If we still have too many processes, now from the least 13569 // recently used process we start finishing activities. 13570 if (Config.LOGV) Log.v( 13571 TAG, "*** NOW HAVE " + mLRUProcesses.size() + 13572 " of " + curMaxProcs + " processes"); 13573 for ( i=0; 13574 i<mLRUProcesses.size() 13575 && mLRUProcesses.size() > curMaxProcs; 13576 i++) { 13577 final ProcessRecord app = mLRUProcesses.get(i); 13578 // Quit the application only if we have a state saved for 13579 // all of its activities. 13580 boolean canQuit = !app.persistent && app.curReceiver == null 13581 && app.services.size() == 0 13582 && app.persistentActivities == 0; 13583 int NUMA = app.activities.size(); 13584 int j; 13585 if (Config.LOGV) Log.v( 13586 TAG, "Looking to quit " + app.processName); 13587 for (j=0; j<NUMA && canQuit; j++) { 13588 HistoryRecord r = (HistoryRecord)app.activities.get(j); 13589 if (Config.LOGV) Log.v( 13590 TAG, " " + r.intent.getComponent().flattenToShortString() 13591 + ": frozen=" + r.haveState + ", visible=" + r.visible); 13592 canQuit = (r.haveState || !r.stateNotNeeded) 13593 && !r.visible && r.stopped; 13594 } 13595 if (canQuit) { 13596 // Finish all of the activities, and then the app itself. 13597 for (j=0; j<NUMA; j++) { 13598 HistoryRecord r = (HistoryRecord)app.activities.get(j); 13599 if (!r.finishing) { 13600 destroyActivityLocked(r, false); 13601 } 13602 r.resultTo = null; 13603 } 13604 Log.i(TAG, "Exiting application process " 13605 + app.processName + " (" 13606 + (app.thread != null ? app.thread.asBinder() : null) 13607 + ")\n"); 13608 if (app.pid > 0 && app.pid != MY_PID) { 13609 Process.killProcess(app.pid); 13610 } else { 13611 try { 13612 app.thread.scheduleExit(); 13613 } catch (Exception e) { 13614 // Ignore exceptions. 13615 } 13616 } 13617 // todo: For now we assume the application is not buggy 13618 // or evil, and will quit as a result of our request. 13619 // Eventually we need to drive this off of the death 13620 // notification, and kill the process if it takes too long. 13621 cleanUpApplicationRecordLocked(app, false, i); 13622 i--; 13623 //dump(); 13624 } 13625 } 13626 13627 } 13628 13629 int curMaxActivities = MAX_ACTIVITIES; 13630 if (mAlwaysFinishActivities) { 13631 curMaxActivities = 1; 13632 } 13633 13634 // Finally, if there are too many activities now running, try to 13635 // finish as many as we can to get back down to the limit. 13636 for ( i=0; 13637 i<mLRUActivities.size() 13638 && mLRUActivities.size() > curMaxActivities; 13639 i++) { 13640 final HistoryRecord r 13641 = (HistoryRecord)mLRUActivities.get(i); 13642 13643 // We can finish this one if we have its icicle saved and 13644 // it is not persistent. 13645 if ((r.haveState || !r.stateNotNeeded) && !r.visible 13646 && r.stopped && !r.persistent && !r.finishing) { 13647 final int origSize = mLRUActivities.size(); 13648 destroyActivityLocked(r, true); 13649 13650 // This will remove it from the LRU list, so keep 13651 // our index at the same value. Note that this check to 13652 // see if the size changes is just paranoia -- if 13653 // something unexpected happens, we don't want to end up 13654 // in an infinite loop. 13655 if (origSize > mLRUActivities.size()) { 13656 i--; 13657 } 13658 } 13659 } 13660 } 13661 } 13662 13663 /** This method sends the specified signal to each of the persistent apps */ 13664 public void signalPersistentProcesses(int sig) throws RemoteException { 13665 if (sig != Process.SIGNAL_USR1) { 13666 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 13667 } 13668 13669 synchronized (this) { 13670 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 13671 != PackageManager.PERMISSION_GRANTED) { 13672 throw new SecurityException("Requires permission " 13673 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 13674 } 13675 13676 for (int i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) { 13677 ProcessRecord r = mLRUProcesses.get(i); 13678 if (r.thread != null && r.persistent) { 13679 Process.sendSignal(r.pid, sig); 13680 } 13681 } 13682 } 13683 } 13684 13685 public boolean profileControl(String process, boolean start, 13686 String path, ParcelFileDescriptor fd) throws RemoteException { 13687 13688 try { 13689 synchronized (this) { 13690 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 13691 // its own permission. 13692 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13693 != PackageManager.PERMISSION_GRANTED) { 13694 throw new SecurityException("Requires permission " 13695 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13696 } 13697 13698 if (start && fd == null) { 13699 throw new IllegalArgumentException("null fd"); 13700 } 13701 13702 ProcessRecord proc = null; 13703 try { 13704 int pid = Integer.parseInt(process); 13705 synchronized (mPidsSelfLocked) { 13706 proc = mPidsSelfLocked.get(pid); 13707 } 13708 } catch (NumberFormatException e) { 13709 } 13710 13711 if (proc == null) { 13712 HashMap<String, SparseArray<ProcessRecord>> all 13713 = mProcessNames.getMap(); 13714 SparseArray<ProcessRecord> procs = all.get(process); 13715 if (procs != null && procs.size() > 0) { 13716 proc = procs.valueAt(0); 13717 } 13718 } 13719 13720 if (proc == null || proc.thread == null) { 13721 throw new IllegalArgumentException("Unknown process: " + process); 13722 } 13723 13724 boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0")); 13725 if (isSecure) { 13726 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 13727 throw new SecurityException("Process not debuggable: " + proc); 13728 } 13729 } 13730 13731 proc.thread.profilerControl(start, path, fd); 13732 fd = null; 13733 return true; 13734 } 13735 } catch (RemoteException e) { 13736 throw new IllegalStateException("Process disappeared"); 13737 } finally { 13738 if (fd != null) { 13739 try { 13740 fd.close(); 13741 } catch (IOException e) { 13742 } 13743 } 13744 } 13745 } 13746 13747 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 13748 public void monitor() { 13749 synchronized (this) { } 13750 } 13751} 13752