ActivityManagerService.java revision 03abb8179f0d912e6dabfc0e2b0f129d85066d17
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import com.android.internal.os.BatteryStatsImpl; 20import com.android.server.AttributeCache; 21import com.android.server.IntentResolver; 22import com.android.server.ProcessMap; 23import com.android.server.ProcessStats; 24import com.android.server.SystemServer; 25import com.android.server.Watchdog; 26import com.android.server.WindowManagerService; 27 28import dalvik.system.Zygote; 29 30import android.app.Activity; 31import android.app.ActivityManager; 32import android.app.ActivityManagerNative; 33import android.app.ActivityThread; 34import android.app.AlertDialog; 35import android.app.ApplicationErrorReport; 36import android.app.Dialog; 37import android.app.IActivityController; 38import android.app.IActivityWatcher; 39import android.app.IApplicationThread; 40import android.app.IInstrumentationWatcher; 41import android.app.IServiceConnection; 42import android.app.IThumbnailReceiver; 43import android.app.Instrumentation; 44import android.app.Notification; 45import android.app.PendingIntent; 46import android.app.ResultInfo; 47import android.app.Service; 48import android.backup.IBackupManager; 49import android.content.ActivityNotFoundException; 50import android.content.ComponentName; 51import android.content.ContentResolver; 52import android.content.Context; 53import android.content.Intent; 54import android.content.IntentFilter; 55import android.content.IIntentReceiver; 56import android.content.IIntentSender; 57import android.content.IntentSender; 58import android.content.pm.ActivityInfo; 59import android.content.pm.ApplicationInfo; 60import android.content.pm.ConfigurationInfo; 61import android.content.pm.IPackageDataObserver; 62import android.content.pm.IPackageManager; 63import android.content.pm.InstrumentationInfo; 64import android.content.pm.PackageManager; 65import android.content.pm.PathPermission; 66import android.content.pm.ProviderInfo; 67import android.content.pm.ResolveInfo; 68import android.content.pm.ServiceInfo; 69import android.content.res.Configuration; 70import android.graphics.Bitmap; 71import android.net.Uri; 72import android.os.Binder; 73import android.os.Bundle; 74import android.os.Build; 75import android.os.Debug; 76import android.os.DropBoxManager; 77import android.os.Environment; 78import android.os.FileUtils; 79import android.os.Handler; 80import android.os.IBinder; 81import android.os.IPermissionController; 82import android.os.Looper; 83import android.os.Message; 84import android.os.Parcel; 85import android.os.ParcelFileDescriptor; 86import android.os.PowerManager; 87import android.os.Process; 88import android.os.RemoteCallbackList; 89import android.os.RemoteException; 90import android.os.ServiceManager; 91import android.os.SystemClock; 92import android.os.SystemProperties; 93import android.provider.Checkin; 94import android.provider.Settings; 95import android.text.TextUtils; 96import android.util.Config; 97import android.util.EventLog; 98import android.util.Log; 99import android.util.PrintWriterPrinter; 100import android.util.SparseArray; 101import android.view.Gravity; 102import android.view.LayoutInflater; 103import android.view.View; 104import android.view.WindowManager; 105import android.view.WindowManagerPolicy; 106 107import java.io.File; 108import java.io.FileDescriptor; 109import java.io.FileInputStream; 110import java.io.FileNotFoundException; 111import java.io.IOException; 112import java.io.PrintWriter; 113import java.lang.IllegalStateException; 114import java.lang.ref.WeakReference; 115import java.util.ArrayList; 116import java.util.HashMap; 117import java.util.HashSet; 118import java.util.Iterator; 119import java.util.List; 120import java.util.Locale; 121import java.util.Map; 122 123public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor { 124 static final String TAG = "ActivityManager"; 125 static final boolean DEBUG = false; 126 static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV; 127 static final boolean DEBUG_SWITCH = localLOGV || false; 128 static final boolean DEBUG_TASKS = localLOGV || false; 129 static final boolean DEBUG_PAUSE = localLOGV || false; 130 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 131 static final boolean DEBUG_TRANSITION = localLOGV || false; 132 static final boolean DEBUG_BROADCAST = localLOGV || false; 133 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 134 static final boolean DEBUG_SERVICE = localLOGV || false; 135 static final boolean DEBUG_VISBILITY = localLOGV || false; 136 static final boolean DEBUG_PROCESSES = localLOGV || false; 137 static final boolean DEBUG_PROVIDER = localLOGV || false; 138 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 139 static final boolean DEBUG_RESULTS = localLOGV || false; 140 static final boolean DEBUG_BACKUP = localLOGV || false; 141 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 142 static final boolean VALIDATE_TOKENS = false; 143 static final boolean SHOW_ACTIVITY_START_TIME = true; 144 145 // Control over CPU and battery monitoring. 146 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 147 static final boolean MONITOR_CPU_USAGE = true; 148 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 149 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 150 static final boolean MONITOR_THREAD_CPU_USAGE = false; 151 152 // The flags that are set for all calls we make to the package manager. 153 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 154 155 private static final String SYSTEM_SECURE = "ro.secure"; 156 157 // This is the maximum number of application processes we would like 158 // to have running. Due to the asynchronous nature of things, we can 159 // temporarily go beyond this limit. 160 static final int MAX_PROCESSES = 2; 161 162 // Set to false to leave processes running indefinitely, relying on 163 // the kernel killing them as resources are required. 164 static final boolean ENFORCE_PROCESS_LIMIT = false; 165 166 // This is the maximum number of activities that we would like to have 167 // running at a given time. 168 static final int MAX_ACTIVITIES = 20; 169 170 // Maximum number of recent tasks that we can remember. 171 static final int MAX_RECENT_TASKS = 20; 172 173 // Amount of time after a call to stopAppSwitches() during which we will 174 // prevent further untrusted switches from happening. 175 static final long APP_SWITCH_DELAY_TIME = 5*1000; 176 177 // How long until we reset a task when the user returns to it. Currently 178 // 30 minutes. 179 static final long ACTIVITY_INACTIVE_RESET_TIME = 1000*60*30; 180 181 // Set to true to disable the icon that is shown while a new activity 182 // is being started. 183 static final boolean SHOW_APP_STARTING_ICON = true; 184 185 // How long we wait until giving up on the last activity to pause. This 186 // is short because it directly impacts the responsiveness of starting the 187 // next activity. 188 static final int PAUSE_TIMEOUT = 500; 189 190 /** 191 * How long we can hold the launch wake lock before giving up. 192 */ 193 static final int LAUNCH_TIMEOUT = 10*1000; 194 195 // How long we wait for a launched process to attach to the activity manager 196 // before we decide it's never going to come up for real. 197 static final int PROC_START_TIMEOUT = 10*1000; 198 199 // How long we wait until giving up on the last activity telling us it 200 // is idle. 201 static final int IDLE_TIMEOUT = 10*1000; 202 203 // How long to wait after going idle before forcing apps to GC. 204 static final int GC_TIMEOUT = 5*1000; 205 206 // The minimum amount of time between successive GC requests for a process. 207 static final int GC_MIN_INTERVAL = 60*1000; 208 209 // How long we wait until giving up on an activity telling us it has 210 // finished destroying itself. 211 static final int DESTROY_TIMEOUT = 10*1000; 212 213 // How long we allow a receiver to run before giving up on it. 214 static final int BROADCAST_TIMEOUT = 10*1000; 215 216 // How long we wait for a service to finish executing. 217 static final int SERVICE_TIMEOUT = 20*1000; 218 219 // How long a service needs to be running until restarting its process 220 // is no longer considered to be a relaunch of the service. 221 static final int SERVICE_RESTART_DURATION = 5*1000; 222 223 // How long a service needs to be running until it will start back at 224 // SERVICE_RESTART_DURATION after being killed. 225 static final int SERVICE_RESET_RUN_DURATION = 60*1000; 226 227 // Multiplying factor to increase restart duration time by, for each time 228 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION. 229 static final int SERVICE_RESTART_DURATION_FACTOR = 4; 230 231 // The minimum amount of time between restarting services that we allow. 232 // That is, when multiple services are restarting, we won't allow each 233 // to restart less than this amount of time from the last one. 234 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000; 235 236 // Maximum amount of time for there to be no activity on a service before 237 // we consider it non-essential and allow its process to go on the 238 // LRU background list. 239 static final int MAX_SERVICE_INACTIVITY = 30*60*1000; 240 241 // How long we wait until we timeout on key dispatching. 242 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 243 244 // The minimum time we allow between crashes, for us to consider this 245 // application to be bad and stop and its services and reject broadcasts. 246 static final int MIN_CRASH_INTERVAL = 60*1000; 247 248 // How long we wait until we timeout on key dispatching during instrumentation. 249 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 250 251 // OOM adjustments for processes in various states: 252 253 // This is a process without anything currently running in it. Definitely 254 // the first to go! Value set in system/rootdir/init.rc on startup. 255 // This value is initalized in the constructor, careful when refering to 256 // this static variable externally. 257 static final int EMPTY_APP_ADJ; 258 259 // This is a process only hosting activities that are not visible, 260 // so it can be killed without any disruption. Value set in 261 // system/rootdir/init.rc on startup. 262 static final int HIDDEN_APP_MAX_ADJ; 263 static int HIDDEN_APP_MIN_ADJ; 264 265 // This is a process holding the home application -- we want to try 266 // avoiding killing it, even if it would normally be in the background, 267 // because the user interacts with it so much. 268 static final int HOME_APP_ADJ; 269 270 // This is a process currently hosting a backup operation. Killing it 271 // is not entirely fatal but is generally a bad idea. 272 static final int BACKUP_APP_ADJ; 273 274 // This is a process holding a secondary server -- killing it will not 275 // have much of an impact as far as the user is concerned. Value set in 276 // system/rootdir/init.rc on startup. 277 static final int SECONDARY_SERVER_ADJ; 278 279 // This is a process only hosting activities that are visible to the 280 // user, so we'd prefer they don't disappear. Value set in 281 // system/rootdir/init.rc on startup. 282 static final int VISIBLE_APP_ADJ; 283 284 // This is the process running the current foreground app. We'd really 285 // rather not kill it! Value set in system/rootdir/init.rc on startup. 286 static final int FOREGROUND_APP_ADJ; 287 288 // This is a process running a core server, such as telephony. Definitely 289 // don't want to kill it, but doing so is not completely fatal. 290 static final int CORE_SERVER_ADJ = -12; 291 292 // The system process runs at the default adjustment. 293 static final int SYSTEM_ADJ = -16; 294 295 // Memory pages are 4K. 296 static final int PAGE_SIZE = 4*1024; 297 298 // System property defining error report receiver for system apps 299 static final String SYSTEM_APPS_ERROR_RECEIVER_PROPERTY = "ro.error.receiver.system.apps"; 300 301 // System property defining default error report receiver 302 static final String DEFAULT_ERROR_RECEIVER_PROPERTY = "ro.error.receiver.default"; 303 304 // Corresponding memory levels for above adjustments. 305 static final int EMPTY_APP_MEM; 306 static final int HIDDEN_APP_MEM; 307 static final int HOME_APP_MEM; 308 static final int BACKUP_APP_MEM; 309 static final int SECONDARY_SERVER_MEM; 310 static final int VISIBLE_APP_MEM; 311 static final int FOREGROUND_APP_MEM; 312 313 // The minimum number of hidden apps we want to be able to keep around, 314 // without empty apps being able to push them out of memory. 315 static final int MIN_HIDDEN_APPS = 2; 316 317 // We put empty content processes after any hidden processes that have 318 // been idle for less than 30 seconds. 319 static final long CONTENT_APP_IDLE_OFFSET = 30*1000; 320 321 // We put empty content processes after any hidden processes that have 322 // been idle for less than 60 seconds. 323 static final long EMPTY_APP_IDLE_OFFSET = 60*1000; 324 325 static { 326 // These values are set in system/rootdir/init.rc on startup. 327 FOREGROUND_APP_ADJ = 328 Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_ADJ")); 329 VISIBLE_APP_ADJ = 330 Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_ADJ")); 331 SECONDARY_SERVER_ADJ = 332 Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_ADJ")); 333 BACKUP_APP_ADJ = 334 Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_ADJ")); 335 HOME_APP_ADJ = 336 Integer.valueOf(SystemProperties.get("ro.HOME_APP_ADJ")); 337 HIDDEN_APP_MIN_ADJ = 338 Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MIN_ADJ")); 339 EMPTY_APP_ADJ = 340 Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_ADJ")); 341 HIDDEN_APP_MAX_ADJ = EMPTY_APP_ADJ-1; 342 FOREGROUND_APP_MEM = 343 Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_MEM"))*PAGE_SIZE; 344 VISIBLE_APP_MEM = 345 Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_MEM"))*PAGE_SIZE; 346 SECONDARY_SERVER_MEM = 347 Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_MEM"))*PAGE_SIZE; 348 BACKUP_APP_MEM = 349 Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_MEM"))*PAGE_SIZE; 350 HOME_APP_MEM = 351 Integer.valueOf(SystemProperties.get("ro.HOME_APP_MEM"))*PAGE_SIZE; 352 HIDDEN_APP_MEM = 353 Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MEM"))*PAGE_SIZE; 354 EMPTY_APP_MEM = 355 Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_MEM"))*PAGE_SIZE; 356 } 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 * Historical data of past broadcasts, for debugging. 414 */ 415 static final int MAX_BROADCAST_HISTORY = 100; 416 final BroadcastRecord[] mBroadcastHistory 417 = new BroadcastRecord[MAX_BROADCAST_HISTORY]; 418 419 /** 420 * Set when we current have a BROADCAST_INTENT_MSG in flight. 421 */ 422 boolean mBroadcastsScheduled = false; 423 424 /** 425 * Set to indicate whether to issue an onUserLeaving callback when a 426 * newly launched activity is being brought in front of us. 427 */ 428 boolean mUserLeaving = false; 429 430 /** 431 * When we are in the process of pausing an activity, before starting the 432 * next one, this variable holds the activity that is currently being paused. 433 */ 434 HistoryRecord mPausingActivity = null; 435 436 /** 437 * Current activity that is resumed, or null if there is none. 438 */ 439 HistoryRecord mResumedActivity = null; 440 441 /** 442 * Activity we have told the window manager to have key focus. 443 */ 444 HistoryRecord mFocusedActivity = null; 445 446 /** 447 * This is the last activity that we put into the paused state. This is 448 * used to determine if we need to do an activity transition while sleeping, 449 * when we normally hold the top activity paused. 450 */ 451 HistoryRecord mLastPausedActivity = null; 452 453 /** 454 * List of activities that are waiting for a new activity 455 * to become visible before completing whatever operation they are 456 * supposed to do. 457 */ 458 final ArrayList mWaitingVisibleActivities = new ArrayList(); 459 460 /** 461 * List of activities that are ready to be stopped, but waiting 462 * for the next activity to settle down before doing so. It contains 463 * HistoryRecord objects. 464 */ 465 final ArrayList<HistoryRecord> mStoppingActivities 466 = new ArrayList<HistoryRecord>(); 467 468 /** 469 * Animations that for the current transition have requested not to 470 * be considered for the transition animation. 471 */ 472 final ArrayList<HistoryRecord> mNoAnimActivities 473 = new ArrayList<HistoryRecord>(); 474 475 /** 476 * List of intents that were used to start the most recent tasks. 477 */ 478 final ArrayList<TaskRecord> mRecentTasks 479 = new ArrayList<TaskRecord>(); 480 481 /** 482 * List of activities that are ready to be finished, but waiting 483 * for the previous activity to settle down before doing so. It contains 484 * HistoryRecord objects. 485 */ 486 final ArrayList mFinishingActivities = new ArrayList(); 487 488 /** 489 * All of the applications we currently have running organized by name. 490 * The keys are strings of the application package name (as 491 * returned by the package manager), and the keys are ApplicationRecord 492 * objects. 493 */ 494 final ProcessMap<ProcessRecord> mProcessNames 495 = new ProcessMap<ProcessRecord>(); 496 497 /** 498 * The last time that various processes have crashed. 499 */ 500 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 501 502 /** 503 * Set of applications that we consider to be bad, and will reject 504 * incoming broadcasts from (which the user has no control over). 505 * Processes are added to this set when they have crashed twice within 506 * a minimum amount of time; they are removed from it when they are 507 * later restarted (hopefully due to some user action). The value is the 508 * time it was added to the list. 509 */ 510 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 511 512 /** 513 * All of the processes we currently have running organized by pid. 514 * The keys are the pid running the application. 515 * 516 * <p>NOTE: This object is protected by its own lock, NOT the global 517 * activity manager lock! 518 */ 519 final SparseArray<ProcessRecord> mPidsSelfLocked 520 = new SparseArray<ProcessRecord>(); 521 522 /** 523 * All of the processes that have been forced to be foreground. The key 524 * is the pid of the caller who requested it (we hold a death 525 * link on it). 526 */ 527 abstract class ForegroundToken implements IBinder.DeathRecipient { 528 int pid; 529 IBinder token; 530 } 531 final SparseArray<ForegroundToken> mForegroundProcesses 532 = new SparseArray<ForegroundToken>(); 533 534 /** 535 * List of records for processes that someone had tried to start before the 536 * system was ready. We don't start them at that point, but ensure they 537 * are started by the time booting is complete. 538 */ 539 final ArrayList<ProcessRecord> mProcessesOnHold 540 = new ArrayList<ProcessRecord>(); 541 542 /** 543 * List of records for processes that we have started and are waiting 544 * for them to call back. This is really only needed when running in 545 * single processes mode, in which case we do not have a unique pid for 546 * each process. 547 */ 548 final ArrayList<ProcessRecord> mStartingProcesses 549 = new ArrayList<ProcessRecord>(); 550 551 /** 552 * List of persistent applications that are in the process 553 * of being started. 554 */ 555 final ArrayList<ProcessRecord> mPersistentStartingProcesses 556 = new ArrayList<ProcessRecord>(); 557 558 /** 559 * Processes that are being forcibly torn down. 560 */ 561 final ArrayList<ProcessRecord> mRemovedProcesses 562 = new ArrayList<ProcessRecord>(); 563 564 /** 565 * List of running applications, sorted by recent usage. 566 * The first entry in the list is the least recently used. 567 * It contains ApplicationRecord objects. This list does NOT include 568 * any persistent application records (since we never want to exit them). 569 */ 570 final ArrayList<ProcessRecord> mLruProcesses 571 = new ArrayList<ProcessRecord>(); 572 573 /** 574 * List of processes that should gc as soon as things are idle. 575 */ 576 final ArrayList<ProcessRecord> mProcessesToGc 577 = new ArrayList<ProcessRecord>(); 578 579 /** 580 * This is the process holding what we currently consider to be 581 * the "home" activity. 582 */ 583 private ProcessRecord mHomeProcess; 584 585 /** 586 * List of running activities, sorted by recent usage. 587 * The first entry in the list is the least recently used. 588 * It contains HistoryRecord objects. 589 */ 590 private final ArrayList mLRUActivities = new ArrayList(); 591 592 /** 593 * Set of PendingResultRecord objects that are currently active. 594 */ 595 final HashSet mPendingResultRecords = new HashSet(); 596 597 /** 598 * Set of IntentSenderRecord objects that are currently active. 599 */ 600 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 601 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 602 603 /** 604 * Intent broadcast that we have tried to start, but are 605 * waiting for its application's process to be created. We only 606 * need one (instead of a list) because we always process broadcasts 607 * one at a time, so no others can be started while waiting for this 608 * one. 609 */ 610 BroadcastRecord mPendingBroadcast = null; 611 612 /** 613 * Keeps track of all IIntentReceivers that have been registered for 614 * broadcasts. Hash keys are the receiver IBinder, hash value is 615 * a ReceiverList. 616 */ 617 final HashMap mRegisteredReceivers = new HashMap(); 618 619 /** 620 * Resolver for broadcast intents to registered receivers. 621 * Holds BroadcastFilter (subclass of IntentFilter). 622 */ 623 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 624 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 625 @Override 626 protected boolean allowFilterResult( 627 BroadcastFilter filter, List<BroadcastFilter> dest) { 628 IBinder target = filter.receiverList.receiver.asBinder(); 629 for (int i=dest.size()-1; i>=0; i--) { 630 if (dest.get(i).receiverList.receiver.asBinder() == target) { 631 return false; 632 } 633 } 634 return true; 635 } 636 }; 637 638 /** 639 * State of all active sticky broadcasts. Keys are the action of the 640 * sticky Intent, values are an ArrayList of all broadcasted intents with 641 * that action (which should usually be one). 642 */ 643 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts = 644 new HashMap<String, ArrayList<Intent>>(); 645 646 /** 647 * All currently running services. 648 */ 649 final HashMap<ComponentName, ServiceRecord> mServices = 650 new HashMap<ComponentName, ServiceRecord>(); 651 652 /** 653 * All currently running services indexed by the Intent used to start them. 654 */ 655 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent = 656 new HashMap<Intent.FilterComparison, ServiceRecord>(); 657 658 /** 659 * All currently bound service connections. Keys are the IBinder of 660 * the client's IServiceConnection. 661 */ 662 final HashMap<IBinder, ConnectionRecord> mServiceConnections 663 = new HashMap<IBinder, ConnectionRecord>(); 664 665 /** 666 * List of services that we have been asked to start, 667 * but haven't yet been able to. It is used to hold start requests 668 * while waiting for their corresponding application thread to get 669 * going. 670 */ 671 final ArrayList<ServiceRecord> mPendingServices 672 = new ArrayList<ServiceRecord>(); 673 674 /** 675 * List of services that are scheduled to restart following a crash. 676 */ 677 final ArrayList<ServiceRecord> mRestartingServices 678 = new ArrayList<ServiceRecord>(); 679 680 /** 681 * List of services that are in the process of being stopped. 682 */ 683 final ArrayList<ServiceRecord> mStoppingServices 684 = new ArrayList<ServiceRecord>(); 685 686 /** 687 * Backup/restore process management 688 */ 689 String mBackupAppName = null; 690 BackupRecord mBackupTarget = null; 691 692 /** 693 * List of PendingThumbnailsRecord objects of clients who are still 694 * waiting to receive all of the thumbnails for a task. 695 */ 696 final ArrayList mPendingThumbnails = new ArrayList(); 697 698 /** 699 * List of HistoryRecord objects that have been finished and must 700 * still report back to a pending thumbnail receiver. 701 */ 702 final ArrayList mCancelledThumbnails = new ArrayList(); 703 704 /** 705 * All of the currently running global content providers. Keys are a 706 * string containing the provider name and values are a 707 * ContentProviderRecord object containing the data about it. Note 708 * that a single provider may be published under multiple names, so 709 * there may be multiple entries here for a single one in mProvidersByClass. 710 */ 711 final HashMap mProvidersByName = new HashMap(); 712 713 /** 714 * All of the currently running global content providers. Keys are a 715 * string containing the provider's implementation class and values are a 716 * ContentProviderRecord object containing the data about it. 717 */ 718 final HashMap mProvidersByClass = new HashMap(); 719 720 /** 721 * List of content providers who have clients waiting for them. The 722 * application is currently being launched and the provider will be 723 * removed from this list once it is published. 724 */ 725 final ArrayList mLaunchingProviders = new ArrayList(); 726 727 /** 728 * Global set of specific Uri permissions that have been granted. 729 */ 730 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 731 = new SparseArray<HashMap<Uri, UriPermission>>(); 732 733 /** 734 * Thread-local storage used to carry caller permissions over through 735 * indirect content-provider access. 736 * @see #ActivityManagerService.openContentUri() 737 */ 738 private class Identity { 739 public int pid; 740 public int uid; 741 742 Identity(int _pid, int _uid) { 743 pid = _pid; 744 uid = _uid; 745 } 746 } 747 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 748 749 /** 750 * All information we have collected about the runtime performance of 751 * any user id that can impact battery performance. 752 */ 753 final BatteryStatsService mBatteryStatsService; 754 755 /** 756 * information about component usage 757 */ 758 final UsageStatsService mUsageStatsService; 759 760 /** 761 * Current configuration information. HistoryRecord objects are given 762 * a reference to this object to indicate which configuration they are 763 * currently running in, so this object must be kept immutable. 764 */ 765 Configuration mConfiguration = new Configuration(); 766 767 /** 768 * Hardware-reported OpenGLES version. 769 */ 770 final int GL_ES_VERSION; 771 772 /** 773 * List of initialization arguments to pass to all processes when binding applications to them. 774 * For example, references to the commonly used services. 775 */ 776 HashMap<String, IBinder> mAppBindArgs; 777 778 /** 779 * Temporary to avoid allocations. Protected by main lock. 780 */ 781 final StringBuilder mStringBuilder = new StringBuilder(256); 782 783 /** 784 * Used to control how we initialize the service. 785 */ 786 boolean mStartRunning = false; 787 ComponentName mTopComponent; 788 String mTopAction; 789 String mTopData; 790 boolean mSystemReady = false; 791 boolean mBooting = false; 792 boolean mWaitingUpdate = false; 793 boolean mDidUpdate = false; 794 795 Context mContext; 796 797 int mFactoryTest; 798 799 boolean mCheckedForSetup; 800 801 /** 802 * The time at which we will allow normal application switches again, 803 * after a call to {@link #stopAppSwitches()}. 804 */ 805 long mAppSwitchesAllowedTime; 806 807 /** 808 * This is set to true after the first switch after mAppSwitchesAllowedTime 809 * is set; any switches after that will clear the time. 810 */ 811 boolean mDidAppSwitch; 812 813 /** 814 * Set while we are wanting to sleep, to prevent any 815 * activities from being started/resumed. 816 */ 817 boolean mSleeping = false; 818 819 /** 820 * Set if we are shutting down the system, similar to sleeping. 821 */ 822 boolean mShuttingDown = false; 823 824 /** 825 * Set when the system is going to sleep, until we have 826 * successfully paused the current activity and released our wake lock. 827 * At that point the system is allowed to actually sleep. 828 */ 829 PowerManager.WakeLock mGoingToSleep; 830 831 /** 832 * We don't want to allow the device to go to sleep while in the process 833 * of launching an activity. This is primarily to allow alarm intent 834 * receivers to launch an activity and get that to run before the device 835 * goes back to sleep. 836 */ 837 PowerManager.WakeLock mLaunchingActivity; 838 839 /** 840 * Task identifier that activities are currently being started 841 * in. Incremented each time a new task is created. 842 * todo: Replace this with a TokenSpace class that generates non-repeating 843 * integers that won't wrap. 844 */ 845 int mCurTask = 1; 846 847 /** 848 * Current sequence id for oom_adj computation traversal. 849 */ 850 int mAdjSeq = 0; 851 852 /** 853 * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar 854 * is set, indicating the user wants processes started in such a way 855 * that they can use ANDROID_PROCESS_WRAPPER and know what will be 856 * running in each process (thus no pre-initialized process, etc). 857 */ 858 boolean mSimpleProcessManagement = false; 859 860 /** 861 * System monitoring: number of processes that died since the last 862 * N procs were started. 863 */ 864 int[] mProcDeaths = new int[20]; 865 866 /** 867 * This is set if we had to do a delayed dexopt of an app before launching 868 * it, to increasing the ANR timeouts in that case. 869 */ 870 boolean mDidDexOpt; 871 872 String mDebugApp = null; 873 boolean mWaitForDebugger = false; 874 boolean mDebugTransient = false; 875 String mOrigDebugApp = null; 876 boolean mOrigWaitForDebugger = false; 877 boolean mAlwaysFinishActivities = false; 878 IActivityController mController = null; 879 880 final RemoteCallbackList<IActivityWatcher> mWatchers 881 = new RemoteCallbackList<IActivityWatcher>(); 882 883 /** 884 * Callback of last caller to {@link #requestPss}. 885 */ 886 Runnable mRequestPssCallback; 887 888 /** 889 * Remaining processes for which we are waiting results from the last 890 * call to {@link #requestPss}. 891 */ 892 final ArrayList<ProcessRecord> mRequestPssList 893 = new ArrayList<ProcessRecord>(); 894 895 /** 896 * Runtime statistics collection thread. This object's lock is used to 897 * protect all related state. 898 */ 899 final Thread mProcessStatsThread; 900 901 /** 902 * Used to collect process stats when showing not responding dialog. 903 * Protected by mProcessStatsThread. 904 */ 905 final ProcessStats mProcessStats = new ProcessStats( 906 MONITOR_THREAD_CPU_USAGE); 907 long mLastCpuTime = 0; 908 long mLastWriteTime = 0; 909 910 long mInitialStartTime = 0; 911 912 /** 913 * Set to true after the system has finished booting. 914 */ 915 boolean mBooted = false; 916 917 int mProcessLimit = 0; 918 919 WindowManagerService mWindowManager; 920 921 static ActivityManagerService mSelf; 922 static ActivityThread mSystemThread; 923 924 private final class AppDeathRecipient implements IBinder.DeathRecipient { 925 final ProcessRecord mApp; 926 final int mPid; 927 final IApplicationThread mAppThread; 928 929 AppDeathRecipient(ProcessRecord app, int pid, 930 IApplicationThread thread) { 931 if (localLOGV) Log.v( 932 TAG, "New death recipient " + this 933 + " for thread " + thread.asBinder()); 934 mApp = app; 935 mPid = pid; 936 mAppThread = thread; 937 } 938 939 public void binderDied() { 940 if (localLOGV) Log.v( 941 TAG, "Death received in " + this 942 + " for thread " + mAppThread.asBinder()); 943 removeRequestedPss(mApp); 944 synchronized(ActivityManagerService.this) { 945 appDiedLocked(mApp, mPid, mAppThread); 946 } 947 } 948 } 949 950 static final int SHOW_ERROR_MSG = 1; 951 static final int SHOW_NOT_RESPONDING_MSG = 2; 952 static final int SHOW_FACTORY_ERROR_MSG = 3; 953 static final int UPDATE_CONFIGURATION_MSG = 4; 954 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 955 static final int WAIT_FOR_DEBUGGER_MSG = 6; 956 static final int BROADCAST_INTENT_MSG = 7; 957 static final int BROADCAST_TIMEOUT_MSG = 8; 958 static final int PAUSE_TIMEOUT_MSG = 9; 959 static final int IDLE_TIMEOUT_MSG = 10; 960 static final int IDLE_NOW_MSG = 11; 961 static final int SERVICE_TIMEOUT_MSG = 12; 962 static final int UPDATE_TIME_ZONE = 13; 963 static final int SHOW_UID_ERROR_MSG = 14; 964 static final int IM_FEELING_LUCKY_MSG = 15; 965 static final int LAUNCH_TIMEOUT_MSG = 16; 966 static final int DESTROY_TIMEOUT_MSG = 17; 967 static final int SERVICE_ERROR_MSG = 18; 968 static final int RESUME_TOP_ACTIVITY_MSG = 19; 969 static final int PROC_START_TIMEOUT_MSG = 20; 970 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 971 static final int KILL_APPLICATION_MSG = 22; 972 973 AlertDialog mUidAlert; 974 975 final Handler mHandler = new Handler() { 976 //public Handler() { 977 // if (localLOGV) Log.v(TAG, "Handler started!"); 978 //} 979 980 public void handleMessage(Message msg) { 981 switch (msg.what) { 982 case SHOW_ERROR_MSG: { 983 HashMap data = (HashMap) msg.obj; 984 synchronized (ActivityManagerService.this) { 985 ProcessRecord proc = (ProcessRecord)data.get("app"); 986 if (proc != null && proc.crashDialog != null) { 987 Log.e(TAG, "App already has crash dialog: " + proc); 988 return; 989 } 990 AppErrorResult res = (AppErrorResult) data.get("result"); 991 if (!mSleeping && !mShuttingDown) { 992 Dialog d = new AppErrorDialog(mContext, res, proc); 993 d.show(); 994 proc.crashDialog = d; 995 } else { 996 // The device is asleep, so just pretend that the user 997 // saw a crash dialog and hit "force quit". 998 res.set(0); 999 } 1000 } 1001 1002 ensureBootCompleted(); 1003 } break; 1004 case SHOW_NOT_RESPONDING_MSG: { 1005 synchronized (ActivityManagerService.this) { 1006 HashMap data = (HashMap) msg.obj; 1007 ProcessRecord proc = (ProcessRecord)data.get("app"); 1008 if (proc != null && proc.anrDialog != null) { 1009 Log.e(TAG, "App already has anr dialog: " + proc); 1010 return; 1011 } 1012 1013 broadcastIntentLocked(null, null, new Intent("android.intent.action.ANR"), 1014 null, null, 0, null, null, null, 1015 false, false, MY_PID, Process.SYSTEM_UID); 1016 1017 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1018 mContext, proc, (HistoryRecord)data.get("activity")); 1019 d.show(); 1020 proc.anrDialog = d; 1021 } 1022 1023 ensureBootCompleted(); 1024 } break; 1025 case SHOW_FACTORY_ERROR_MSG: { 1026 Dialog d = new FactoryErrorDialog( 1027 mContext, msg.getData().getCharSequence("msg")); 1028 d.show(); 1029 ensureBootCompleted(); 1030 } break; 1031 case UPDATE_CONFIGURATION_MSG: { 1032 final ContentResolver resolver = mContext.getContentResolver(); 1033 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1034 } break; 1035 case GC_BACKGROUND_PROCESSES_MSG: { 1036 synchronized (ActivityManagerService.this) { 1037 performAppGcsIfAppropriateLocked(); 1038 } 1039 } break; 1040 case WAIT_FOR_DEBUGGER_MSG: { 1041 synchronized (ActivityManagerService.this) { 1042 ProcessRecord app = (ProcessRecord)msg.obj; 1043 if (msg.arg1 != 0) { 1044 if (!app.waitedForDebugger) { 1045 Dialog d = new AppWaitingForDebuggerDialog( 1046 ActivityManagerService.this, 1047 mContext, app); 1048 app.waitDialog = d; 1049 app.waitedForDebugger = true; 1050 d.show(); 1051 } 1052 } else { 1053 if (app.waitDialog != null) { 1054 app.waitDialog.dismiss(); 1055 app.waitDialog = null; 1056 } 1057 } 1058 } 1059 } break; 1060 case BROADCAST_INTENT_MSG: { 1061 if (DEBUG_BROADCAST) Log.v( 1062 TAG, "Received BROADCAST_INTENT_MSG"); 1063 processNextBroadcast(true); 1064 } break; 1065 case BROADCAST_TIMEOUT_MSG: { 1066 if (mDidDexOpt) { 1067 mDidDexOpt = false; 1068 Message nmsg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG); 1069 mHandler.sendMessageDelayed(nmsg, BROADCAST_TIMEOUT); 1070 return; 1071 } 1072 broadcastTimeout(); 1073 } break; 1074 case PAUSE_TIMEOUT_MSG: { 1075 IBinder token = (IBinder)msg.obj; 1076 // We don't at this point know if the activity is fullscreen, 1077 // so we need to be conservative and assume it isn't. 1078 Log.w(TAG, "Activity pause timeout for " + token); 1079 activityPaused(token, null, true); 1080 } break; 1081 case IDLE_TIMEOUT_MSG: { 1082 if (mDidDexOpt) { 1083 mDidDexOpt = false; 1084 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 1085 nmsg.obj = msg.obj; 1086 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); 1087 return; 1088 } 1089 // We don't at this point know if the activity is fullscreen, 1090 // so we need to be conservative and assume it isn't. 1091 IBinder token = (IBinder)msg.obj; 1092 Log.w(TAG, "Activity idle timeout for " + token); 1093 activityIdleInternal(token, true, null); 1094 } break; 1095 case DESTROY_TIMEOUT_MSG: { 1096 IBinder token = (IBinder)msg.obj; 1097 // We don't at this point know if the activity is fullscreen, 1098 // so we need to be conservative and assume it isn't. 1099 Log.w(TAG, "Activity destroy timeout for " + token); 1100 activityDestroyed(token); 1101 } break; 1102 case IDLE_NOW_MSG: { 1103 IBinder token = (IBinder)msg.obj; 1104 activityIdle(token, null); 1105 } break; 1106 case SERVICE_TIMEOUT_MSG: { 1107 if (mDidDexOpt) { 1108 mDidDexOpt = false; 1109 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1110 nmsg.obj = msg.obj; 1111 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT); 1112 return; 1113 } 1114 serviceTimeout((ProcessRecord)msg.obj); 1115 } break; 1116 case UPDATE_TIME_ZONE: { 1117 synchronized (ActivityManagerService.this) { 1118 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1119 ProcessRecord r = mLruProcesses.get(i); 1120 if (r.thread != null) { 1121 try { 1122 r.thread.updateTimeZone(); 1123 } catch (RemoteException ex) { 1124 Log.w(TAG, "Failed to update time zone for: " + r.info.processName); 1125 } 1126 } 1127 } 1128 } 1129 } break; 1130 case SHOW_UID_ERROR_MSG: { 1131 // XXX This is a temporary dialog, no need to localize. 1132 AlertDialog d = new BaseErrorDialog(mContext); 1133 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1134 d.setCancelable(false); 1135 d.setTitle("System UIDs Inconsistent"); 1136 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable."); 1137 d.setButton("I'm Feeling Lucky", 1138 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1139 mUidAlert = d; 1140 d.show(); 1141 } break; 1142 case IM_FEELING_LUCKY_MSG: { 1143 if (mUidAlert != null) { 1144 mUidAlert.dismiss(); 1145 mUidAlert = null; 1146 } 1147 } break; 1148 case LAUNCH_TIMEOUT_MSG: { 1149 if (mDidDexOpt) { 1150 mDidDexOpt = false; 1151 Message nmsg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG); 1152 mHandler.sendMessageDelayed(nmsg, LAUNCH_TIMEOUT); 1153 return; 1154 } 1155 synchronized (ActivityManagerService.this) { 1156 if (mLaunchingActivity.isHeld()) { 1157 Log.w(TAG, "Launch timeout has expired, giving up wake lock!"); 1158 mLaunchingActivity.release(); 1159 } 1160 } 1161 } break; 1162 case SERVICE_ERROR_MSG: { 1163 ServiceRecord srv = (ServiceRecord)msg.obj; 1164 // This needs to be *un*synchronized to avoid deadlock. 1165 Checkin.logEvent(mContext.getContentResolver(), 1166 Checkin.Events.Tag.SYSTEM_SERVICE_LOOPING, 1167 srv.name.toShortString()); 1168 } break; 1169 case RESUME_TOP_ACTIVITY_MSG: { 1170 synchronized (ActivityManagerService.this) { 1171 resumeTopActivityLocked(null); 1172 } 1173 } break; 1174 case PROC_START_TIMEOUT_MSG: { 1175 if (mDidDexOpt) { 1176 mDidDexOpt = false; 1177 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1178 nmsg.obj = msg.obj; 1179 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1180 return; 1181 } 1182 ProcessRecord app = (ProcessRecord)msg.obj; 1183 synchronized (ActivityManagerService.this) { 1184 processStartTimedOutLocked(app); 1185 } 1186 } break; 1187 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1188 synchronized (ActivityManagerService.this) { 1189 doPendingActivityLaunchesLocked(true); 1190 } 1191 } break; 1192 case KILL_APPLICATION_MSG: { 1193 synchronized (ActivityManagerService.this) { 1194 int uid = msg.arg1; 1195 boolean restart = (msg.arg2 == 1); 1196 String pkg = (String) msg.obj; 1197 forceStopPackageLocked(pkg, uid, restart); 1198 } 1199 } break; 1200 } 1201 } 1202 }; 1203 1204 public static void setSystemProcess() { 1205 try { 1206 ActivityManagerService m = mSelf; 1207 1208 ServiceManager.addService("activity", m); 1209 ServiceManager.addService("meminfo", new MemBinder(m)); 1210 if (MONITOR_CPU_USAGE) { 1211 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1212 } 1213 ServiceManager.addService("permission", new PermissionController(m)); 1214 1215 ApplicationInfo info = 1216 mSelf.mContext.getPackageManager().getApplicationInfo( 1217 "android", STOCK_PM_FLAGS); 1218 mSystemThread.installSystemApplicationInfo(info); 1219 1220 synchronized (mSelf) { 1221 ProcessRecord app = mSelf.newProcessRecordLocked( 1222 mSystemThread.getApplicationThread(), info, 1223 info.processName); 1224 app.persistent = true; 1225 app.pid = Process.myPid(); 1226 app.maxAdj = SYSTEM_ADJ; 1227 mSelf.mProcessNames.put(app.processName, app.info.uid, app); 1228 synchronized (mSelf.mPidsSelfLocked) { 1229 mSelf.mPidsSelfLocked.put(app.pid, app); 1230 } 1231 mSelf.updateLruProcessLocked(app, true, true); 1232 } 1233 } catch (PackageManager.NameNotFoundException e) { 1234 throw new RuntimeException( 1235 "Unable to find android system package", e); 1236 } 1237 } 1238 1239 public void setWindowManager(WindowManagerService wm) { 1240 mWindowManager = wm; 1241 } 1242 1243 public static final Context main(int factoryTest) { 1244 AThread thr = new AThread(); 1245 thr.start(); 1246 1247 synchronized (thr) { 1248 while (thr.mService == null) { 1249 try { 1250 thr.wait(); 1251 } catch (InterruptedException e) { 1252 } 1253 } 1254 } 1255 1256 ActivityManagerService m = thr.mService; 1257 mSelf = m; 1258 ActivityThread at = ActivityThread.systemMain(); 1259 mSystemThread = at; 1260 Context context = at.getSystemContext(); 1261 m.mContext = context; 1262 m.mFactoryTest = factoryTest; 1263 PowerManager pm = 1264 (PowerManager)context.getSystemService(Context.POWER_SERVICE); 1265 m.mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep"); 1266 m.mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch"); 1267 m.mLaunchingActivity.setReferenceCounted(false); 1268 1269 m.mBatteryStatsService.publish(context); 1270 m.mUsageStatsService.publish(context); 1271 1272 synchronized (thr) { 1273 thr.mReady = true; 1274 thr.notifyAll(); 1275 } 1276 1277 m.startRunning(null, null, null, null); 1278 1279 return context; 1280 } 1281 1282 public static ActivityManagerService self() { 1283 return mSelf; 1284 } 1285 1286 static class AThread extends Thread { 1287 ActivityManagerService mService; 1288 boolean mReady = false; 1289 1290 public AThread() { 1291 super("ActivityManager"); 1292 } 1293 1294 public void run() { 1295 Looper.prepare(); 1296 1297 android.os.Process.setThreadPriority( 1298 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1299 1300 ActivityManagerService m = new ActivityManagerService(); 1301 1302 synchronized (this) { 1303 mService = m; 1304 notifyAll(); 1305 } 1306 1307 synchronized (this) { 1308 while (!mReady) { 1309 try { 1310 wait(); 1311 } catch (InterruptedException e) { 1312 } 1313 } 1314 } 1315 1316 Looper.loop(); 1317 } 1318 } 1319 1320 static class MemBinder extends Binder { 1321 ActivityManagerService mActivityManagerService; 1322 MemBinder(ActivityManagerService activityManagerService) { 1323 mActivityManagerService = activityManagerService; 1324 } 1325 1326 @Override 1327 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1328 ActivityManagerService service = mActivityManagerService; 1329 ArrayList<ProcessRecord> procs; 1330 synchronized (mActivityManagerService) { 1331 if (args != null && args.length > 0 1332 && args[0].charAt(0) != '-') { 1333 procs = new ArrayList<ProcessRecord>(); 1334 int pid = -1; 1335 try { 1336 pid = Integer.parseInt(args[0]); 1337 } catch (NumberFormatException e) { 1338 1339 } 1340 for (int i=service.mLruProcesses.size()-1; i>=0; i--) { 1341 ProcessRecord proc = service.mLruProcesses.get(i); 1342 if (proc.pid == pid) { 1343 procs.add(proc); 1344 } else if (proc.processName.equals(args[0])) { 1345 procs.add(proc); 1346 } 1347 } 1348 if (procs.size() <= 0) { 1349 pw.println("No process found for: " + args[0]); 1350 return; 1351 } 1352 } else { 1353 procs = service.mLruProcesses; 1354 } 1355 } 1356 dumpApplicationMemoryUsage(fd, pw, procs, " ", args); 1357 } 1358 } 1359 1360 static class CpuBinder extends Binder { 1361 ActivityManagerService mActivityManagerService; 1362 CpuBinder(ActivityManagerService activityManagerService) { 1363 mActivityManagerService = activityManagerService; 1364 } 1365 1366 @Override 1367 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1368 synchronized (mActivityManagerService.mProcessStatsThread) { 1369 pw.print(mActivityManagerService.mProcessStats.printCurrentState()); 1370 } 1371 } 1372 } 1373 1374 private ActivityManagerService() { 1375 String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT"); 1376 if (v != null && Integer.getInteger(v) != 0) { 1377 mSimpleProcessManagement = true; 1378 } 1379 v = System.getenv("ANDROID_DEBUG_APP"); 1380 if (v != null) { 1381 mSimpleProcessManagement = true; 1382 } 1383 1384 Log.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1385 1386 MY_PID = Process.myPid(); 1387 1388 File dataDir = Environment.getDataDirectory(); 1389 File systemDir = new File(dataDir, "system"); 1390 systemDir.mkdirs(); 1391 mBatteryStatsService = new BatteryStatsService(new File( 1392 systemDir, "batterystats.bin").toString()); 1393 mBatteryStatsService.getActiveStatistics().readLocked(); 1394 mBatteryStatsService.getActiveStatistics().writeLocked(); 1395 1396 mUsageStatsService = new UsageStatsService( new File( 1397 systemDir, "usagestats").toString()); 1398 1399 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1400 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1401 1402 mConfiguration.makeDefault(); 1403 mProcessStats.init(); 1404 1405 // Add ourself to the Watchdog monitors. 1406 Watchdog.getInstance().addMonitor(this); 1407 1408 mProcessStatsThread = new Thread("ProcessStats") { 1409 public void run() { 1410 while (true) { 1411 try { 1412 try { 1413 synchronized(this) { 1414 final long now = SystemClock.uptimeMillis(); 1415 long nextCpuDelay = (mLastCpuTime+MONITOR_CPU_MAX_TIME)-now; 1416 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1417 //Log.i(TAG, "Cpu delay=" + nextCpuDelay 1418 // + ", write delay=" + nextWriteDelay); 1419 if (nextWriteDelay < nextCpuDelay) { 1420 nextCpuDelay = nextWriteDelay; 1421 } 1422 if (nextCpuDelay > 0) { 1423 this.wait(nextCpuDelay); 1424 } 1425 } 1426 } catch (InterruptedException e) { 1427 } 1428 1429 updateCpuStatsNow(); 1430 } catch (Exception e) { 1431 Log.e(TAG, "Unexpected exception collecting process stats", e); 1432 } 1433 } 1434 } 1435 }; 1436 mProcessStatsThread.start(); 1437 } 1438 1439 @Override 1440 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1441 throws RemoteException { 1442 try { 1443 return super.onTransact(code, data, reply, flags); 1444 } catch (RuntimeException e) { 1445 // The activity manager only throws security exceptions, so let's 1446 // log all others. 1447 if (!(e instanceof SecurityException)) { 1448 Log.e(TAG, "Activity Manager Crash", e); 1449 } 1450 throw e; 1451 } 1452 } 1453 1454 void updateCpuStats() { 1455 synchronized (mProcessStatsThread) { 1456 final long now = SystemClock.uptimeMillis(); 1457 if (mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) { 1458 mProcessStatsThread.notify(); 1459 } 1460 } 1461 } 1462 1463 void updateCpuStatsNow() { 1464 synchronized (mProcessStatsThread) { 1465 final long now = SystemClock.uptimeMillis(); 1466 boolean haveNewCpuStats = false; 1467 1468 if (MONITOR_CPU_USAGE && 1469 mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) { 1470 mLastCpuTime = now; 1471 haveNewCpuStats = true; 1472 mProcessStats.update(); 1473 //Log.i(TAG, mProcessStats.printCurrentState()); 1474 //Log.i(TAG, "Total CPU usage: " 1475 // + mProcessStats.getTotalCpuPercent() + "%"); 1476 1477 // Log the cpu usage if the property is set. 1478 if ("true".equals(SystemProperties.get("events.cpu"))) { 1479 int user = mProcessStats.getLastUserTime(); 1480 int system = mProcessStats.getLastSystemTime(); 1481 int iowait = mProcessStats.getLastIoWaitTime(); 1482 int irq = mProcessStats.getLastIrqTime(); 1483 int softIrq = mProcessStats.getLastSoftIrqTime(); 1484 int idle = mProcessStats.getLastIdleTime(); 1485 1486 int total = user + system + iowait + irq + softIrq + idle; 1487 if (total == 0) total = 1; 1488 1489 EventLog.writeEvent(EventLogTags.CPU, 1490 ((user+system+iowait+irq+softIrq) * 100) / total, 1491 (user * 100) / total, 1492 (system * 100) / total, 1493 (iowait * 100) / total, 1494 (irq * 100) / total, 1495 (softIrq * 100) / total); 1496 } 1497 } 1498 1499 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1500 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1501 synchronized(bstats) { 1502 synchronized(mPidsSelfLocked) { 1503 if (haveNewCpuStats) { 1504 if (mBatteryStatsService.isOnBattery()) { 1505 final int N = mProcessStats.countWorkingStats(); 1506 for (int i=0; i<N; i++) { 1507 ProcessStats.Stats st 1508 = mProcessStats.getWorkingStats(i); 1509 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1510 if (pr != null) { 1511 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1512 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); 1513 ps.addSpeedStepTimes(cpuSpeedTimes); 1514 } else { 1515 BatteryStatsImpl.Uid.Proc ps = 1516 bstats.getProcessStatsLocked(st.name, st.pid); 1517 if (ps != null) { 1518 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); 1519 ps.addSpeedStepTimes(cpuSpeedTimes); 1520 } 1521 } 1522 } 1523 } 1524 } 1525 } 1526 1527 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1528 mLastWriteTime = now; 1529 mBatteryStatsService.getActiveStatistics().writeLocked(); 1530 } 1531 } 1532 } 1533 } 1534 1535 /** 1536 * Initialize the application bind args. These are passed to each 1537 * process when the bindApplication() IPC is sent to the process. They're 1538 * lazily setup to make sure the services are running when they're asked for. 1539 */ 1540 private HashMap<String, IBinder> getCommonServicesLocked() { 1541 if (mAppBindArgs == null) { 1542 mAppBindArgs = new HashMap<String, IBinder>(); 1543 1544 // Setup the application init args 1545 mAppBindArgs.put("package", ServiceManager.getService("package")); 1546 mAppBindArgs.put("window", ServiceManager.getService("window")); 1547 mAppBindArgs.put(Context.ALARM_SERVICE, 1548 ServiceManager.getService(Context.ALARM_SERVICE)); 1549 } 1550 return mAppBindArgs; 1551 } 1552 1553 private final void setFocusedActivityLocked(HistoryRecord r) { 1554 if (mFocusedActivity != r) { 1555 mFocusedActivity = r; 1556 mWindowManager.setFocusedApp(r, true); 1557 } 1558 } 1559 1560 private final void updateLruProcessLocked(ProcessRecord app, 1561 boolean oomAdj, boolean updateActivityTime) { 1562 // put it on the LRU to keep track of when it should be exited. 1563 int lrui = mLruProcesses.indexOf(app); 1564 if (lrui >= 0) mLruProcesses.remove(lrui); 1565 1566 int i = mLruProcesses.size()-1; 1567 int skipTop = 0; 1568 1569 // compute the new weight for this process. 1570 if (updateActivityTime) { 1571 app.lastActivityTime = SystemClock.uptimeMillis(); 1572 } 1573 if (app.activities.size() > 0) { 1574 // If this process has activities, we more strongly want to keep 1575 // it around. 1576 app.lruWeight = app.lastActivityTime; 1577 } else if (app.pubProviders.size() > 0) { 1578 // If this process contains content providers, we want to keep 1579 // it a little more strongly. 1580 app.lruWeight = app.lastActivityTime - CONTENT_APP_IDLE_OFFSET; 1581 // Also don't let it kick out the first few "real" hidden processes. 1582 skipTop = MIN_HIDDEN_APPS; 1583 } else { 1584 // If this process doesn't have activities, we less strongly 1585 // want to keep it around, and generally want to avoid getting 1586 // in front of any very recently used activities. 1587 app.lruWeight = app.lastActivityTime - EMPTY_APP_IDLE_OFFSET; 1588 // Also don't let it kick out the first few "real" hidden processes. 1589 skipTop = MIN_HIDDEN_APPS; 1590 } 1591 while (i >= 0) { 1592 ProcessRecord p = mLruProcesses.get(i); 1593 // If this app shouldn't be in front of the first N background 1594 // apps, then skip over that many that are currently hidden. 1595 if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) { 1596 skipTop--; 1597 } 1598 if (p.lruWeight <= app.lruWeight){ 1599 mLruProcesses.add(i+1, app); 1600 break; 1601 } 1602 i--; 1603 } 1604 if (i < 0) { 1605 mLruProcesses.add(0, app); 1606 } 1607 1608 //Log.i(TAG, "Putting proc to front: " + app.processName); 1609 if (oomAdj) { 1610 updateOomAdjLocked(); 1611 } 1612 } 1613 1614 private final boolean updateLRUListLocked(HistoryRecord r) { 1615 final boolean hadit = mLRUActivities.remove(r); 1616 mLRUActivities.add(r); 1617 return hadit; 1618 } 1619 1620 private final HistoryRecord topRunningActivityLocked(HistoryRecord notTop) { 1621 int i = mHistory.size()-1; 1622 while (i >= 0) { 1623 HistoryRecord r = (HistoryRecord)mHistory.get(i); 1624 if (!r.finishing && r != notTop) { 1625 return r; 1626 } 1627 i--; 1628 } 1629 return null; 1630 } 1631 1632 private final HistoryRecord topRunningNonDelayedActivityLocked(HistoryRecord notTop) { 1633 int i = mHistory.size()-1; 1634 while (i >= 0) { 1635 HistoryRecord r = (HistoryRecord)mHistory.get(i); 1636 if (!r.finishing && !r.delayedResume && r != notTop) { 1637 return r; 1638 } 1639 i--; 1640 } 1641 return null; 1642 } 1643 1644 /** 1645 * This is a simplified version of topRunningActivityLocked that provides a number of 1646 * optional skip-over modes. It is intended for use with the ActivityController hook only. 1647 * 1648 * @param token If non-null, any history records matching this token will be skipped. 1649 * @param taskId If non-zero, we'll attempt to skip over records with the same task ID. 1650 * 1651 * @return Returns the HistoryRecord of the next activity on the stack. 1652 */ 1653 private final HistoryRecord topRunningActivityLocked(IBinder token, int taskId) { 1654 int i = mHistory.size()-1; 1655 while (i >= 0) { 1656 HistoryRecord r = (HistoryRecord)mHistory.get(i); 1657 // Note: the taskId check depends on real taskId fields being non-zero 1658 if (!r.finishing && (token != r) && (taskId != r.task.taskId)) { 1659 return r; 1660 } 1661 i--; 1662 } 1663 return null; 1664 } 1665 1666 private final ProcessRecord getProcessRecordLocked( 1667 String processName, int uid) { 1668 if (uid == Process.SYSTEM_UID) { 1669 // The system gets to run in any process. If there are multiple 1670 // processes with the same uid, just pick the first (this 1671 // should never happen). 1672 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1673 processName); 1674 return procs != null ? procs.valueAt(0) : null; 1675 } 1676 ProcessRecord proc = mProcessNames.get(processName, uid); 1677 return proc; 1678 } 1679 1680 private void ensurePackageDexOpt(String packageName) { 1681 IPackageManager pm = ActivityThread.getPackageManager(); 1682 try { 1683 if (pm.performDexOpt(packageName)) { 1684 mDidDexOpt = true; 1685 } 1686 } catch (RemoteException e) { 1687 } 1688 } 1689 1690 private boolean isNextTransitionForward() { 1691 int transit = mWindowManager.getPendingAppTransition(); 1692 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1693 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1694 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1695 } 1696 1697 private final boolean realStartActivityLocked(HistoryRecord r, 1698 ProcessRecord app, boolean andResume, boolean checkConfig) 1699 throws RemoteException { 1700 1701 r.startFreezingScreenLocked(app, 0); 1702 mWindowManager.setAppVisibility(r, true); 1703 1704 // Have the window manager re-evaluate the orientation of 1705 // the screen based on the new activity order. Note that 1706 // as a result of this, it can call back into the activity 1707 // manager with a new orientation. We don't care about that, 1708 // because the activity is not currently running so we are 1709 // just restarting it anyway. 1710 if (checkConfig) { 1711 Configuration config = mWindowManager.updateOrientationFromAppTokens( 1712 mConfiguration, 1713 r.mayFreezeScreenLocked(app) ? r : null); 1714 updateConfigurationLocked(config, r); 1715 } 1716 1717 r.app = app; 1718 1719 if (localLOGV) Log.v(TAG, "Launching: " + r); 1720 1721 int idx = app.activities.indexOf(r); 1722 if (idx < 0) { 1723 app.activities.add(r); 1724 } 1725 updateLruProcessLocked(app, true, true); 1726 1727 try { 1728 if (app.thread == null) { 1729 throw new RemoteException(); 1730 } 1731 List<ResultInfo> results = null; 1732 List<Intent> newIntents = null; 1733 if (andResume) { 1734 results = r.results; 1735 newIntents = r.newIntents; 1736 } 1737 if (DEBUG_SWITCH) Log.v(TAG, "Launching: " + r 1738 + " icicle=" + r.icicle 1739 + " with results=" + results + " newIntents=" + newIntents 1740 + " andResume=" + andResume); 1741 if (andResume) { 1742 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY, 1743 System.identityHashCode(r), 1744 r.task.taskId, r.shortComponentName); 1745 } 1746 if (r.isHomeActivity) { 1747 mHomeProcess = app; 1748 } 1749 ensurePackageDexOpt(r.intent.getComponent().getPackageName()); 1750 app.thread.scheduleLaunchActivity(new Intent(r.intent), r, 1751 System.identityHashCode(r), 1752 r.info, r.icicle, results, newIntents, !andResume, 1753 isNextTransitionForward()); 1754 } catch (RemoteException e) { 1755 if (r.launchFailed) { 1756 // This is the second time we failed -- finish activity 1757 // and give up. 1758 Log.e(TAG, "Second failure launching " 1759 + r.intent.getComponent().flattenToShortString() 1760 + ", giving up", e); 1761 appDiedLocked(app, app.pid, app.thread); 1762 requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null, 1763 "2nd-crash"); 1764 return false; 1765 } 1766 1767 // This is the first time we failed -- restart process and 1768 // retry. 1769 app.activities.remove(r); 1770 throw e; 1771 } 1772 1773 r.launchFailed = false; 1774 if (updateLRUListLocked(r)) { 1775 Log.w(TAG, "Activity " + r 1776 + " being launched, but already in LRU list"); 1777 } 1778 1779 if (andResume) { 1780 // As part of the process of launching, ActivityThread also performs 1781 // a resume. 1782 r.state = ActivityState.RESUMED; 1783 r.icicle = null; 1784 r.haveState = false; 1785 r.stopped = false; 1786 mResumedActivity = r; 1787 r.task.touchActiveTime(); 1788 completeResumeLocked(r); 1789 pauseIfSleepingLocked(); 1790 } else { 1791 // This activity is not starting in the resumed state... which 1792 // should look like we asked it to pause+stop (but remain visible), 1793 // and it has done so and reported back the current icicle and 1794 // other state. 1795 r.state = ActivityState.STOPPED; 1796 r.stopped = true; 1797 } 1798 1799 // Launch the new version setup screen if needed. We do this -after- 1800 // launching the initial activity (that is, home), so that it can have 1801 // a chance to initialize itself while in the background, making the 1802 // switch back to it faster and look better. 1803 startSetupActivityLocked(); 1804 1805 return true; 1806 } 1807 1808 private final void startSpecificActivityLocked(HistoryRecord r, 1809 boolean andResume, boolean checkConfig) { 1810 // Is this activity's application already running? 1811 ProcessRecord app = getProcessRecordLocked(r.processName, 1812 r.info.applicationInfo.uid); 1813 1814 if (r.startTime == 0) { 1815 r.startTime = SystemClock.uptimeMillis(); 1816 if (mInitialStartTime == 0) { 1817 mInitialStartTime = r.startTime; 1818 } 1819 } else if (mInitialStartTime == 0) { 1820 mInitialStartTime = SystemClock.uptimeMillis(); 1821 } 1822 1823 if (app != null && app.thread != null) { 1824 try { 1825 realStartActivityLocked(r, app, andResume, checkConfig); 1826 return; 1827 } catch (RemoteException e) { 1828 Log.w(TAG, "Exception when starting activity " 1829 + r.intent.getComponent().flattenToShortString(), e); 1830 } 1831 1832 // If a dead object exception was thrown -- fall through to 1833 // restart the application. 1834 } 1835 1836 startProcessLocked(r.processName, r.info.applicationInfo, true, 0, 1837 "activity", r.intent.getComponent(), false); 1838 } 1839 1840 private final ProcessRecord startProcessLocked(String processName, 1841 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1842 String hostingType, ComponentName hostingName, boolean allowWhileBooting) { 1843 ProcessRecord app = getProcessRecordLocked(processName, info.uid); 1844 // We don't have to do anything more if: 1845 // (1) There is an existing application record; and 1846 // (2) The caller doesn't think it is dead, OR there is no thread 1847 // object attached to it so we know it couldn't have crashed; and 1848 // (3) There is a pid assigned to it, so it is either starting or 1849 // already running. 1850 if (DEBUG_PROCESSES) Log.v(TAG, "startProcess: name=" + processName 1851 + " app=" + app + " knownToBeDead=" + knownToBeDead 1852 + " thread=" + (app != null ? app.thread : null) 1853 + " pid=" + (app != null ? app.pid : -1)); 1854 if (app != null && 1855 (!knownToBeDead || app.thread == null) && app.pid > 0) { 1856 return app; 1857 } 1858 1859 String hostingNameStr = hostingName != null 1860 ? hostingName.flattenToShortString() : null; 1861 1862 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1863 // If we are in the background, then check to see if this process 1864 // is bad. If so, we will just silently fail. 1865 if (mBadProcesses.get(info.processName, info.uid) != null) { 1866 return null; 1867 } 1868 } else { 1869 // When the user is explicitly starting a process, then clear its 1870 // crash count so that we won't make it bad until they see at 1871 // least one crash dialog again, and make the process good again 1872 // if it had been bad. 1873 mProcessCrashTimes.remove(info.processName, info.uid); 1874 if (mBadProcesses.get(info.processName, info.uid) != null) { 1875 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1876 info.processName); 1877 mBadProcesses.remove(info.processName, info.uid); 1878 if (app != null) { 1879 app.bad = false; 1880 } 1881 } 1882 } 1883 1884 if (app == null) { 1885 app = newProcessRecordLocked(null, info, processName); 1886 mProcessNames.put(processName, info.uid, app); 1887 } else { 1888 // If this is a new package in the process, add the package to the list 1889 app.addPackage(info.packageName); 1890 } 1891 1892 // If the system is not ready yet, then hold off on starting this 1893 // process until it is. 1894 if (!mSystemReady 1895 && !isAllowedWhileBooting(info) 1896 && !allowWhileBooting) { 1897 if (!mProcessesOnHold.contains(app)) { 1898 mProcessesOnHold.add(app); 1899 } 1900 return app; 1901 } 1902 1903 startProcessLocked(app, hostingType, hostingNameStr); 1904 return (app.pid != 0) ? app : null; 1905 } 1906 1907 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1908 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1909 } 1910 1911 private final void startProcessLocked(ProcessRecord app, 1912 String hostingType, String hostingNameStr) { 1913 if (app.pid > 0 && app.pid != MY_PID) { 1914 synchronized (mPidsSelfLocked) { 1915 mPidsSelfLocked.remove(app.pid); 1916 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1917 } 1918 app.pid = 0; 1919 } 1920 1921 mProcessesOnHold.remove(app); 1922 1923 updateCpuStats(); 1924 1925 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 1926 mProcDeaths[0] = 0; 1927 1928 try { 1929 int uid = app.info.uid; 1930 int[] gids = null; 1931 try { 1932 gids = mContext.getPackageManager().getPackageGids( 1933 app.info.packageName); 1934 } catch (PackageManager.NameNotFoundException e) { 1935 Log.w(TAG, "Unable to retrieve gids", e); 1936 } 1937 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 1938 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 1939 && mTopComponent != null 1940 && app.processName.equals(mTopComponent.getPackageName())) { 1941 uid = 0; 1942 } 1943 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 1944 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 1945 uid = 0; 1946 } 1947 } 1948 int debugFlags = 0; 1949 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 1950 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 1951 } 1952 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 1953 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 1954 } 1955 if ("1".equals(SystemProperties.get("debug.assert"))) { 1956 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 1957 } 1958 int pid = Process.start("android.app.ActivityThread", 1959 mSimpleProcessManagement ? app.processName : null, uid, uid, 1960 gids, debugFlags, null); 1961 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 1962 synchronized (bs) { 1963 if (bs.isOnBattery()) { 1964 app.batteryStats.incStartsLocked(); 1965 } 1966 } 1967 1968 EventLog.writeEvent(EventLogTags.AM_PROC_START, pid, uid, 1969 app.processName, hostingType, 1970 hostingNameStr != null ? hostingNameStr : ""); 1971 1972 if (app.persistent) { 1973 Watchdog.getInstance().processStarted(app, app.processName, pid); 1974 } 1975 1976 StringBuilder buf = mStringBuilder; 1977 buf.setLength(0); 1978 buf.append("Start proc "); 1979 buf.append(app.processName); 1980 buf.append(" for "); 1981 buf.append(hostingType); 1982 if (hostingNameStr != null) { 1983 buf.append(" "); 1984 buf.append(hostingNameStr); 1985 } 1986 buf.append(": pid="); 1987 buf.append(pid); 1988 buf.append(" uid="); 1989 buf.append(uid); 1990 buf.append(" gids={"); 1991 if (gids != null) { 1992 for (int gi=0; gi<gids.length; gi++) { 1993 if (gi != 0) buf.append(", "); 1994 buf.append(gids[gi]); 1995 1996 } 1997 } 1998 buf.append("}"); 1999 Log.i(TAG, buf.toString()); 2000 if (pid == 0 || pid == MY_PID) { 2001 // Processes are being emulated with threads. 2002 app.pid = MY_PID; 2003 app.removed = false; 2004 mStartingProcesses.add(app); 2005 } else if (pid > 0) { 2006 app.pid = pid; 2007 app.removed = false; 2008 synchronized (mPidsSelfLocked) { 2009 this.mPidsSelfLocked.put(pid, app); 2010 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2011 msg.obj = app; 2012 mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT); 2013 } 2014 } else { 2015 app.pid = 0; 2016 RuntimeException e = new RuntimeException( 2017 "Failure starting process " + app.processName 2018 + ": returned pid=" + pid); 2019 Log.e(TAG, e.getMessage(), e); 2020 } 2021 } catch (RuntimeException e) { 2022 // XXX do better error recovery. 2023 app.pid = 0; 2024 Log.e(TAG, "Failure starting process " + app.processName, e); 2025 } 2026 } 2027 2028 private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) { 2029 if (mPausingActivity != null) { 2030 RuntimeException e = new RuntimeException(); 2031 Log.e(TAG, "Trying to pause when pause is already pending for " 2032 + mPausingActivity, e); 2033 } 2034 HistoryRecord prev = mResumedActivity; 2035 if (prev == null) { 2036 RuntimeException e = new RuntimeException(); 2037 Log.e(TAG, "Trying to pause when nothing is resumed", e); 2038 resumeTopActivityLocked(null); 2039 return; 2040 } 2041 if (DEBUG_PAUSE) Log.v(TAG, "Start pausing: " + prev); 2042 mResumedActivity = null; 2043 mPausingActivity = prev; 2044 mLastPausedActivity = prev; 2045 prev.state = ActivityState.PAUSING; 2046 prev.task.touchActiveTime(); 2047 2048 updateCpuStats(); 2049 2050 if (prev.app != null && prev.app.thread != null) { 2051 if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending pause: " + prev); 2052 try { 2053 EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY, 2054 System.identityHashCode(prev), 2055 prev.shortComponentName); 2056 prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving, 2057 prev.configChangeFlags); 2058 updateUsageStats(prev, false); 2059 } catch (Exception e) { 2060 // Ignore exception, if process died other code will cleanup. 2061 Log.w(TAG, "Exception thrown during pause", e); 2062 mPausingActivity = null; 2063 mLastPausedActivity = null; 2064 } 2065 } else { 2066 mPausingActivity = null; 2067 mLastPausedActivity = null; 2068 } 2069 2070 // If we are not going to sleep, we want to ensure the device is 2071 // awake until the next activity is started. 2072 if (!mSleeping && !mShuttingDown) { 2073 mLaunchingActivity.acquire(); 2074 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) { 2075 // To be safe, don't allow the wake lock to be held for too long. 2076 Message msg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG); 2077 mHandler.sendMessageDelayed(msg, LAUNCH_TIMEOUT); 2078 } 2079 } 2080 2081 2082 if (mPausingActivity != null) { 2083 // Have the window manager pause its key dispatching until the new 2084 // activity has started. If we're pausing the activity just because 2085 // the screen is being turned off and the UI is sleeping, don't interrupt 2086 // key dispatch; the same activity will pick it up again on wakeup. 2087 if (!uiSleeping) { 2088 prev.pauseKeyDispatchingLocked(); 2089 } else { 2090 if (DEBUG_PAUSE) Log.v(TAG, "Key dispatch not paused for screen off"); 2091 } 2092 2093 // Schedule a pause timeout in case the app doesn't respond. 2094 // We don't give it much time because this directly impacts the 2095 // responsiveness seen by the user. 2096 Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG); 2097 msg.obj = prev; 2098 mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT); 2099 if (DEBUG_PAUSE) Log.v(TAG, "Waiting for pause to complete..."); 2100 } else { 2101 // This activity failed to schedule the 2102 // pause, so just treat it as being paused now. 2103 if (DEBUG_PAUSE) Log.v(TAG, "Activity not running, resuming next."); 2104 resumeTopActivityLocked(null); 2105 } 2106 } 2107 2108 private final void completePauseLocked() { 2109 HistoryRecord prev = mPausingActivity; 2110 if (DEBUG_PAUSE) Log.v(TAG, "Complete pause: " + prev); 2111 2112 if (prev != null) { 2113 if (prev.finishing) { 2114 if (DEBUG_PAUSE) Log.v(TAG, "Executing finish of activity: " + prev); 2115 prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE); 2116 } else if (prev.app != null) { 2117 if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending stop: " + prev); 2118 if (prev.waitingVisible) { 2119 prev.waitingVisible = false; 2120 mWaitingVisibleActivities.remove(prev); 2121 if (DEBUG_SWITCH || DEBUG_PAUSE) Log.v( 2122 TAG, "Complete pause, no longer waiting: " + prev); 2123 } 2124 if (prev.configDestroy) { 2125 // The previous is being paused because the configuration 2126 // is changing, which means it is actually stopping... 2127 // To juggle the fact that we are also starting a new 2128 // instance right now, we need to first completely stop 2129 // the current instance before starting the new one. 2130 if (DEBUG_PAUSE) Log.v(TAG, "Destroying after pause: " + prev); 2131 destroyActivityLocked(prev, true); 2132 } else { 2133 mStoppingActivities.add(prev); 2134 if (mStoppingActivities.size() > 3) { 2135 // If we already have a few activities waiting to stop, 2136 // then give up on things going idle and start clearing 2137 // them out. 2138 if (DEBUG_PAUSE) Log.v(TAG, "To many pending stops, forcing idle"); 2139 Message msg = Message.obtain(); 2140 msg.what = ActivityManagerService.IDLE_NOW_MSG; 2141 mHandler.sendMessage(msg); 2142 } 2143 } 2144 } else { 2145 if (DEBUG_PAUSE) Log.v(TAG, "App died during pause, not stopping: " + prev); 2146 prev = null; 2147 } 2148 mPausingActivity = null; 2149 } 2150 2151 if (!mSleeping && !mShuttingDown) { 2152 resumeTopActivityLocked(prev); 2153 } else { 2154 if (mGoingToSleep.isHeld()) { 2155 mGoingToSleep.release(); 2156 } 2157 if (mShuttingDown) { 2158 notifyAll(); 2159 } 2160 } 2161 2162 if (prev != null) { 2163 prev.resumeKeyDispatchingLocked(); 2164 } 2165 2166 if (prev.app != null && prev.cpuTimeAtResume > 0 && mBatteryStatsService.isOnBattery()) { 2167 long diff = 0; 2168 synchronized (mProcessStatsThread) { 2169 diff = mProcessStats.getCpuTimeForPid(prev.app.pid) - prev.cpuTimeAtResume; 2170 } 2171 if (diff > 0) { 2172 BatteryStatsImpl bsi = mBatteryStatsService.getActiveStatistics(); 2173 synchronized (bsi) { 2174 BatteryStatsImpl.Uid.Proc ps = 2175 bsi.getProcessStatsLocked(prev.info.applicationInfo.uid, 2176 prev.info.packageName); 2177 if (ps != null) { 2178 ps.addForegroundTimeLocked(diff); 2179 } 2180 } 2181 } 2182 } 2183 prev.cpuTimeAtResume = 0; // reset it 2184 } 2185 2186 /** 2187 * Once we know that we have asked an application to put an activity in 2188 * the resumed state (either by launching it or explicitly telling it), 2189 * this function updates the rest of our state to match that fact. 2190 */ 2191 private final void completeResumeLocked(HistoryRecord next) { 2192 next.idle = false; 2193 next.results = null; 2194 next.newIntents = null; 2195 2196 // schedule an idle timeout in case the app doesn't do it for us. 2197 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 2198 msg.obj = next; 2199 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 2200 2201 if (false) { 2202 // The activity was never told to pause, so just keep 2203 // things going as-is. To maintain our own state, 2204 // we need to emulate it coming back and saying it is 2205 // idle. 2206 msg = mHandler.obtainMessage(IDLE_NOW_MSG); 2207 msg.obj = next; 2208 mHandler.sendMessage(msg); 2209 } 2210 2211 reportResumedActivityLocked(next); 2212 2213 next.thumbnail = null; 2214 setFocusedActivityLocked(next); 2215 next.resumeKeyDispatchingLocked(); 2216 ensureActivitiesVisibleLocked(null, 0); 2217 mWindowManager.executeAppTransition(); 2218 mNoAnimActivities.clear(); 2219 2220 // Mark the point when the activity is resuming 2221 // TODO: To be more accurate, the mark should be before the onCreate, 2222 // not after the onResume. But for subsequent starts, onResume is fine. 2223 if (next.app != null) { 2224 synchronized (mProcessStatsThread) { 2225 next.cpuTimeAtResume = mProcessStats.getCpuTimeForPid(next.app.pid); 2226 } 2227 } else { 2228 next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process 2229 } 2230 } 2231 2232 /** 2233 * Make sure that all activities that need to be visible (that is, they 2234 * currently can be seen by the user) actually are. 2235 */ 2236 private final void ensureActivitiesVisibleLocked(HistoryRecord top, 2237 HistoryRecord starting, String onlyThisProcess, int configChanges) { 2238 if (DEBUG_VISBILITY) Log.v( 2239 TAG, "ensureActivitiesVisible behind " + top 2240 + " configChanges=0x" + Integer.toHexString(configChanges)); 2241 2242 // If the top activity is not fullscreen, then we need to 2243 // make sure any activities under it are now visible. 2244 final int count = mHistory.size(); 2245 int i = count-1; 2246 while (mHistory.get(i) != top) { 2247 i--; 2248 } 2249 HistoryRecord r; 2250 boolean behindFullscreen = false; 2251 for (; i>=0; i--) { 2252 r = (HistoryRecord)mHistory.get(i); 2253 if (DEBUG_VISBILITY) Log.v( 2254 TAG, "Make visible? " + r + " finishing=" + r.finishing 2255 + " state=" + r.state); 2256 if (r.finishing) { 2257 continue; 2258 } 2259 2260 final boolean doThisProcess = onlyThisProcess == null 2261 || onlyThisProcess.equals(r.processName); 2262 2263 // First: if this is not the current activity being started, make 2264 // sure it matches the current configuration. 2265 if (r != starting && doThisProcess) { 2266 ensureActivityConfigurationLocked(r, 0); 2267 } 2268 2269 if (r.app == null || r.app.thread == null) { 2270 if (onlyThisProcess == null 2271 || onlyThisProcess.equals(r.processName)) { 2272 // This activity needs to be visible, but isn't even 2273 // running... get it started, but don't resume it 2274 // at this point. 2275 if (DEBUG_VISBILITY) Log.v( 2276 TAG, "Start and freeze screen for " + r); 2277 if (r != starting) { 2278 r.startFreezingScreenLocked(r.app, configChanges); 2279 } 2280 if (!r.visible) { 2281 if (DEBUG_VISBILITY) Log.v( 2282 TAG, "Starting and making visible: " + r); 2283 mWindowManager.setAppVisibility(r, true); 2284 } 2285 if (r != starting) { 2286 startSpecificActivityLocked(r, false, false); 2287 } 2288 } 2289 2290 } else if (r.visible) { 2291 // If this activity is already visible, then there is nothing 2292 // else to do here. 2293 if (DEBUG_VISBILITY) Log.v( 2294 TAG, "Skipping: already visible at " + r); 2295 r.stopFreezingScreenLocked(false); 2296 2297 } else if (onlyThisProcess == null) { 2298 // This activity is not currently visible, but is running. 2299 // Tell it to become visible. 2300 r.visible = true; 2301 if (r.state != ActivityState.RESUMED && r != starting) { 2302 // If this activity is paused, tell it 2303 // to now show its window. 2304 if (DEBUG_VISBILITY) Log.v( 2305 TAG, "Making visible and scheduling visibility: " + r); 2306 try { 2307 mWindowManager.setAppVisibility(r, true); 2308 r.app.thread.scheduleWindowVisibility(r, true); 2309 r.stopFreezingScreenLocked(false); 2310 } catch (Exception e) { 2311 // Just skip on any failure; we'll make it 2312 // visible when it next restarts. 2313 Log.w(TAG, "Exception thrown making visibile: " 2314 + r.intent.getComponent(), e); 2315 } 2316 } 2317 } 2318 2319 // Aggregate current change flags. 2320 configChanges |= r.configChangeFlags; 2321 2322 if (r.fullscreen) { 2323 // At this point, nothing else needs to be shown 2324 if (DEBUG_VISBILITY) Log.v( 2325 TAG, "Stopping: fullscreen at " + r); 2326 behindFullscreen = true; 2327 i--; 2328 break; 2329 } 2330 } 2331 2332 // Now for any activities that aren't visible to the user, make 2333 // sure they no longer are keeping the screen frozen. 2334 while (i >= 0) { 2335 r = (HistoryRecord)mHistory.get(i); 2336 if (DEBUG_VISBILITY) Log.v( 2337 TAG, "Make invisible? " + r + " finishing=" + r.finishing 2338 + " state=" + r.state 2339 + " behindFullscreen=" + behindFullscreen); 2340 if (!r.finishing) { 2341 if (behindFullscreen) { 2342 if (r.visible) { 2343 if (DEBUG_VISBILITY) Log.v( 2344 TAG, "Making invisible: " + r); 2345 r.visible = false; 2346 try { 2347 mWindowManager.setAppVisibility(r, false); 2348 if ((r.state == ActivityState.STOPPING 2349 || r.state == ActivityState.STOPPED) 2350 && r.app != null && r.app.thread != null) { 2351 if (DEBUG_VISBILITY) Log.v( 2352 TAG, "Scheduling invisibility: " + r); 2353 r.app.thread.scheduleWindowVisibility(r, false); 2354 } 2355 } catch (Exception e) { 2356 // Just skip on any failure; we'll make it 2357 // visible when it next restarts. 2358 Log.w(TAG, "Exception thrown making hidden: " 2359 + r.intent.getComponent(), e); 2360 } 2361 } else { 2362 if (DEBUG_VISBILITY) Log.v( 2363 TAG, "Already invisible: " + r); 2364 } 2365 } else if (r.fullscreen) { 2366 if (DEBUG_VISBILITY) Log.v( 2367 TAG, "Now behindFullscreen: " + r); 2368 behindFullscreen = true; 2369 } 2370 } 2371 i--; 2372 } 2373 } 2374 2375 /** 2376 * Version of ensureActivitiesVisible that can easily be called anywhere. 2377 */ 2378 private final void ensureActivitiesVisibleLocked(HistoryRecord starting, 2379 int configChanges) { 2380 HistoryRecord r = topRunningActivityLocked(null); 2381 if (r != null) { 2382 ensureActivitiesVisibleLocked(r, starting, null, configChanges); 2383 } 2384 } 2385 2386 private void updateUsageStats(HistoryRecord resumedComponent, boolean resumed) { 2387 if (resumed) { 2388 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2389 } else { 2390 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2391 } 2392 } 2393 2394 private boolean startHomeActivityLocked() { 2395 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2396 && mTopAction == null) { 2397 // We are running in factory test mode, but unable to find 2398 // the factory test app, so just sit around displaying the 2399 // error message and don't try to start anything. 2400 return false; 2401 } 2402 Intent intent = new Intent( 2403 mTopAction, 2404 mTopData != null ? Uri.parse(mTopData) : null); 2405 intent.setComponent(mTopComponent); 2406 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2407 intent.addCategory(Intent.CATEGORY_HOME); 2408 } 2409 ActivityInfo aInfo = 2410 intent.resolveActivityInfo(mContext.getPackageManager(), 2411 STOCK_PM_FLAGS); 2412 if (aInfo != null) { 2413 intent.setComponent(new ComponentName( 2414 aInfo.applicationInfo.packageName, aInfo.name)); 2415 // Don't do this if the home app is currently being 2416 // instrumented. 2417 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2418 aInfo.applicationInfo.uid); 2419 if (app == null || app.instrumentationClass == null) { 2420 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2421 startActivityLocked(null, intent, null, null, 0, aInfo, 2422 null, null, 0, 0, 0, false, false); 2423 } 2424 } 2425 2426 2427 return true; 2428 } 2429 2430 /** 2431 * Starts the "new version setup screen" if appropriate. 2432 */ 2433 private void startSetupActivityLocked() { 2434 // Only do this once per boot. 2435 if (mCheckedForSetup) { 2436 return; 2437 } 2438 2439 // We will show this screen if the current one is a different 2440 // version than the last one shown, and we are not running in 2441 // low-level factory test mode. 2442 final ContentResolver resolver = mContext.getContentResolver(); 2443 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2444 Settings.Secure.getInt(resolver, 2445 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2446 mCheckedForSetup = true; 2447 2448 // See if we should be showing the platform update setup UI. 2449 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2450 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2451 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2452 2453 // We don't allow third party apps to replace this. 2454 ResolveInfo ri = null; 2455 for (int i=0; ris != null && i<ris.size(); i++) { 2456 if ((ris.get(i).activityInfo.applicationInfo.flags 2457 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2458 ri = ris.get(i); 2459 break; 2460 } 2461 } 2462 2463 if (ri != null) { 2464 String vers = ri.activityInfo.metaData != null 2465 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2466 : null; 2467 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2468 vers = ri.activityInfo.applicationInfo.metaData.getString( 2469 Intent.METADATA_SETUP_VERSION); 2470 } 2471 String lastVers = Settings.Secure.getString( 2472 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2473 if (vers != null && !vers.equals(lastVers)) { 2474 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2475 intent.setComponent(new ComponentName( 2476 ri.activityInfo.packageName, ri.activityInfo.name)); 2477 startActivityLocked(null, intent, null, null, 0, ri.activityInfo, 2478 null, null, 0, 0, 0, false, false); 2479 } 2480 } 2481 } 2482 } 2483 2484 private void reportResumedActivityLocked(HistoryRecord r) { 2485 //Log.i(TAG, "**** REPORT RESUME: " + r); 2486 2487 final int identHash = System.identityHashCode(r); 2488 updateUsageStats(r, true); 2489 2490 int i = mWatchers.beginBroadcast(); 2491 while (i > 0) { 2492 i--; 2493 IActivityWatcher w = mWatchers.getBroadcastItem(i); 2494 if (w != null) { 2495 try { 2496 w.activityResuming(identHash); 2497 } catch (RemoteException e) { 2498 } 2499 } 2500 } 2501 mWatchers.finishBroadcast(); 2502 } 2503 2504 /** 2505 * Ensure that the top activity in the stack is resumed. 2506 * 2507 * @param prev The previously resumed activity, for when in the process 2508 * of pausing; can be null to call from elsewhere. 2509 * 2510 * @return Returns true if something is being resumed, or false if 2511 * nothing happened. 2512 */ 2513 private final boolean resumeTopActivityLocked(HistoryRecord prev) { 2514 // Find the first activity that is not finishing. 2515 HistoryRecord next = topRunningActivityLocked(null); 2516 2517 // Remember how we'll process this pause/resume situation, and ensure 2518 // that the state is reset however we wind up proceeding. 2519 final boolean userLeaving = mUserLeaving; 2520 mUserLeaving = false; 2521 2522 if (next == null) { 2523 // There are no more activities! Let's just start up the 2524 // Launcher... 2525 return startHomeActivityLocked(); 2526 } 2527 2528 next.delayedResume = false; 2529 2530 // If the top activity is the resumed one, nothing to do. 2531 if (mResumedActivity == next && next.state == ActivityState.RESUMED) { 2532 // Make sure we have executed any pending transitions, since there 2533 // should be nothing left to do at this point. 2534 mWindowManager.executeAppTransition(); 2535 mNoAnimActivities.clear(); 2536 return false; 2537 } 2538 2539 // If we are sleeping, and there is no resumed activity, and the top 2540 // activity is paused, well that is the state we want. 2541 if ((mSleeping || mShuttingDown) 2542 && mLastPausedActivity == next && next.state == ActivityState.PAUSED) { 2543 // Make sure we have executed any pending transitions, since there 2544 // should be nothing left to do at this point. 2545 mWindowManager.executeAppTransition(); 2546 mNoAnimActivities.clear(); 2547 return false; 2548 } 2549 2550 // The activity may be waiting for stop, but that is no longer 2551 // appropriate for it. 2552 mStoppingActivities.remove(next); 2553 mWaitingVisibleActivities.remove(next); 2554 2555 if (DEBUG_SWITCH) Log.v(TAG, "Resuming " + next); 2556 2557 // If we are currently pausing an activity, then don't do anything 2558 // until that is done. 2559 if (mPausingActivity != null) { 2560 if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: pausing=" + mPausingActivity); 2561 return false; 2562 } 2563 2564 // We need to start pausing the current activity so the top one 2565 // can be resumed... 2566 if (mResumedActivity != null) { 2567 if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: need to start pausing"); 2568 startPausingLocked(userLeaving, false); 2569 return true; 2570 } 2571 2572 if (prev != null && prev != next) { 2573 if (!prev.waitingVisible && next != null && !next.nowVisible) { 2574 prev.waitingVisible = true; 2575 mWaitingVisibleActivities.add(prev); 2576 if (DEBUG_SWITCH) Log.v( 2577 TAG, "Resuming top, waiting visible to hide: " + prev); 2578 } else { 2579 // The next activity is already visible, so hide the previous 2580 // activity's windows right now so we can show the new one ASAP. 2581 // We only do this if the previous is finishing, which should mean 2582 // it is on top of the one being resumed so hiding it quickly 2583 // is good. Otherwise, we want to do the normal route of allowing 2584 // the resumed activity to be shown so we can decide if the 2585 // previous should actually be hidden depending on whether the 2586 // new one is found to be full-screen or not. 2587 if (prev.finishing) { 2588 mWindowManager.setAppVisibility(prev, false); 2589 if (DEBUG_SWITCH) Log.v(TAG, "Not waiting for visible to hide: " 2590 + prev + ", waitingVisible=" 2591 + (prev != null ? prev.waitingVisible : null) 2592 + ", nowVisible=" + next.nowVisible); 2593 } else { 2594 if (DEBUG_SWITCH) Log.v(TAG, "Previous already visible but still waiting to hide: " 2595 + prev + ", waitingVisible=" 2596 + (prev != null ? prev.waitingVisible : null) 2597 + ", nowVisible=" + next.nowVisible); 2598 } 2599 } 2600 } 2601 2602 // We are starting up the next activity, so tell the window manager 2603 // that the previous one will be hidden soon. This way it can know 2604 // to ignore it when computing the desired screen orientation. 2605 if (prev != null) { 2606 if (prev.finishing) { 2607 if (DEBUG_TRANSITION) Log.v(TAG, 2608 "Prepare close transition: prev=" + prev); 2609 if (mNoAnimActivities.contains(prev)) { 2610 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 2611 } else { 2612 mWindowManager.prepareAppTransition(prev.task == next.task 2613 ? WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE 2614 : WindowManagerPolicy.TRANSIT_TASK_CLOSE); 2615 } 2616 mWindowManager.setAppWillBeHidden(prev); 2617 mWindowManager.setAppVisibility(prev, false); 2618 } else { 2619 if (DEBUG_TRANSITION) Log.v(TAG, 2620 "Prepare open transition: prev=" + prev); 2621 if (mNoAnimActivities.contains(next)) { 2622 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 2623 } else { 2624 mWindowManager.prepareAppTransition(prev.task == next.task 2625 ? WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 2626 : WindowManagerPolicy.TRANSIT_TASK_OPEN); 2627 } 2628 } 2629 if (false) { 2630 mWindowManager.setAppWillBeHidden(prev); 2631 mWindowManager.setAppVisibility(prev, false); 2632 } 2633 } else if (mHistory.size() > 1) { 2634 if (DEBUG_TRANSITION) Log.v(TAG, 2635 "Prepare open transition: no previous"); 2636 if (mNoAnimActivities.contains(next)) { 2637 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 2638 } else { 2639 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN); 2640 } 2641 } 2642 2643 if (next.app != null && next.app.thread != null) { 2644 if (DEBUG_SWITCH) Log.v(TAG, "Resume running: " + next); 2645 2646 // This activity is now becoming visible. 2647 mWindowManager.setAppVisibility(next, true); 2648 2649 HistoryRecord lastResumedActivity = mResumedActivity; 2650 ActivityState lastState = next.state; 2651 2652 updateCpuStats(); 2653 2654 next.state = ActivityState.RESUMED; 2655 mResumedActivity = next; 2656 next.task.touchActiveTime(); 2657 updateLruProcessLocked(next.app, true, true); 2658 updateLRUListLocked(next); 2659 2660 // Have the window manager re-evaluate the orientation of 2661 // the screen based on the new activity order. 2662 boolean updated; 2663 synchronized (this) { 2664 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2665 mConfiguration, 2666 next.mayFreezeScreenLocked(next.app) ? next : null); 2667 if (config != null) { 2668 /* 2669 * Explicitly restore the locale to the one from the 2670 * old configuration, since the one that comes back from 2671 * the window manager has the default (boot) locale. 2672 * 2673 * It looks like previously the locale picker only worked 2674 * by coincidence: usually it would do its setting of 2675 * the locale after the activity transition, so it didn't 2676 * matter that this lost it. With the synchronized 2677 * block now keeping them from happening at the same time, 2678 * this one always would happen second and undo what the 2679 * locale picker had just done. 2680 */ 2681 config.locale = mConfiguration.locale; 2682 next.frozenBeforeDestroy = true; 2683 } 2684 updated = updateConfigurationLocked(config, next); 2685 } 2686 if (!updated) { 2687 // The configuration update wasn't able to keep the existing 2688 // instance of the activity, and instead started a new one. 2689 // We should be all done, but let's just make sure our activity 2690 // is still at the top and schedule another run if something 2691 // weird happened. 2692 HistoryRecord nextNext = topRunningActivityLocked(null); 2693 if (DEBUG_SWITCH) Log.i(TAG, 2694 "Activity config changed during resume: " + next 2695 + ", new next: " + nextNext); 2696 if (nextNext != next) { 2697 // Do over! 2698 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 2699 } 2700 setFocusedActivityLocked(next); 2701 ensureActivitiesVisibleLocked(null, 0); 2702 mWindowManager.executeAppTransition(); 2703 mNoAnimActivities.clear(); 2704 return true; 2705 } 2706 2707 try { 2708 // Deliver all pending results. 2709 ArrayList a = next.results; 2710 if (a != null) { 2711 final int N = a.size(); 2712 if (!next.finishing && N > 0) { 2713 if (DEBUG_RESULTS) Log.v( 2714 TAG, "Delivering results to " + next 2715 + ": " + a); 2716 next.app.thread.scheduleSendResult(next, a); 2717 } 2718 } 2719 2720 if (next.newIntents != null) { 2721 next.app.thread.scheduleNewIntent(next.newIntents, next); 2722 } 2723 2724 EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, 2725 System.identityHashCode(next), 2726 next.task.taskId, next.shortComponentName); 2727 2728 next.app.thread.scheduleResumeActivity(next, 2729 isNextTransitionForward()); 2730 2731 pauseIfSleepingLocked(); 2732 2733 } catch (Exception e) { 2734 // Whoops, need to restart this activity! 2735 next.state = lastState; 2736 mResumedActivity = lastResumedActivity; 2737 Log.i(TAG, "Restarting because process died: " + next); 2738 if (!next.hasBeenLaunched) { 2739 next.hasBeenLaunched = true; 2740 } else { 2741 if (SHOW_APP_STARTING_ICON) { 2742 mWindowManager.setAppStartingWindow( 2743 next, next.packageName, next.theme, 2744 next.nonLocalizedLabel, 2745 next.labelRes, next.icon, null, true); 2746 } 2747 } 2748 startSpecificActivityLocked(next, true, false); 2749 return true; 2750 } 2751 2752 // From this point on, if something goes wrong there is no way 2753 // to recover the activity. 2754 try { 2755 next.visible = true; 2756 completeResumeLocked(next); 2757 } catch (Exception e) { 2758 // If any exception gets thrown, toss away this 2759 // activity and try the next one. 2760 Log.w(TAG, "Exception thrown during resume of " + next, e); 2761 requestFinishActivityLocked(next, Activity.RESULT_CANCELED, null, 2762 "resume-exception"); 2763 return true; 2764 } 2765 2766 // Didn't need to use the icicle, and it is now out of date. 2767 next.icicle = null; 2768 next.haveState = false; 2769 next.stopped = false; 2770 2771 } else { 2772 // Whoops, need to restart this activity! 2773 if (!next.hasBeenLaunched) { 2774 next.hasBeenLaunched = true; 2775 } else { 2776 if (SHOW_APP_STARTING_ICON) { 2777 mWindowManager.setAppStartingWindow( 2778 next, next.packageName, next.theme, 2779 next.nonLocalizedLabel, 2780 next.labelRes, next.icon, null, true); 2781 } 2782 if (DEBUG_SWITCH) Log.v(TAG, "Restarting: " + next); 2783 } 2784 startSpecificActivityLocked(next, true, true); 2785 } 2786 2787 return true; 2788 } 2789 2790 private final void startActivityLocked(HistoryRecord r, boolean newTask, 2791 boolean doResume) { 2792 final int NH = mHistory.size(); 2793 2794 int addPos = -1; 2795 2796 if (!newTask) { 2797 // If starting in an existing task, find where that is... 2798 HistoryRecord next = null; 2799 boolean startIt = true; 2800 for (int i = NH-1; i >= 0; i--) { 2801 HistoryRecord p = (HistoryRecord)mHistory.get(i); 2802 if (p.finishing) { 2803 continue; 2804 } 2805 if (p.task == r.task) { 2806 // Here it is! Now, if this is not yet visible to the 2807 // user, then just add it without starting; it will 2808 // get started when the user navigates back to it. 2809 addPos = i+1; 2810 if (!startIt) { 2811 mHistory.add(addPos, r); 2812 r.inHistory = true; 2813 r.task.numActivities++; 2814 mWindowManager.addAppToken(addPos, r, r.task.taskId, 2815 r.info.screenOrientation, r.fullscreen); 2816 if (VALIDATE_TOKENS) { 2817 mWindowManager.validateAppTokens(mHistory); 2818 } 2819 return; 2820 } 2821 break; 2822 } 2823 if (p.fullscreen) { 2824 startIt = false; 2825 } 2826 next = p; 2827 } 2828 } 2829 2830 // Place a new activity at top of stack, so it is next to interact 2831 // with the user. 2832 if (addPos < 0) { 2833 addPos = mHistory.size(); 2834 } 2835 2836 // If we are not placing the new activity frontmost, we do not want 2837 // to deliver the onUserLeaving callback to the actual frontmost 2838 // activity 2839 if (addPos < NH) { 2840 mUserLeaving = false; 2841 if (DEBUG_USER_LEAVING) Log.v(TAG, "startActivity() behind front, mUserLeaving=false"); 2842 } 2843 2844 // Slot the activity into the history stack and proceed 2845 mHistory.add(addPos, r); 2846 r.inHistory = true; 2847 r.frontOfTask = newTask; 2848 r.task.numActivities++; 2849 if (NH > 0) { 2850 // We want to show the starting preview window if we are 2851 // switching to a new task, or the next activity's process is 2852 // not currently running. 2853 boolean showStartingIcon = newTask; 2854 ProcessRecord proc = r.app; 2855 if (proc == null) { 2856 proc = mProcessNames.get(r.processName, r.info.applicationInfo.uid); 2857 } 2858 if (proc == null || proc.thread == null) { 2859 showStartingIcon = true; 2860 } 2861 if (DEBUG_TRANSITION) Log.v(TAG, 2862 "Prepare open transition: starting " + r); 2863 if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { 2864 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 2865 mNoAnimActivities.add(r); 2866 } else if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) { 2867 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_OPEN); 2868 mNoAnimActivities.remove(r); 2869 } else { 2870 mWindowManager.prepareAppTransition(newTask 2871 ? WindowManagerPolicy.TRANSIT_TASK_OPEN 2872 : WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN); 2873 mNoAnimActivities.remove(r); 2874 } 2875 mWindowManager.addAppToken( 2876 addPos, r, r.task.taskId, r.info.screenOrientation, r.fullscreen); 2877 boolean doShow = true; 2878 if (newTask) { 2879 // Even though this activity is starting fresh, we still need 2880 // to reset it to make sure we apply affinities to move any 2881 // existing activities from other tasks in to it. 2882 // If the caller has requested that the target task be 2883 // reset, then do so. 2884 if ((r.intent.getFlags() 2885 &Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 2886 resetTaskIfNeededLocked(r, r); 2887 doShow = topRunningNonDelayedActivityLocked(null) == r; 2888 } 2889 } 2890 if (SHOW_APP_STARTING_ICON && doShow) { 2891 // Figure out if we are transitioning from another activity that is 2892 // "has the same starting icon" as the next one. This allows the 2893 // window manager to keep the previous window it had previously 2894 // created, if it still had one. 2895 HistoryRecord prev = mResumedActivity; 2896 if (prev != null) { 2897 // We don't want to reuse the previous starting preview if: 2898 // (1) The current activity is in a different task. 2899 if (prev.task != r.task) prev = null; 2900 // (2) The current activity is already displayed. 2901 else if (prev.nowVisible) prev = null; 2902 } 2903 mWindowManager.setAppStartingWindow( 2904 r, r.packageName, r.theme, r.nonLocalizedLabel, 2905 r.labelRes, r.icon, prev, showStartingIcon); 2906 } 2907 } else { 2908 // If this is the first activity, don't do any fancy animations, 2909 // because there is nothing for it to animate on top of. 2910 mWindowManager.addAppToken(addPos, r, r.task.taskId, 2911 r.info.screenOrientation, r.fullscreen); 2912 } 2913 if (VALIDATE_TOKENS) { 2914 mWindowManager.validateAppTokens(mHistory); 2915 } 2916 2917 if (doResume) { 2918 resumeTopActivityLocked(null); 2919 } 2920 } 2921 2922 /** 2923 * Perform clear operation as requested by 2924 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the 2925 * stack to the given task, then look for 2926 * an instance of that activity in the stack and, if found, finish all 2927 * activities on top of it and return the instance. 2928 * 2929 * @param newR Description of the new activity being started. 2930 * @return Returns the old activity that should be continue to be used, 2931 * or null if none was found. 2932 */ 2933 private final HistoryRecord performClearTaskLocked(int taskId, 2934 HistoryRecord newR, int launchFlags, boolean doClear) { 2935 int i = mHistory.size(); 2936 2937 // First find the requested task. 2938 while (i > 0) { 2939 i--; 2940 HistoryRecord r = (HistoryRecord)mHistory.get(i); 2941 if (r.task.taskId == taskId) { 2942 i++; 2943 break; 2944 } 2945 } 2946 2947 // Now clear it. 2948 while (i > 0) { 2949 i--; 2950 HistoryRecord r = (HistoryRecord)mHistory.get(i); 2951 if (r.finishing) { 2952 continue; 2953 } 2954 if (r.task.taskId != taskId) { 2955 return null; 2956 } 2957 if (r.realActivity.equals(newR.realActivity)) { 2958 // Here it is! Now finish everything in front... 2959 HistoryRecord ret = r; 2960 if (doClear) { 2961 while (i < (mHistory.size()-1)) { 2962 i++; 2963 r = (HistoryRecord)mHistory.get(i); 2964 if (r.finishing) { 2965 continue; 2966 } 2967 if (finishActivityLocked(r, i, Activity.RESULT_CANCELED, 2968 null, "clear")) { 2969 i--; 2970 } 2971 } 2972 } 2973 2974 // Finally, if this is a normal launch mode (that is, not 2975 // expecting onNewIntent()), then we will finish the current 2976 // instance of the activity so a new fresh one can be started. 2977 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE 2978 && (launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) { 2979 if (!ret.finishing) { 2980 int index = indexOfTokenLocked(ret); 2981 if (index >= 0) { 2982 finishActivityLocked(ret, 0, Activity.RESULT_CANCELED, 2983 null, "clear"); 2984 } 2985 return null; 2986 } 2987 } 2988 2989 return ret; 2990 } 2991 } 2992 2993 return null; 2994 } 2995 2996 /** 2997 * Find the activity in the history stack within the given task. Returns 2998 * the index within the history at which it's found, or < 0 if not found. 2999 */ 3000 private final int findActivityInHistoryLocked(HistoryRecord r, int task) { 3001 int i = mHistory.size(); 3002 while (i > 0) { 3003 i--; 3004 HistoryRecord candidate = (HistoryRecord)mHistory.get(i); 3005 if (candidate.task.taskId != task) { 3006 break; 3007 } 3008 if (candidate.realActivity.equals(r.realActivity)) { 3009 return i; 3010 } 3011 } 3012 3013 return -1; 3014 } 3015 3016 /** 3017 * Reorder the history stack so that the activity at the given index is 3018 * brought to the front. 3019 */ 3020 private final HistoryRecord moveActivityToFrontLocked(int where) { 3021 HistoryRecord newTop = (HistoryRecord)mHistory.remove(where); 3022 int top = mHistory.size(); 3023 HistoryRecord oldTop = (HistoryRecord)mHistory.get(top-1); 3024 mHistory.add(top, newTop); 3025 oldTop.frontOfTask = false; 3026 newTop.frontOfTask = true; 3027 return newTop; 3028 } 3029 3030 /** 3031 * Deliver a new Intent to an existing activity, so that its onNewIntent() 3032 * method will be called at the proper time. 3033 */ 3034 private final void deliverNewIntentLocked(HistoryRecord r, Intent intent) { 3035 boolean sent = false; 3036 if (r.state == ActivityState.RESUMED 3037 && r.app != null && r.app.thread != null) { 3038 try { 3039 ArrayList<Intent> ar = new ArrayList<Intent>(); 3040 ar.add(new Intent(intent)); 3041 r.app.thread.scheduleNewIntent(ar, r); 3042 sent = true; 3043 } catch (Exception e) { 3044 Log.w(TAG, "Exception thrown sending new intent to " + r, e); 3045 } 3046 } 3047 if (!sent) { 3048 r.addNewIntentLocked(new Intent(intent)); 3049 } 3050 } 3051 3052 private final void logStartActivity(int tag, HistoryRecord r, 3053 TaskRecord task) { 3054 EventLog.writeEvent(tag, 3055 System.identityHashCode(r), task.taskId, 3056 r.shortComponentName, r.intent.getAction(), 3057 r.intent.getType(), r.intent.getDataString(), 3058 r.intent.getFlags()); 3059 } 3060 3061 private final int startActivityLocked(IApplicationThread caller, 3062 Intent intent, String resolvedType, 3063 Uri[] grantedUriPermissions, 3064 int grantedMode, ActivityInfo aInfo, IBinder resultTo, 3065 String resultWho, int requestCode, 3066 int callingPid, int callingUid, boolean onlyIfNeeded, 3067 boolean componentSpecified) { 3068 Log.i(TAG, "Starting activity: " + intent); 3069 3070 HistoryRecord sourceRecord = null; 3071 HistoryRecord resultRecord = null; 3072 if (resultTo != null) { 3073 int index = indexOfTokenLocked(resultTo); 3074 if (DEBUG_RESULTS) Log.v( 3075 TAG, "Sending result to " + resultTo + " (index " + index + ")"); 3076 if (index >= 0) { 3077 sourceRecord = (HistoryRecord)mHistory.get(index); 3078 if (requestCode >= 0 && !sourceRecord.finishing) { 3079 resultRecord = sourceRecord; 3080 } 3081 } 3082 } 3083 3084 int launchFlags = intent.getFlags(); 3085 3086 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 3087 && sourceRecord != null) { 3088 // Transfer the result target from the source activity to the new 3089 // one being started, including any failures. 3090 if (requestCode >= 0) { 3091 return START_FORWARD_AND_REQUEST_CONFLICT; 3092 } 3093 resultRecord = sourceRecord.resultTo; 3094 resultWho = sourceRecord.resultWho; 3095 requestCode = sourceRecord.requestCode; 3096 sourceRecord.resultTo = null; 3097 if (resultRecord != null) { 3098 resultRecord.removeResultsLocked( 3099 sourceRecord, resultWho, requestCode); 3100 } 3101 } 3102 3103 int err = START_SUCCESS; 3104 3105 if (intent.getComponent() == null) { 3106 // We couldn't find a class that can handle the given Intent. 3107 // That's the end of that! 3108 err = START_INTENT_NOT_RESOLVED; 3109 } 3110 3111 if (err == START_SUCCESS && aInfo == null) { 3112 // We couldn't find the specific class specified in the Intent. 3113 // Also the end of the line. 3114 err = START_CLASS_NOT_FOUND; 3115 } 3116 3117 ProcessRecord callerApp = null; 3118 if (err == START_SUCCESS && caller != null) { 3119 callerApp = getRecordForAppLocked(caller); 3120 if (callerApp != null) { 3121 callingPid = callerApp.pid; 3122 callingUid = callerApp.info.uid; 3123 } else { 3124 Log.w(TAG, "Unable to find app for caller " + caller 3125 + " (pid=" + callingPid + ") when starting: " 3126 + intent.toString()); 3127 err = START_PERMISSION_DENIED; 3128 } 3129 } 3130 3131 if (err != START_SUCCESS) { 3132 if (resultRecord != null) { 3133 sendActivityResultLocked(-1, 3134 resultRecord, resultWho, requestCode, 3135 Activity.RESULT_CANCELED, null); 3136 } 3137 return err; 3138 } 3139 3140 final int perm = checkComponentPermission(aInfo.permission, callingPid, 3141 callingUid, aInfo.exported ? -1 : aInfo.applicationInfo.uid); 3142 if (perm != PackageManager.PERMISSION_GRANTED) { 3143 if (resultRecord != null) { 3144 sendActivityResultLocked(-1, 3145 resultRecord, resultWho, requestCode, 3146 Activity.RESULT_CANCELED, null); 3147 } 3148 String msg = "Permission Denial: starting " + intent.toString() 3149 + " from " + callerApp + " (pid=" + callingPid 3150 + ", uid=" + callingUid + ")" 3151 + " requires " + aInfo.permission; 3152 Log.w(TAG, msg); 3153 throw new SecurityException(msg); 3154 } 3155 3156 if (mController != null) { 3157 boolean abort = false; 3158 try { 3159 // The Intent we give to the watcher has the extra data 3160 // stripped off, since it can contain private information. 3161 Intent watchIntent = intent.cloneFilter(); 3162 abort = !mController.activityStarting(watchIntent, 3163 aInfo.applicationInfo.packageName); 3164 } catch (RemoteException e) { 3165 mController = null; 3166 } 3167 3168 if (abort) { 3169 if (resultRecord != null) { 3170 sendActivityResultLocked(-1, 3171 resultRecord, resultWho, requestCode, 3172 Activity.RESULT_CANCELED, null); 3173 } 3174 // We pretend to the caller that it was really started, but 3175 // they will just get a cancel result. 3176 return START_SUCCESS; 3177 } 3178 } 3179 3180 HistoryRecord r = new HistoryRecord(this, callerApp, callingUid, 3181 intent, resolvedType, aInfo, mConfiguration, 3182 resultRecord, resultWho, requestCode, componentSpecified); 3183 3184 if (mResumedActivity == null 3185 || mResumedActivity.info.applicationInfo.uid != callingUid) { 3186 if (!checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) { 3187 PendingActivityLaunch pal = new PendingActivityLaunch(); 3188 pal.r = r; 3189 pal.sourceRecord = sourceRecord; 3190 pal.grantedUriPermissions = grantedUriPermissions; 3191 pal.grantedMode = grantedMode; 3192 pal.onlyIfNeeded = onlyIfNeeded; 3193 mPendingActivityLaunches.add(pal); 3194 return START_SWITCHES_CANCELED; 3195 } 3196 } 3197 3198 if (mDidAppSwitch) { 3199 // This is the second allowed switch since we stopped switches, 3200 // so now just generally allow switches. Use case: user presses 3201 // home (switches disabled, switch to home, mDidAppSwitch now true); 3202 // user taps a home icon (coming from home so allowed, we hit here 3203 // and now allow anyone to switch again). 3204 mAppSwitchesAllowedTime = 0; 3205 } else { 3206 mDidAppSwitch = true; 3207 } 3208 3209 doPendingActivityLaunchesLocked(false); 3210 3211 return startActivityUncheckedLocked(r, sourceRecord, 3212 grantedUriPermissions, grantedMode, onlyIfNeeded, true); 3213 } 3214 3215 private final void doPendingActivityLaunchesLocked(boolean doResume) { 3216 final int N = mPendingActivityLaunches.size(); 3217 if (N <= 0) { 3218 return; 3219 } 3220 for (int i=0; i<N; i++) { 3221 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3222 startActivityUncheckedLocked(pal.r, pal.sourceRecord, 3223 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded, 3224 doResume && i == (N-1)); 3225 } 3226 mPendingActivityLaunches.clear(); 3227 } 3228 3229 private final int startActivityUncheckedLocked(HistoryRecord r, 3230 HistoryRecord sourceRecord, Uri[] grantedUriPermissions, 3231 int grantedMode, boolean onlyIfNeeded, boolean doResume) { 3232 final Intent intent = r.intent; 3233 final int callingUid = r.launchedFromUid; 3234 3235 int launchFlags = intent.getFlags(); 3236 3237 // We'll invoke onUserLeaving before onPause only if the launching 3238 // activity did not explicitly state that this is an automated launch. 3239 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0; 3240 if (DEBUG_USER_LEAVING) Log.v(TAG, 3241 "startActivity() => mUserLeaving=" + mUserLeaving); 3242 3243 // If the caller has asked not to resume at this point, we make note 3244 // of this in the record so that we can skip it when trying to find 3245 // the top running activity. 3246 if (!doResume) { 3247 r.delayedResume = true; 3248 } 3249 3250 HistoryRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) 3251 != 0 ? r : null; 3252 3253 // If the onlyIfNeeded flag is set, then we can do this if the activity 3254 // being launched is the same as the one making the call... or, as 3255 // a special case, if we do not know the caller then we count the 3256 // current top activity as the caller. 3257 if (onlyIfNeeded) { 3258 HistoryRecord checkedCaller = sourceRecord; 3259 if (checkedCaller == null) { 3260 checkedCaller = topRunningNonDelayedActivityLocked(notTop); 3261 } 3262 if (!checkedCaller.realActivity.equals(r.realActivity)) { 3263 // Caller is not the same as launcher, so always needed. 3264 onlyIfNeeded = false; 3265 } 3266 } 3267 3268 if (grantedUriPermissions != null && callingUid > 0) { 3269 for (int i=0; i<grantedUriPermissions.length; i++) { 3270 grantUriPermissionLocked(callingUid, r.packageName, 3271 grantedUriPermissions[i], grantedMode, r); 3272 } 3273 } 3274 3275 grantUriPermissionFromIntentLocked(callingUid, r.packageName, 3276 intent, r); 3277 3278 if (sourceRecord == null) { 3279 // This activity is not being started from another... in this 3280 // case we -always- start a new task. 3281 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 3282 Log.w(TAG, "startActivity called from non-Activity context; forcing Intent.FLAG_ACTIVITY_NEW_TASK for: " 3283 + intent); 3284 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 3285 } 3286 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 3287 // The original activity who is starting us is running as a single 3288 // instance... this new activity it is starting must go on its 3289 // own task. 3290 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 3291 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE 3292 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 3293 // The activity being started is a single instance... it always 3294 // gets launched into its own task. 3295 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 3296 } 3297 3298 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 3299 // For whatever reason this activity is being launched into a new 3300 // task... yet the caller has requested a result back. Well, that 3301 // is pretty messed up, so instead immediately send back a cancel 3302 // and let the new task continue launched as normal without a 3303 // dependency on its originator. 3304 Log.w(TAG, "Activity is launching as a new task, so cancelling activity result."); 3305 sendActivityResultLocked(-1, 3306 r.resultTo, r.resultWho, r.requestCode, 3307 Activity.RESULT_CANCELED, null); 3308 r.resultTo = null; 3309 } 3310 3311 boolean addingToTask = false; 3312 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && 3313 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) 3314 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 3315 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 3316 // If bring to front is requested, and no result is requested, and 3317 // we can find a task that was started with this same 3318 // component, then instead of launching bring that one to the front. 3319 if (r.resultTo == null) { 3320 // See if there is a task to bring to the front. If this is 3321 // a SINGLE_INSTANCE activity, there can be one and only one 3322 // instance of it in the history, and it is always in its own 3323 // unique task, so we do a special search. 3324 HistoryRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE 3325 ? findTaskLocked(intent, r.info) 3326 : findActivityLocked(intent, r.info); 3327 if (taskTop != null) { 3328 if (taskTop.task.intent == null) { 3329 // This task was started because of movement of 3330 // the activity based on affinity... now that we 3331 // are actually launching it, we can assign the 3332 // base intent. 3333 taskTop.task.setIntent(intent, r.info); 3334 } 3335 // If the target task is not in the front, then we need 3336 // to bring it to the front... except... well, with 3337 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like 3338 // to have the same behavior as if a new instance was 3339 // being started, which means not bringing it to the front 3340 // if the caller is not itself in the front. 3341 HistoryRecord curTop = topRunningNonDelayedActivityLocked(notTop); 3342 if (curTop.task != taskTop.task) { 3343 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); 3344 boolean callerAtFront = sourceRecord == null 3345 || curTop.task == sourceRecord.task; 3346 if (callerAtFront) { 3347 // We really do want to push this one into the 3348 // user's face, right now. 3349 moveTaskToFrontLocked(taskTop.task, r); 3350 } 3351 } 3352 // If the caller has requested that the target task be 3353 // reset, then do so. 3354 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 3355 taskTop = resetTaskIfNeededLocked(taskTop, r); 3356 } 3357 if (onlyIfNeeded) { 3358 // We don't need to start a new activity, and 3359 // the client said not to do anything if that 3360 // is the case, so this is it! And for paranoia, make 3361 // sure we have correctly resumed the top activity. 3362 if (doResume) { 3363 resumeTopActivityLocked(null); 3364 } 3365 return START_RETURN_INTENT_TO_CALLER; 3366 } 3367 if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0 3368 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 3369 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 3370 // In this situation we want to remove all activities 3371 // from the task up to the one being started. In most 3372 // cases this means we are resetting the task to its 3373 // initial state. 3374 HistoryRecord top = performClearTaskLocked( 3375 taskTop.task.taskId, r, launchFlags, true); 3376 if (top != null) { 3377 if (top.frontOfTask) { 3378 // Activity aliases may mean we use different 3379 // intents for the top activity, so make sure 3380 // the task now has the identity of the new 3381 // intent. 3382 top.task.setIntent(r.intent, r.info); 3383 } 3384 logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); 3385 deliverNewIntentLocked(top, r.intent); 3386 } else { 3387 // A special case: we need to 3388 // start the activity because it is not currently 3389 // running, and the caller has asked to clear the 3390 // current task to have this activity at the top. 3391 addingToTask = true; 3392 // Now pretend like this activity is being started 3393 // by the top of its task, so it is put in the 3394 // right place. 3395 sourceRecord = taskTop; 3396 } 3397 } else if (r.realActivity.equals(taskTop.task.realActivity)) { 3398 // In this case the top activity on the task is the 3399 // same as the one being launched, so we take that 3400 // as a request to bring the task to the foreground. 3401 // If the top activity in the task is the root 3402 // activity, deliver this new intent to it if it 3403 // desires. 3404 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 3405 && taskTop.realActivity.equals(r.realActivity)) { 3406 logStartActivity(EventLogTags.AM_NEW_INTENT, r, taskTop.task); 3407 if (taskTop.frontOfTask) { 3408 taskTop.task.setIntent(r.intent, r.info); 3409 } 3410 deliverNewIntentLocked(taskTop, r.intent); 3411 } else if (!r.intent.filterEquals(taskTop.task.intent)) { 3412 // In this case we are launching the root activity 3413 // of the task, but with a different intent. We 3414 // should start a new instance on top. 3415 addingToTask = true; 3416 sourceRecord = taskTop; 3417 } 3418 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) { 3419 // In this case an activity is being launched in to an 3420 // existing task, without resetting that task. This 3421 // is typically the situation of launching an activity 3422 // from a notification or shortcut. We want to place 3423 // the new activity on top of the current task. 3424 addingToTask = true; 3425 sourceRecord = taskTop; 3426 } else if (!taskTop.task.rootWasReset) { 3427 // In this case we are launching in to an existing task 3428 // that has not yet been started from its front door. 3429 // The current task has been brought to the front. 3430 // Ideally, we'd probably like to place this new task 3431 // at the bottom of its stack, but that's a little hard 3432 // to do with the current organization of the code so 3433 // for now we'll just drop it. 3434 taskTop.task.setIntent(r.intent, r.info); 3435 } 3436 if (!addingToTask) { 3437 // We didn't do anything... but it was needed (a.k.a., client 3438 // don't use that intent!) And for paranoia, make 3439 // sure we have correctly resumed the top activity. 3440 if (doResume) { 3441 resumeTopActivityLocked(null); 3442 } 3443 return START_TASK_TO_FRONT; 3444 } 3445 } 3446 } 3447 } 3448 3449 //String uri = r.intent.toURI(); 3450 //Intent intent2 = new Intent(uri); 3451 //Log.i(TAG, "Given intent: " + r.intent); 3452 //Log.i(TAG, "URI is: " + uri); 3453 //Log.i(TAG, "To intent: " + intent2); 3454 3455 if (r.packageName != null) { 3456 // If the activity being launched is the same as the one currently 3457 // at the top, then we need to check if it should only be launched 3458 // once. 3459 HistoryRecord top = topRunningNonDelayedActivityLocked(notTop); 3460 if (top != null && r.resultTo == null) { 3461 if (top.realActivity.equals(r.realActivity)) { 3462 if (top.app != null && top.app.thread != null) { 3463 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 3464 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP 3465 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 3466 logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task); 3467 // For paranoia, make sure we have correctly 3468 // resumed the top activity. 3469 if (doResume) { 3470 resumeTopActivityLocked(null); 3471 } 3472 if (onlyIfNeeded) { 3473 // We don't need to start a new activity, and 3474 // the client said not to do anything if that 3475 // is the case, so this is it! 3476 return START_RETURN_INTENT_TO_CALLER; 3477 } 3478 deliverNewIntentLocked(top, r.intent); 3479 return START_DELIVERED_TO_TOP; 3480 } 3481 } 3482 } 3483 } 3484 3485 } else { 3486 if (r.resultTo != null) { 3487 sendActivityResultLocked(-1, 3488 r.resultTo, r.resultWho, r.requestCode, 3489 Activity.RESULT_CANCELED, null); 3490 } 3491 return START_CLASS_NOT_FOUND; 3492 } 3493 3494 boolean newTask = false; 3495 3496 // Should this be considered a new task? 3497 if (r.resultTo == null && !addingToTask 3498 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 3499 // todo: should do better management of integers. 3500 mCurTask++; 3501 if (mCurTask <= 0) { 3502 mCurTask = 1; 3503 } 3504 r.task = new TaskRecord(mCurTask, r.info, intent, 3505 (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0); 3506 if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r 3507 + " in new task " + r.task); 3508 newTask = true; 3509 addRecentTask(r.task); 3510 3511 } else if (sourceRecord != null) { 3512 if (!addingToTask && 3513 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 3514 // In this case, we are adding the activity to an existing 3515 // task, but the caller has asked to clear that task if the 3516 // activity is already running. 3517 HistoryRecord top = performClearTaskLocked( 3518 sourceRecord.task.taskId, r, launchFlags, true); 3519 if (top != null) { 3520 logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); 3521 deliverNewIntentLocked(top, r.intent); 3522 // For paranoia, make sure we have correctly 3523 // resumed the top activity. 3524 if (doResume) { 3525 resumeTopActivityLocked(null); 3526 } 3527 return START_DELIVERED_TO_TOP; 3528 } 3529 } else if (!addingToTask && 3530 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { 3531 // In this case, we are launching an activity in our own task 3532 // that may already be running somewhere in the history, and 3533 // we want to shuffle it to the front of the stack if so. 3534 int where = findActivityInHistoryLocked(r, sourceRecord.task.taskId); 3535 if (where >= 0) { 3536 HistoryRecord top = moveActivityToFrontLocked(where); 3537 logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); 3538 deliverNewIntentLocked(top, r.intent); 3539 if (doResume) { 3540 resumeTopActivityLocked(null); 3541 } 3542 return START_DELIVERED_TO_TOP; 3543 } 3544 } 3545 // An existing activity is starting this new activity, so we want 3546 // to keep the new one in the same task as the one that is starting 3547 // it. 3548 r.task = sourceRecord.task; 3549 if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r 3550 + " in existing task " + r.task); 3551 3552 } else { 3553 // This not being started from an existing activity, and not part 3554 // of a new task... just put it in the top task, though these days 3555 // this case should never happen. 3556 final int N = mHistory.size(); 3557 HistoryRecord prev = 3558 N > 0 ? (HistoryRecord)mHistory.get(N-1) : null; 3559 r.task = prev != null 3560 ? prev.task 3561 : new TaskRecord(mCurTask, r.info, intent, 3562 (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0); 3563 if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r 3564 + " in new guessed " + r.task); 3565 } 3566 if (newTask) { 3567 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.task.taskId); 3568 } 3569 logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task); 3570 startActivityLocked(r, newTask, doResume); 3571 return START_SUCCESS; 3572 } 3573 3574 public final int startActivity(IApplicationThread caller, 3575 Intent intent, String resolvedType, Uri[] grantedUriPermissions, 3576 int grantedMode, IBinder resultTo, 3577 String resultWho, int requestCode, boolean onlyIfNeeded, 3578 boolean debug) { 3579 // Refuse possible leaked file descriptors 3580 if (intent != null && intent.hasFileDescriptors()) { 3581 throw new IllegalArgumentException("File descriptors passed in Intent"); 3582 } 3583 3584 final boolean componentSpecified = intent.getComponent() != null; 3585 3586 // Don't modify the client's object! 3587 intent = new Intent(intent); 3588 3589 // Collect information about the target of the Intent. 3590 ActivityInfo aInfo; 3591 try { 3592 ResolveInfo rInfo = 3593 ActivityThread.getPackageManager().resolveIntent( 3594 intent, resolvedType, 3595 PackageManager.MATCH_DEFAULT_ONLY 3596 | STOCK_PM_FLAGS); 3597 aInfo = rInfo != null ? rInfo.activityInfo : null; 3598 } catch (RemoteException e) { 3599 aInfo = null; 3600 } 3601 3602 if (aInfo != null) { 3603 // Store the found target back into the intent, because now that 3604 // we have it we never want to do this again. For example, if the 3605 // user navigates back to this point in the history, we should 3606 // always restart the exact same activity. 3607 intent.setComponent(new ComponentName( 3608 aInfo.applicationInfo.packageName, aInfo.name)); 3609 3610 // Don't debug things in the system process 3611 if (debug) { 3612 if (!aInfo.processName.equals("system")) { 3613 setDebugApp(aInfo.processName, true, false); 3614 } 3615 } 3616 } 3617 3618 synchronized(this) { 3619 final long origId = Binder.clearCallingIdentity(); 3620 int res = startActivityLocked(caller, intent, resolvedType, 3621 grantedUriPermissions, grantedMode, aInfo, 3622 resultTo, resultWho, requestCode, -1, -1, 3623 onlyIfNeeded, componentSpecified); 3624 Binder.restoreCallingIdentity(origId); 3625 return res; 3626 } 3627 } 3628 3629 public int startActivityIntentSender(IApplicationThread caller, 3630 IntentSender intent, Intent fillInIntent, String resolvedType, 3631 IBinder resultTo, String resultWho, int requestCode, 3632 int flagsMask, int flagsValues) { 3633 // Refuse possible leaked file descriptors 3634 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3635 throw new IllegalArgumentException("File descriptors passed in Intent"); 3636 } 3637 3638 IIntentSender sender = intent.getTarget(); 3639 if (!(sender instanceof PendingIntentRecord)) { 3640 throw new IllegalArgumentException("Bad PendingIntent object"); 3641 } 3642 3643 PendingIntentRecord pir = (PendingIntentRecord)sender; 3644 3645 synchronized (this) { 3646 // If this is coming from the currently resumed activity, it is 3647 // effectively saying that app switches are allowed at this point. 3648 if (mResumedActivity != null 3649 && mResumedActivity.info.applicationInfo.uid == 3650 Binder.getCallingUid()) { 3651 mAppSwitchesAllowedTime = 0; 3652 } 3653 } 3654 3655 return pir.sendInner(0, fillInIntent, resolvedType, 3656 null, resultTo, resultWho, requestCode, flagsMask, flagsValues); 3657 } 3658 3659 public boolean startNextMatchingActivity(IBinder callingActivity, 3660 Intent intent) { 3661 // Refuse possible leaked file descriptors 3662 if (intent != null && intent.hasFileDescriptors() == true) { 3663 throw new IllegalArgumentException("File descriptors passed in Intent"); 3664 } 3665 3666 synchronized (this) { 3667 int index = indexOfTokenLocked(callingActivity); 3668 if (index < 0) { 3669 return false; 3670 } 3671 HistoryRecord r = (HistoryRecord)mHistory.get(index); 3672 if (r.app == null || r.app.thread == null) { 3673 // The caller is not running... d'oh! 3674 return false; 3675 } 3676 intent = new Intent(intent); 3677 // The caller is not allowed to change the data. 3678 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3679 // And we are resetting to find the next component... 3680 intent.setComponent(null); 3681 3682 ActivityInfo aInfo = null; 3683 try { 3684 List<ResolveInfo> resolves = 3685 ActivityThread.getPackageManager().queryIntentActivities( 3686 intent, r.resolvedType, 3687 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS); 3688 3689 // Look for the original activity in the list... 3690 final int N = resolves != null ? resolves.size() : 0; 3691 for (int i=0; i<N; i++) { 3692 ResolveInfo rInfo = resolves.get(i); 3693 if (rInfo.activityInfo.packageName.equals(r.packageName) 3694 && rInfo.activityInfo.name.equals(r.info.name)) { 3695 // We found the current one... the next matching is 3696 // after it. 3697 i++; 3698 if (i<N) { 3699 aInfo = resolves.get(i).activityInfo; 3700 } 3701 break; 3702 } 3703 } 3704 } catch (RemoteException e) { 3705 } 3706 3707 if (aInfo == null) { 3708 // Nobody who is next! 3709 return false; 3710 } 3711 3712 intent.setComponent(new ComponentName( 3713 aInfo.applicationInfo.packageName, aInfo.name)); 3714 intent.setFlags(intent.getFlags()&~( 3715 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3716 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3717 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3718 Intent.FLAG_ACTIVITY_NEW_TASK)); 3719 3720 // Okay now we need to start the new activity, replacing the 3721 // currently running activity. This is a little tricky because 3722 // we want to start the new one as if the current one is finished, 3723 // but not finish the current one first so that there is no flicker. 3724 // And thus... 3725 final boolean wasFinishing = r.finishing; 3726 r.finishing = true; 3727 3728 // Propagate reply information over to the new activity. 3729 final HistoryRecord resultTo = r.resultTo; 3730 final String resultWho = r.resultWho; 3731 final int requestCode = r.requestCode; 3732 r.resultTo = null; 3733 if (resultTo != null) { 3734 resultTo.removeResultsLocked(r, resultWho, requestCode); 3735 } 3736 3737 final long origId = Binder.clearCallingIdentity(); 3738 // XXX we are not dealing with propagating grantedUriPermissions... 3739 // those are not yet exposed to user code, so there is no need. 3740 int res = startActivityLocked(r.app.thread, intent, 3741 r.resolvedType, null, 0, aInfo, resultTo, resultWho, 3742 requestCode, -1, r.launchedFromUid, false, false); 3743 Binder.restoreCallingIdentity(origId); 3744 3745 r.finishing = wasFinishing; 3746 if (res != START_SUCCESS) { 3747 return false; 3748 } 3749 return true; 3750 } 3751 } 3752 3753 public final int startActivityInPackage(int uid, 3754 Intent intent, String resolvedType, IBinder resultTo, 3755 String resultWho, int requestCode, boolean onlyIfNeeded) { 3756 3757 // This is so super not safe, that only the system (or okay root) 3758 // can do it. 3759 final int callingUid = Binder.getCallingUid(); 3760 if (callingUid != 0 && callingUid != Process.myUid()) { 3761 throw new SecurityException( 3762 "startActivityInPackage only available to the system"); 3763 } 3764 3765 final boolean componentSpecified = intent.getComponent() != null; 3766 3767 // Don't modify the client's object! 3768 intent = new Intent(intent); 3769 3770 // Collect information about the target of the Intent. 3771 ActivityInfo aInfo; 3772 try { 3773 ResolveInfo rInfo = 3774 ActivityThread.getPackageManager().resolveIntent( 3775 intent, resolvedType, 3776 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS); 3777 aInfo = rInfo != null ? rInfo.activityInfo : null; 3778 } catch (RemoteException e) { 3779 aInfo = null; 3780 } 3781 3782 if (aInfo != null) { 3783 // Store the found target back into the intent, because now that 3784 // we have it we never want to do this again. For example, if the 3785 // user navigates back to this point in the history, we should 3786 // always restart the exact same activity. 3787 intent.setComponent(new ComponentName( 3788 aInfo.applicationInfo.packageName, aInfo.name)); 3789 } 3790 3791 synchronized(this) { 3792 return startActivityLocked(null, intent, resolvedType, 3793 null, 0, aInfo, resultTo, resultWho, requestCode, -1, uid, 3794 onlyIfNeeded, componentSpecified); 3795 } 3796 } 3797 3798 private final void addRecentTask(TaskRecord task) { 3799 // Remove any existing entries that are the same kind of task. 3800 int N = mRecentTasks.size(); 3801 for (int i=0; i<N; i++) { 3802 TaskRecord tr = mRecentTasks.get(i); 3803 if ((task.affinity != null && task.affinity.equals(tr.affinity)) 3804 || (task.intent != null && task.intent.filterEquals(tr.intent))) { 3805 mRecentTasks.remove(i); 3806 i--; 3807 N--; 3808 if (task.intent == null) { 3809 // If the new recent task we are adding is not fully 3810 // specified, then replace it with the existing recent task. 3811 task = tr; 3812 } 3813 } 3814 } 3815 if (N >= MAX_RECENT_TASKS) { 3816 mRecentTasks.remove(N-1); 3817 } 3818 mRecentTasks.add(0, task); 3819 } 3820 3821 public void setRequestedOrientation(IBinder token, 3822 int requestedOrientation) { 3823 synchronized (this) { 3824 int index = indexOfTokenLocked(token); 3825 if (index < 0) { 3826 return; 3827 } 3828 HistoryRecord r = (HistoryRecord)mHistory.get(index); 3829 final long origId = Binder.clearCallingIdentity(); 3830 mWindowManager.setAppOrientation(r, requestedOrientation); 3831 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3832 mConfiguration, 3833 r.mayFreezeScreenLocked(r.app) ? r : null); 3834 if (config != null) { 3835 r.frozenBeforeDestroy = true; 3836 if (!updateConfigurationLocked(config, r)) { 3837 resumeTopActivityLocked(null); 3838 } 3839 } 3840 Binder.restoreCallingIdentity(origId); 3841 } 3842 } 3843 3844 public int getRequestedOrientation(IBinder token) { 3845 synchronized (this) { 3846 int index = indexOfTokenLocked(token); 3847 if (index < 0) { 3848 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3849 } 3850 HistoryRecord r = (HistoryRecord)mHistory.get(index); 3851 return mWindowManager.getAppOrientation(r); 3852 } 3853 } 3854 3855 private final void stopActivityLocked(HistoryRecord r) { 3856 if (DEBUG_SWITCH) Log.d(TAG, "Stopping: " + r); 3857 if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0 3858 || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) { 3859 if (!r.finishing) { 3860 requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null, 3861 "no-history"); 3862 } 3863 } else if (r.app != null && r.app.thread != null) { 3864 if (mFocusedActivity == r) { 3865 setFocusedActivityLocked(topRunningActivityLocked(null)); 3866 } 3867 r.resumeKeyDispatchingLocked(); 3868 try { 3869 r.stopped = false; 3870 r.state = ActivityState.STOPPING; 3871 if (DEBUG_VISBILITY) Log.v( 3872 TAG, "Stopping visible=" + r.visible + " for " + r); 3873 if (!r.visible) { 3874 mWindowManager.setAppVisibility(r, false); 3875 } 3876 r.app.thread.scheduleStopActivity(r, r.visible, r.configChangeFlags); 3877 } catch (Exception e) { 3878 // Maybe just ignore exceptions here... if the process 3879 // has crashed, our death notification will clean things 3880 // up. 3881 Log.w(TAG, "Exception thrown during pause", e); 3882 // Just in case, assume it to be stopped. 3883 r.stopped = true; 3884 r.state = ActivityState.STOPPED; 3885 if (r.configDestroy) { 3886 destroyActivityLocked(r, true); 3887 } 3888 } 3889 } 3890 } 3891 3892 /** 3893 * @return Returns true if the activity is being finished, false if for 3894 * some reason it is being left as-is. 3895 */ 3896 private final boolean requestFinishActivityLocked(IBinder token, int resultCode, 3897 Intent resultData, String reason) { 3898 if (DEBUG_RESULTS) Log.v( 3899 TAG, "Finishing activity: token=" + token 3900 + ", result=" + resultCode + ", data=" + resultData); 3901 3902 int index = indexOfTokenLocked(token); 3903 if (index < 0) { 3904 return false; 3905 } 3906 HistoryRecord r = (HistoryRecord)mHistory.get(index); 3907 3908 // Is this the last activity left? 3909 boolean lastActivity = true; 3910 for (int i=mHistory.size()-1; i>=0; i--) { 3911 HistoryRecord p = (HistoryRecord)mHistory.get(i); 3912 if (!p.finishing && p != r) { 3913 lastActivity = false; 3914 break; 3915 } 3916 } 3917 3918 // If this is the last activity, but it is the home activity, then 3919 // just don't finish it. 3920 if (lastActivity) { 3921 if (r.intent.hasCategory(Intent.CATEGORY_HOME)) { 3922 return false; 3923 } 3924 } 3925 3926 finishActivityLocked(r, index, resultCode, resultData, reason); 3927 return true; 3928 } 3929 3930 /** 3931 * @return Returns true if this activity has been removed from the history 3932 * list, or false if it is still in the list and will be removed later. 3933 */ 3934 private final boolean finishActivityLocked(HistoryRecord r, int index, 3935 int resultCode, Intent resultData, String reason) { 3936 if (r.finishing) { 3937 Log.w(TAG, "Duplicate finish request for " + r); 3938 return false; 3939 } 3940 3941 r.finishing = true; 3942 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 3943 System.identityHashCode(r), 3944 r.task.taskId, r.shortComponentName, reason); 3945 r.task.numActivities--; 3946 if (r.frontOfTask && index < (mHistory.size()-1)) { 3947 HistoryRecord next = (HistoryRecord)mHistory.get(index+1); 3948 if (next.task == r.task) { 3949 next.frontOfTask = true; 3950 } 3951 } 3952 3953 r.pauseKeyDispatchingLocked(); 3954 if (mFocusedActivity == r) { 3955 setFocusedActivityLocked(topRunningActivityLocked(null)); 3956 } 3957 3958 // send the result 3959 HistoryRecord resultTo = r.resultTo; 3960 if (resultTo != null) { 3961 if (DEBUG_RESULTS) Log.v(TAG, "Adding result to " + resultTo 3962 + " who=" + r.resultWho + " req=" + r.requestCode 3963 + " res=" + resultCode + " data=" + resultData); 3964 if (r.info.applicationInfo.uid > 0) { 3965 grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid, 3966 r.packageName, resultData, r); 3967 } 3968 resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode, 3969 resultData); 3970 r.resultTo = null; 3971 } 3972 else if (DEBUG_RESULTS) Log.v(TAG, "No result destination from " + r); 3973 3974 // Make sure this HistoryRecord is not holding on to other resources, 3975 // because clients have remote IPC references to this object so we 3976 // can't assume that will go away and want to avoid circular IPC refs. 3977 r.results = null; 3978 r.pendingResults = null; 3979 r.newIntents = null; 3980 r.icicle = null; 3981 3982 if (mPendingThumbnails.size() > 0) { 3983 // There are clients waiting to receive thumbnails so, in case 3984 // this is an activity that someone is waiting for, add it 3985 // to the pending list so we can correctly update the clients. 3986 mCancelledThumbnails.add(r); 3987 } 3988 3989 if (mResumedActivity == r) { 3990 boolean endTask = index <= 0 3991 || ((HistoryRecord)mHistory.get(index-1)).task != r.task; 3992 if (DEBUG_TRANSITION) Log.v(TAG, 3993 "Prepare close transition: finishing " + r); 3994 mWindowManager.prepareAppTransition(endTask 3995 ? WindowManagerPolicy.TRANSIT_TASK_CLOSE 3996 : WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE); 3997 3998 // Tell window manager to prepare for this one to be removed. 3999 mWindowManager.setAppVisibility(r, false); 4000 4001 if (mPausingActivity == null) { 4002 if (DEBUG_PAUSE) Log.v(TAG, "Finish needs to pause: " + r); 4003 if (DEBUG_USER_LEAVING) Log.v(TAG, "finish() => pause with userLeaving=false"); 4004 startPausingLocked(false, false); 4005 } 4006 4007 } else if (r.state != ActivityState.PAUSING) { 4008 // If the activity is PAUSING, we will complete the finish once 4009 // it is done pausing; else we can just directly finish it here. 4010 if (DEBUG_PAUSE) Log.v(TAG, "Finish not pausing: " + r); 4011 return finishCurrentActivityLocked(r, index, 4012 FINISH_AFTER_PAUSE) == null; 4013 } else { 4014 if (DEBUG_PAUSE) Log.v(TAG, "Finish waiting for pause of: " + r); 4015 } 4016 4017 return false; 4018 } 4019 4020 private static final int FINISH_IMMEDIATELY = 0; 4021 private static final int FINISH_AFTER_PAUSE = 1; 4022 private static final int FINISH_AFTER_VISIBLE = 2; 4023 4024 private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r, 4025 int mode) { 4026 final int index = indexOfTokenLocked(r); 4027 if (index < 0) { 4028 return null; 4029 } 4030 4031 return finishCurrentActivityLocked(r, index, mode); 4032 } 4033 4034 private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r, 4035 int index, int mode) { 4036 // First things first: if this activity is currently visible, 4037 // and the resumed activity is not yet visible, then hold off on 4038 // finishing until the resumed one becomes visible. 4039 if (mode == FINISH_AFTER_VISIBLE && r.nowVisible) { 4040 if (!mStoppingActivities.contains(r)) { 4041 mStoppingActivities.add(r); 4042 if (mStoppingActivities.size() > 3) { 4043 // If we already have a few activities waiting to stop, 4044 // then give up on things going idle and start clearing 4045 // them out. 4046 Message msg = Message.obtain(); 4047 msg.what = ActivityManagerService.IDLE_NOW_MSG; 4048 mHandler.sendMessage(msg); 4049 } 4050 } 4051 r.state = ActivityState.STOPPING; 4052 updateOomAdjLocked(); 4053 return r; 4054 } 4055 4056 // make sure the record is cleaned out of other places. 4057 mStoppingActivities.remove(r); 4058 mWaitingVisibleActivities.remove(r); 4059 if (mResumedActivity == r) { 4060 mResumedActivity = null; 4061 } 4062 final ActivityState prevState = r.state; 4063 r.state = ActivityState.FINISHING; 4064 4065 if (mode == FINISH_IMMEDIATELY 4066 || prevState == ActivityState.STOPPED 4067 || prevState == ActivityState.INITIALIZING) { 4068 // If this activity is already stopped, we can just finish 4069 // it right now. 4070 return destroyActivityLocked(r, true) ? null : r; 4071 } else { 4072 // Need to go through the full pause cycle to get this 4073 // activity into the stopped state and then finish it. 4074 if (localLOGV) Log.v(TAG, "Enqueueing pending finish: " + r); 4075 mFinishingActivities.add(r); 4076 resumeTopActivityLocked(null); 4077 } 4078 return r; 4079 } 4080 4081 /** 4082 * This is the internal entry point for handling Activity.finish(). 4083 * 4084 * @param token The Binder token referencing the Activity we want to finish. 4085 * @param resultCode Result code, if any, from this Activity. 4086 * @param resultData Result data (Intent), if any, from this Activity. 4087 * 4088 * @return Returns true if the activity successfully finished, or false if it is still running. 4089 */ 4090 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 4091 // Refuse possible leaked file descriptors 4092 if (resultData != null && resultData.hasFileDescriptors() == true) { 4093 throw new IllegalArgumentException("File descriptors passed in Intent"); 4094 } 4095 4096 synchronized(this) { 4097 if (mController != null) { 4098 // Find the first activity that is not finishing. 4099 HistoryRecord next = topRunningActivityLocked(token, 0); 4100 if (next != null) { 4101 // ask watcher if this is allowed 4102 boolean resumeOK = true; 4103 try { 4104 resumeOK = mController.activityResuming(next.packageName); 4105 } catch (RemoteException e) { 4106 mController = null; 4107 } 4108 4109 if (!resumeOK) { 4110 return false; 4111 } 4112 } 4113 } 4114 final long origId = Binder.clearCallingIdentity(); 4115 boolean res = requestFinishActivityLocked(token, resultCode, 4116 resultData, "app-request"); 4117 Binder.restoreCallingIdentity(origId); 4118 return res; 4119 } 4120 } 4121 4122 void sendActivityResultLocked(int callingUid, HistoryRecord r, 4123 String resultWho, int requestCode, int resultCode, Intent data) { 4124 4125 if (callingUid > 0) { 4126 grantUriPermissionFromIntentLocked(callingUid, r.packageName, 4127 data, r); 4128 } 4129 4130 if (DEBUG_RESULTS) Log.v(TAG, "Send activity result to " + r 4131 + " : who=" + resultWho + " req=" + requestCode 4132 + " res=" + resultCode + " data=" + data); 4133 if (mResumedActivity == r && r.app != null && r.app.thread != null) { 4134 try { 4135 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>(); 4136 list.add(new ResultInfo(resultWho, requestCode, 4137 resultCode, data)); 4138 r.app.thread.scheduleSendResult(r, list); 4139 return; 4140 } catch (Exception e) { 4141 Log.w(TAG, "Exception thrown sending result to " + r, e); 4142 } 4143 } 4144 4145 r.addResultLocked(null, resultWho, requestCode, resultCode, data); 4146 } 4147 4148 public final void finishSubActivity(IBinder token, String resultWho, 4149 int requestCode) { 4150 synchronized(this) { 4151 int index = indexOfTokenLocked(token); 4152 if (index < 0) { 4153 return; 4154 } 4155 HistoryRecord self = (HistoryRecord)mHistory.get(index); 4156 4157 final long origId = Binder.clearCallingIdentity(); 4158 4159 int i; 4160 for (i=mHistory.size()-1; i>=0; i--) { 4161 HistoryRecord r = (HistoryRecord)mHistory.get(i); 4162 if (r.resultTo == self && r.requestCode == requestCode) { 4163 if ((r.resultWho == null && resultWho == null) || 4164 (r.resultWho != null && r.resultWho.equals(resultWho))) { 4165 finishActivityLocked(r, i, 4166 Activity.RESULT_CANCELED, null, "request-sub"); 4167 } 4168 } 4169 } 4170 4171 Binder.restoreCallingIdentity(origId); 4172 } 4173 } 4174 4175 public void overridePendingTransition(IBinder token, String packageName, 4176 int enterAnim, int exitAnim) { 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 if (self.state == ActivityState.RESUMED 4187 || self.state == ActivityState.PAUSING) { 4188 mWindowManager.overridePendingAppTransition(packageName, 4189 enterAnim, exitAnim); 4190 } 4191 4192 Binder.restoreCallingIdentity(origId); 4193 } 4194 } 4195 4196 /** 4197 * Perform clean-up of service connections in an activity record. 4198 */ 4199 private final void cleanUpActivityServicesLocked(HistoryRecord r) { 4200 // Throw away any services that have been bound by this activity. 4201 if (r.connections != null) { 4202 Iterator<ConnectionRecord> it = r.connections.iterator(); 4203 while (it.hasNext()) { 4204 ConnectionRecord c = it.next(); 4205 removeConnectionLocked(c, null, r); 4206 } 4207 r.connections = null; 4208 } 4209 } 4210 4211 /** 4212 * Perform the common clean-up of an activity record. This is called both 4213 * as part of destroyActivityLocked() (when destroying the client-side 4214 * representation) and cleaning things up as a result of its hosting 4215 * processing going away, in which case there is no remaining client-side 4216 * state to destroy so only the cleanup here is needed. 4217 */ 4218 private final void cleanUpActivityLocked(HistoryRecord r, boolean cleanServices) { 4219 if (mResumedActivity == r) { 4220 mResumedActivity = null; 4221 } 4222 if (mFocusedActivity == r) { 4223 mFocusedActivity = null; 4224 } 4225 4226 r.configDestroy = false; 4227 r.frozenBeforeDestroy = false; 4228 4229 // Make sure this record is no longer in the pending finishes list. 4230 // This could happen, for example, if we are trimming activities 4231 // down to the max limit while they are still waiting to finish. 4232 mFinishingActivities.remove(r); 4233 mWaitingVisibleActivities.remove(r); 4234 4235 // Remove any pending results. 4236 if (r.finishing && r.pendingResults != null) { 4237 for (WeakReference<PendingIntentRecord> apr : r.pendingResults) { 4238 PendingIntentRecord rec = apr.get(); 4239 if (rec != null) { 4240 cancelIntentSenderLocked(rec, false); 4241 } 4242 } 4243 r.pendingResults = null; 4244 } 4245 4246 if (cleanServices) { 4247 cleanUpActivityServicesLocked(r); 4248 } 4249 4250 if (mPendingThumbnails.size() > 0) { 4251 // There are clients waiting to receive thumbnails so, in case 4252 // this is an activity that someone is waiting for, add it 4253 // to the pending list so we can correctly update the clients. 4254 mCancelledThumbnails.add(r); 4255 } 4256 4257 // Get rid of any pending idle timeouts. 4258 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); 4259 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 4260 } 4261 4262 private final void removeActivityFromHistoryLocked(HistoryRecord r) { 4263 if (r.state != ActivityState.DESTROYED) { 4264 mHistory.remove(r); 4265 r.inHistory = false; 4266 r.state = ActivityState.DESTROYED; 4267 mWindowManager.removeAppToken(r); 4268 if (VALIDATE_TOKENS) { 4269 mWindowManager.validateAppTokens(mHistory); 4270 } 4271 cleanUpActivityServicesLocked(r); 4272 removeActivityUriPermissionsLocked(r); 4273 } 4274 } 4275 4276 /** 4277 * Destroy the current CLIENT SIDE instance of an activity. This may be 4278 * called both when actually finishing an activity, or when performing 4279 * a configuration switch where we destroy the current client-side object 4280 * but then create a new client-side object for this same HistoryRecord. 4281 */ 4282 private final boolean destroyActivityLocked(HistoryRecord r, 4283 boolean removeFromApp) { 4284 if (DEBUG_SWITCH) Log.v( 4285 TAG, "Removing activity: token=" + r 4286 + ", app=" + (r.app != null ? r.app.processName : "(null)")); 4287 EventLog.writeEvent(EventLogTags.AM_DESTROY_ACTIVITY, 4288 System.identityHashCode(r), 4289 r.task.taskId, r.shortComponentName); 4290 4291 boolean removedFromHistory = false; 4292 4293 cleanUpActivityLocked(r, false); 4294 4295 final boolean hadApp = r.app != null; 4296 4297 if (hadApp) { 4298 if (removeFromApp) { 4299 int idx = r.app.activities.indexOf(r); 4300 if (idx >= 0) { 4301 r.app.activities.remove(idx); 4302 } 4303 if (r.persistent) { 4304 decPersistentCountLocked(r.app); 4305 } 4306 if (r.app.activities.size() == 0) { 4307 // No longer have activities, so update location in 4308 // LRU list. 4309 updateLruProcessLocked(r.app, true, false); 4310 } 4311 } 4312 4313 boolean skipDestroy = false; 4314 4315 try { 4316 if (DEBUG_SWITCH) Log.i(TAG, "Destroying: " + r); 4317 r.app.thread.scheduleDestroyActivity(r, r.finishing, 4318 r.configChangeFlags); 4319 } catch (Exception e) { 4320 // We can just ignore exceptions here... if the process 4321 // has crashed, our death notification will clean things 4322 // up. 4323 //Log.w(TAG, "Exception thrown during finish", e); 4324 if (r.finishing) { 4325 removeActivityFromHistoryLocked(r); 4326 removedFromHistory = true; 4327 skipDestroy = true; 4328 } 4329 } 4330 4331 r.app = null; 4332 r.nowVisible = false; 4333 4334 if (r.finishing && !skipDestroy) { 4335 r.state = ActivityState.DESTROYING; 4336 Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG); 4337 msg.obj = r; 4338 mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT); 4339 } else { 4340 r.state = ActivityState.DESTROYED; 4341 } 4342 } else { 4343 // remove this record from the history. 4344 if (r.finishing) { 4345 removeActivityFromHistoryLocked(r); 4346 removedFromHistory = true; 4347 } else { 4348 r.state = ActivityState.DESTROYED; 4349 } 4350 } 4351 4352 r.configChangeFlags = 0; 4353 4354 if (!mLRUActivities.remove(r) && hadApp) { 4355 Log.w(TAG, "Activity " + r + " being finished, but not in LRU list"); 4356 } 4357 4358 return removedFromHistory; 4359 } 4360 4361 private static void removeHistoryRecordsForAppLocked(ArrayList list, ProcessRecord app) { 4362 int i = list.size(); 4363 if (localLOGV) Log.v( 4364 TAG, "Removing app " + app + " from list " + list 4365 + " with " + i + " entries"); 4366 while (i > 0) { 4367 i--; 4368 HistoryRecord r = (HistoryRecord)list.get(i); 4369 if (localLOGV) Log.v( 4370 TAG, "Record #" + i + " " + r + ": app=" + r.app); 4371 if (r.app == app) { 4372 if (localLOGV) Log.v(TAG, "Removing this entry!"); 4373 list.remove(i); 4374 } 4375 } 4376 } 4377 4378 /** 4379 * Main function for removing an existing process from the activity manager 4380 * as a result of that process going away. Clears out all connections 4381 * to the process. 4382 */ 4383 private final void handleAppDiedLocked(ProcessRecord app, 4384 boolean restarting) { 4385 cleanUpApplicationRecordLocked(app, restarting, -1); 4386 if (!restarting) { 4387 mLruProcesses.remove(app); 4388 } 4389 4390 // Just in case... 4391 if (mPausingActivity != null && mPausingActivity.app == app) { 4392 if (DEBUG_PAUSE) Log.v(TAG, "App died while pausing: " + mPausingActivity); 4393 mPausingActivity = null; 4394 } 4395 if (mLastPausedActivity != null && mLastPausedActivity.app == app) { 4396 mLastPausedActivity = null; 4397 } 4398 4399 // Remove this application's activities from active lists. 4400 removeHistoryRecordsForAppLocked(mLRUActivities, app); 4401 removeHistoryRecordsForAppLocked(mStoppingActivities, app); 4402 removeHistoryRecordsForAppLocked(mWaitingVisibleActivities, app); 4403 removeHistoryRecordsForAppLocked(mFinishingActivities, app); 4404 4405 boolean atTop = true; 4406 boolean hasVisibleActivities = false; 4407 4408 // Clean out the history list. 4409 int i = mHistory.size(); 4410 if (localLOGV) Log.v( 4411 TAG, "Removing app " + app + " from history with " + i + " entries"); 4412 while (i > 0) { 4413 i--; 4414 HistoryRecord r = (HistoryRecord)mHistory.get(i); 4415 if (localLOGV) Log.v( 4416 TAG, "Record #" + i + " " + r + ": app=" + r.app); 4417 if (r.app == app) { 4418 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 4419 if (localLOGV) Log.v( 4420 TAG, "Removing this entry! frozen=" + r.haveState 4421 + " finishing=" + r.finishing); 4422 mHistory.remove(i); 4423 4424 r.inHistory = false; 4425 mWindowManager.removeAppToken(r); 4426 if (VALIDATE_TOKENS) { 4427 mWindowManager.validateAppTokens(mHistory); 4428 } 4429 removeActivityUriPermissionsLocked(r); 4430 4431 } else { 4432 // We have the current state for this activity, so 4433 // it can be restarted later when needed. 4434 if (localLOGV) Log.v( 4435 TAG, "Keeping entry, setting app to null"); 4436 if (r.visible) { 4437 hasVisibleActivities = true; 4438 } 4439 r.app = null; 4440 r.nowVisible = false; 4441 if (!r.haveState) { 4442 r.icicle = null; 4443 } 4444 } 4445 4446 cleanUpActivityLocked(r, true); 4447 r.state = ActivityState.STOPPED; 4448 } 4449 atTop = false; 4450 } 4451 4452 app.activities.clear(); 4453 4454 if (app.instrumentationClass != null) { 4455 Log.w(TAG, "Crash of app " + app.processName 4456 + " running instrumentation " + app.instrumentationClass); 4457 Bundle info = new Bundle(); 4458 info.putString("shortMsg", "Process crashed."); 4459 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4460 } 4461 4462 if (!restarting) { 4463 if (!resumeTopActivityLocked(null)) { 4464 // If there was nothing to resume, and we are not already 4465 // restarting this process, but there is a visible activity that 4466 // is hosted by the process... then make sure all visible 4467 // activities are running, taking care of restarting this 4468 // process. 4469 if (hasVisibleActivities) { 4470 ensureActivitiesVisibleLocked(null, 0); 4471 } 4472 } 4473 } 4474 } 4475 4476 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4477 IBinder threadBinder = thread.asBinder(); 4478 4479 // Find the application record. 4480 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4481 ProcessRecord rec = mLruProcesses.get(i); 4482 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4483 return i; 4484 } 4485 } 4486 return -1; 4487 } 4488 4489 private final ProcessRecord getRecordForAppLocked( 4490 IApplicationThread thread) { 4491 if (thread == null) { 4492 return null; 4493 } 4494 4495 int appIndex = getLRURecordIndexForAppLocked(thread); 4496 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4497 } 4498 4499 private final void appDiedLocked(ProcessRecord app, int pid, 4500 IApplicationThread thread) { 4501 4502 mProcDeaths[0]++; 4503 4504 if (app.thread != null && app.thread.asBinder() == thread.asBinder()) { 4505 Log.i(TAG, "Process " + app.processName + " (pid " + pid 4506 + ") has died."); 4507 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 4508 if (localLOGV) Log.v( 4509 TAG, "Dying app: " + app + ", pid: " + pid 4510 + ", thread: " + thread.asBinder()); 4511 boolean doLowMem = app.instrumentationClass == null; 4512 handleAppDiedLocked(app, false); 4513 4514 if (doLowMem) { 4515 // If there are no longer any background processes running, 4516 // and the app that died was not running instrumentation, 4517 // then tell everyone we are now low on memory. 4518 boolean haveBg = false; 4519 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4520 ProcessRecord rec = mLruProcesses.get(i); 4521 if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) { 4522 haveBg = true; 4523 break; 4524 } 4525 } 4526 4527 if (!haveBg) { 4528 Log.i(TAG, "Low Memory: No more background processes."); 4529 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4530 long now = SystemClock.uptimeMillis(); 4531 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4532 ProcessRecord rec = mLruProcesses.get(i); 4533 if (rec != app && rec.thread != null && 4534 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4535 // The low memory report is overriding any current 4536 // state for a GC request. Make sure to do 4537 // visible/foreground processes first. 4538 if (rec.setAdj <= VISIBLE_APP_ADJ) { 4539 rec.lastRequestedGc = 0; 4540 } else { 4541 rec.lastRequestedGc = rec.lastLowMemory; 4542 } 4543 rec.reportLowMemory = true; 4544 rec.lastLowMemory = now; 4545 mProcessesToGc.remove(rec); 4546 addProcessToGcListLocked(rec); 4547 } 4548 } 4549 scheduleAppGcsLocked(); 4550 } 4551 } 4552 } else if (DEBUG_PROCESSES) { 4553 Log.d(TAG, "Received spurious death notification for thread " 4554 + thread.asBinder()); 4555 } 4556 } 4557 4558 final String readFile(String filename) { 4559 try { 4560 FileInputStream fs = new FileInputStream(filename); 4561 byte[] inp = new byte[8192]; 4562 int size = fs.read(inp); 4563 fs.close(); 4564 return new String(inp, 0, 0, size); 4565 } catch (java.io.IOException e) { 4566 } 4567 return ""; 4568 } 4569 4570 final void appNotRespondingLocked(ProcessRecord app, HistoryRecord activity, 4571 HistoryRecord reportedActivity, final String annotation) { 4572 if (app.notResponding || app.crashing) { 4573 return; 4574 } 4575 4576 // Log the ANR to the event log. 4577 EventLog.writeEvent(EventLogTags.ANR, app.pid, app.processName, annotation); 4578 4579 // If we are on a secure build and the application is not interesting to the user (it is 4580 // not visible or in the background), just kill it instead of displaying a dialog. 4581 boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0")); 4582 if (isSecure && !app.isInterestingToUserLocked() && Process.myPid() != app.pid) { 4583 Process.killProcess(app.pid); 4584 return; 4585 } 4586 4587 // DeviceMonitor.start(); 4588 4589 String processInfo = null; 4590 if (MONITOR_CPU_USAGE) { 4591 updateCpuStatsNow(); 4592 synchronized (mProcessStatsThread) { 4593 processInfo = mProcessStats.printCurrentState(); 4594 } 4595 } 4596 4597 StringBuilder info = mStringBuilder; 4598 info.setLength(0); 4599 info.append("ANR in process: "); 4600 info.append(app.processName); 4601 if (reportedActivity != null && reportedActivity.app != null) { 4602 info.append(" (last in "); 4603 info.append(reportedActivity.app.processName); 4604 info.append(")"); 4605 } 4606 if (annotation != null) { 4607 info.append("\nAnnotation: "); 4608 info.append(annotation); 4609 } 4610 if (MONITOR_CPU_USAGE) { 4611 info.append("\nCPU usage:\n"); 4612 info.append(processInfo); 4613 } 4614 Log.i(TAG, info.toString()); 4615 4616 // The application is not responding. Dump as many thread traces as we can. 4617 boolean fileDump = prepareTraceFile(true); 4618 if (!fileDump) { 4619 // Dumping traces to the log, just dump the process that isn't responding so 4620 // we don't overflow the log 4621 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4622 } else { 4623 // Dumping traces to a file so dump all active processes we know about 4624 synchronized (this) { 4625 // First, these are the most important processes. 4626 final int[] imppids = new int[3]; 4627 int i=0; 4628 imppids[0] = app.pid; 4629 i++; 4630 if (reportedActivity != null && reportedActivity.app != null 4631 && reportedActivity.app.thread != null 4632 && reportedActivity.app.pid != app.pid) { 4633 imppids[i] = reportedActivity.app.pid; 4634 i++; 4635 } 4636 imppids[i] = Process.myPid(); 4637 for (i=0; i<imppids.length && imppids[i] != 0; i++) { 4638 Process.sendSignal(imppids[i], Process.SIGNAL_QUIT); 4639 synchronized (this) { 4640 try { 4641 wait(200); 4642 } catch (InterruptedException e) { 4643 } 4644 } 4645 } 4646 for (i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 4647 ProcessRecord r = mLruProcesses.get(i); 4648 boolean done = false; 4649 for (int j=0; j<imppids.length && imppids[j] != 0; j++) { 4650 if (imppids[j] == r.pid) { 4651 done = true; 4652 break; 4653 } 4654 } 4655 if (!done && r.thread != null) { 4656 Process.sendSignal(r.pid, Process.SIGNAL_QUIT); 4657 synchronized (this) { 4658 try { 4659 wait(200); 4660 } catch (InterruptedException e) { 4661 } 4662 } 4663 } 4664 } 4665 } 4666 } 4667 4668 if (mController != null) { 4669 try { 4670 int res = mController.appNotResponding(app.processName, 4671 app.pid, info.toString()); 4672 if (res != 0) { 4673 if (res < 0) { 4674 // wait until the SIGQUIT has had a chance to process before killing the 4675 // process. 4676 try { 4677 wait(2000); 4678 } catch (InterruptedException e) { 4679 } 4680 4681 Process.killProcess(app.pid); 4682 return; 4683 } 4684 } 4685 } catch (RemoteException e) { 4686 mController = null; 4687 } 4688 } 4689 4690 makeAppNotRespondingLocked(app, 4691 activity != null ? activity.shortComponentName : null, 4692 annotation != null ? "ANR " + annotation : "ANR", 4693 info.toString()); 4694 Message msg = Message.obtain(); 4695 HashMap map = new HashMap(); 4696 msg.what = SHOW_NOT_RESPONDING_MSG; 4697 msg.obj = map; 4698 map.put("app", app); 4699 if (activity != null) { 4700 map.put("activity", activity); 4701 } 4702 4703 mHandler.sendMessage(msg); 4704 return; 4705 } 4706 4707 /** 4708 * If a stack trace file has been configured, prepare the filesystem 4709 * by creating the directory if it doesn't exist and optionally 4710 * removing the old trace file. 4711 * 4712 * @param removeExisting If set, the existing trace file will be removed. 4713 * @return Returns true if the trace file preparations succeeded 4714 */ 4715 public static boolean prepareTraceFile(boolean removeExisting) { 4716 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4717 boolean fileReady = false; 4718 if (!TextUtils.isEmpty(tracesPath)) { 4719 File f = new File(tracesPath); 4720 if (!f.exists()) { 4721 // Ensure the enclosing directory exists 4722 File dir = f.getParentFile(); 4723 if (!dir.exists()) { 4724 fileReady = dir.mkdirs(); 4725 FileUtils.setPermissions(dir.getAbsolutePath(), 4726 FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IXOTH, -1, -1); 4727 } else if (dir.isDirectory()) { 4728 fileReady = true; 4729 } 4730 } else if (removeExisting) { 4731 // Remove the previous traces file, so we don't fill the disk. 4732 // The VM will recreate it 4733 Log.i(TAG, "Removing old ANR trace file from " + tracesPath); 4734 fileReady = f.delete(); 4735 } 4736 4737 if (removeExisting) { 4738 try { 4739 f.createNewFile(); 4740 FileUtils.setPermissions(f.getAbsolutePath(), 4741 FileUtils.S_IRWXU | FileUtils.S_IRWXG 4742 | FileUtils.S_IWOTH | FileUtils.S_IROTH, -1, -1); 4743 fileReady = true; 4744 } catch (IOException e) { 4745 Log.w(TAG, "Unable to make ANR traces file", e); 4746 } 4747 } 4748 } 4749 4750 return fileReady; 4751 } 4752 4753 4754 private final void decPersistentCountLocked(ProcessRecord app) 4755 { 4756 app.persistentActivities--; 4757 if (app.persistentActivities > 0) { 4758 // Still more of 'em... 4759 return; 4760 } 4761 if (app.persistent) { 4762 // Ah, but the application itself is persistent. Whatever! 4763 return; 4764 } 4765 4766 // App is no longer persistent... make sure it and the ones 4767 // following it in the LRU list have the correc oom_adj. 4768 updateOomAdjLocked(); 4769 } 4770 4771 public void setPersistent(IBinder token, boolean isPersistent) { 4772 if (checkCallingPermission(android.Manifest.permission.PERSISTENT_ACTIVITY) 4773 != PackageManager.PERMISSION_GRANTED) { 4774 String msg = "Permission Denial: setPersistent() from pid=" 4775 + Binder.getCallingPid() 4776 + ", uid=" + Binder.getCallingUid() 4777 + " requires " + android.Manifest.permission.PERSISTENT_ACTIVITY; 4778 Log.w(TAG, msg); 4779 throw new SecurityException(msg); 4780 } 4781 4782 synchronized(this) { 4783 int index = indexOfTokenLocked(token); 4784 if (index < 0) { 4785 return; 4786 } 4787 HistoryRecord r = (HistoryRecord)mHistory.get(index); 4788 ProcessRecord app = r.app; 4789 4790 if (localLOGV) Log.v( 4791 TAG, "Setting persistence " + isPersistent + ": " + r); 4792 4793 if (isPersistent) { 4794 if (r.persistent) { 4795 // Okay okay, I heard you already! 4796 if (localLOGV) Log.v(TAG, "Already persistent!"); 4797 return; 4798 } 4799 r.persistent = true; 4800 app.persistentActivities++; 4801 if (localLOGV) Log.v(TAG, "Num persistent now: " + app.persistentActivities); 4802 if (app.persistentActivities > 1) { 4803 // We aren't the first... 4804 if (localLOGV) Log.v(TAG, "Not the first!"); 4805 return; 4806 } 4807 if (app.persistent) { 4808 // This would be redundant. 4809 if (localLOGV) Log.v(TAG, "App is persistent!"); 4810 return; 4811 } 4812 4813 // App is now persistent... make sure it and the ones 4814 // following it now have the correct oom_adj. 4815 final long origId = Binder.clearCallingIdentity(); 4816 updateOomAdjLocked(); 4817 Binder.restoreCallingIdentity(origId); 4818 4819 } else { 4820 if (!r.persistent) { 4821 // Okay okay, I heard you already! 4822 return; 4823 } 4824 r.persistent = false; 4825 final long origId = Binder.clearCallingIdentity(); 4826 decPersistentCountLocked(app); 4827 Binder.restoreCallingIdentity(origId); 4828 4829 } 4830 } 4831 } 4832 4833 public boolean clearApplicationUserData(final String packageName, 4834 final IPackageDataObserver observer) { 4835 int uid = Binder.getCallingUid(); 4836 int pid = Binder.getCallingPid(); 4837 long callingId = Binder.clearCallingIdentity(); 4838 try { 4839 IPackageManager pm = ActivityThread.getPackageManager(); 4840 int pkgUid = -1; 4841 synchronized(this) { 4842 try { 4843 pkgUid = pm.getPackageUid(packageName); 4844 } catch (RemoteException e) { 4845 } 4846 if (pkgUid == -1) { 4847 Log.w(TAG, "Invalid packageName:" + packageName); 4848 return false; 4849 } 4850 if (uid == pkgUid || checkComponentPermission( 4851 android.Manifest.permission.CLEAR_APP_USER_DATA, 4852 pid, uid, -1) 4853 == PackageManager.PERMISSION_GRANTED) { 4854 forceStopPackageLocked(packageName, pkgUid); 4855 } else { 4856 throw new SecurityException(pid+" does not have permission:"+ 4857 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 4858 "for process:"+packageName); 4859 } 4860 } 4861 4862 try { 4863 //clear application user data 4864 pm.clearApplicationUserData(packageName, observer); 4865 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4866 Uri.fromParts("package", packageName, null)); 4867 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4868 broadcastIntentLocked(null, null, intent, 4869 null, null, 0, null, null, null, 4870 false, false, MY_PID, Process.SYSTEM_UID); 4871 } catch (RemoteException e) { 4872 } 4873 } finally { 4874 Binder.restoreCallingIdentity(callingId); 4875 } 4876 return true; 4877 } 4878 4879 public void killBackgroundProcesses(final String packageName) { 4880 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4881 != PackageManager.PERMISSION_GRANTED && 4882 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4883 != PackageManager.PERMISSION_GRANTED) { 4884 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4885 + Binder.getCallingPid() 4886 + ", uid=" + Binder.getCallingUid() 4887 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4888 Log.w(TAG, msg); 4889 throw new SecurityException(msg); 4890 } 4891 4892 long callingId = Binder.clearCallingIdentity(); 4893 try { 4894 IPackageManager pm = ActivityThread.getPackageManager(); 4895 int pkgUid = -1; 4896 synchronized(this) { 4897 try { 4898 pkgUid = pm.getPackageUid(packageName); 4899 } catch (RemoteException e) { 4900 } 4901 if (pkgUid == -1) { 4902 Log.w(TAG, "Invalid packageName: " + packageName); 4903 return; 4904 } 4905 killPackageProcessesLocked(packageName, pkgUid, 4906 SECONDARY_SERVER_ADJ, false); 4907 } 4908 } finally { 4909 Binder.restoreCallingIdentity(callingId); 4910 } 4911 } 4912 4913 public void forceStopPackage(final String packageName) { 4914 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4915 != PackageManager.PERMISSION_GRANTED) { 4916 String msg = "Permission Denial: forceStopPackage() from pid=" 4917 + Binder.getCallingPid() 4918 + ", uid=" + Binder.getCallingUid() 4919 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4920 Log.w(TAG, msg); 4921 throw new SecurityException(msg); 4922 } 4923 4924 long callingId = Binder.clearCallingIdentity(); 4925 try { 4926 IPackageManager pm = ActivityThread.getPackageManager(); 4927 int pkgUid = -1; 4928 synchronized(this) { 4929 try { 4930 pkgUid = pm.getPackageUid(packageName); 4931 } catch (RemoteException e) { 4932 } 4933 if (pkgUid == -1) { 4934 Log.w(TAG, "Invalid packageName: " + packageName); 4935 return; 4936 } 4937 forceStopPackageLocked(packageName, pkgUid); 4938 } 4939 } finally { 4940 Binder.restoreCallingIdentity(callingId); 4941 } 4942 } 4943 4944 /* 4945 * The pkg name and uid have to be specified. 4946 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 4947 */ 4948 public void killApplicationWithUid(String pkg, int uid) { 4949 if (pkg == null) { 4950 return; 4951 } 4952 // Make sure the uid is valid. 4953 if (uid < 0) { 4954 Log.w(TAG, "Invalid uid specified for pkg : " + pkg); 4955 return; 4956 } 4957 int callerUid = Binder.getCallingUid(); 4958 // Only the system server can kill an application 4959 if (callerUid == Process.SYSTEM_UID) { 4960 // Post an aysnc message to kill the application 4961 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4962 msg.arg1 = uid; 4963 msg.arg2 = 0; 4964 msg.obj = pkg; 4965 mHandler.sendMessage(msg); 4966 } else { 4967 throw new SecurityException(callerUid + " cannot kill pkg: " + 4968 pkg); 4969 } 4970 } 4971 4972 public void closeSystemDialogs(String reason) { 4973 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4974 if (reason != null) { 4975 intent.putExtra("reason", reason); 4976 } 4977 4978 final int uid = Binder.getCallingUid(); 4979 final long origId = Binder.clearCallingIdentity(); 4980 synchronized (this) { 4981 int i = mWatchers.beginBroadcast(); 4982 while (i > 0) { 4983 i--; 4984 IActivityWatcher w = mWatchers.getBroadcastItem(i); 4985 if (w != null) { 4986 try { 4987 w.closingSystemDialogs(reason); 4988 } catch (RemoteException e) { 4989 } 4990 } 4991 } 4992 mWatchers.finishBroadcast(); 4993 4994 mWindowManager.closeSystemDialogs(reason); 4995 4996 for (i=mHistory.size()-1; i>=0; i--) { 4997 HistoryRecord r = (HistoryRecord)mHistory.get(i); 4998 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 4999 finishActivityLocked(r, i, 5000 Activity.RESULT_CANCELED, null, "close-sys"); 5001 } 5002 } 5003 5004 broadcastIntentLocked(null, null, intent, null, 5005 null, 0, null, null, null, false, false, -1, uid); 5006 } 5007 Binder.restoreCallingIdentity(origId); 5008 } 5009 5010 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 5011 throws RemoteException { 5012 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5013 for (int i=pids.length-1; i>=0; i--) { 5014 infos[i] = new Debug.MemoryInfo(); 5015 Debug.getMemoryInfo(pids[i], infos[i]); 5016 } 5017 return infos; 5018 } 5019 5020 public void killApplicationProcess(String processName, int uid) { 5021 if (processName == null) { 5022 return; 5023 } 5024 5025 int callerUid = Binder.getCallingUid(); 5026 // Only the system server can kill an application 5027 if (callerUid == Process.SYSTEM_UID) { 5028 synchronized (this) { 5029 ProcessRecord app = getProcessRecordLocked(processName, uid); 5030 if (app != null) { 5031 try { 5032 app.thread.scheduleSuicide(); 5033 } catch (RemoteException e) { 5034 // If the other end already died, then our work here is done. 5035 } 5036 } else { 5037 Log.w(TAG, "Process/uid not found attempting kill of " 5038 + processName + " / " + uid); 5039 } 5040 } 5041 } else { 5042 throw new SecurityException(callerUid + " cannot kill app process: " + 5043 processName); 5044 } 5045 } 5046 5047 private void forceStopPackageLocked(final String packageName, int uid) { 5048 forceStopPackageLocked(packageName, uid, false); 5049 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5050 Uri.fromParts("package", packageName, null)); 5051 intent.putExtra(Intent.EXTRA_UID, uid); 5052 broadcastIntentLocked(null, null, intent, 5053 null, null, 0, null, null, null, 5054 false, false, MY_PID, Process.SYSTEM_UID); 5055 } 5056 5057 private final void killPackageProcessesLocked(String packageName, int uid, 5058 int minOomAdj, boolean callerWillRestart) { 5059 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5060 5061 // Remove all processes this package may have touched: all with the 5062 // same UID (except for the system or root user), and all whose name 5063 // matches the package name. 5064 final String procNamePrefix = packageName + ":"; 5065 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 5066 final int NA = apps.size(); 5067 for (int ia=0; ia<NA; ia++) { 5068 ProcessRecord app = apps.valueAt(ia); 5069 if (app.removed) { 5070 procs.add(app); 5071 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 5072 || app.processName.equals(packageName) 5073 || app.processName.startsWith(procNamePrefix)) { 5074 if (app.setAdj >= minOomAdj) { 5075 app.removed = true; 5076 procs.add(app); 5077 } 5078 } 5079 } 5080 } 5081 5082 int N = procs.size(); 5083 for (int i=0; i<N; i++) { 5084 removeProcessLocked(procs.get(i), callerWillRestart); 5085 } 5086 } 5087 5088 private final void forceStopPackageLocked(String name, int uid, 5089 boolean callerWillRestart) { 5090 int i, N; 5091 5092 if (uid < 0) { 5093 try { 5094 uid = ActivityThread.getPackageManager().getPackageUid(name); 5095 } catch (RemoteException e) { 5096 } 5097 } 5098 5099 Log.i(TAG, "Force stopping package " + name + " uid=" + uid); 5100 5101 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 5102 while (badApps.hasNext()) { 5103 SparseArray<Long> ba = badApps.next(); 5104 if (ba.get(uid) != null) { 5105 badApps.remove(); 5106 } 5107 } 5108 5109 killPackageProcessesLocked(name, uid, -100, callerWillRestart); 5110 5111 for (i=mHistory.size()-1; i>=0; i--) { 5112 HistoryRecord r = (HistoryRecord)mHistory.get(i); 5113 if (r.packageName.equals(name)) { 5114 Log.i(TAG, " Force finishing activity " + r); 5115 if (r.app != null) { 5116 r.app.removed = true; 5117 } 5118 r.app = null; 5119 finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall"); 5120 } 5121 } 5122 5123 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 5124 for (ServiceRecord service : mServices.values()) { 5125 if (service.packageName.equals(name)) { 5126 Log.i(TAG, " Force stopping service " + service); 5127 if (service.app != null) { 5128 service.app.removed = true; 5129 } 5130 service.app = null; 5131 services.add(service); 5132 } 5133 } 5134 5135 N = services.size(); 5136 for (i=0; i<N; i++) { 5137 bringDownServiceLocked(services.get(i), true); 5138 } 5139 5140 resumeTopActivityLocked(null); 5141 } 5142 5143 private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) { 5144 final String name = app.processName; 5145 final int uid = app.info.uid; 5146 if (DEBUG_PROCESSES) Log.d( 5147 TAG, "Force removing process " + app + " (" + name 5148 + "/" + uid + ")"); 5149 5150 mProcessNames.remove(name, uid); 5151 boolean needRestart = false; 5152 if (app.pid > 0 && app.pid != MY_PID) { 5153 int pid = app.pid; 5154 synchronized (mPidsSelfLocked) { 5155 mPidsSelfLocked.remove(pid); 5156 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5157 } 5158 handleAppDiedLocked(app, true); 5159 mLruProcesses.remove(app); 5160 Process.killProcess(pid); 5161 5162 if (app.persistent) { 5163 if (!callerWillRestart) { 5164 addAppLocked(app.info); 5165 } else { 5166 needRestart = true; 5167 } 5168 } 5169 } else { 5170 mRemovedProcesses.add(app); 5171 } 5172 5173 return needRestart; 5174 } 5175 5176 private final void processStartTimedOutLocked(ProcessRecord app) { 5177 final int pid = app.pid; 5178 boolean gone = false; 5179 synchronized (mPidsSelfLocked) { 5180 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5181 if (knownApp != null && knownApp.thread == null) { 5182 mPidsSelfLocked.remove(pid); 5183 gone = true; 5184 } 5185 } 5186 5187 if (gone) { 5188 Log.w(TAG, "Process " + app + " failed to attach"); 5189 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid, 5190 app.processName); 5191 mProcessNames.remove(app.processName, app.info.uid); 5192 // Take care of any launching providers waiting for this process. 5193 checkAppInLaunchingProvidersLocked(app, true); 5194 // Take care of any services that are waiting for the process. 5195 for (int i=0; i<mPendingServices.size(); i++) { 5196 ServiceRecord sr = mPendingServices.get(i); 5197 if (app.info.uid == sr.appInfo.uid 5198 && app.processName.equals(sr.processName)) { 5199 Log.w(TAG, "Forcing bringing down service: " + sr); 5200 mPendingServices.remove(i); 5201 i--; 5202 bringDownServiceLocked(sr, true); 5203 } 5204 } 5205 Process.killProcess(pid); 5206 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5207 Log.w(TAG, "Unattached app died before backup, skipping"); 5208 try { 5209 IBackupManager bm = IBackupManager.Stub.asInterface( 5210 ServiceManager.getService(Context.BACKUP_SERVICE)); 5211 bm.agentDisconnected(app.info.packageName); 5212 } catch (RemoteException e) { 5213 // Can't happen; the backup manager is local 5214 } 5215 } 5216 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) { 5217 Log.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5218 mPendingBroadcast = null; 5219 scheduleBroadcastsLocked(); 5220 } 5221 } else { 5222 Log.w(TAG, "Spurious process start timeout - pid not known for " + app); 5223 } 5224 } 5225 5226 private final boolean attachApplicationLocked(IApplicationThread thread, 5227 int pid) { 5228 5229 // Find the application record that is being attached... either via 5230 // the pid if we are running in multiple processes, or just pull the 5231 // next app record if we are emulating process with anonymous threads. 5232 ProcessRecord app; 5233 if (pid != MY_PID && pid >= 0) { 5234 synchronized (mPidsSelfLocked) { 5235 app = mPidsSelfLocked.get(pid); 5236 } 5237 } else if (mStartingProcesses.size() > 0) { 5238 app = mStartingProcesses.remove(0); 5239 app.setPid(pid); 5240 } else { 5241 app = null; 5242 } 5243 5244 if (app == null) { 5245 Log.w(TAG, "No pending application record for pid " + pid 5246 + " (IApplicationThread " + thread + "); dropping process"); 5247 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5248 if (pid > 0 && pid != MY_PID) { 5249 Process.killProcess(pid); 5250 } else { 5251 try { 5252 thread.scheduleExit(); 5253 } catch (Exception e) { 5254 // Ignore exceptions. 5255 } 5256 } 5257 return false; 5258 } 5259 5260 // If this application record is still attached to a previous 5261 // process, clean it up now. 5262 if (app.thread != null) { 5263 handleAppDiedLocked(app, true); 5264 } 5265 5266 // Tell the process all about itself. 5267 5268 if (localLOGV) Log.v( 5269 TAG, "Binding process pid " + pid + " to record " + app); 5270 5271 String processName = app.processName; 5272 try { 5273 thread.asBinder().linkToDeath(new AppDeathRecipient( 5274 app, pid, thread), 0); 5275 } catch (RemoteException e) { 5276 app.resetPackageList(); 5277 startProcessLocked(app, "link fail", processName); 5278 return false; 5279 } 5280 5281 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 5282 5283 app.thread = thread; 5284 app.curAdj = app.setAdj = -100; 5285 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 5286 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 5287 app.forcingToForeground = null; 5288 app.foregroundServices = false; 5289 app.debugging = false; 5290 5291 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5292 5293 boolean normalMode = mSystemReady || isAllowedWhileBooting(app.info); 5294 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5295 5296 if (!normalMode) { 5297 Log.i(TAG, "Launching preboot mode app: " + app); 5298 } 5299 5300 if (localLOGV) Log.v( 5301 TAG, "New app record " + app 5302 + " thread=" + thread.asBinder() + " pid=" + pid); 5303 try { 5304 int testMode = IApplicationThread.DEBUG_OFF; 5305 if (mDebugApp != null && mDebugApp.equals(processName)) { 5306 testMode = mWaitForDebugger 5307 ? IApplicationThread.DEBUG_WAIT 5308 : IApplicationThread.DEBUG_ON; 5309 app.debugging = true; 5310 if (mDebugTransient) { 5311 mDebugApp = mOrigDebugApp; 5312 mWaitForDebugger = mOrigWaitForDebugger; 5313 } 5314 } 5315 5316 // If the app is being launched for restore or full backup, set it up specially 5317 boolean isRestrictedBackupMode = false; 5318 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5319 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5320 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5321 } 5322 5323 ensurePackageDexOpt(app.instrumentationInfo != null 5324 ? app.instrumentationInfo.packageName 5325 : app.info.packageName); 5326 if (app.instrumentationClass != null) { 5327 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5328 } 5329 if (DEBUG_CONFIGURATION) Log.v(TAG, "Binding proc " 5330 + processName + " with config " + mConfiguration); 5331 thread.bindApplication(processName, app.instrumentationInfo != null 5332 ? app.instrumentationInfo : app.info, providers, 5333 app.instrumentationClass, app.instrumentationProfileFile, 5334 app.instrumentationArguments, app.instrumentationWatcher, testMode, 5335 isRestrictedBackupMode || !normalMode, 5336 mConfiguration, getCommonServicesLocked()); 5337 updateLruProcessLocked(app, false, true); 5338 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5339 } catch (Exception e) { 5340 // todo: Yikes! What should we do? For now we will try to 5341 // start another process, but that could easily get us in 5342 // an infinite loop of restarting processes... 5343 Log.w(TAG, "Exception thrown during bind!", e); 5344 5345 app.resetPackageList(); 5346 startProcessLocked(app, "bind fail", processName); 5347 return false; 5348 } 5349 5350 // Remove this record from the list of starting applications. 5351 mPersistentStartingProcesses.remove(app); 5352 mProcessesOnHold.remove(app); 5353 5354 boolean badApp = false; 5355 boolean didSomething = false; 5356 5357 // See if the top visible activity is waiting to run in this process... 5358 HistoryRecord hr = topRunningActivityLocked(null); 5359 if (hr != null) { 5360 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid 5361 && processName.equals(hr.processName)) { 5362 try { 5363 if (realStartActivityLocked(hr, app, true, true)) { 5364 didSomething = true; 5365 } 5366 } catch (Exception e) { 5367 Log.w(TAG, "Exception in new application when starting activity " 5368 + hr.intent.getComponent().flattenToShortString(), e); 5369 badApp = true; 5370 } 5371 } else { 5372 ensureActivitiesVisibleLocked(hr, null, processName, 0); 5373 } 5374 } 5375 5376 // Find any services that should be running in this process... 5377 if (!badApp && mPendingServices.size() > 0) { 5378 ServiceRecord sr = null; 5379 try { 5380 for (int i=0; i<mPendingServices.size(); i++) { 5381 sr = mPendingServices.get(i); 5382 if (app.info.uid != sr.appInfo.uid 5383 || !processName.equals(sr.processName)) { 5384 continue; 5385 } 5386 5387 mPendingServices.remove(i); 5388 i--; 5389 realStartServiceLocked(sr, app); 5390 didSomething = true; 5391 } 5392 } catch (Exception e) { 5393 Log.w(TAG, "Exception in new application when starting service " 5394 + sr.shortName, e); 5395 badApp = true; 5396 } 5397 } 5398 5399 // Check if the next broadcast receiver is in this process... 5400 BroadcastRecord br = mPendingBroadcast; 5401 if (!badApp && br != null && br.curApp == app) { 5402 try { 5403 mPendingBroadcast = null; 5404 processCurBroadcastLocked(br, app); 5405 didSomething = true; 5406 } catch (Exception e) { 5407 Log.w(TAG, "Exception in new application when starting receiver " 5408 + br.curComponent.flattenToShortString(), e); 5409 badApp = true; 5410 logBroadcastReceiverDiscard(br); 5411 finishReceiverLocked(br.receiver, br.resultCode, br.resultData, 5412 br.resultExtras, br.resultAbort, true); 5413 scheduleBroadcastsLocked(); 5414 } 5415 } 5416 5417 // Check whether the next backup agent is in this process... 5418 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) { 5419 if (DEBUG_BACKUP) Log.v(TAG, "New app is backup target, launching agent for " + app); 5420 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5421 try { 5422 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, mBackupTarget.backupMode); 5423 } catch (Exception e) { 5424 Log.w(TAG, "Exception scheduling backup agent creation: "); 5425 e.printStackTrace(); 5426 } 5427 } 5428 5429 if (badApp) { 5430 // todo: Also need to kill application to deal with all 5431 // kinds of exceptions. 5432 handleAppDiedLocked(app, false); 5433 return false; 5434 } 5435 5436 if (!didSomething) { 5437 updateOomAdjLocked(); 5438 } 5439 5440 return true; 5441 } 5442 5443 public final void attachApplication(IApplicationThread thread) { 5444 synchronized (this) { 5445 int callingPid = Binder.getCallingPid(); 5446 final long origId = Binder.clearCallingIdentity(); 5447 attachApplicationLocked(thread, callingPid); 5448 Binder.restoreCallingIdentity(origId); 5449 } 5450 } 5451 5452 public final void activityIdle(IBinder token, Configuration config) { 5453 final long origId = Binder.clearCallingIdentity(); 5454 activityIdleInternal(token, false, config); 5455 Binder.restoreCallingIdentity(origId); 5456 } 5457 5458 final ArrayList<HistoryRecord> processStoppingActivitiesLocked( 5459 boolean remove) { 5460 int N = mStoppingActivities.size(); 5461 if (N <= 0) return null; 5462 5463 ArrayList<HistoryRecord> stops = null; 5464 5465 final boolean nowVisible = mResumedActivity != null 5466 && mResumedActivity.nowVisible 5467 && !mResumedActivity.waitingVisible; 5468 for (int i=0; i<N; i++) { 5469 HistoryRecord s = mStoppingActivities.get(i); 5470 if (localLOGV) Log.v(TAG, "Stopping " + s + ": nowVisible=" 5471 + nowVisible + " waitingVisible=" + s.waitingVisible 5472 + " finishing=" + s.finishing); 5473 if (s.waitingVisible && nowVisible) { 5474 mWaitingVisibleActivities.remove(s); 5475 s.waitingVisible = false; 5476 if (s.finishing) { 5477 // If this activity is finishing, it is sitting on top of 5478 // everyone else but we now know it is no longer needed... 5479 // so get rid of it. Otherwise, we need to go through the 5480 // normal flow and hide it once we determine that it is 5481 // hidden by the activities in front of it. 5482 if (localLOGV) Log.v(TAG, "Before stopping, can hide: " + s); 5483 mWindowManager.setAppVisibility(s, false); 5484 } 5485 } 5486 if (!s.waitingVisible && remove) { 5487 if (localLOGV) Log.v(TAG, "Ready to stop: " + s); 5488 if (stops == null) { 5489 stops = new ArrayList<HistoryRecord>(); 5490 } 5491 stops.add(s); 5492 mStoppingActivities.remove(i); 5493 N--; 5494 i--; 5495 } 5496 } 5497 5498 return stops; 5499 } 5500 5501 void enableScreenAfterBoot() { 5502 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5503 SystemClock.uptimeMillis()); 5504 mWindowManager.enableScreenAfterBoot(); 5505 } 5506 5507 final void activityIdleInternal(IBinder token, boolean fromTimeout, 5508 Configuration config) { 5509 if (localLOGV) Log.v(TAG, "Activity idle: " + token); 5510 5511 ArrayList<HistoryRecord> stops = null; 5512 ArrayList<HistoryRecord> finishes = null; 5513 ArrayList<HistoryRecord> thumbnails = null; 5514 int NS = 0; 5515 int NF = 0; 5516 int NT = 0; 5517 IApplicationThread sendThumbnail = null; 5518 boolean booting = false; 5519 boolean enableScreen = false; 5520 5521 synchronized (this) { 5522 if (token != null) { 5523 mHandler.removeMessages(IDLE_TIMEOUT_MSG, token); 5524 } 5525 5526 // Get the activity record. 5527 int index = indexOfTokenLocked(token); 5528 if (index >= 0) { 5529 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5530 5531 // This is a hack to semi-deal with a race condition 5532 // in the client where it can be constructed with a 5533 // newer configuration from when we asked it to launch. 5534 // We'll update with whatever configuration it now says 5535 // it used to launch. 5536 if (config != null) { 5537 r.configuration = config; 5538 } 5539 5540 // No longer need to keep the device awake. 5541 if (mResumedActivity == r && mLaunchingActivity.isHeld()) { 5542 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 5543 mLaunchingActivity.release(); 5544 } 5545 5546 // We are now idle. If someone is waiting for a thumbnail from 5547 // us, we can now deliver. 5548 r.idle = true; 5549 scheduleAppGcsLocked(); 5550 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) { 5551 sendThumbnail = r.app.thread; 5552 r.thumbnailNeeded = false; 5553 } 5554 5555 // If this activity is fullscreen, set up to hide those under it. 5556 5557 if (DEBUG_VISBILITY) Log.v(TAG, "Idle activity for " + r); 5558 ensureActivitiesVisibleLocked(null, 0); 5559 5560 //Log.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); 5561 if (!mBooted && !fromTimeout) { 5562 mBooted = true; 5563 enableScreen = true; 5564 } 5565 } 5566 5567 // Atomically retrieve all of the other things to do. 5568 stops = processStoppingActivitiesLocked(true); 5569 NS = stops != null ? stops.size() : 0; 5570 if ((NF=mFinishingActivities.size()) > 0) { 5571 finishes = new ArrayList<HistoryRecord>(mFinishingActivities); 5572 mFinishingActivities.clear(); 5573 } 5574 if ((NT=mCancelledThumbnails.size()) > 0) { 5575 thumbnails = new ArrayList<HistoryRecord>(mCancelledThumbnails); 5576 mCancelledThumbnails.clear(); 5577 } 5578 5579 booting = mBooting; 5580 mBooting = false; 5581 } 5582 5583 int i; 5584 5585 // Send thumbnail if requested. 5586 if (sendThumbnail != null) { 5587 try { 5588 sendThumbnail.requestThumbnail(token); 5589 } catch (Exception e) { 5590 Log.w(TAG, "Exception thrown when requesting thumbnail", e); 5591 sendPendingThumbnail(null, token, null, null, true); 5592 } 5593 } 5594 5595 // Stop any activities that are scheduled to do so but have been 5596 // waiting for the next one to start. 5597 for (i=0; i<NS; i++) { 5598 HistoryRecord r = (HistoryRecord)stops.get(i); 5599 synchronized (this) { 5600 if (r.finishing) { 5601 finishCurrentActivityLocked(r, FINISH_IMMEDIATELY); 5602 } else { 5603 stopActivityLocked(r); 5604 } 5605 } 5606 } 5607 5608 // Finish any activities that are scheduled to do so but have been 5609 // waiting for the next one to start. 5610 for (i=0; i<NF; i++) { 5611 HistoryRecord r = (HistoryRecord)finishes.get(i); 5612 synchronized (this) { 5613 destroyActivityLocked(r, true); 5614 } 5615 } 5616 5617 // Report back to any thumbnail receivers. 5618 for (i=0; i<NT; i++) { 5619 HistoryRecord r = (HistoryRecord)thumbnails.get(i); 5620 sendPendingThumbnail(r, null, null, null, true); 5621 } 5622 5623 if (booting) { 5624 finishBooting(); 5625 } 5626 5627 trimApplications(); 5628 //dump(); 5629 //mWindowManager.dump(); 5630 5631 if (enableScreen) { 5632 enableScreenAfterBoot(); 5633 } 5634 } 5635 5636 final void finishBooting() { 5637 // Ensure that any processes we had put on hold are now started 5638 // up. 5639 final int NP = mProcessesOnHold.size(); 5640 if (NP > 0) { 5641 ArrayList<ProcessRecord> procs = 5642 new ArrayList<ProcessRecord>(mProcessesOnHold); 5643 for (int ip=0; ip<NP; ip++) { 5644 this.startProcessLocked(procs.get(ip), "on-hold", null); 5645 } 5646 } 5647 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 5648 // Tell anyone interested that we are done booting! 5649 synchronized (this) { 5650 broadcastIntentLocked(null, null, 5651 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 5652 null, null, 0, null, null, 5653 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5654 false, false, MY_PID, Process.SYSTEM_UID); 5655 } 5656 } 5657 } 5658 5659 final void ensureBootCompleted() { 5660 boolean booting; 5661 boolean enableScreen; 5662 synchronized (this) { 5663 booting = mBooting; 5664 mBooting = false; 5665 enableScreen = !mBooted; 5666 mBooted = true; 5667 } 5668 5669 if (booting) { 5670 finishBooting(); 5671 } 5672 5673 if (enableScreen) { 5674 enableScreenAfterBoot(); 5675 } 5676 } 5677 5678 public final void activityPaused(IBinder token, Bundle icicle) { 5679 // Refuse possible leaked file descriptors 5680 if (icicle != null && icicle.hasFileDescriptors()) { 5681 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5682 } 5683 5684 final long origId = Binder.clearCallingIdentity(); 5685 activityPaused(token, icicle, false); 5686 Binder.restoreCallingIdentity(origId); 5687 } 5688 5689 final void activityPaused(IBinder token, Bundle icicle, boolean timeout) { 5690 if (DEBUG_PAUSE) Log.v( 5691 TAG, "Activity paused: token=" + token + ", icicle=" + icicle 5692 + ", timeout=" + timeout); 5693 5694 HistoryRecord r = null; 5695 5696 synchronized (this) { 5697 int index = indexOfTokenLocked(token); 5698 if (index >= 0) { 5699 r = (HistoryRecord)mHistory.get(index); 5700 if (!timeout) { 5701 r.icicle = icicle; 5702 r.haveState = true; 5703 } 5704 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); 5705 if (mPausingActivity == r) { 5706 r.state = ActivityState.PAUSED; 5707 completePauseLocked(); 5708 } else { 5709 EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE, 5710 System.identityHashCode(r), r.shortComponentName, 5711 mPausingActivity != null 5712 ? mPausingActivity.shortComponentName : "(none)"); 5713 } 5714 } 5715 } 5716 } 5717 5718 public final void activityStopped(IBinder token, Bitmap thumbnail, 5719 CharSequence description) { 5720 if (localLOGV) Log.v( 5721 TAG, "Activity stopped: token=" + token); 5722 5723 HistoryRecord r = null; 5724 5725 final long origId = Binder.clearCallingIdentity(); 5726 5727 synchronized (this) { 5728 int index = indexOfTokenLocked(token); 5729 if (index >= 0) { 5730 r = (HistoryRecord)mHistory.get(index); 5731 r.thumbnail = thumbnail; 5732 r.description = description; 5733 r.stopped = true; 5734 r.state = ActivityState.STOPPED; 5735 if (!r.finishing) { 5736 if (r.configDestroy) { 5737 destroyActivityLocked(r, true); 5738 resumeTopActivityLocked(null); 5739 } 5740 } 5741 } 5742 } 5743 5744 if (r != null) { 5745 sendPendingThumbnail(r, null, null, null, false); 5746 } 5747 5748 trimApplications(); 5749 5750 Binder.restoreCallingIdentity(origId); 5751 } 5752 5753 public final void activityDestroyed(IBinder token) { 5754 if (DEBUG_SWITCH) Log.v(TAG, "ACTIVITY DESTROYED: " + token); 5755 synchronized (this) { 5756 mHandler.removeMessages(DESTROY_TIMEOUT_MSG, token); 5757 5758 int index = indexOfTokenLocked(token); 5759 if (index >= 0) { 5760 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5761 if (r.state == ActivityState.DESTROYING) { 5762 final long origId = Binder.clearCallingIdentity(); 5763 removeActivityFromHistoryLocked(r); 5764 Binder.restoreCallingIdentity(origId); 5765 } 5766 } 5767 } 5768 } 5769 5770 public String getCallingPackage(IBinder token) { 5771 synchronized (this) { 5772 HistoryRecord r = getCallingRecordLocked(token); 5773 return r != null && r.app != null ? r.info.packageName : null; 5774 } 5775 } 5776 5777 public ComponentName getCallingActivity(IBinder token) { 5778 synchronized (this) { 5779 HistoryRecord r = getCallingRecordLocked(token); 5780 return r != null ? r.intent.getComponent() : null; 5781 } 5782 } 5783 5784 private HistoryRecord getCallingRecordLocked(IBinder token) { 5785 int index = indexOfTokenLocked(token); 5786 if (index >= 0) { 5787 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5788 if (r != null) { 5789 return r.resultTo; 5790 } 5791 } 5792 return null; 5793 } 5794 5795 public ComponentName getActivityClassForToken(IBinder token) { 5796 synchronized(this) { 5797 int index = indexOfTokenLocked(token); 5798 if (index >= 0) { 5799 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5800 return r.intent.getComponent(); 5801 } 5802 return null; 5803 } 5804 } 5805 5806 public String getPackageForToken(IBinder token) { 5807 synchronized(this) { 5808 int index = indexOfTokenLocked(token); 5809 if (index >= 0) { 5810 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5811 return r.packageName; 5812 } 5813 return null; 5814 } 5815 } 5816 5817 public IIntentSender getIntentSender(int type, 5818 String packageName, IBinder token, String resultWho, 5819 int requestCode, Intent intent, String resolvedType, int flags) { 5820 // Refuse possible leaked file descriptors 5821 if (intent != null && intent.hasFileDescriptors() == true) { 5822 throw new IllegalArgumentException("File descriptors passed in Intent"); 5823 } 5824 5825 if (type == INTENT_SENDER_BROADCAST) { 5826 if ((intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5827 throw new IllegalArgumentException( 5828 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5829 } 5830 } 5831 5832 synchronized(this) { 5833 int callingUid = Binder.getCallingUid(); 5834 try { 5835 if (callingUid != 0 && callingUid != Process.SYSTEM_UID && 5836 Process.supportsProcesses()) { 5837 int uid = ActivityThread.getPackageManager() 5838 .getPackageUid(packageName); 5839 if (uid != Binder.getCallingUid()) { 5840 String msg = "Permission Denial: getIntentSender() from pid=" 5841 + Binder.getCallingPid() 5842 + ", uid=" + Binder.getCallingUid() 5843 + ", (need uid=" + uid + ")" 5844 + " is not allowed to send as package " + packageName; 5845 Log.w(TAG, msg); 5846 throw new SecurityException(msg); 5847 } 5848 } 5849 } catch (RemoteException e) { 5850 throw new SecurityException(e); 5851 } 5852 HistoryRecord activity = null; 5853 if (type == INTENT_SENDER_ACTIVITY_RESULT) { 5854 int index = indexOfTokenLocked(token); 5855 if (index < 0) { 5856 return null; 5857 } 5858 activity = (HistoryRecord)mHistory.get(index); 5859 if (activity.finishing) { 5860 return null; 5861 } 5862 } 5863 5864 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5865 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5866 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5867 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5868 |PendingIntent.FLAG_UPDATE_CURRENT); 5869 5870 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5871 type, packageName, activity, resultWho, 5872 requestCode, intent, resolvedType, flags); 5873 WeakReference<PendingIntentRecord> ref; 5874 ref = mIntentSenderRecords.get(key); 5875 PendingIntentRecord rec = ref != null ? ref.get() : null; 5876 if (rec != null) { 5877 if (!cancelCurrent) { 5878 if (updateCurrent) { 5879 rec.key.requestIntent.replaceExtras(intent); 5880 } 5881 return rec; 5882 } 5883 rec.canceled = true; 5884 mIntentSenderRecords.remove(key); 5885 } 5886 if (noCreate) { 5887 return rec; 5888 } 5889 rec = new PendingIntentRecord(this, key, callingUid); 5890 mIntentSenderRecords.put(key, rec.ref); 5891 if (type == INTENT_SENDER_ACTIVITY_RESULT) { 5892 if (activity.pendingResults == null) { 5893 activity.pendingResults 5894 = new HashSet<WeakReference<PendingIntentRecord>>(); 5895 } 5896 activity.pendingResults.add(rec.ref); 5897 } 5898 return rec; 5899 } 5900 } 5901 5902 public void cancelIntentSender(IIntentSender sender) { 5903 if (!(sender instanceof PendingIntentRecord)) { 5904 return; 5905 } 5906 synchronized(this) { 5907 PendingIntentRecord rec = (PendingIntentRecord)sender; 5908 try { 5909 int uid = ActivityThread.getPackageManager() 5910 .getPackageUid(rec.key.packageName); 5911 if (uid != Binder.getCallingUid()) { 5912 String msg = "Permission Denial: cancelIntentSender() from pid=" 5913 + Binder.getCallingPid() 5914 + ", uid=" + Binder.getCallingUid() 5915 + " is not allowed to cancel packges " 5916 + rec.key.packageName; 5917 Log.w(TAG, msg); 5918 throw new SecurityException(msg); 5919 } 5920 } catch (RemoteException e) { 5921 throw new SecurityException(e); 5922 } 5923 cancelIntentSenderLocked(rec, true); 5924 } 5925 } 5926 5927 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5928 rec.canceled = true; 5929 mIntentSenderRecords.remove(rec.key); 5930 if (cleanActivity && rec.key.activity != null) { 5931 rec.key.activity.pendingResults.remove(rec.ref); 5932 } 5933 } 5934 5935 public String getPackageForIntentSender(IIntentSender pendingResult) { 5936 if (!(pendingResult instanceof PendingIntentRecord)) { 5937 return null; 5938 } 5939 synchronized(this) { 5940 try { 5941 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5942 return res.key.packageName; 5943 } catch (ClassCastException e) { 5944 } 5945 } 5946 return null; 5947 } 5948 5949 public void setProcessLimit(int max) { 5950 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5951 "setProcessLimit()"); 5952 mProcessLimit = max; 5953 } 5954 5955 public int getProcessLimit() { 5956 return mProcessLimit; 5957 } 5958 5959 void foregroundTokenDied(ForegroundToken token) { 5960 synchronized (ActivityManagerService.this) { 5961 synchronized (mPidsSelfLocked) { 5962 ForegroundToken cur 5963 = mForegroundProcesses.get(token.pid); 5964 if (cur != token) { 5965 return; 5966 } 5967 mForegroundProcesses.remove(token.pid); 5968 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5969 if (pr == null) { 5970 return; 5971 } 5972 pr.forcingToForeground = null; 5973 pr.foregroundServices = false; 5974 } 5975 updateOomAdjLocked(); 5976 } 5977 } 5978 5979 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5980 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5981 "setProcessForeground()"); 5982 synchronized(this) { 5983 boolean changed = false; 5984 5985 synchronized (mPidsSelfLocked) { 5986 ProcessRecord pr = mPidsSelfLocked.get(pid); 5987 if (pr == null) { 5988 Log.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5989 return; 5990 } 5991 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5992 if (oldToken != null) { 5993 oldToken.token.unlinkToDeath(oldToken, 0); 5994 mForegroundProcesses.remove(pid); 5995 pr.forcingToForeground = null; 5996 changed = true; 5997 } 5998 if (isForeground && token != null) { 5999 ForegroundToken newToken = new ForegroundToken() { 6000 public void binderDied() { 6001 foregroundTokenDied(this); 6002 } 6003 }; 6004 newToken.pid = pid; 6005 newToken.token = token; 6006 try { 6007 token.linkToDeath(newToken, 0); 6008 mForegroundProcesses.put(pid, newToken); 6009 pr.forcingToForeground = token; 6010 changed = true; 6011 } catch (RemoteException e) { 6012 // If the process died while doing this, we will later 6013 // do the cleanup with the process death link. 6014 } 6015 } 6016 } 6017 6018 if (changed) { 6019 updateOomAdjLocked(); 6020 } 6021 } 6022 } 6023 6024 // ========================================================= 6025 // PERMISSIONS 6026 // ========================================================= 6027 6028 static class PermissionController extends IPermissionController.Stub { 6029 ActivityManagerService mActivityManagerService; 6030 PermissionController(ActivityManagerService activityManagerService) { 6031 mActivityManagerService = activityManagerService; 6032 } 6033 6034 public boolean checkPermission(String permission, int pid, int uid) { 6035 return mActivityManagerService.checkPermission(permission, pid, 6036 uid) == PackageManager.PERMISSION_GRANTED; 6037 } 6038 } 6039 6040 /** 6041 * This can be called with or without the global lock held. 6042 */ 6043 int checkComponentPermission(String permission, int pid, int uid, 6044 int reqUid) { 6045 // We might be performing an operation on behalf of an indirect binder 6046 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6047 // client identity accordingly before proceeding. 6048 Identity tlsIdentity = sCallerIdentity.get(); 6049 if (tlsIdentity != null) { 6050 Log.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6051 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6052 uid = tlsIdentity.uid; 6053 pid = tlsIdentity.pid; 6054 } 6055 6056 // Root, system server and our own process get to do everything. 6057 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID || 6058 !Process.supportsProcesses()) { 6059 return PackageManager.PERMISSION_GRANTED; 6060 } 6061 // If the target requires a specific UID, always fail for others. 6062 if (reqUid >= 0 && uid != reqUid) { 6063 Log.w(TAG, "Permission denied: checkComponentPermission() reqUid=" + reqUid); 6064 return PackageManager.PERMISSION_DENIED; 6065 } 6066 if (permission == null) { 6067 return PackageManager.PERMISSION_GRANTED; 6068 } 6069 try { 6070 return ActivityThread.getPackageManager() 6071 .checkUidPermission(permission, uid); 6072 } catch (RemoteException e) { 6073 // Should never happen, but if it does... deny! 6074 Log.e(TAG, "PackageManager is dead?!?", e); 6075 } 6076 return PackageManager.PERMISSION_DENIED; 6077 } 6078 6079 /** 6080 * As the only public entry point for permissions checking, this method 6081 * can enforce the semantic that requesting a check on a null global 6082 * permission is automatically denied. (Internally a null permission 6083 * string is used when calling {@link #checkComponentPermission} in cases 6084 * when only uid-based security is needed.) 6085 * 6086 * This can be called with or without the global lock held. 6087 */ 6088 public int checkPermission(String permission, int pid, int uid) { 6089 if (permission == null) { 6090 return PackageManager.PERMISSION_DENIED; 6091 } 6092 return checkComponentPermission(permission, pid, uid, -1); 6093 } 6094 6095 /** 6096 * Binder IPC calls go through the public entry point. 6097 * This can be called with or without the global lock held. 6098 */ 6099 int checkCallingPermission(String permission) { 6100 return checkPermission(permission, 6101 Binder.getCallingPid(), 6102 Binder.getCallingUid()); 6103 } 6104 6105 /** 6106 * This can be called with or without the global lock held. 6107 */ 6108 void enforceCallingPermission(String permission, String func) { 6109 if (checkCallingPermission(permission) 6110 == PackageManager.PERMISSION_GRANTED) { 6111 return; 6112 } 6113 6114 String msg = "Permission Denial: " + func + " from pid=" 6115 + Binder.getCallingPid() 6116 + ", uid=" + Binder.getCallingUid() 6117 + " requires " + permission; 6118 Log.w(TAG, msg); 6119 throw new SecurityException(msg); 6120 } 6121 6122 private final boolean checkHoldingPermissionsLocked(IPackageManager pm, 6123 ProviderInfo pi, int uid, int modeFlags) { 6124 try { 6125 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6126 if ((pi.readPermission != null) && 6127 (pm.checkUidPermission(pi.readPermission, uid) 6128 != PackageManager.PERMISSION_GRANTED)) { 6129 return false; 6130 } 6131 } 6132 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6133 if ((pi.writePermission != null) && 6134 (pm.checkUidPermission(pi.writePermission, uid) 6135 != PackageManager.PERMISSION_GRANTED)) { 6136 return false; 6137 } 6138 } 6139 return true; 6140 } catch (RemoteException e) { 6141 return false; 6142 } 6143 } 6144 6145 private final boolean checkUriPermissionLocked(Uri uri, int uid, 6146 int modeFlags) { 6147 // Root gets to do everything. 6148 if (uid == 0 || !Process.supportsProcesses()) { 6149 return true; 6150 } 6151 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6152 if (perms == null) return false; 6153 UriPermission perm = perms.get(uri); 6154 if (perm == null) return false; 6155 return (modeFlags&perm.modeFlags) == modeFlags; 6156 } 6157 6158 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 6159 // Another redirected-binder-call permissions check as in 6160 // {@link checkComponentPermission}. 6161 Identity tlsIdentity = sCallerIdentity.get(); 6162 if (tlsIdentity != null) { 6163 uid = tlsIdentity.uid; 6164 pid = tlsIdentity.pid; 6165 } 6166 6167 // Our own process gets to do everything. 6168 if (pid == MY_PID) { 6169 return PackageManager.PERMISSION_GRANTED; 6170 } 6171 synchronized(this) { 6172 return checkUriPermissionLocked(uri, uid, modeFlags) 6173 ? PackageManager.PERMISSION_GRANTED 6174 : PackageManager.PERMISSION_DENIED; 6175 } 6176 } 6177 6178 private void grantUriPermissionLocked(int callingUid, 6179 String targetPkg, Uri uri, int modeFlags, HistoryRecord activity) { 6180 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6181 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6182 if (modeFlags == 0) { 6183 return; 6184 } 6185 6186 final IPackageManager pm = ActivityThread.getPackageManager(); 6187 6188 // If this is not a content: uri, we can't do anything with it. 6189 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 6190 return; 6191 } 6192 6193 String name = uri.getAuthority(); 6194 ProviderInfo pi = null; 6195 ContentProviderRecord cpr 6196 = (ContentProviderRecord)mProvidersByName.get(name); 6197 if (cpr != null) { 6198 pi = cpr.info; 6199 } else { 6200 try { 6201 pi = pm.resolveContentProvider(name, 6202 PackageManager.GET_URI_PERMISSION_PATTERNS); 6203 } catch (RemoteException ex) { 6204 } 6205 } 6206 if (pi == null) { 6207 Log.w(TAG, "No content provider found for: " + name); 6208 return; 6209 } 6210 6211 int targetUid; 6212 try { 6213 targetUid = pm.getPackageUid(targetPkg); 6214 if (targetUid < 0) { 6215 return; 6216 } 6217 } catch (RemoteException ex) { 6218 return; 6219 } 6220 6221 // First... does the target actually need this permission? 6222 if (checkHoldingPermissionsLocked(pm, pi, targetUid, modeFlags)) { 6223 // No need to grant the target this permission. 6224 return; 6225 } 6226 6227 // Second... maybe someone else has already granted the 6228 // permission? 6229 if (checkUriPermissionLocked(uri, targetUid, modeFlags)) { 6230 // No need to grant the target this permission. 6231 return; 6232 } 6233 6234 // Third... is the provider allowing granting of URI permissions? 6235 if (!pi.grantUriPermissions) { 6236 throw new SecurityException("Provider " + pi.packageName 6237 + "/" + pi.name 6238 + " does not allow granting of Uri permissions (uri " 6239 + uri + ")"); 6240 } 6241 if (pi.uriPermissionPatterns != null) { 6242 final int N = pi.uriPermissionPatterns.length; 6243 boolean allowed = false; 6244 for (int i=0; i<N; i++) { 6245 if (pi.uriPermissionPatterns[i] != null 6246 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6247 allowed = true; 6248 break; 6249 } 6250 } 6251 if (!allowed) { 6252 throw new SecurityException("Provider " + pi.packageName 6253 + "/" + pi.name 6254 + " does not allow granting of permission to path of Uri " 6255 + uri); 6256 } 6257 } 6258 6259 // Fourth... does the caller itself have permission to access 6260 // this uri? 6261 if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) { 6262 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6263 throw new SecurityException("Uid " + callingUid 6264 + " does not have permission to uri " + uri); 6265 } 6266 } 6267 6268 // Okay! So here we are: the caller has the assumed permission 6269 // to the uri, and the target doesn't. Let's now give this to 6270 // the target. 6271 6272 HashMap<Uri, UriPermission> targetUris 6273 = mGrantedUriPermissions.get(targetUid); 6274 if (targetUris == null) { 6275 targetUris = new HashMap<Uri, UriPermission>(); 6276 mGrantedUriPermissions.put(targetUid, targetUris); 6277 } 6278 6279 UriPermission perm = targetUris.get(uri); 6280 if (perm == null) { 6281 perm = new UriPermission(targetUid, uri); 6282 targetUris.put(uri, perm); 6283 6284 } 6285 perm.modeFlags |= modeFlags; 6286 if (activity == null) { 6287 perm.globalModeFlags |= modeFlags; 6288 } else if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6289 perm.readActivities.add(activity); 6290 if (activity.readUriPermissions == null) { 6291 activity.readUriPermissions = new HashSet<UriPermission>(); 6292 } 6293 activity.readUriPermissions.add(perm); 6294 } else if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6295 perm.writeActivities.add(activity); 6296 if (activity.writeUriPermissions == null) { 6297 activity.writeUriPermissions = new HashSet<UriPermission>(); 6298 } 6299 activity.writeUriPermissions.add(perm); 6300 } 6301 } 6302 6303 private void grantUriPermissionFromIntentLocked(int callingUid, 6304 String targetPkg, Intent intent, HistoryRecord activity) { 6305 if (intent == null) { 6306 return; 6307 } 6308 Uri data = intent.getData(); 6309 if (data == null) { 6310 return; 6311 } 6312 grantUriPermissionLocked(callingUid, targetPkg, data, 6313 intent.getFlags(), activity); 6314 } 6315 6316 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6317 Uri uri, int modeFlags) { 6318 synchronized(this) { 6319 final ProcessRecord r = getRecordForAppLocked(caller); 6320 if (r == null) { 6321 throw new SecurityException("Unable to find app for caller " 6322 + caller 6323 + " when granting permission to uri " + uri); 6324 } 6325 if (targetPkg == null) { 6326 Log.w(TAG, "grantUriPermission: null target"); 6327 return; 6328 } 6329 if (uri == null) { 6330 Log.w(TAG, "grantUriPermission: null uri"); 6331 return; 6332 } 6333 6334 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags, 6335 null); 6336 } 6337 } 6338 6339 private void removeUriPermissionIfNeededLocked(UriPermission perm) { 6340 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6341 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6342 HashMap<Uri, UriPermission> perms 6343 = mGrantedUriPermissions.get(perm.uid); 6344 if (perms != null) { 6345 perms.remove(perm.uri); 6346 if (perms.size() == 0) { 6347 mGrantedUriPermissions.remove(perm.uid); 6348 } 6349 } 6350 } 6351 } 6352 6353 private void removeActivityUriPermissionsLocked(HistoryRecord activity) { 6354 if (activity.readUriPermissions != null) { 6355 for (UriPermission perm : activity.readUriPermissions) { 6356 perm.readActivities.remove(activity); 6357 if (perm.readActivities.size() == 0 && (perm.globalModeFlags 6358 &Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0) { 6359 perm.modeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION; 6360 removeUriPermissionIfNeededLocked(perm); 6361 } 6362 } 6363 } 6364 if (activity.writeUriPermissions != null) { 6365 for (UriPermission perm : activity.writeUriPermissions) { 6366 perm.writeActivities.remove(activity); 6367 if (perm.writeActivities.size() == 0 && (perm.globalModeFlags 6368 &Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0) { 6369 perm.modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION; 6370 removeUriPermissionIfNeededLocked(perm); 6371 } 6372 } 6373 } 6374 } 6375 6376 private void revokeUriPermissionLocked(int callingUid, Uri uri, 6377 int modeFlags) { 6378 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6379 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6380 if (modeFlags == 0) { 6381 return; 6382 } 6383 6384 final IPackageManager pm = ActivityThread.getPackageManager(); 6385 6386 final String authority = uri.getAuthority(); 6387 ProviderInfo pi = null; 6388 ContentProviderRecord cpr 6389 = (ContentProviderRecord)mProvidersByName.get(authority); 6390 if (cpr != null) { 6391 pi = cpr.info; 6392 } else { 6393 try { 6394 pi = pm.resolveContentProvider(authority, 6395 PackageManager.GET_URI_PERMISSION_PATTERNS); 6396 } catch (RemoteException ex) { 6397 } 6398 } 6399 if (pi == null) { 6400 Log.w(TAG, "No content provider found for: " + authority); 6401 return; 6402 } 6403 6404 // Does the caller have this permission on the URI? 6405 if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) { 6406 // Right now, if you are not the original owner of the permission, 6407 // you are not allowed to revoke it. 6408 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6409 throw new SecurityException("Uid " + callingUid 6410 + " does not have permission to uri " + uri); 6411 //} 6412 } 6413 6414 // Go through all of the permissions and remove any that match. 6415 final List<String> SEGMENTS = uri.getPathSegments(); 6416 if (SEGMENTS != null) { 6417 final int NS = SEGMENTS.size(); 6418 int N = mGrantedUriPermissions.size(); 6419 for (int i=0; i<N; i++) { 6420 HashMap<Uri, UriPermission> perms 6421 = mGrantedUriPermissions.valueAt(i); 6422 Iterator<UriPermission> it = perms.values().iterator(); 6423 toploop: 6424 while (it.hasNext()) { 6425 UriPermission perm = it.next(); 6426 Uri targetUri = perm.uri; 6427 if (!authority.equals(targetUri.getAuthority())) { 6428 continue; 6429 } 6430 List<String> targetSegments = targetUri.getPathSegments(); 6431 if (targetSegments == null) { 6432 continue; 6433 } 6434 if (targetSegments.size() < NS) { 6435 continue; 6436 } 6437 for (int j=0; j<NS; j++) { 6438 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6439 continue toploop; 6440 } 6441 } 6442 perm.clearModes(modeFlags); 6443 if (perm.modeFlags == 0) { 6444 it.remove(); 6445 } 6446 } 6447 if (perms.size() == 0) { 6448 mGrantedUriPermissions.remove( 6449 mGrantedUriPermissions.keyAt(i)); 6450 N--; 6451 i--; 6452 } 6453 } 6454 } 6455 } 6456 6457 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6458 int modeFlags) { 6459 synchronized(this) { 6460 final ProcessRecord r = getRecordForAppLocked(caller); 6461 if (r == null) { 6462 throw new SecurityException("Unable to find app for caller " 6463 + caller 6464 + " when revoking permission to uri " + uri); 6465 } 6466 if (uri == null) { 6467 Log.w(TAG, "revokeUriPermission: null uri"); 6468 return; 6469 } 6470 6471 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6472 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6473 if (modeFlags == 0) { 6474 return; 6475 } 6476 6477 final IPackageManager pm = ActivityThread.getPackageManager(); 6478 6479 final String authority = uri.getAuthority(); 6480 ProviderInfo pi = null; 6481 ContentProviderRecord cpr 6482 = (ContentProviderRecord)mProvidersByName.get(authority); 6483 if (cpr != null) { 6484 pi = cpr.info; 6485 } else { 6486 try { 6487 pi = pm.resolveContentProvider(authority, 6488 PackageManager.GET_URI_PERMISSION_PATTERNS); 6489 } catch (RemoteException ex) { 6490 } 6491 } 6492 if (pi == null) { 6493 Log.w(TAG, "No content provider found for: " + authority); 6494 return; 6495 } 6496 6497 revokeUriPermissionLocked(r.info.uid, uri, modeFlags); 6498 } 6499 } 6500 6501 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6502 synchronized (this) { 6503 ProcessRecord app = 6504 who != null ? getRecordForAppLocked(who) : null; 6505 if (app == null) return; 6506 6507 Message msg = Message.obtain(); 6508 msg.what = WAIT_FOR_DEBUGGER_MSG; 6509 msg.obj = app; 6510 msg.arg1 = waiting ? 1 : 0; 6511 mHandler.sendMessage(msg); 6512 } 6513 } 6514 6515 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6516 outInfo.availMem = Process.getFreeMemory(); 6517 outInfo.threshold = HOME_APP_MEM; 6518 outInfo.lowMemory = outInfo.availMem < 6519 (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2)); 6520 } 6521 6522 // ========================================================= 6523 // TASK MANAGEMENT 6524 // ========================================================= 6525 6526 public List getTasks(int maxNum, int flags, 6527 IThumbnailReceiver receiver) { 6528 ArrayList list = new ArrayList(); 6529 6530 PendingThumbnailsRecord pending = null; 6531 IApplicationThread topThumbnail = null; 6532 HistoryRecord topRecord = null; 6533 6534 synchronized(this) { 6535 if (localLOGV) Log.v( 6536 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6537 + ", receiver=" + receiver); 6538 6539 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6540 != PackageManager.PERMISSION_GRANTED) { 6541 if (receiver != null) { 6542 // If the caller wants to wait for pending thumbnails, 6543 // it ain't gonna get them. 6544 try { 6545 receiver.finished(); 6546 } catch (RemoteException ex) { 6547 } 6548 } 6549 String msg = "Permission Denial: getTasks() from pid=" 6550 + Binder.getCallingPid() 6551 + ", uid=" + Binder.getCallingUid() 6552 + " requires " + android.Manifest.permission.GET_TASKS; 6553 Log.w(TAG, msg); 6554 throw new SecurityException(msg); 6555 } 6556 6557 int pos = mHistory.size()-1; 6558 HistoryRecord next = 6559 pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null; 6560 HistoryRecord top = null; 6561 CharSequence topDescription = null; 6562 TaskRecord curTask = null; 6563 int numActivities = 0; 6564 int numRunning = 0; 6565 while (pos >= 0 && maxNum > 0) { 6566 final HistoryRecord r = next; 6567 pos--; 6568 next = pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null; 6569 6570 // Initialize state for next task if needed. 6571 if (top == null || 6572 (top.state == ActivityState.INITIALIZING 6573 && top.task == r.task)) { 6574 top = r; 6575 topDescription = r.description; 6576 curTask = r.task; 6577 numActivities = numRunning = 0; 6578 } 6579 6580 // Add 'r' into the current task. 6581 numActivities++; 6582 if (r.app != null && r.app.thread != null) { 6583 numRunning++; 6584 } 6585 if (topDescription == null) { 6586 topDescription = r.description; 6587 } 6588 6589 if (localLOGV) Log.v( 6590 TAG, r.intent.getComponent().flattenToShortString() 6591 + ": task=" + r.task); 6592 6593 // If the next one is a different task, generate a new 6594 // TaskInfo entry for what we have. 6595 if (next == null || next.task != curTask) { 6596 ActivityManager.RunningTaskInfo ci 6597 = new ActivityManager.RunningTaskInfo(); 6598 ci.id = curTask.taskId; 6599 ci.baseActivity = r.intent.getComponent(); 6600 ci.topActivity = top.intent.getComponent(); 6601 ci.thumbnail = top.thumbnail; 6602 ci.description = topDescription; 6603 ci.numActivities = numActivities; 6604 ci.numRunning = numRunning; 6605 //System.out.println( 6606 // "#" + maxNum + ": " + " descr=" + ci.description); 6607 if (ci.thumbnail == null && receiver != null) { 6608 if (localLOGV) Log.v( 6609 TAG, "State=" + top.state + "Idle=" + top.idle 6610 + " app=" + top.app 6611 + " thr=" + (top.app != null ? top.app.thread : null)); 6612 if (top.state == ActivityState.RESUMED 6613 || top.state == ActivityState.PAUSING) { 6614 if (top.idle && top.app != null 6615 && top.app.thread != null) { 6616 topRecord = top; 6617 topThumbnail = top.app.thread; 6618 } else { 6619 top.thumbnailNeeded = true; 6620 } 6621 } 6622 if (pending == null) { 6623 pending = new PendingThumbnailsRecord(receiver); 6624 } 6625 pending.pendingRecords.add(top); 6626 } 6627 list.add(ci); 6628 maxNum--; 6629 top = null; 6630 } 6631 } 6632 6633 if (pending != null) { 6634 mPendingThumbnails.add(pending); 6635 } 6636 } 6637 6638 if (localLOGV) Log.v(TAG, "We have pending thumbnails: " + pending); 6639 6640 if (topThumbnail != null) { 6641 if (localLOGV) Log.v(TAG, "Requesting top thumbnail"); 6642 try { 6643 topThumbnail.requestThumbnail(topRecord); 6644 } catch (Exception e) { 6645 Log.w(TAG, "Exception thrown when requesting thumbnail", e); 6646 sendPendingThumbnail(null, topRecord, null, null, true); 6647 } 6648 } 6649 6650 if (pending == null && receiver != null) { 6651 // In this case all thumbnails were available and the client 6652 // is being asked to be told when the remaining ones come in... 6653 // which is unusually, since the top-most currently running 6654 // activity should never have a canned thumbnail! Oh well. 6655 try { 6656 receiver.finished(); 6657 } catch (RemoteException ex) { 6658 } 6659 } 6660 6661 return list; 6662 } 6663 6664 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6665 int flags) { 6666 synchronized (this) { 6667 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6668 "getRecentTasks()"); 6669 6670 final int N = mRecentTasks.size(); 6671 ArrayList<ActivityManager.RecentTaskInfo> res 6672 = new ArrayList<ActivityManager.RecentTaskInfo>( 6673 maxNum < N ? maxNum : N); 6674 for (int i=0; i<N && maxNum > 0; i++) { 6675 TaskRecord tr = mRecentTasks.get(i); 6676 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6677 || (tr.intent == null) 6678 || ((tr.intent.getFlags() 6679 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6680 ActivityManager.RecentTaskInfo rti 6681 = new ActivityManager.RecentTaskInfo(); 6682 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6683 rti.baseIntent = new Intent( 6684 tr.intent != null ? tr.intent : tr.affinityIntent); 6685 rti.origActivity = tr.origActivity; 6686 res.add(rti); 6687 maxNum--; 6688 } 6689 } 6690 return res; 6691 } 6692 } 6693 6694 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 6695 int j; 6696 TaskRecord startTask = ((HistoryRecord)mHistory.get(startIndex)).task; 6697 TaskRecord jt = startTask; 6698 6699 // First look backwards 6700 for (j=startIndex-1; j>=0; j--) { 6701 HistoryRecord r = (HistoryRecord)mHistory.get(j); 6702 if (r.task != jt) { 6703 jt = r.task; 6704 if (affinity.equals(jt.affinity)) { 6705 return j; 6706 } 6707 } 6708 } 6709 6710 // Now look forwards 6711 final int N = mHistory.size(); 6712 jt = startTask; 6713 for (j=startIndex+1; j<N; j++) { 6714 HistoryRecord r = (HistoryRecord)mHistory.get(j); 6715 if (r.task != jt) { 6716 if (affinity.equals(jt.affinity)) { 6717 return j; 6718 } 6719 jt = r.task; 6720 } 6721 } 6722 6723 // Might it be at the top? 6724 if (affinity.equals(((HistoryRecord)mHistory.get(N-1)).task.affinity)) { 6725 return N-1; 6726 } 6727 6728 return -1; 6729 } 6730 6731 /** 6732 * Perform a reset of the given task, if needed as part of launching it. 6733 * Returns the new HistoryRecord at the top of the task. 6734 */ 6735 private final HistoryRecord resetTaskIfNeededLocked(HistoryRecord taskTop, 6736 HistoryRecord newActivity) { 6737 boolean forceReset = (newActivity.info.flags 6738 &ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0; 6739 if (taskTop.task.getInactiveDuration() > ACTIVITY_INACTIVE_RESET_TIME) { 6740 if ((newActivity.info.flags 6741 &ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE) == 0) { 6742 forceReset = true; 6743 } 6744 } 6745 6746 final TaskRecord task = taskTop.task; 6747 6748 // We are going to move through the history list so that we can look 6749 // at each activity 'target' with 'below' either the interesting 6750 // activity immediately below it in the stack or null. 6751 HistoryRecord target = null; 6752 int targetI = 0; 6753 int taskTopI = -1; 6754 int replyChainEnd = -1; 6755 int lastReparentPos = -1; 6756 for (int i=mHistory.size()-1; i>=-1; i--) { 6757 HistoryRecord below = i >= 0 ? (HistoryRecord)mHistory.get(i) : null; 6758 6759 if (below != null && below.finishing) { 6760 continue; 6761 } 6762 if (target == null) { 6763 target = below; 6764 targetI = i; 6765 // If we were in the middle of a reply chain before this 6766 // task, it doesn't appear like the root of the chain wants 6767 // anything interesting, so drop it. 6768 replyChainEnd = -1; 6769 continue; 6770 } 6771 6772 final int flags = target.info.flags; 6773 6774 final boolean finishOnTaskLaunch = 6775 (flags&ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0; 6776 final boolean allowTaskReparenting = 6777 (flags&ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0; 6778 6779 if (target.task == task) { 6780 // We are inside of the task being reset... we'll either 6781 // finish this activity, push it out for another task, 6782 // or leave it as-is. We only do this 6783 // for activities that are not the root of the task (since 6784 // if we finish the root, we may no longer have the task!). 6785 if (taskTopI < 0) { 6786 taskTopI = targetI; 6787 } 6788 if (below != null && below.task == task) { 6789 final boolean clearWhenTaskReset = 6790 (target.intent.getFlags() 6791 &Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0; 6792 if (!finishOnTaskLaunch && !clearWhenTaskReset && target.resultTo != null) { 6793 // If this activity is sending a reply to a previous 6794 // activity, we can't do anything with it now until 6795 // we reach the start of the reply chain. 6796 // XXX note that we are assuming the result is always 6797 // to the previous activity, which is almost always 6798 // the case but we really shouldn't count on. 6799 if (replyChainEnd < 0) { 6800 replyChainEnd = targetI; 6801 } 6802 } else if (!finishOnTaskLaunch && !clearWhenTaskReset && allowTaskReparenting 6803 && target.taskAffinity != null 6804 && !target.taskAffinity.equals(task.affinity)) { 6805 // If this activity has an affinity for another 6806 // task, then we need to move it out of here. We will 6807 // move it as far out of the way as possible, to the 6808 // bottom of the activity stack. This also keeps it 6809 // correctly ordered with any activities we previously 6810 // moved. 6811 HistoryRecord p = (HistoryRecord)mHistory.get(0); 6812 if (target.taskAffinity != null 6813 && target.taskAffinity.equals(p.task.affinity)) { 6814 // If the activity currently at the bottom has the 6815 // same task affinity as the one we are moving, 6816 // then merge it into the same task. 6817 target.task = p.task; 6818 if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target 6819 + " out to bottom task " + p.task); 6820 } else { 6821 mCurTask++; 6822 if (mCurTask <= 0) { 6823 mCurTask = 1; 6824 } 6825 target.task = new TaskRecord(mCurTask, target.info, null, 6826 (target.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0); 6827 target.task.affinityIntent = target.intent; 6828 if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target 6829 + " out to new task " + target.task); 6830 } 6831 mWindowManager.setAppGroupId(target, task.taskId); 6832 if (replyChainEnd < 0) { 6833 replyChainEnd = targetI; 6834 } 6835 int dstPos = 0; 6836 for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) { 6837 p = (HistoryRecord)mHistory.get(srcPos); 6838 if (p.finishing) { 6839 continue; 6840 } 6841 if (DEBUG_TASKS) Log.v(TAG, "Pushing next activity " + p 6842 + " out to target's task " + target.task); 6843 task.numActivities--; 6844 p.task = target.task; 6845 target.task.numActivities++; 6846 mHistory.remove(srcPos); 6847 mHistory.add(dstPos, p); 6848 mWindowManager.moveAppToken(dstPos, p); 6849 mWindowManager.setAppGroupId(p, p.task.taskId); 6850 dstPos++; 6851 if (VALIDATE_TOKENS) { 6852 mWindowManager.validateAppTokens(mHistory); 6853 } 6854 i++; 6855 } 6856 if (taskTop == p) { 6857 taskTop = below; 6858 } 6859 if (taskTopI == replyChainEnd) { 6860 taskTopI = -1; 6861 } 6862 replyChainEnd = -1; 6863 addRecentTask(target.task); 6864 } else if (forceReset || finishOnTaskLaunch 6865 || clearWhenTaskReset) { 6866 // If the activity should just be removed -- either 6867 // because it asks for it, or the task should be 6868 // cleared -- then finish it and anything that is 6869 // part of its reply chain. 6870 if (clearWhenTaskReset) { 6871 // In this case, we want to finish this activity 6872 // and everything above it, so be sneaky and pretend 6873 // like these are all in the reply chain. 6874 replyChainEnd = targetI+1; 6875 while (replyChainEnd < mHistory.size() && 6876 ((HistoryRecord)mHistory.get( 6877 replyChainEnd)).task == task) { 6878 replyChainEnd++; 6879 } 6880 replyChainEnd--; 6881 } else if (replyChainEnd < 0) { 6882 replyChainEnd = targetI; 6883 } 6884 HistoryRecord p = null; 6885 for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) { 6886 p = (HistoryRecord)mHistory.get(srcPos); 6887 if (p.finishing) { 6888 continue; 6889 } 6890 if (finishActivityLocked(p, srcPos, 6891 Activity.RESULT_CANCELED, null, "reset")) { 6892 replyChainEnd--; 6893 srcPos--; 6894 } 6895 } 6896 if (taskTop == p) { 6897 taskTop = below; 6898 } 6899 if (taskTopI == replyChainEnd) { 6900 taskTopI = -1; 6901 } 6902 replyChainEnd = -1; 6903 } else { 6904 // If we were in the middle of a chain, well the 6905 // activity that started it all doesn't want anything 6906 // special, so leave it all as-is. 6907 replyChainEnd = -1; 6908 } 6909 } else { 6910 // Reached the bottom of the task -- any reply chain 6911 // should be left as-is. 6912 replyChainEnd = -1; 6913 } 6914 6915 } else if (target.resultTo != null) { 6916 // If this activity is sending a reply to a previous 6917 // activity, we can't do anything with it now until 6918 // we reach the start of the reply chain. 6919 // XXX note that we are assuming the result is always 6920 // to the previous activity, which is almost always 6921 // the case but we really shouldn't count on. 6922 if (replyChainEnd < 0) { 6923 replyChainEnd = targetI; 6924 } 6925 6926 } else if (taskTopI >= 0 && allowTaskReparenting 6927 && task.affinity != null 6928 && task.affinity.equals(target.taskAffinity)) { 6929 // We are inside of another task... if this activity has 6930 // an affinity for our task, then either remove it if we are 6931 // clearing or move it over to our task. Note that 6932 // we currently punt on the case where we are resetting a 6933 // task that is not at the top but who has activities above 6934 // with an affinity to it... this is really not a normal 6935 // case, and we will need to later pull that task to the front 6936 // and usually at that point we will do the reset and pick 6937 // up those remaining activities. (This only happens if 6938 // someone starts an activity in a new task from an activity 6939 // in a task that is not currently on top.) 6940 if (forceReset || finishOnTaskLaunch) { 6941 if (replyChainEnd < 0) { 6942 replyChainEnd = targetI; 6943 } 6944 HistoryRecord p = null; 6945 for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) { 6946 p = (HistoryRecord)mHistory.get(srcPos); 6947 if (p.finishing) { 6948 continue; 6949 } 6950 if (finishActivityLocked(p, srcPos, 6951 Activity.RESULT_CANCELED, null, "reset")) { 6952 taskTopI--; 6953 lastReparentPos--; 6954 replyChainEnd--; 6955 srcPos--; 6956 } 6957 } 6958 replyChainEnd = -1; 6959 } else { 6960 if (replyChainEnd < 0) { 6961 replyChainEnd = targetI; 6962 } 6963 for (int srcPos=replyChainEnd; srcPos>=targetI; srcPos--) { 6964 HistoryRecord p = (HistoryRecord)mHistory.get(srcPos); 6965 if (p.finishing) { 6966 continue; 6967 } 6968 if (lastReparentPos < 0) { 6969 lastReparentPos = taskTopI; 6970 taskTop = p; 6971 } else { 6972 lastReparentPos--; 6973 } 6974 mHistory.remove(srcPos); 6975 p.task.numActivities--; 6976 p.task = task; 6977 mHistory.add(lastReparentPos, p); 6978 if (DEBUG_TASKS) Log.v(TAG, "Pulling activity " + p 6979 + " in to resetting task " + task); 6980 task.numActivities++; 6981 mWindowManager.moveAppToken(lastReparentPos, p); 6982 mWindowManager.setAppGroupId(p, p.task.taskId); 6983 if (VALIDATE_TOKENS) { 6984 mWindowManager.validateAppTokens(mHistory); 6985 } 6986 } 6987 replyChainEnd = -1; 6988 6989 // Now we've moved it in to place... but what if this is 6990 // a singleTop activity and we have put it on top of another 6991 // instance of the same activity? Then we drop the instance 6992 // below so it remains singleTop. 6993 if (target.info.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) { 6994 for (int j=lastReparentPos-1; j>=0; j--) { 6995 HistoryRecord p = (HistoryRecord)mHistory.get(j); 6996 if (p.finishing) { 6997 continue; 6998 } 6999 if (p.intent.getComponent().equals(target.intent.getComponent())) { 7000 if (finishActivityLocked(p, j, 7001 Activity.RESULT_CANCELED, null, "replace")) { 7002 taskTopI--; 7003 lastReparentPos--; 7004 } 7005 } 7006 } 7007 } 7008 } 7009 } 7010 7011 target = below; 7012 targetI = i; 7013 } 7014 7015 return taskTop; 7016 } 7017 7018 /** 7019 * TODO: Add mController hook 7020 */ 7021 public void moveTaskToFront(int task) { 7022 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7023 "moveTaskToFront()"); 7024 7025 synchronized(this) { 7026 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7027 Binder.getCallingUid(), "Task to front")) { 7028 return; 7029 } 7030 final long origId = Binder.clearCallingIdentity(); 7031 try { 7032 int N = mRecentTasks.size(); 7033 for (int i=0; i<N; i++) { 7034 TaskRecord tr = mRecentTasks.get(i); 7035 if (tr.taskId == task) { 7036 moveTaskToFrontLocked(tr, null); 7037 return; 7038 } 7039 } 7040 for (int i=mHistory.size()-1; i>=0; i--) { 7041 HistoryRecord hr = (HistoryRecord)mHistory.get(i); 7042 if (hr.task.taskId == task) { 7043 moveTaskToFrontLocked(hr.task, null); 7044 return; 7045 } 7046 } 7047 } finally { 7048 Binder.restoreCallingIdentity(origId); 7049 } 7050 } 7051 } 7052 7053 private final void moveTaskToFrontLocked(TaskRecord tr, HistoryRecord reason) { 7054 if (DEBUG_SWITCH) Log.v(TAG, "moveTaskToFront: " + tr); 7055 7056 final int task = tr.taskId; 7057 int top = mHistory.size()-1; 7058 7059 if (top < 0 || ((HistoryRecord)mHistory.get(top)).task.taskId == task) { 7060 // nothing to do! 7061 return; 7062 } 7063 7064 ArrayList moved = new ArrayList(); 7065 7066 // Applying the affinities may have removed entries from the history, 7067 // so get the size again. 7068 top = mHistory.size()-1; 7069 int pos = top; 7070 7071 // Shift all activities with this task up to the top 7072 // of the stack, keeping them in the same internal order. 7073 while (pos >= 0) { 7074 HistoryRecord r = (HistoryRecord)mHistory.get(pos); 7075 if (localLOGV) Log.v( 7076 TAG, "At " + pos + " ckp " + r.task + ": " + r); 7077 boolean first = true; 7078 if (r.task.taskId == task) { 7079 if (localLOGV) Log.v(TAG, "Removing and adding at " + top); 7080 mHistory.remove(pos); 7081 mHistory.add(top, r); 7082 moved.add(0, r); 7083 top--; 7084 if (first) { 7085 addRecentTask(r.task); 7086 first = false; 7087 } 7088 } 7089 pos--; 7090 } 7091 7092 if (DEBUG_TRANSITION) Log.v(TAG, 7093 "Prepare to front transition: task=" + tr); 7094 if (reason != null && 7095 (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { 7096 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 7097 HistoryRecord r = topRunningActivityLocked(null); 7098 if (r != null) { 7099 mNoAnimActivities.add(r); 7100 } 7101 } else { 7102 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT); 7103 } 7104 7105 mWindowManager.moveAppTokensToTop(moved); 7106 if (VALIDATE_TOKENS) { 7107 mWindowManager.validateAppTokens(mHistory); 7108 } 7109 7110 finishTaskMove(task); 7111 EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, task); 7112 } 7113 7114 private final void finishTaskMove(int task) { 7115 resumeTopActivityLocked(null); 7116 } 7117 7118 public void moveTaskToBack(int task) { 7119 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7120 "moveTaskToBack()"); 7121 7122 synchronized(this) { 7123 if (mResumedActivity != null && mResumedActivity.task.taskId == task) { 7124 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7125 Binder.getCallingUid(), "Task to back")) { 7126 return; 7127 } 7128 } 7129 final long origId = Binder.clearCallingIdentity(); 7130 moveTaskToBackLocked(task, null); 7131 Binder.restoreCallingIdentity(origId); 7132 } 7133 } 7134 7135 /** 7136 * Moves an activity, and all of the other activities within the same task, to the bottom 7137 * of the history stack. The activity's order within the task is unchanged. 7138 * 7139 * @param token A reference to the activity we wish to move 7140 * @param nonRoot If false then this only works if the activity is the root 7141 * of a task; if true it will work for any activity in a task. 7142 * @return Returns true if the move completed, false if not. 7143 */ 7144 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7145 synchronized(this) { 7146 final long origId = Binder.clearCallingIdentity(); 7147 int taskId = getTaskForActivityLocked(token, !nonRoot); 7148 if (taskId >= 0) { 7149 return moveTaskToBackLocked(taskId, null); 7150 } 7151 Binder.restoreCallingIdentity(origId); 7152 } 7153 return false; 7154 } 7155 7156 /** 7157 * Worker method for rearranging history stack. Implements the function of moving all 7158 * activities for a specific task (gathering them if disjoint) into a single group at the 7159 * bottom of the stack. 7160 * 7161 * If a watcher is installed, the action is preflighted and the watcher has an opportunity 7162 * to premeptively cancel the move. 7163 * 7164 * @param task The taskId to collect and move to the bottom. 7165 * @return Returns true if the move completed, false if not. 7166 */ 7167 private final boolean moveTaskToBackLocked(int task, HistoryRecord reason) { 7168 Log.i(TAG, "moveTaskToBack: " + task); 7169 7170 // If we have a watcher, preflight the move before committing to it. First check 7171 // for *other* available tasks, but if none are available, then try again allowing the 7172 // current task to be selected. 7173 if (mController != null) { 7174 HistoryRecord next = topRunningActivityLocked(null, task); 7175 if (next == null) { 7176 next = topRunningActivityLocked(null, 0); 7177 } 7178 if (next != null) { 7179 // ask watcher if this is allowed 7180 boolean moveOK = true; 7181 try { 7182 moveOK = mController.activityResuming(next.packageName); 7183 } catch (RemoteException e) { 7184 mController = null; 7185 } 7186 if (!moveOK) { 7187 return false; 7188 } 7189 } 7190 } 7191 7192 ArrayList moved = new ArrayList(); 7193 7194 if (DEBUG_TRANSITION) Log.v(TAG, 7195 "Prepare to back transition: task=" + task); 7196 7197 final int N = mHistory.size(); 7198 int bottom = 0; 7199 int pos = 0; 7200 7201 // Shift all activities with this task down to the bottom 7202 // of the stack, keeping them in the same internal order. 7203 while (pos < N) { 7204 HistoryRecord r = (HistoryRecord)mHistory.get(pos); 7205 if (localLOGV) Log.v( 7206 TAG, "At " + pos + " ckp " + r.task + ": " + r); 7207 if (r.task.taskId == task) { 7208 if (localLOGV) Log.v(TAG, "Removing and adding at " + (N-1)); 7209 mHistory.remove(pos); 7210 mHistory.add(bottom, r); 7211 moved.add(r); 7212 bottom++; 7213 } 7214 pos++; 7215 } 7216 7217 if (reason != null && 7218 (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { 7219 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 7220 HistoryRecord r = topRunningActivityLocked(null); 7221 if (r != null) { 7222 mNoAnimActivities.add(r); 7223 } 7224 } else { 7225 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_BACK); 7226 } 7227 mWindowManager.moveAppTokensToBottom(moved); 7228 if (VALIDATE_TOKENS) { 7229 mWindowManager.validateAppTokens(mHistory); 7230 } 7231 7232 finishTaskMove(task); 7233 return true; 7234 } 7235 7236 public void moveTaskBackwards(int task) { 7237 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7238 "moveTaskBackwards()"); 7239 7240 synchronized(this) { 7241 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7242 Binder.getCallingUid(), "Task backwards")) { 7243 return; 7244 } 7245 final long origId = Binder.clearCallingIdentity(); 7246 moveTaskBackwardsLocked(task); 7247 Binder.restoreCallingIdentity(origId); 7248 } 7249 } 7250 7251 private final void moveTaskBackwardsLocked(int task) { 7252 Log.e(TAG, "moveTaskBackwards not yet implemented!"); 7253 } 7254 7255 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7256 synchronized(this) { 7257 return getTaskForActivityLocked(token, onlyRoot); 7258 } 7259 } 7260 7261 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 7262 final int N = mHistory.size(); 7263 TaskRecord lastTask = null; 7264 for (int i=0; i<N; i++) { 7265 HistoryRecord r = (HistoryRecord)mHistory.get(i); 7266 if (r == token) { 7267 if (!onlyRoot || lastTask != r.task) { 7268 return r.task.taskId; 7269 } 7270 return -1; 7271 } 7272 lastTask = r.task; 7273 } 7274 7275 return -1; 7276 } 7277 7278 /** 7279 * Returns the top activity in any existing task matching the given 7280 * Intent. Returns null if no such task is found. 7281 */ 7282 private HistoryRecord findTaskLocked(Intent intent, ActivityInfo info) { 7283 ComponentName cls = intent.getComponent(); 7284 if (info.targetActivity != null) { 7285 cls = new ComponentName(info.packageName, info.targetActivity); 7286 } 7287 7288 TaskRecord cp = null; 7289 7290 final int N = mHistory.size(); 7291 for (int i=(N-1); i>=0; i--) { 7292 HistoryRecord r = (HistoryRecord)mHistory.get(i); 7293 if (!r.finishing && r.task != cp 7294 && r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 7295 cp = r.task; 7296 //Log.i(TAG, "Comparing existing cls=" + r.task.intent.getComponent().flattenToShortString() 7297 // + "/aff=" + r.task.affinity + " to new cls=" 7298 // + intent.getComponent().flattenToShortString() + "/aff=" + taskAffinity); 7299 if (r.task.affinity != null) { 7300 if (r.task.affinity.equals(info.taskAffinity)) { 7301 //Log.i(TAG, "Found matching affinity!"); 7302 return r; 7303 } 7304 } else if (r.task.intent != null 7305 && r.task.intent.getComponent().equals(cls)) { 7306 //Log.i(TAG, "Found matching class!"); 7307 //dump(); 7308 //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent); 7309 return r; 7310 } else if (r.task.affinityIntent != null 7311 && r.task.affinityIntent.getComponent().equals(cls)) { 7312 //Log.i(TAG, "Found matching class!"); 7313 //dump(); 7314 //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent); 7315 return r; 7316 } 7317 } 7318 } 7319 7320 return null; 7321 } 7322 7323 /** 7324 * Returns the first activity (starting from the top of the stack) that 7325 * is the same as the given activity. Returns null if no such activity 7326 * is found. 7327 */ 7328 private HistoryRecord findActivityLocked(Intent intent, ActivityInfo info) { 7329 ComponentName cls = intent.getComponent(); 7330 if (info.targetActivity != null) { 7331 cls = new ComponentName(info.packageName, info.targetActivity); 7332 } 7333 7334 final int N = mHistory.size(); 7335 for (int i=(N-1); i>=0; i--) { 7336 HistoryRecord r = (HistoryRecord)mHistory.get(i); 7337 if (!r.finishing) { 7338 if (r.intent.getComponent().equals(cls)) { 7339 //Log.i(TAG, "Found matching class!"); 7340 //dump(); 7341 //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent); 7342 return r; 7343 } 7344 } 7345 } 7346 7347 return null; 7348 } 7349 7350 public void finishOtherInstances(IBinder token, ComponentName className) { 7351 synchronized(this) { 7352 final long origId = Binder.clearCallingIdentity(); 7353 7354 int N = mHistory.size(); 7355 TaskRecord lastTask = null; 7356 for (int i=0; i<N; i++) { 7357 HistoryRecord r = (HistoryRecord)mHistory.get(i); 7358 if (r.realActivity.equals(className) 7359 && r != token && lastTask != r.task) { 7360 if (finishActivityLocked(r, i, Activity.RESULT_CANCELED, 7361 null, "others")) { 7362 i--; 7363 N--; 7364 } 7365 } 7366 lastTask = r.task; 7367 } 7368 7369 Binder.restoreCallingIdentity(origId); 7370 } 7371 } 7372 7373 // ========================================================= 7374 // THUMBNAILS 7375 // ========================================================= 7376 7377 public void reportThumbnail(IBinder token, 7378 Bitmap thumbnail, CharSequence description) { 7379 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7380 final long origId = Binder.clearCallingIdentity(); 7381 sendPendingThumbnail(null, token, thumbnail, description, true); 7382 Binder.restoreCallingIdentity(origId); 7383 } 7384 7385 final void sendPendingThumbnail(HistoryRecord r, IBinder token, 7386 Bitmap thumbnail, CharSequence description, boolean always) { 7387 TaskRecord task = null; 7388 ArrayList receivers = null; 7389 7390 //System.out.println("Send pending thumbnail: " + r); 7391 7392 synchronized(this) { 7393 if (r == null) { 7394 int index = indexOfTokenLocked(token); 7395 if (index < 0) { 7396 return; 7397 } 7398 r = (HistoryRecord)mHistory.get(index); 7399 } 7400 if (thumbnail == null) { 7401 thumbnail = r.thumbnail; 7402 description = r.description; 7403 } 7404 if (thumbnail == null && !always) { 7405 // If there is no thumbnail, and this entry is not actually 7406 // going away, then abort for now and pick up the next 7407 // thumbnail we get. 7408 return; 7409 } 7410 task = r.task; 7411 7412 int N = mPendingThumbnails.size(); 7413 int i=0; 7414 while (i<N) { 7415 PendingThumbnailsRecord pr = 7416 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 7417 //System.out.println("Looking in " + pr.pendingRecords); 7418 if (pr.pendingRecords.remove(r)) { 7419 if (receivers == null) { 7420 receivers = new ArrayList(); 7421 } 7422 receivers.add(pr); 7423 if (pr.pendingRecords.size() == 0) { 7424 pr.finished = true; 7425 mPendingThumbnails.remove(i); 7426 N--; 7427 continue; 7428 } 7429 } 7430 i++; 7431 } 7432 } 7433 7434 if (receivers != null) { 7435 final int N = receivers.size(); 7436 for (int i=0; i<N; i++) { 7437 try { 7438 PendingThumbnailsRecord pr = 7439 (PendingThumbnailsRecord)receivers.get(i); 7440 pr.receiver.newThumbnail( 7441 task != null ? task.taskId : -1, thumbnail, description); 7442 if (pr.finished) { 7443 pr.receiver.finished(); 7444 } 7445 } catch (Exception e) { 7446 Log.w(TAG, "Exception thrown when sending thumbnail", e); 7447 } 7448 } 7449 } 7450 } 7451 7452 // ========================================================= 7453 // CONTENT PROVIDERS 7454 // ========================================================= 7455 7456 private final List generateApplicationProvidersLocked(ProcessRecord app) { 7457 List providers = null; 7458 try { 7459 providers = ActivityThread.getPackageManager(). 7460 queryContentProviders(app.processName, app.info.uid, 7461 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7462 } catch (RemoteException ex) { 7463 } 7464 if (providers != null) { 7465 final int N = providers.size(); 7466 for (int i=0; i<N; i++) { 7467 ProviderInfo cpi = 7468 (ProviderInfo)providers.get(i); 7469 ContentProviderRecord cpr = 7470 (ContentProviderRecord)mProvidersByClass.get(cpi.name); 7471 if (cpr == null) { 7472 cpr = new ContentProviderRecord(cpi, app.info); 7473 mProvidersByClass.put(cpi.name, cpr); 7474 } 7475 app.pubProviders.put(cpi.name, cpr); 7476 app.addPackage(cpi.applicationInfo.packageName); 7477 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7478 } 7479 } 7480 return providers; 7481 } 7482 7483 private final String checkContentProviderPermissionLocked( 7484 ProviderInfo cpi, ProcessRecord r, int mode) { 7485 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7486 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid(); 7487 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7488 cpi.exported ? -1 : cpi.applicationInfo.uid) 7489 == PackageManager.PERMISSION_GRANTED 7490 && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) { 7491 return null; 7492 } 7493 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7494 cpi.exported ? -1 : cpi.applicationInfo.uid) 7495 == PackageManager.PERMISSION_GRANTED) { 7496 return null; 7497 } 7498 7499 PathPermission[] pps = cpi.pathPermissions; 7500 if (pps != null) { 7501 int i = pps.length; 7502 while (i > 0) { 7503 i--; 7504 PathPermission pp = pps[i]; 7505 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7506 cpi.exported ? -1 : cpi.applicationInfo.uid) 7507 == PackageManager.PERMISSION_GRANTED 7508 && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) { 7509 return null; 7510 } 7511 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7512 cpi.exported ? -1 : cpi.applicationInfo.uid) 7513 == PackageManager.PERMISSION_GRANTED) { 7514 return null; 7515 } 7516 } 7517 } 7518 7519 String msg = "Permission Denial: opening provider " + cpi.name 7520 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7521 + ", uid=" + callingUid + ") requires " 7522 + cpi.readPermission + " or " + cpi.writePermission; 7523 Log.w(TAG, msg); 7524 return msg; 7525 } 7526 7527 private final ContentProviderHolder getContentProviderImpl( 7528 IApplicationThread caller, String name) { 7529 ContentProviderRecord cpr; 7530 ProviderInfo cpi = null; 7531 7532 synchronized(this) { 7533 ProcessRecord r = null; 7534 if (caller != null) { 7535 r = getRecordForAppLocked(caller); 7536 if (r == null) { 7537 throw new SecurityException( 7538 "Unable to find app for caller " + caller 7539 + " (pid=" + Binder.getCallingPid() 7540 + ") when getting content provider " + name); 7541 } 7542 } 7543 7544 // First check if this content provider has been published... 7545 cpr = (ContentProviderRecord)mProvidersByName.get(name); 7546 if (cpr != null) { 7547 cpi = cpr.info; 7548 if (checkContentProviderPermissionLocked(cpi, r, -1) != null) { 7549 return new ContentProviderHolder(cpi, 7550 cpi.readPermission != null 7551 ? cpi.readPermission : cpi.writePermission); 7552 } 7553 7554 if (r != null && cpr.canRunHere(r)) { 7555 // This provider has been published or is in the process 7556 // of being published... but it is also allowed to run 7557 // in the caller's process, so don't make a connection 7558 // and just let the caller instantiate its own instance. 7559 if (cpr.provider != null) { 7560 // don't give caller the provider object, it needs 7561 // to make its own. 7562 cpr = new ContentProviderRecord(cpr); 7563 } 7564 return cpr; 7565 } 7566 7567 final long origId = Binder.clearCallingIdentity(); 7568 7569 // In this case the provider instance already exists, so we can 7570 // return it right away. 7571 if (r != null) { 7572 if (DEBUG_PROVIDER) Log.v(TAG, 7573 "Adding provider requested by " 7574 + r.processName + " from process " 7575 + cpr.info.processName); 7576 Integer cnt = r.conProviders.get(cpr); 7577 if (cnt == null) { 7578 r.conProviders.put(cpr, new Integer(1)); 7579 } else { 7580 r.conProviders.put(cpr, new Integer(cnt.intValue()+1)); 7581 } 7582 cpr.clients.add(r); 7583 } else { 7584 cpr.externals++; 7585 } 7586 7587 if (cpr.app != null) { 7588 updateOomAdjLocked(cpr.app); 7589 } 7590 7591 Binder.restoreCallingIdentity(origId); 7592 7593 } else { 7594 try { 7595 cpi = ActivityThread.getPackageManager(). 7596 resolveContentProvider(name, 7597 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7598 } catch (RemoteException ex) { 7599 } 7600 if (cpi == null) { 7601 return null; 7602 } 7603 7604 if (checkContentProviderPermissionLocked(cpi, r, -1) != null) { 7605 return new ContentProviderHolder(cpi, 7606 cpi.readPermission != null 7607 ? cpi.readPermission : cpi.writePermission); 7608 } 7609 7610 cpr = (ContentProviderRecord)mProvidersByClass.get(cpi.name); 7611 final boolean firstClass = cpr == null; 7612 if (firstClass) { 7613 try { 7614 ApplicationInfo ai = 7615 ActivityThread.getPackageManager(). 7616 getApplicationInfo( 7617 cpi.applicationInfo.packageName, 7618 STOCK_PM_FLAGS); 7619 if (ai == null) { 7620 Log.w(TAG, "No package info for content provider " 7621 + cpi.name); 7622 return null; 7623 } 7624 cpr = new ContentProviderRecord(cpi, ai); 7625 } catch (RemoteException ex) { 7626 // pm is in same process, this will never happen. 7627 } 7628 } 7629 7630 if (r != null && cpr.canRunHere(r)) { 7631 // If this is a multiprocess provider, then just return its 7632 // info and allow the caller to instantiate it. Only do 7633 // this if the provider is the same user as the caller's 7634 // process, or can run as root (so can be in any process). 7635 return cpr; 7636 } 7637 7638 if (DEBUG_PROVIDER) { 7639 RuntimeException e = new RuntimeException("here"); 7640 Log.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid 7641 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7642 } 7643 7644 // This is single process, and our app is now connecting to it. 7645 // See if we are already in the process of launching this 7646 // provider. 7647 final int N = mLaunchingProviders.size(); 7648 int i; 7649 for (i=0; i<N; i++) { 7650 if (mLaunchingProviders.get(i) == cpr) { 7651 break; 7652 } 7653 } 7654 7655 // If the provider is not already being launched, then get it 7656 // started. 7657 if (i >= N) { 7658 final long origId = Binder.clearCallingIdentity(); 7659 ProcessRecord proc = startProcessLocked(cpi.processName, 7660 cpr.appInfo, false, 0, "content provider", 7661 new ComponentName(cpi.applicationInfo.packageName, 7662 cpi.name), false); 7663 if (proc == null) { 7664 Log.w(TAG, "Unable to launch app " 7665 + cpi.applicationInfo.packageName + "/" 7666 + cpi.applicationInfo.uid + " for provider " 7667 + name + ": process is bad"); 7668 return null; 7669 } 7670 cpr.launchingApp = proc; 7671 mLaunchingProviders.add(cpr); 7672 Binder.restoreCallingIdentity(origId); 7673 } 7674 7675 // Make sure the provider is published (the same provider class 7676 // may be published under multiple names). 7677 if (firstClass) { 7678 mProvidersByClass.put(cpi.name, cpr); 7679 } 7680 mProvidersByName.put(name, cpr); 7681 7682 if (r != null) { 7683 if (DEBUG_PROVIDER) Log.v(TAG, 7684 "Adding provider requested by " 7685 + r.processName + " from process " 7686 + cpr.info.processName); 7687 Integer cnt = r.conProviders.get(cpr); 7688 if (cnt == null) { 7689 r.conProviders.put(cpr, new Integer(1)); 7690 } else { 7691 r.conProviders.put(cpr, new Integer(cnt.intValue()+1)); 7692 } 7693 cpr.clients.add(r); 7694 } else { 7695 cpr.externals++; 7696 } 7697 } 7698 } 7699 7700 // Wait for the provider to be published... 7701 synchronized (cpr) { 7702 while (cpr.provider == null) { 7703 if (cpr.launchingApp == null) { 7704 Log.w(TAG, "Unable to launch app " 7705 + cpi.applicationInfo.packageName + "/" 7706 + cpi.applicationInfo.uid + " for provider " 7707 + name + ": launching app became null"); 7708 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7709 cpi.applicationInfo.packageName, 7710 cpi.applicationInfo.uid, name); 7711 return null; 7712 } 7713 try { 7714 cpr.wait(); 7715 } catch (InterruptedException ex) { 7716 } 7717 } 7718 } 7719 return cpr; 7720 } 7721 7722 public final ContentProviderHolder getContentProvider( 7723 IApplicationThread caller, String name) { 7724 if (caller == null) { 7725 String msg = "null IApplicationThread when getting content provider " 7726 + name; 7727 Log.w(TAG, msg); 7728 throw new SecurityException(msg); 7729 } 7730 7731 return getContentProviderImpl(caller, name); 7732 } 7733 7734 private ContentProviderHolder getContentProviderExternal(String name) { 7735 return getContentProviderImpl(null, name); 7736 } 7737 7738 /** 7739 * Drop a content provider from a ProcessRecord's bookkeeping 7740 * @param cpr 7741 */ 7742 public void removeContentProvider(IApplicationThread caller, String name) { 7743 synchronized (this) { 7744 ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name); 7745 if(cpr == null) { 7746 // remove from mProvidersByClass 7747 if (DEBUG_PROVIDER) Log.v(TAG, name + 7748 " provider not found in providers list"); 7749 return; 7750 } 7751 final ProcessRecord r = getRecordForAppLocked(caller); 7752 if (r == null) { 7753 throw new SecurityException( 7754 "Unable to find app for caller " + caller + 7755 " when removing content provider " + name); 7756 } 7757 //update content provider record entry info 7758 ContentProviderRecord localCpr = (ContentProviderRecord) 7759 mProvidersByClass.get(cpr.info.name); 7760 if (DEBUG_PROVIDER) Log.v(TAG, "Removing provider requested by " 7761 + r.info.processName + " from process " 7762 + localCpr.appInfo.processName); 7763 if (localCpr.app == r) { 7764 //should not happen. taken care of as a local provider 7765 Log.w(TAG, "removeContentProvider called on local provider: " 7766 + cpr.info.name + " in process " + r.processName); 7767 return; 7768 } else { 7769 Integer cnt = r.conProviders.get(localCpr); 7770 if (cnt == null || cnt.intValue() <= 1) { 7771 localCpr.clients.remove(r); 7772 r.conProviders.remove(localCpr); 7773 } else { 7774 r.conProviders.put(localCpr, new Integer(cnt.intValue()-1)); 7775 } 7776 } 7777 updateOomAdjLocked(); 7778 } 7779 } 7780 7781 private void removeContentProviderExternal(String name) { 7782 synchronized (this) { 7783 ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name); 7784 if(cpr == null) { 7785 //remove from mProvidersByClass 7786 if(localLOGV) Log.v(TAG, name+" content provider not found in providers list"); 7787 return; 7788 } 7789 7790 //update content provider record entry info 7791 ContentProviderRecord localCpr = (ContentProviderRecord) mProvidersByClass.get(cpr.info.name); 7792 localCpr.externals--; 7793 if (localCpr.externals < 0) { 7794 Log.e(TAG, "Externals < 0 for content provider " + localCpr); 7795 } 7796 updateOomAdjLocked(); 7797 } 7798 } 7799 7800 public final void publishContentProviders(IApplicationThread caller, 7801 List<ContentProviderHolder> providers) { 7802 if (providers == null) { 7803 return; 7804 } 7805 7806 synchronized(this) { 7807 final ProcessRecord r = getRecordForAppLocked(caller); 7808 if (r == null) { 7809 throw new SecurityException( 7810 "Unable to find app for caller " + caller 7811 + " (pid=" + Binder.getCallingPid() 7812 + ") when publishing content providers"); 7813 } 7814 7815 final long origId = Binder.clearCallingIdentity(); 7816 7817 final int N = providers.size(); 7818 for (int i=0; i<N; i++) { 7819 ContentProviderHolder src = providers.get(i); 7820 if (src == null || src.info == null || src.provider == null) { 7821 continue; 7822 } 7823 ContentProviderRecord dst = 7824 (ContentProviderRecord)r.pubProviders.get(src.info.name); 7825 if (dst != null) { 7826 mProvidersByClass.put(dst.info.name, dst); 7827 String names[] = dst.info.authority.split(";"); 7828 for (int j = 0; j < names.length; j++) { 7829 mProvidersByName.put(names[j], dst); 7830 } 7831 7832 int NL = mLaunchingProviders.size(); 7833 int j; 7834 for (j=0; j<NL; j++) { 7835 if (mLaunchingProviders.get(j) == dst) { 7836 mLaunchingProviders.remove(j); 7837 j--; 7838 NL--; 7839 } 7840 } 7841 synchronized (dst) { 7842 dst.provider = src.provider; 7843 dst.app = r; 7844 dst.notifyAll(); 7845 } 7846 updateOomAdjLocked(r); 7847 } 7848 } 7849 7850 Binder.restoreCallingIdentity(origId); 7851 } 7852 } 7853 7854 public static final void installSystemProviders() { 7855 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 7856 List providers = mSelf.generateApplicationProvidersLocked(app); 7857 mSystemThread.installSystemProviders(providers); 7858 } 7859 7860 // ========================================================= 7861 // GLOBAL MANAGEMENT 7862 // ========================================================= 7863 7864 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 7865 ApplicationInfo info, String customProcess) { 7866 String proc = customProcess != null ? customProcess : info.processName; 7867 BatteryStatsImpl.Uid.Proc ps = null; 7868 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 7869 synchronized (stats) { 7870 ps = stats.getProcessStatsLocked(info.uid, proc); 7871 } 7872 return new ProcessRecord(ps, thread, info, proc); 7873 } 7874 7875 final ProcessRecord addAppLocked(ApplicationInfo info) { 7876 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid); 7877 7878 if (app == null) { 7879 app = newProcessRecordLocked(null, info, null); 7880 mProcessNames.put(info.processName, info.uid, app); 7881 updateLruProcessLocked(app, true, true); 7882 } 7883 7884 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 7885 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 7886 app.persistent = true; 7887 app.maxAdj = CORE_SERVER_ADJ; 7888 } 7889 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 7890 mPersistentStartingProcesses.add(app); 7891 startProcessLocked(app, "added application", app.processName); 7892 } 7893 7894 return app; 7895 } 7896 7897 public void unhandledBack() { 7898 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 7899 "unhandledBack()"); 7900 7901 synchronized(this) { 7902 int count = mHistory.size(); 7903 if (DEBUG_SWITCH) Log.d( 7904 TAG, "Performing unhandledBack(): stack size = " + count); 7905 if (count > 1) { 7906 final long origId = Binder.clearCallingIdentity(); 7907 finishActivityLocked((HistoryRecord)mHistory.get(count-1), 7908 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 7909 Binder.restoreCallingIdentity(origId); 7910 } 7911 } 7912 } 7913 7914 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 7915 String name = uri.getAuthority(); 7916 ContentProviderHolder cph = getContentProviderExternal(name); 7917 ParcelFileDescriptor pfd = null; 7918 if (cph != null) { 7919 // We record the binder invoker's uid in thread-local storage before 7920 // going to the content provider to open the file. Later, in the code 7921 // that handles all permissions checks, we look for this uid and use 7922 // that rather than the Activity Manager's own uid. The effect is that 7923 // we do the check against the caller's permissions even though it looks 7924 // to the content provider like the Activity Manager itself is making 7925 // the request. 7926 sCallerIdentity.set(new Identity( 7927 Binder.getCallingPid(), Binder.getCallingUid())); 7928 try { 7929 pfd = cph.provider.openFile(uri, "r"); 7930 } catch (FileNotFoundException e) { 7931 // do nothing; pfd will be returned null 7932 } finally { 7933 // Ensure that whatever happens, we clean up the identity state 7934 sCallerIdentity.remove(); 7935 } 7936 7937 // We've got the fd now, so we're done with the provider. 7938 removeContentProviderExternal(name); 7939 } else { 7940 Log.d(TAG, "Failed to get provider for authority '" + name + "'"); 7941 } 7942 return pfd; 7943 } 7944 7945 public void goingToSleep() { 7946 synchronized(this) { 7947 mSleeping = true; 7948 mWindowManager.setEventDispatching(false); 7949 7950 if (mResumedActivity != null) { 7951 pauseIfSleepingLocked(); 7952 } else { 7953 Log.w(TAG, "goingToSleep with no resumed activity!"); 7954 } 7955 } 7956 } 7957 7958 public boolean shutdown(int timeout) { 7959 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 7960 != PackageManager.PERMISSION_GRANTED) { 7961 throw new SecurityException("Requires permission " 7962 + android.Manifest.permission.SHUTDOWN); 7963 } 7964 7965 boolean timedout = false; 7966 7967 synchronized(this) { 7968 mShuttingDown = true; 7969 mWindowManager.setEventDispatching(false); 7970 7971 if (mResumedActivity != null) { 7972 pauseIfSleepingLocked(); 7973 final long endTime = System.currentTimeMillis() + timeout; 7974 while (mResumedActivity != null || mPausingActivity != null) { 7975 long delay = endTime - System.currentTimeMillis(); 7976 if (delay <= 0) { 7977 Log.w(TAG, "Activity manager shutdown timed out"); 7978 timedout = true; 7979 break; 7980 } 7981 try { 7982 this.wait(); 7983 } catch (InterruptedException e) { 7984 } 7985 } 7986 } 7987 } 7988 7989 mUsageStatsService.shutdown(); 7990 mBatteryStatsService.shutdown(); 7991 7992 return timedout; 7993 } 7994 7995 void pauseIfSleepingLocked() { 7996 if (mSleeping || mShuttingDown) { 7997 if (!mGoingToSleep.isHeld()) { 7998 mGoingToSleep.acquire(); 7999 if (mLaunchingActivity.isHeld()) { 8000 mLaunchingActivity.release(); 8001 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 8002 } 8003 } 8004 8005 // If we are not currently pausing an activity, get the current 8006 // one to pause. If we are pausing one, we will just let that stuff 8007 // run and release the wake lock when all done. 8008 if (mPausingActivity == null) { 8009 if (DEBUG_PAUSE) Log.v(TAG, "Sleep needs to pause..."); 8010 if (DEBUG_USER_LEAVING) Log.v(TAG, "Sleep => pause with userLeaving=false"); 8011 startPausingLocked(false, true); 8012 } 8013 } 8014 } 8015 8016 public void wakingUp() { 8017 synchronized(this) { 8018 if (mGoingToSleep.isHeld()) { 8019 mGoingToSleep.release(); 8020 } 8021 mWindowManager.setEventDispatching(true); 8022 mSleeping = false; 8023 resumeTopActivityLocked(null); 8024 } 8025 } 8026 8027 public void stopAppSwitches() { 8028 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8029 != PackageManager.PERMISSION_GRANTED) { 8030 throw new SecurityException("Requires permission " 8031 + android.Manifest.permission.STOP_APP_SWITCHES); 8032 } 8033 8034 synchronized(this) { 8035 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8036 + APP_SWITCH_DELAY_TIME; 8037 mDidAppSwitch = false; 8038 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8039 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8040 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8041 } 8042 } 8043 8044 public void resumeAppSwitches() { 8045 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8046 != PackageManager.PERMISSION_GRANTED) { 8047 throw new SecurityException("Requires permission " 8048 + android.Manifest.permission.STOP_APP_SWITCHES); 8049 } 8050 8051 synchronized(this) { 8052 // Note that we don't execute any pending app switches... we will 8053 // let those wait until either the timeout, or the next start 8054 // activity request. 8055 mAppSwitchesAllowedTime = 0; 8056 } 8057 } 8058 8059 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8060 String name) { 8061 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8062 return true; 8063 } 8064 8065 final int perm = checkComponentPermission( 8066 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8067 callingUid, -1); 8068 if (perm == PackageManager.PERMISSION_GRANTED) { 8069 return true; 8070 } 8071 8072 Log.w(TAG, name + " request from " + callingUid + " stopped"); 8073 return false; 8074 } 8075 8076 public void setDebugApp(String packageName, boolean waitForDebugger, 8077 boolean persistent) { 8078 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8079 "setDebugApp()"); 8080 8081 // Note that this is not really thread safe if there are multiple 8082 // callers into it at the same time, but that's not a situation we 8083 // care about. 8084 if (persistent) { 8085 final ContentResolver resolver = mContext.getContentResolver(); 8086 Settings.System.putString( 8087 resolver, Settings.System.DEBUG_APP, 8088 packageName); 8089 Settings.System.putInt( 8090 resolver, Settings.System.WAIT_FOR_DEBUGGER, 8091 waitForDebugger ? 1 : 0); 8092 } 8093 8094 synchronized (this) { 8095 if (!persistent) { 8096 mOrigDebugApp = mDebugApp; 8097 mOrigWaitForDebugger = mWaitForDebugger; 8098 } 8099 mDebugApp = packageName; 8100 mWaitForDebugger = waitForDebugger; 8101 mDebugTransient = !persistent; 8102 if (packageName != null) { 8103 final long origId = Binder.clearCallingIdentity(); 8104 forceStopPackageLocked(packageName, -1, false); 8105 Binder.restoreCallingIdentity(origId); 8106 } 8107 } 8108 } 8109 8110 public void setAlwaysFinish(boolean enabled) { 8111 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8112 "setAlwaysFinish()"); 8113 8114 Settings.System.putInt( 8115 mContext.getContentResolver(), 8116 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8117 8118 synchronized (this) { 8119 mAlwaysFinishActivities = enabled; 8120 } 8121 } 8122 8123 public void setActivityController(IActivityController controller) { 8124 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8125 "setActivityController()"); 8126 synchronized (this) { 8127 mController = controller; 8128 } 8129 } 8130 8131 public void registerActivityWatcher(IActivityWatcher watcher) { 8132 mWatchers.register(watcher); 8133 } 8134 8135 public void unregisterActivityWatcher(IActivityWatcher watcher) { 8136 mWatchers.unregister(watcher); 8137 } 8138 8139 public final void enterSafeMode() { 8140 synchronized(this) { 8141 // It only makes sense to do this before the system is ready 8142 // and started launching other packages. 8143 if (!mSystemReady) { 8144 try { 8145 ActivityThread.getPackageManager().enterSafeMode(); 8146 } catch (RemoteException e) { 8147 } 8148 8149 View v = LayoutInflater.from(mContext).inflate( 8150 com.android.internal.R.layout.safe_mode, null); 8151 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8152 lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; 8153 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8154 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8155 lp.gravity = Gravity.BOTTOM | Gravity.LEFT; 8156 lp.format = v.getBackground().getOpacity(); 8157 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8158 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8159 ((WindowManager)mContext.getSystemService( 8160 Context.WINDOW_SERVICE)).addView(v, lp); 8161 } 8162 } 8163 } 8164 8165 public void noteWakeupAlarm(IIntentSender sender) { 8166 if (!(sender instanceof PendingIntentRecord)) { 8167 return; 8168 } 8169 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8170 synchronized (stats) { 8171 if (mBatteryStatsService.isOnBattery()) { 8172 mBatteryStatsService.enforceCallingPermission(); 8173 PendingIntentRecord rec = (PendingIntentRecord)sender; 8174 int MY_UID = Binder.getCallingUid(); 8175 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8176 BatteryStatsImpl.Uid.Pkg pkg = 8177 stats.getPackageStatsLocked(uid, rec.key.packageName); 8178 pkg.incWakeupsLocked(); 8179 } 8180 } 8181 } 8182 8183 public boolean killPidsForMemory(int[] pids) { 8184 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8185 throw new SecurityException("killPidsForMemory only available to the system"); 8186 } 8187 8188 // XXX Note: don't acquire main activity lock here, because the window 8189 // manager calls in with its locks held. 8190 8191 boolean killed = false; 8192 synchronized (mPidsSelfLocked) { 8193 int[] types = new int[pids.length]; 8194 int worstType = 0; 8195 for (int i=0; i<pids.length; i++) { 8196 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8197 if (proc != null) { 8198 int type = proc.setAdj; 8199 types[i] = type; 8200 if (type > worstType) { 8201 worstType = type; 8202 } 8203 } 8204 } 8205 8206 // If the worse oom_adj is somewhere in the hidden proc LRU range, 8207 // then constrain it so we will kill all hidden procs. 8208 if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) { 8209 worstType = HIDDEN_APP_MIN_ADJ; 8210 } 8211 Log.w(TAG, "Killing processes for memory at adjustment " + worstType); 8212 for (int i=0; i<pids.length; i++) { 8213 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8214 if (proc == null) { 8215 continue; 8216 } 8217 int adj = proc.setAdj; 8218 if (adj >= worstType) { 8219 Log.w(TAG, "Killing for memory: " + proc + " (adj " 8220 + adj + ")"); 8221 EventLog.writeEvent(EventLogTags.AM_KILL_FOR_MEMORY, proc.pid, 8222 proc.processName, adj); 8223 killed = true; 8224 Process.killProcess(pids[i]); 8225 } 8226 } 8227 } 8228 return killed; 8229 } 8230 8231 public void reportPss(IApplicationThread caller, int pss) { 8232 Watchdog.PssRequestor req; 8233 String name; 8234 ProcessRecord callerApp; 8235 synchronized (this) { 8236 if (caller == null) { 8237 return; 8238 } 8239 callerApp = getRecordForAppLocked(caller); 8240 if (callerApp == null) { 8241 return; 8242 } 8243 callerApp.lastPss = pss; 8244 req = callerApp; 8245 name = callerApp.processName; 8246 } 8247 Watchdog.getInstance().reportPss(req, name, pss); 8248 if (!callerApp.persistent) { 8249 removeRequestedPss(callerApp); 8250 } 8251 } 8252 8253 public void requestPss(Runnable completeCallback) { 8254 ArrayList<ProcessRecord> procs; 8255 synchronized (this) { 8256 mRequestPssCallback = completeCallback; 8257 mRequestPssList.clear(); 8258 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8259 ProcessRecord proc = mLruProcesses.get(i); 8260 if (!proc.persistent) { 8261 mRequestPssList.add(proc); 8262 } 8263 } 8264 procs = new ArrayList<ProcessRecord>(mRequestPssList); 8265 } 8266 8267 int oldPri = Process.getThreadPriority(Process.myTid()); 8268 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 8269 for (int i=procs.size()-1; i>=0; i--) { 8270 ProcessRecord proc = procs.get(i); 8271 proc.lastPss = 0; 8272 proc.requestPss(); 8273 } 8274 Process.setThreadPriority(oldPri); 8275 } 8276 8277 void removeRequestedPss(ProcessRecord proc) { 8278 Runnable callback = null; 8279 synchronized (this) { 8280 if (mRequestPssList.remove(proc)) { 8281 if (mRequestPssList.size() == 0) { 8282 callback = mRequestPssCallback; 8283 mRequestPssCallback = null; 8284 } 8285 } 8286 } 8287 8288 if (callback != null) { 8289 callback.run(); 8290 } 8291 } 8292 8293 public void collectPss(Watchdog.PssStats stats) { 8294 stats.mEmptyPss = 0; 8295 stats.mEmptyCount = 0; 8296 stats.mBackgroundPss = 0; 8297 stats.mBackgroundCount = 0; 8298 stats.mServicePss = 0; 8299 stats.mServiceCount = 0; 8300 stats.mVisiblePss = 0; 8301 stats.mVisibleCount = 0; 8302 stats.mForegroundPss = 0; 8303 stats.mForegroundCount = 0; 8304 stats.mNoPssCount = 0; 8305 synchronized (this) { 8306 int i; 8307 int NPD = mProcDeaths.length < stats.mProcDeaths.length 8308 ? mProcDeaths.length : stats.mProcDeaths.length; 8309 int aggr = 0; 8310 for (i=0; i<NPD; i++) { 8311 aggr += mProcDeaths[i]; 8312 stats.mProcDeaths[i] = aggr; 8313 } 8314 while (i<stats.mProcDeaths.length) { 8315 stats.mProcDeaths[i] = 0; 8316 i++; 8317 } 8318 8319 for (i=mLruProcesses.size()-1; i>=0; i--) { 8320 ProcessRecord proc = mLruProcesses.get(i); 8321 if (proc.persistent) { 8322 continue; 8323 } 8324 //Log.i(TAG, "Proc " + proc + ": pss=" + proc.lastPss); 8325 if (proc.lastPss == 0) { 8326 stats.mNoPssCount++; 8327 continue; 8328 } 8329 if (proc.setAdj >= HIDDEN_APP_MIN_ADJ) { 8330 if (proc.empty) { 8331 stats.mEmptyPss += proc.lastPss; 8332 stats.mEmptyCount++; 8333 } else { 8334 stats.mBackgroundPss += proc.lastPss; 8335 stats.mBackgroundCount++; 8336 } 8337 } else if (proc.setAdj >= VISIBLE_APP_ADJ) { 8338 stats.mVisiblePss += proc.lastPss; 8339 stats.mVisibleCount++; 8340 } else { 8341 stats.mForegroundPss += proc.lastPss; 8342 stats.mForegroundCount++; 8343 } 8344 } 8345 } 8346 } 8347 8348 public final void startRunning(String pkg, String cls, String action, 8349 String data) { 8350 synchronized(this) { 8351 if (mStartRunning) { 8352 return; 8353 } 8354 mStartRunning = true; 8355 mTopComponent = pkg != null && cls != null 8356 ? new ComponentName(pkg, cls) : null; 8357 mTopAction = action != null ? action : Intent.ACTION_MAIN; 8358 mTopData = data; 8359 if (!mSystemReady) { 8360 return; 8361 } 8362 } 8363 8364 systemReady(null); 8365 } 8366 8367 private void retrieveSettings() { 8368 final ContentResolver resolver = mContext.getContentResolver(); 8369 String debugApp = Settings.System.getString( 8370 resolver, Settings.System.DEBUG_APP); 8371 boolean waitForDebugger = Settings.System.getInt( 8372 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 8373 boolean alwaysFinishActivities = Settings.System.getInt( 8374 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 8375 8376 Configuration configuration = new Configuration(); 8377 Settings.System.getConfiguration(resolver, configuration); 8378 8379 synchronized (this) { 8380 mDebugApp = mOrigDebugApp = debugApp; 8381 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 8382 mAlwaysFinishActivities = alwaysFinishActivities; 8383 // This happens before any activities are started, so we can 8384 // change mConfiguration in-place. 8385 mConfiguration.updateFrom(configuration); 8386 if (DEBUG_CONFIGURATION) Log.v(TAG, "Initial config: " + mConfiguration); 8387 } 8388 } 8389 8390 public boolean testIsSystemReady() { 8391 // no need to synchronize(this) just to read & return the value 8392 return mSystemReady; 8393 } 8394 8395 public void systemReady(final Runnable goingCallback) { 8396 // In the simulator, startRunning will never have been called, which 8397 // normally sets a few crucial variables. Do it here instead. 8398 if (!Process.supportsProcesses()) { 8399 mStartRunning = true; 8400 mTopAction = Intent.ACTION_MAIN; 8401 } 8402 8403 synchronized(this) { 8404 if (mSystemReady) { 8405 if (goingCallback != null) goingCallback.run(); 8406 return; 8407 } 8408 8409 // Check to see if there are any update receivers to run. 8410 if (!mDidUpdate) { 8411 if (mWaitingUpdate) { 8412 return; 8413 } 8414 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 8415 List<ResolveInfo> ris = null; 8416 try { 8417 ris = ActivityThread.getPackageManager().queryIntentReceivers( 8418 intent, null, 0); 8419 } catch (RemoteException e) { 8420 } 8421 if (ris != null) { 8422 for (int i=ris.size()-1; i>=0; i--) { 8423 if ((ris.get(i).activityInfo.applicationInfo.flags 8424 &ApplicationInfo.FLAG_SYSTEM) == 0) { 8425 ris.remove(i); 8426 } 8427 } 8428 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 8429 for (int i=0; i<ris.size(); i++) { 8430 ActivityInfo ai = ris.get(i).activityInfo; 8431 intent.setComponent(new ComponentName(ai.packageName, ai.name)); 8432 IIntentReceiver finisher = null; 8433 if (i == 0) { 8434 finisher = new IIntentReceiver.Stub() { 8435 public void performReceive(Intent intent, int resultCode, 8436 String data, Bundle extras, boolean ordered, 8437 boolean sticky) 8438 throws RemoteException { 8439 synchronized (ActivityManagerService.this) { 8440 mDidUpdate = true; 8441 } 8442 systemReady(goingCallback); 8443 } 8444 }; 8445 } 8446 Log.i(TAG, "Sending system update to: " + intent.getComponent()); 8447 broadcastIntentLocked(null, null, intent, null, finisher, 8448 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID); 8449 if (i == 0) { 8450 mWaitingUpdate = true; 8451 } 8452 } 8453 } 8454 if (mWaitingUpdate) { 8455 return; 8456 } 8457 mDidUpdate = true; 8458 } 8459 8460 mSystemReady = true; 8461 if (!mStartRunning) { 8462 return; 8463 } 8464 } 8465 8466 ArrayList<ProcessRecord> procsToKill = null; 8467 synchronized(mPidsSelfLocked) { 8468 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 8469 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8470 if (!isAllowedWhileBooting(proc.info)){ 8471 if (procsToKill == null) { 8472 procsToKill = new ArrayList<ProcessRecord>(); 8473 } 8474 procsToKill.add(proc); 8475 } 8476 } 8477 } 8478 8479 if (procsToKill != null) { 8480 synchronized(this) { 8481 for (int i=procsToKill.size()-1; i>=0; i--) { 8482 ProcessRecord proc = procsToKill.get(i); 8483 Log.i(TAG, "Removing system update proc: " + proc); 8484 removeProcessLocked(proc, true); 8485 } 8486 } 8487 } 8488 8489 Log.i(TAG, "System now ready"); 8490 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 8491 SystemClock.uptimeMillis()); 8492 8493 synchronized(this) { 8494 // Make sure we have no pre-ready processes sitting around. 8495 8496 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 8497 ResolveInfo ri = mContext.getPackageManager() 8498 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 8499 STOCK_PM_FLAGS); 8500 CharSequence errorMsg = null; 8501 if (ri != null) { 8502 ActivityInfo ai = ri.activityInfo; 8503 ApplicationInfo app = ai.applicationInfo; 8504 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 8505 mTopAction = Intent.ACTION_FACTORY_TEST; 8506 mTopData = null; 8507 mTopComponent = new ComponentName(app.packageName, 8508 ai.name); 8509 } else { 8510 errorMsg = mContext.getResources().getText( 8511 com.android.internal.R.string.factorytest_not_system); 8512 } 8513 } else { 8514 errorMsg = mContext.getResources().getText( 8515 com.android.internal.R.string.factorytest_no_action); 8516 } 8517 if (errorMsg != null) { 8518 mTopAction = null; 8519 mTopData = null; 8520 mTopComponent = null; 8521 Message msg = Message.obtain(); 8522 msg.what = SHOW_FACTORY_ERROR_MSG; 8523 msg.getData().putCharSequence("msg", errorMsg); 8524 mHandler.sendMessage(msg); 8525 } 8526 } 8527 } 8528 8529 retrieveSettings(); 8530 8531 if (goingCallback != null) goingCallback.run(); 8532 8533 synchronized (this) { 8534 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 8535 try { 8536 List apps = ActivityThread.getPackageManager(). 8537 getPersistentApplications(STOCK_PM_FLAGS); 8538 if (apps != null) { 8539 int N = apps.size(); 8540 int i; 8541 for (i=0; i<N; i++) { 8542 ApplicationInfo info 8543 = (ApplicationInfo)apps.get(i); 8544 if (info != null && 8545 !info.packageName.equals("android")) { 8546 addAppLocked(info); 8547 } 8548 } 8549 } 8550 } catch (RemoteException ex) { 8551 // pm is in same process, this will never happen. 8552 } 8553 } 8554 8555 // Start up initial activity. 8556 mBooting = true; 8557 8558 try { 8559 if (ActivityThread.getPackageManager().hasSystemUidErrors()) { 8560 Message msg = Message.obtain(); 8561 msg.what = SHOW_UID_ERROR_MSG; 8562 mHandler.sendMessage(msg); 8563 } 8564 } catch (RemoteException e) { 8565 } 8566 8567 resumeTopActivityLocked(null); 8568 } 8569 } 8570 8571 private boolean makeAppCrashingLocked(ProcessRecord app, 8572 String shortMsg, String longMsg, String stackTrace) { 8573 app.crashing = true; 8574 app.crashingReport = generateProcessError(app, 8575 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 8576 startAppProblemLocked(app); 8577 app.stopFreezingAllLocked(); 8578 return handleAppCrashLocked(app); 8579 } 8580 8581 private ComponentName getErrorReportReceiver(ProcessRecord app) { 8582 // check if error reporting is enabled in Gservices 8583 int enabled = Settings.Gservices.getInt(mContext.getContentResolver(), 8584 Settings.Gservices.SEND_ACTION_APP_ERROR, 0); 8585 if (enabled == 0) { 8586 return null; 8587 } 8588 8589 IPackageManager pm = ActivityThread.getPackageManager(); 8590 8591 try { 8592 // look for receiver in the installer package 8593 String candidate = pm.getInstallerPackageName(app.info.packageName); 8594 ComponentName result = getErrorReportReceiver(pm, app.info.packageName, candidate); 8595 if (result != null) { 8596 return result; 8597 } 8598 8599 // if the error app is on the system image, look for system apps 8600 // error receiver 8601 if ((app.info.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 8602 candidate = SystemProperties.get(SYSTEM_APPS_ERROR_RECEIVER_PROPERTY); 8603 result = getErrorReportReceiver(pm, app.info.packageName, candidate); 8604 if (result != null) { 8605 return result; 8606 } 8607 } 8608 8609 // if there is a default receiver, try that 8610 candidate = SystemProperties.get(DEFAULT_ERROR_RECEIVER_PROPERTY); 8611 return getErrorReportReceiver(pm, app.info.packageName, candidate); 8612 } catch (RemoteException e) { 8613 // should not happen 8614 Log.e(TAG, "error talking to PackageManager", e); 8615 return null; 8616 } 8617 } 8618 8619 /** 8620 * Return activity in receiverPackage that handles ACTION_APP_ERROR. 8621 * 8622 * @param pm PackageManager isntance 8623 * @param errorPackage package which caused the error 8624 * @param receiverPackage candidate package to receive the error 8625 * @return activity component within receiverPackage which handles 8626 * ACTION_APP_ERROR, or null if not found 8627 */ 8628 private ComponentName getErrorReportReceiver(IPackageManager pm, String errorPackage, 8629 String receiverPackage) throws RemoteException { 8630 if (receiverPackage == null || receiverPackage.length() == 0) { 8631 return null; 8632 } 8633 8634 // break the loop if it's the error report receiver package that crashed 8635 if (receiverPackage.equals(errorPackage)) { 8636 return null; 8637 } 8638 8639 Intent intent = new Intent(Intent.ACTION_APP_ERROR); 8640 intent.setPackage(receiverPackage); 8641 ResolveInfo info = pm.resolveIntent(intent, null, 0); 8642 if (info == null || info.activityInfo == null) { 8643 return null; 8644 } 8645 return new ComponentName(receiverPackage, info.activityInfo.name); 8646 } 8647 8648 private void makeAppNotRespondingLocked(ProcessRecord app, 8649 String activity, String shortMsg, String longMsg) { 8650 app.notResponding = true; 8651 app.notRespondingReport = generateProcessError(app, 8652 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 8653 activity, shortMsg, longMsg, null); 8654 startAppProblemLocked(app); 8655 app.stopFreezingAllLocked(); 8656 } 8657 8658 /** 8659 * Generate a process error record, suitable for attachment to a ProcessRecord. 8660 * 8661 * @param app The ProcessRecord in which the error occurred. 8662 * @param condition Crashing, Application Not Responding, etc. Values are defined in 8663 * ActivityManager.AppErrorStateInfo 8664 * @param activity The activity associated with the crash, if known. 8665 * @param shortMsg Short message describing the crash. 8666 * @param longMsg Long message describing the crash. 8667 * @param stackTrace Full crash stack trace, may be null. 8668 * 8669 * @return Returns a fully-formed AppErrorStateInfo record. 8670 */ 8671 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 8672 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 8673 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 8674 8675 report.condition = condition; 8676 report.processName = app.processName; 8677 report.pid = app.pid; 8678 report.uid = app.info.uid; 8679 report.tag = activity; 8680 report.shortMsg = shortMsg; 8681 report.longMsg = longMsg; 8682 report.stackTrace = stackTrace; 8683 8684 return report; 8685 } 8686 8687 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog, 8688 boolean crashed) { 8689 synchronized (this) { 8690 app.crashing = false; 8691 app.crashingReport = null; 8692 app.notResponding = false; 8693 app.notRespondingReport = null; 8694 if (app.anrDialog == fromDialog) { 8695 app.anrDialog = null; 8696 } 8697 if (app.waitDialog == fromDialog) { 8698 app.waitDialog = null; 8699 } 8700 if (app.pid > 0 && app.pid != MY_PID) { 8701 if (crashed) { 8702 handleAppCrashLocked(app); 8703 } 8704 Log.i(ActivityManagerService.TAG, "Killing process " 8705 + app.processName 8706 + " (pid=" + app.pid + ") at user's request"); 8707 Process.killProcess(app.pid); 8708 } 8709 8710 } 8711 } 8712 8713 private boolean handleAppCrashLocked(ProcessRecord app) { 8714 long now = SystemClock.uptimeMillis(); 8715 8716 Long crashTime = mProcessCrashTimes.get(app.info.processName, 8717 app.info.uid); 8718 if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) { 8719 // This process loses! 8720 Log.w(TAG, "Process " + app.info.processName 8721 + " has crashed too many times: killing!"); 8722 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 8723 app.info.processName, app.info.uid); 8724 killServicesLocked(app, false); 8725 for (int i=mHistory.size()-1; i>=0; i--) { 8726 HistoryRecord r = (HistoryRecord)mHistory.get(i); 8727 if (r.app == app) { 8728 Log.w(TAG, " Force finishing activity " 8729 + r.intent.getComponent().flattenToShortString()); 8730 finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 8731 } 8732 } 8733 if (!app.persistent) { 8734 // We don't want to start this process again until the user 8735 // explicitly does so... but for persistent process, we really 8736 // need to keep it running. If a persistent process is actually 8737 // repeatedly crashing, then badness for everyone. 8738 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid, 8739 app.info.processName); 8740 mBadProcesses.put(app.info.processName, app.info.uid, now); 8741 app.bad = true; 8742 mProcessCrashTimes.remove(app.info.processName, app.info.uid); 8743 app.removed = true; 8744 removeProcessLocked(app, false); 8745 return false; 8746 } 8747 } 8748 8749 // Bump up the crash count of any services currently running in the proc. 8750 if (app.services.size() != 0) { 8751 // Any services running in the application need to be placed 8752 // back in the pending list. 8753 Iterator it = app.services.iterator(); 8754 while (it.hasNext()) { 8755 ServiceRecord sr = (ServiceRecord)it.next(); 8756 sr.crashCount++; 8757 } 8758 } 8759 8760 mProcessCrashTimes.put(app.info.processName, app.info.uid, now); 8761 return true; 8762 } 8763 8764 void startAppProblemLocked(ProcessRecord app) { 8765 app.errorReportReceiver = getErrorReportReceiver(app); 8766 skipCurrentReceiverLocked(app); 8767 } 8768 8769 void skipCurrentReceiverLocked(ProcessRecord app) { 8770 boolean reschedule = false; 8771 BroadcastRecord r = app.curReceiver; 8772 if (r != null) { 8773 // The current broadcast is waiting for this app's receiver 8774 // to be finished. Looks like that's not going to happen, so 8775 // let the broadcast continue. 8776 logBroadcastReceiverDiscard(r); 8777 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 8778 r.resultExtras, r.resultAbort, true); 8779 reschedule = true; 8780 } 8781 r = mPendingBroadcast; 8782 if (r != null && r.curApp == app) { 8783 if (DEBUG_BROADCAST) Log.v(TAG, 8784 "skip & discard pending app " + r); 8785 logBroadcastReceiverDiscard(r); 8786 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 8787 r.resultExtras, r.resultAbort, true); 8788 reschedule = true; 8789 } 8790 if (reschedule) { 8791 scheduleBroadcastsLocked(); 8792 } 8793 } 8794 8795 /** 8796 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 8797 * The application process will exit immediately after this call returns. 8798 * @param app object of the crashing app, null for the system server 8799 * @param crashInfo describing the exception 8800 */ 8801 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 8802 ProcessRecord r = findAppProcess(app); 8803 8804 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 8805 app == null ? "system" : (r == null ? "unknown" : r.processName), 8806 crashInfo.exceptionClassName, 8807 crashInfo.exceptionMessage, 8808 crashInfo.throwFileName, 8809 crashInfo.throwLineNumber); 8810 8811 addExceptionToDropBox("crash", r, null, crashInfo); 8812 8813 crashApplication(r, crashInfo); 8814 } 8815 8816 /** 8817 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 8818 * @param app object of the crashing app, null for the system server 8819 * @param tag reported by the caller 8820 * @param crashInfo describing the context of the error 8821 * @return true if the process should exit immediately (WTF is fatal) 8822 */ 8823 public boolean handleApplicationWtf(IBinder app, String tag, 8824 ApplicationErrorReport.CrashInfo crashInfo) { 8825 ProcessRecord r = findAppProcess(app); 8826 8827 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 8828 app == null ? "system" : (r == null ? "unknown" : r.processName), 8829 tag, crashInfo.exceptionMessage); 8830 8831 addExceptionToDropBox("wtf", r, tag, crashInfo); 8832 8833 if (Settings.Gservices.getInt(mContext.getContentResolver(), 8834 Settings.Gservices.WTF_IS_FATAL, 0) != 0) { 8835 crashApplication(r, crashInfo); 8836 return true; 8837 } else { 8838 return false; 8839 } 8840 } 8841 8842 /** 8843 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 8844 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 8845 */ 8846 private ProcessRecord findAppProcess(IBinder app) { 8847 if (app == null) { 8848 return null; 8849 } 8850 8851 synchronized (this) { 8852 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 8853 final int NA = apps.size(); 8854 for (int ia=0; ia<NA; ia++) { 8855 ProcessRecord p = apps.valueAt(ia); 8856 if (p.thread != null && p.thread.asBinder() == app) { 8857 return p; 8858 } 8859 } 8860 } 8861 8862 Log.w(TAG, "Can't find mystery application: " + app); 8863 return null; 8864 } 8865 } 8866 8867 /** 8868 * Write a description of an exception (from a crash or WTF report) to the drop box. 8869 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 8870 * @param r the process which crashed, null for the system server 8871 * @param tag supplied by the application (in the case of WTF), or null 8872 * @param crashInfo describing the exception 8873 */ 8874 private void addExceptionToDropBox(String eventType, ProcessRecord r, String tag, 8875 ApplicationErrorReport.CrashInfo crashInfo) { 8876 String dropboxTag, processName; 8877 if (r == null) { 8878 dropboxTag = "system_server_" + eventType; 8879 } else if ((r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8880 dropboxTag = "system_app_" + eventType; 8881 } else { 8882 dropboxTag = "data_app_" + eventType; 8883 } 8884 8885 DropBoxManager dbox = (DropBoxManager) mContext.getSystemService(Context.DROPBOX_SERVICE); 8886 if (dbox != null && dbox.isTagEnabled(dropboxTag)) { 8887 StringBuilder sb = new StringBuilder(1024); 8888 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 8889 if (r == null) { 8890 sb.append("Process: system_server\n"); 8891 } else { 8892 sb.append("Package: ").append(r.info.packageName).append("\n"); 8893 if (!r.processName.equals(r.info.packageName)) { 8894 sb.append("Process: ").append(r.processName).append("\n"); 8895 } 8896 } 8897 if (tag != null) { 8898 sb.append("Tag: ").append(tag).append("\n"); 8899 } 8900 if (crashInfo != null && crashInfo.stackTrace != null) { 8901 sb.append("\n").append(crashInfo.stackTrace); 8902 } 8903 dbox.addText(dropboxTag, sb.toString()); 8904 } 8905 } 8906 8907 /** 8908 * Bring up the "unexpected error" dialog box for a crashing app. 8909 * Deal with edge cases (intercepts from instrumented applications, 8910 * ActivityController, error intent receivers, that sort of thing). 8911 * @param r the application crashing 8912 * @param crashInfo describing the failure 8913 */ 8914 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 8915 long timeMillis = System.currentTimeMillis(); 8916 String shortMsg = crashInfo.exceptionClassName; 8917 String longMsg = crashInfo.exceptionMessage; 8918 String stackTrace = crashInfo.stackTrace; 8919 if (shortMsg != null && longMsg != null) { 8920 longMsg = shortMsg + ": " + longMsg; 8921 } else if (shortMsg != null) { 8922 longMsg = shortMsg; 8923 } 8924 8925 AppErrorResult result = new AppErrorResult(); 8926 synchronized (this) { 8927 if (r != null) { 8928 // The application has crashed. Send the SIGQUIT to the process so 8929 // that it can dump its state. 8930 Process.sendSignal(r.pid, Process.SIGNAL_QUIT); 8931 //Log.i(TAG, "Current system threads:"); 8932 //Process.sendSignal(MY_PID, Process.SIGNAL_QUIT); 8933 } 8934 8935 if (mController != null) { 8936 try { 8937 String name = r != null ? r.processName : null; 8938 int pid = r != null ? r.pid : Binder.getCallingPid(); 8939 if (!mController.appCrashed(name, pid, 8940 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 8941 Log.w(TAG, "Force-killing crashed app " + name 8942 + " at watcher's request"); 8943 Process.killProcess(pid); 8944 return; 8945 } 8946 } catch (RemoteException e) { 8947 mController = null; 8948 } 8949 } 8950 8951 final long origId = Binder.clearCallingIdentity(); 8952 8953 // If this process is running instrumentation, finish it. 8954 if (r != null && r.instrumentationClass != null) { 8955 Log.w(TAG, "Error in app " + r.processName 8956 + " running instrumentation " + r.instrumentationClass + ":"); 8957 if (shortMsg != null) Log.w(TAG, " " + shortMsg); 8958 if (longMsg != null) Log.w(TAG, " " + longMsg); 8959 Bundle info = new Bundle(); 8960 info.putString("shortMsg", shortMsg); 8961 info.putString("longMsg", longMsg); 8962 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 8963 Binder.restoreCallingIdentity(origId); 8964 return; 8965 } 8966 8967 // If we can't identify the process or it's already exceeded its crash quota, 8968 // quit right away without showing a crash dialog. 8969 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 8970 Binder.restoreCallingIdentity(origId); 8971 return; 8972 } 8973 8974 Message msg = Message.obtain(); 8975 msg.what = SHOW_ERROR_MSG; 8976 HashMap data = new HashMap(); 8977 data.put("result", result); 8978 data.put("app", r); 8979 msg.obj = data; 8980 mHandler.sendMessage(msg); 8981 8982 Binder.restoreCallingIdentity(origId); 8983 } 8984 8985 int res = result.get(); 8986 8987 Intent appErrorIntent = null; 8988 synchronized (this) { 8989 if (r != null) { 8990 mProcessCrashTimes.put(r.info.processName, r.info.uid, 8991 SystemClock.uptimeMillis()); 8992 } 8993 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 8994 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 8995 } 8996 } 8997 8998 if (appErrorIntent != null) { 8999 try { 9000 mContext.startActivity(appErrorIntent); 9001 } catch (ActivityNotFoundException e) { 9002 Log.w(TAG, "bug report receiver dissappeared", e); 9003 } 9004 } 9005 } 9006 9007 Intent createAppErrorIntentLocked(ProcessRecord r, 9008 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 9009 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 9010 if (report == null) { 9011 return null; 9012 } 9013 Intent result = new Intent(Intent.ACTION_APP_ERROR); 9014 result.setComponent(r.errorReportReceiver); 9015 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 9016 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 9017 return result; 9018 } 9019 9020 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 9021 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 9022 if (r.errorReportReceiver == null) { 9023 return null; 9024 } 9025 9026 if (!r.crashing && !r.notResponding) { 9027 return null; 9028 } 9029 9030 ApplicationErrorReport report = new ApplicationErrorReport(); 9031 report.packageName = r.info.packageName; 9032 report.installerPackageName = r.errorReportReceiver.getPackageName(); 9033 report.processName = r.processName; 9034 report.time = timeMillis; 9035 9036 if (r.crashing) { 9037 report.type = ApplicationErrorReport.TYPE_CRASH; 9038 report.crashInfo = crashInfo; 9039 } else if (r.notResponding) { 9040 report.type = ApplicationErrorReport.TYPE_ANR; 9041 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 9042 9043 report.anrInfo.activity = r.notRespondingReport.tag; 9044 report.anrInfo.cause = r.notRespondingReport.shortMsg; 9045 report.anrInfo.info = r.notRespondingReport.longMsg; 9046 } 9047 9048 return report; 9049 } 9050 9051 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 9052 // assume our apps are happy - lazy create the list 9053 List<ActivityManager.ProcessErrorStateInfo> errList = null; 9054 9055 synchronized (this) { 9056 9057 // iterate across all processes 9058 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9059 ProcessRecord app = mLruProcesses.get(i); 9060 if ((app.thread != null) && (app.crashing || app.notResponding)) { 9061 // This one's in trouble, so we'll generate a report for it 9062 // crashes are higher priority (in case there's a crash *and* an anr) 9063 ActivityManager.ProcessErrorStateInfo report = null; 9064 if (app.crashing) { 9065 report = app.crashingReport; 9066 } else if (app.notResponding) { 9067 report = app.notRespondingReport; 9068 } 9069 9070 if (report != null) { 9071 if (errList == null) { 9072 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 9073 } 9074 errList.add(report); 9075 } else { 9076 Log.w(TAG, "Missing app error report, app = " + app.processName + 9077 " crashing = " + app.crashing + 9078 " notResponding = " + app.notResponding); 9079 } 9080 } 9081 } 9082 } 9083 9084 return errList; 9085 } 9086 9087 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 9088 // Lazy instantiation of list 9089 List<ActivityManager.RunningAppProcessInfo> runList = null; 9090 synchronized (this) { 9091 // Iterate across all processes 9092 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9093 ProcessRecord app = mLruProcesses.get(i); 9094 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 9095 // Generate process state info for running application 9096 ActivityManager.RunningAppProcessInfo currApp = 9097 new ActivityManager.RunningAppProcessInfo(app.processName, 9098 app.pid, app.getPackageList()); 9099 currApp.uid = app.info.uid; 9100 int adj = app.curAdj; 9101 if (adj >= EMPTY_APP_ADJ) { 9102 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY; 9103 } else if (adj >= HIDDEN_APP_MIN_ADJ) { 9104 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 9105 currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1; 9106 } else if (adj >= HOME_APP_ADJ) { 9107 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 9108 currApp.lru = 0; 9109 } else if (adj >= SECONDARY_SERVER_ADJ) { 9110 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 9111 } else if (adj >= VISIBLE_APP_ADJ) { 9112 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 9113 } else { 9114 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 9115 } 9116 currApp.importanceReasonCode = app.adjTypeCode; 9117 if (app.adjSource instanceof ProcessRecord) { 9118 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 9119 } else if (app.adjSource instanceof HistoryRecord) { 9120 HistoryRecord r = (HistoryRecord)app.adjSource; 9121 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 9122 } 9123 if (app.adjTarget instanceof ComponentName) { 9124 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 9125 } 9126 //Log.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 9127 // + " lru=" + currApp.lru); 9128 if (runList == null) { 9129 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 9130 } 9131 runList.add(currApp); 9132 } 9133 } 9134 } 9135 return runList; 9136 } 9137 9138 @Override 9139 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 9140 if (checkCallingPermission(android.Manifest.permission.DUMP) 9141 != PackageManager.PERMISSION_GRANTED) { 9142 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 9143 + Binder.getCallingPid() 9144 + ", uid=" + Binder.getCallingUid() 9145 + " without permission " 9146 + android.Manifest.permission.DUMP); 9147 return; 9148 } 9149 9150 boolean dumpAll = false; 9151 9152 int opti = 0; 9153 while (opti < args.length) { 9154 String opt = args[opti]; 9155 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 9156 break; 9157 } 9158 opti++; 9159 if ("-a".equals(opt)) { 9160 dumpAll = true; 9161 } else if ("-h".equals(opt)) { 9162 pw.println("Activity manager dump options:"); 9163 pw.println(" [-a] [h- [cmd] ..."); 9164 pw.println(" cmd may be one of:"); 9165 pw.println(" activities: activity stack state"); 9166 pw.println(" broadcasts: broadcast state"); 9167 pw.println(" intents: pending intent state"); 9168 pw.println(" processes: process state"); 9169 pw.println(" providers: content provider state"); 9170 pw.println(" services: service state"); 9171 pw.println(" service [name]: service client-side state"); 9172 return; 9173 } else { 9174 pw.println("Unknown argument: " + opt + "; use -h for help"); 9175 } 9176 } 9177 9178 // Is the caller requesting to dump a particular piece of data? 9179 if (opti < args.length) { 9180 String cmd = args[opti]; 9181 opti++; 9182 if ("activities".equals(cmd) || "a".equals(cmd)) { 9183 synchronized (this) { 9184 dumpActivitiesLocked(fd, pw, args, opti, true, true); 9185 } 9186 return; 9187 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 9188 synchronized (this) { 9189 dumpBroadcastsLocked(fd, pw, args, opti, true); 9190 } 9191 return; 9192 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 9193 synchronized (this) { 9194 dumpPendingIntentsLocked(fd, pw, args, opti, true); 9195 } 9196 return; 9197 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 9198 synchronized (this) { 9199 dumpProcessesLocked(fd, pw, args, opti, true); 9200 } 9201 return; 9202 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 9203 synchronized (this) { 9204 dumpProvidersLocked(fd, pw, args, opti, true); 9205 } 9206 return; 9207 } else if ("service".equals(cmd)) { 9208 dumpService(fd, pw, args, opti, true); 9209 return; 9210 } else if ("services".equals(cmd) || "s".equals(cmd)) { 9211 synchronized (this) { 9212 dumpServicesLocked(fd, pw, args, opti, true); 9213 } 9214 return; 9215 } 9216 } 9217 9218 // No piece of data specified, dump everything. 9219 synchronized (this) { 9220 boolean needSep; 9221 if (dumpAll) { 9222 pw.println("Providers in Current Activity Manager State:"); 9223 } 9224 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll); 9225 if (needSep) { 9226 pw.println(" "); 9227 } 9228 if (dumpAll) { 9229 pw.println("-------------------------------------------------------------------------------"); 9230 pw.println("Broadcasts in Current Activity Manager State:"); 9231 } 9232 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll); 9233 if (needSep) { 9234 pw.println(" "); 9235 } 9236 if (dumpAll) { 9237 pw.println("-------------------------------------------------------------------------------"); 9238 pw.println("Services in Current Activity Manager State:"); 9239 } 9240 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll); 9241 if (needSep) { 9242 pw.println(" "); 9243 } 9244 if (dumpAll) { 9245 pw.println("-------------------------------------------------------------------------------"); 9246 pw.println("PendingIntents in Current Activity Manager State:"); 9247 } 9248 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll); 9249 if (needSep) { 9250 pw.println(" "); 9251 } 9252 if (dumpAll) { 9253 pw.println("-------------------------------------------------------------------------------"); 9254 pw.println("Activities in Current Activity Manager State:"); 9255 } 9256 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, !dumpAll); 9257 if (needSep) { 9258 pw.println(" "); 9259 } 9260 if (dumpAll) { 9261 pw.println("-------------------------------------------------------------------------------"); 9262 pw.println("Processes in Current Activity Manager State:"); 9263 } 9264 dumpProcessesLocked(fd, pw, args, opti, dumpAll); 9265 } 9266 } 9267 9268 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9269 int opti, boolean dumpAll, boolean needHeader) { 9270 if (needHeader) { 9271 pw.println(" Activity stack:"); 9272 } 9273 dumpHistoryList(pw, mHistory, " ", "Hist", true); 9274 pw.println(" "); 9275 pw.println(" Running activities (most recent first):"); 9276 dumpHistoryList(pw, mLRUActivities, " ", "Run", false); 9277 if (mWaitingVisibleActivities.size() > 0) { 9278 pw.println(" "); 9279 pw.println(" Activities waiting for another to become visible:"); 9280 dumpHistoryList(pw, mWaitingVisibleActivities, " ", "Wait", false); 9281 } 9282 if (mStoppingActivities.size() > 0) { 9283 pw.println(" "); 9284 pw.println(" Activities waiting to stop:"); 9285 dumpHistoryList(pw, mStoppingActivities, " ", "Stop", false); 9286 } 9287 if (mFinishingActivities.size() > 0) { 9288 pw.println(" "); 9289 pw.println(" Activities waiting to finish:"); 9290 dumpHistoryList(pw, mFinishingActivities, " ", "Fin", false); 9291 } 9292 9293 pw.println(" "); 9294 pw.println(" mPausingActivity: " + mPausingActivity); 9295 pw.println(" mResumedActivity: " + mResumedActivity); 9296 pw.println(" mFocusedActivity: " + mFocusedActivity); 9297 pw.println(" mLastPausedActivity: " + mLastPausedActivity); 9298 9299 if (dumpAll && mRecentTasks.size() > 0) { 9300 pw.println(" "); 9301 pw.println("Recent tasks in Current Activity Manager State:"); 9302 9303 final int N = mRecentTasks.size(); 9304 for (int i=0; i<N; i++) { 9305 TaskRecord tr = mRecentTasks.get(i); 9306 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 9307 pw.println(tr); 9308 mRecentTasks.get(i).dump(pw, " "); 9309 } 9310 } 9311 9312 pw.println(" "); 9313 pw.println(" mCurTask: " + mCurTask); 9314 9315 return true; 9316 } 9317 9318 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9319 int opti, boolean dumpAll) { 9320 boolean needSep = false; 9321 int numPers = 0; 9322 9323 if (dumpAll) { 9324 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 9325 final int NA = procs.size(); 9326 for (int ia=0; ia<NA; ia++) { 9327 if (!needSep) { 9328 pw.println(" All known processes:"); 9329 needSep = true; 9330 } 9331 ProcessRecord r = procs.valueAt(ia); 9332 pw.print(r.persistent ? " *PERS*" : " *APP*"); 9333 pw.print(" UID "); pw.print(procs.keyAt(ia)); 9334 pw.print(" "); pw.println(r); 9335 r.dump(pw, " "); 9336 if (r.persistent) { 9337 numPers++; 9338 } 9339 } 9340 } 9341 } 9342 9343 if (mLruProcesses.size() > 0) { 9344 if (needSep) pw.println(" "); 9345 needSep = true; 9346 pw.println(" Running processes (most recent first):"); 9347 dumpProcessList(pw, this, mLruProcesses, " ", 9348 "App ", "PERS", true); 9349 needSep = true; 9350 } 9351 9352 synchronized (mPidsSelfLocked) { 9353 if (mPidsSelfLocked.size() > 0) { 9354 if (needSep) pw.println(" "); 9355 needSep = true; 9356 pw.println(" PID mappings:"); 9357 for (int i=0; i<mPidsSelfLocked.size(); i++) { 9358 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 9359 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 9360 } 9361 } 9362 } 9363 9364 if (mForegroundProcesses.size() > 0) { 9365 if (needSep) pw.println(" "); 9366 needSep = true; 9367 pw.println(" Foreground Processes:"); 9368 for (int i=0; i<mForegroundProcesses.size(); i++) { 9369 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 9370 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 9371 } 9372 } 9373 9374 if (mPersistentStartingProcesses.size() > 0) { 9375 if (needSep) pw.println(" "); 9376 needSep = true; 9377 pw.println(" Persisent processes that are starting:"); 9378 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 9379 "Starting Norm", "Restarting PERS", false); 9380 } 9381 9382 if (mStartingProcesses.size() > 0) { 9383 if (needSep) pw.println(" "); 9384 needSep = true; 9385 pw.println(" Processes that are starting:"); 9386 dumpProcessList(pw, this, mStartingProcesses, " ", 9387 "Starting Norm", "Starting PERS", false); 9388 } 9389 9390 if (mRemovedProcesses.size() > 0) { 9391 if (needSep) pw.println(" "); 9392 needSep = true; 9393 pw.println(" Processes that are being removed:"); 9394 dumpProcessList(pw, this, mRemovedProcesses, " ", 9395 "Removed Norm", "Removed PERS", false); 9396 } 9397 9398 if (mProcessesOnHold.size() > 0) { 9399 if (needSep) pw.println(" "); 9400 needSep = true; 9401 pw.println(" Processes that are on old until the system is ready:"); 9402 dumpProcessList(pw, this, mProcessesOnHold, " ", 9403 "OnHold Norm", "OnHold PERS", false); 9404 } 9405 9406 if (mProcessesToGc.size() > 0) { 9407 if (needSep) pw.println(" "); 9408 needSep = true; 9409 pw.println(" Processes that are waiting to GC:"); 9410 long now = SystemClock.uptimeMillis(); 9411 for (int i=0; i<mProcessesToGc.size(); i++) { 9412 ProcessRecord proc = mProcessesToGc.get(i); 9413 pw.print(" Process "); pw.println(proc); 9414 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9415 pw.print(", last gced="); 9416 pw.print(now-proc.lastRequestedGc); 9417 pw.print(" ms ago, last lowMem="); 9418 pw.print(now-proc.lastLowMemory); 9419 pw.println(" ms ago"); 9420 9421 } 9422 } 9423 9424 if (mProcessCrashTimes.getMap().size() > 0) { 9425 if (needSep) pw.println(" "); 9426 needSep = true; 9427 pw.println(" Time since processes crashed:"); 9428 long now = SystemClock.uptimeMillis(); 9429 for (Map.Entry<String, SparseArray<Long>> procs 9430 : mProcessCrashTimes.getMap().entrySet()) { 9431 SparseArray<Long> uids = procs.getValue(); 9432 final int N = uids.size(); 9433 for (int i=0; i<N; i++) { 9434 pw.print(" Process "); pw.print(procs.getKey()); 9435 pw.print(" uid "); pw.print(uids.keyAt(i)); 9436 pw.print(": last crashed "); 9437 pw.print((now-uids.valueAt(i))); 9438 pw.println(" ms ago"); 9439 } 9440 } 9441 } 9442 9443 if (mBadProcesses.getMap().size() > 0) { 9444 if (needSep) pw.println(" "); 9445 needSep = true; 9446 pw.println(" Bad processes:"); 9447 for (Map.Entry<String, SparseArray<Long>> procs 9448 : mBadProcesses.getMap().entrySet()) { 9449 SparseArray<Long> uids = procs.getValue(); 9450 final int N = uids.size(); 9451 for (int i=0; i<N; i++) { 9452 pw.print(" Bad process "); pw.print(procs.getKey()); 9453 pw.print(" uid "); pw.print(uids.keyAt(i)); 9454 pw.print(": crashed at time "); 9455 pw.println(uids.valueAt(i)); 9456 } 9457 } 9458 } 9459 9460 pw.println(" "); 9461 pw.println(" mHomeProcess: " + mHomeProcess); 9462 pw.println(" mConfiguration: " + mConfiguration); 9463 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown); 9464 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9465 || mOrigWaitForDebugger) { 9466 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9467 + " mDebugTransient=" + mDebugTransient 9468 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9469 } 9470 if (mAlwaysFinishActivities || mController != null) { 9471 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9472 + " mController=" + mController); 9473 } 9474 if (dumpAll) { 9475 pw.println(" Total persistent processes: " + numPers); 9476 pw.println(" mStartRunning=" + mStartRunning 9477 + " mSystemReady=" + mSystemReady 9478 + " mBooting=" + mBooting 9479 + " mBooted=" + mBooted 9480 + " mFactoryTest=" + mFactoryTest); 9481 pw.println(" mGoingToSleep=" + mGoingToSleep); 9482 pw.println(" mLaunchingActivity=" + mLaunchingActivity); 9483 } 9484 9485 return true; 9486 } 9487 9488 /** 9489 * There are three ways to call this: 9490 * - no service specified: dump all the services 9491 * - a flattened component name that matched an existing service was specified as the 9492 * first arg: dump that one service 9493 * - the first arg isn't the flattened component name of an existing service: 9494 * dump all services whose component contains the first arg as a substring 9495 */ 9496 protected void dumpService(FileDescriptor fd, PrintWriter pw, String[] args, 9497 int opti, boolean dumpAll) { 9498 String[] newArgs; 9499 String componentNameString; 9500 ServiceRecord r; 9501 if (opti <= args.length) { 9502 componentNameString = null; 9503 newArgs = EMPTY_STRING_ARRAY; 9504 r = null; 9505 } else { 9506 componentNameString = args[opti]; 9507 opti++; 9508 ComponentName componentName = ComponentName.unflattenFromString(componentNameString); 9509 r = componentName != null ? mServices.get(componentName) : null; 9510 newArgs = new String[args.length - opti]; 9511 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9512 } 9513 9514 if (r != null) { 9515 dumpService(fd, pw, r, newArgs); 9516 } else { 9517 for (ServiceRecord r1 : mServices.values()) { 9518 if (componentNameString == null 9519 || r1.name.flattenToString().contains(componentNameString)) { 9520 dumpService(fd, pw, r1, newArgs); 9521 } 9522 } 9523 } 9524 } 9525 9526 /** 9527 * Invokes IApplicationThread.dumpService() on the thread of the specified service if 9528 * there is a thread associated with the service. 9529 */ 9530 private void dumpService(FileDescriptor fd, PrintWriter pw, ServiceRecord r, String[] args) { 9531 pw.println(" Service " + r.name.flattenToString()); 9532 if (r.app != null && r.app.thread != null) { 9533 try { 9534 // flush anything that is already in the PrintWriter since the thread is going 9535 // to write to the file descriptor directly 9536 pw.flush(); 9537 r.app.thread.dumpService(fd, r, args); 9538 pw.print("\n"); 9539 } catch (RemoteException e) { 9540 pw.println("got a RemoteException while dumping the service"); 9541 } 9542 } 9543 } 9544 9545 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9546 int opti, boolean dumpAll) { 9547 boolean needSep = false; 9548 9549 if (dumpAll) { 9550 if (mRegisteredReceivers.size() > 0) { 9551 pw.println(" "); 9552 pw.println(" Registered Receivers:"); 9553 Iterator it = mRegisteredReceivers.values().iterator(); 9554 while (it.hasNext()) { 9555 ReceiverList r = (ReceiverList)it.next(); 9556 pw.print(" * "); pw.println(r); 9557 r.dump(pw, " "); 9558 } 9559 } 9560 9561 pw.println(" "); 9562 pw.println("Receiver Resolver Table:"); 9563 mReceiverResolver.dump(pw, " "); 9564 needSep = true; 9565 } 9566 9567 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0 9568 || mPendingBroadcast != null) { 9569 if (mParallelBroadcasts.size() > 0) { 9570 pw.println(" "); 9571 pw.println(" Active broadcasts:"); 9572 } 9573 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) { 9574 pw.println(" Broadcast #" + i + ":"); 9575 mParallelBroadcasts.get(i).dump(pw, " "); 9576 } 9577 if (mOrderedBroadcasts.size() > 0) { 9578 pw.println(" "); 9579 pw.println(" Active serialized broadcasts:"); 9580 } 9581 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) { 9582 pw.println(" Serialized Broadcast #" + i + ":"); 9583 mOrderedBroadcasts.get(i).dump(pw, " "); 9584 } 9585 pw.println(" "); 9586 pw.println(" Pending broadcast:"); 9587 if (mPendingBroadcast != null) { 9588 mPendingBroadcast.dump(pw, " "); 9589 } else { 9590 pw.println(" (null)"); 9591 } 9592 needSep = true; 9593 } 9594 9595 if (dumpAll) { 9596 pw.println(" "); 9597 pw.println(" Historical broadcasts:"); 9598 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) { 9599 BroadcastRecord r = mBroadcastHistory[i]; 9600 if (r == null) { 9601 break; 9602 } 9603 pw.println(" Historical Broadcast #" + i + ":"); 9604 r.dump(pw, " "); 9605 } 9606 needSep = true; 9607 } 9608 9609 if (mStickyBroadcasts != null) { 9610 pw.println(" "); 9611 pw.println(" Sticky broadcasts:"); 9612 StringBuilder sb = new StringBuilder(128); 9613 for (Map.Entry<String, ArrayList<Intent>> ent 9614 : mStickyBroadcasts.entrySet()) { 9615 pw.print(" * Sticky action "); pw.print(ent.getKey()); 9616 pw.println(":"); 9617 ArrayList<Intent> intents = ent.getValue(); 9618 final int N = intents.size(); 9619 for (int i=0; i<N; i++) { 9620 sb.setLength(0); 9621 sb.append(" Intent: "); 9622 intents.get(i).toShortString(sb, true, false); 9623 pw.println(sb.toString()); 9624 Bundle bundle = intents.get(i).getExtras(); 9625 if (bundle != null) { 9626 pw.print(" "); 9627 pw.println(bundle.toString()); 9628 } 9629 } 9630 } 9631 needSep = true; 9632 } 9633 9634 if (dumpAll) { 9635 pw.println(" "); 9636 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled); 9637 pw.println(" mHandler:"); 9638 mHandler.dump(new PrintWriterPrinter(pw), " "); 9639 needSep = true; 9640 } 9641 9642 return needSep; 9643 } 9644 9645 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9646 int opti, boolean dumpAll) { 9647 boolean needSep = false; 9648 9649 if (dumpAll) { 9650 if (mServices.size() > 0) { 9651 pw.println(" Active services:"); 9652 Iterator<ServiceRecord> it = mServices.values().iterator(); 9653 while (it.hasNext()) { 9654 ServiceRecord r = it.next(); 9655 pw.print(" * "); pw.println(r); 9656 r.dump(pw, " "); 9657 } 9658 needSep = true; 9659 } 9660 } 9661 9662 if (mPendingServices.size() > 0) { 9663 if (needSep) pw.println(" "); 9664 pw.println(" Pending services:"); 9665 for (int i=0; i<mPendingServices.size(); i++) { 9666 ServiceRecord r = mPendingServices.get(i); 9667 pw.print(" * Pending "); pw.println(r); 9668 r.dump(pw, " "); 9669 } 9670 needSep = true; 9671 } 9672 9673 if (mRestartingServices.size() > 0) { 9674 if (needSep) pw.println(" "); 9675 pw.println(" Restarting services:"); 9676 for (int i=0; i<mRestartingServices.size(); i++) { 9677 ServiceRecord r = mRestartingServices.get(i); 9678 pw.print(" * Restarting "); pw.println(r); 9679 r.dump(pw, " "); 9680 } 9681 needSep = true; 9682 } 9683 9684 if (mStoppingServices.size() > 0) { 9685 if (needSep) pw.println(" "); 9686 pw.println(" Stopping services:"); 9687 for (int i=0; i<mStoppingServices.size(); i++) { 9688 ServiceRecord r = mStoppingServices.get(i); 9689 pw.print(" * Stopping "); pw.println(r); 9690 r.dump(pw, " "); 9691 } 9692 needSep = true; 9693 } 9694 9695 if (dumpAll) { 9696 if (mServiceConnections.size() > 0) { 9697 if (needSep) pw.println(" "); 9698 pw.println(" Connection bindings to services:"); 9699 Iterator<ConnectionRecord> it 9700 = mServiceConnections.values().iterator(); 9701 while (it.hasNext()) { 9702 ConnectionRecord r = it.next(); 9703 pw.print(" * "); pw.println(r); 9704 r.dump(pw, " "); 9705 } 9706 needSep = true; 9707 } 9708 } 9709 9710 return needSep; 9711 } 9712 9713 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9714 int opti, boolean dumpAll) { 9715 boolean needSep = false; 9716 9717 if (dumpAll) { 9718 if (mProvidersByClass.size() > 0) { 9719 if (needSep) pw.println(" "); 9720 pw.println(" Published content providers (by class):"); 9721 Iterator it = mProvidersByClass.entrySet().iterator(); 9722 while (it.hasNext()) { 9723 Map.Entry e = (Map.Entry)it.next(); 9724 ContentProviderRecord r = (ContentProviderRecord)e.getValue(); 9725 pw.print(" * "); pw.println(r); 9726 r.dump(pw, " "); 9727 } 9728 needSep = true; 9729 } 9730 9731 if (mProvidersByName.size() > 0) { 9732 pw.println(" "); 9733 pw.println(" Authority to provider mappings:"); 9734 Iterator it = mProvidersByName.entrySet().iterator(); 9735 while (it.hasNext()) { 9736 Map.Entry e = (Map.Entry)it.next(); 9737 ContentProviderRecord r = (ContentProviderRecord)e.getValue(); 9738 pw.print(" "); pw.print(e.getKey()); pw.print(": "); 9739 pw.println(r); 9740 } 9741 needSep = true; 9742 } 9743 } 9744 9745 if (mLaunchingProviders.size() > 0) { 9746 if (needSep) pw.println(" "); 9747 pw.println(" Launching content providers:"); 9748 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 9749 pw.print(" Launching #"); pw.print(i); pw.print(": "); 9750 pw.println(mLaunchingProviders.get(i)); 9751 } 9752 needSep = true; 9753 } 9754 9755 if (mGrantedUriPermissions.size() > 0) { 9756 pw.println(); 9757 pw.println("Granted Uri Permissions:"); 9758 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 9759 int uid = mGrantedUriPermissions.keyAt(i); 9760 HashMap<Uri, UriPermission> perms 9761 = mGrantedUriPermissions.valueAt(i); 9762 pw.print(" * UID "); pw.print(uid); 9763 pw.println(" holds:"); 9764 for (UriPermission perm : perms.values()) { 9765 pw.print(" "); pw.println(perm); 9766 perm.dump(pw, " "); 9767 } 9768 } 9769 needSep = true; 9770 } 9771 9772 return needSep; 9773 } 9774 9775 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9776 int opti, boolean dumpAll) { 9777 boolean needSep = false; 9778 9779 if (dumpAll) { 9780 if (this.mIntentSenderRecords.size() > 0) { 9781 Iterator<WeakReference<PendingIntentRecord>> it 9782 = mIntentSenderRecords.values().iterator(); 9783 while (it.hasNext()) { 9784 WeakReference<PendingIntentRecord> ref = it.next(); 9785 PendingIntentRecord rec = ref != null ? ref.get(): null; 9786 needSep = true; 9787 if (rec != null) { 9788 pw.print(" * "); pw.println(rec); 9789 rec.dump(pw, " "); 9790 } else { 9791 pw.print(" * "); pw.print(ref); 9792 } 9793 } 9794 } 9795 } 9796 9797 return needSep; 9798 } 9799 9800 private static final void dumpHistoryList(PrintWriter pw, List list, 9801 String prefix, String label, boolean complete) { 9802 TaskRecord lastTask = null; 9803 for (int i=list.size()-1; i>=0; i--) { 9804 HistoryRecord r = (HistoryRecord)list.get(i); 9805 final boolean full = complete || !r.inHistory; 9806 if (lastTask != r.task) { 9807 lastTask = r.task; 9808 pw.print(prefix); 9809 pw.print(full ? "* " : " "); 9810 pw.println(lastTask); 9811 if (full) { 9812 lastTask.dump(pw, prefix + " "); 9813 } 9814 } 9815 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 9816 pw.print(" #"); pw.print(i); pw.print(": "); 9817 pw.println(r); 9818 if (full) { 9819 r.dump(pw, prefix + " "); 9820 } 9821 } 9822 } 9823 9824 private static String buildOomTag(String prefix, String space, int val, int base) { 9825 if (val == base) { 9826 if (space == null) return prefix; 9827 return prefix + " "; 9828 } 9829 return prefix + "+" + Integer.toString(val-base); 9830 } 9831 9832 private static final int dumpProcessList(PrintWriter pw, 9833 ActivityManagerService service, List list, 9834 String prefix, String normalLabel, String persistentLabel, 9835 boolean inclOomAdj) { 9836 int numPers = 0; 9837 for (int i=list.size()-1; i>=0; i--) { 9838 ProcessRecord r = (ProcessRecord)list.get(i); 9839 if (false) { 9840 pw.println(prefix + (r.persistent ? persistentLabel : normalLabel) 9841 + " #" + i + ":"); 9842 r.dump(pw, prefix + " "); 9843 } else if (inclOomAdj) { 9844 String oomAdj; 9845 if (r.setAdj >= EMPTY_APP_ADJ) { 9846 oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ); 9847 } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) { 9848 oomAdj = buildOomTag("bak", " ", r.setAdj, HIDDEN_APP_MIN_ADJ); 9849 } else if (r.setAdj >= HOME_APP_ADJ) { 9850 oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ); 9851 } else if (r.setAdj >= SECONDARY_SERVER_ADJ) { 9852 oomAdj = buildOomTag("svc", " ", r.setAdj, SECONDARY_SERVER_ADJ); 9853 } else if (r.setAdj >= BACKUP_APP_ADJ) { 9854 oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ); 9855 } else if (r.setAdj >= VISIBLE_APP_ADJ) { 9856 oomAdj = buildOomTag("vis ", null, r.setAdj, VISIBLE_APP_ADJ); 9857 } else if (r.setAdj >= FOREGROUND_APP_ADJ) { 9858 oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ); 9859 } else if (r.setAdj >= CORE_SERVER_ADJ) { 9860 oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ); 9861 } else if (r.setAdj >= SYSTEM_ADJ) { 9862 oomAdj = buildOomTag("sys ", null, r.setAdj, SYSTEM_ADJ); 9863 } else { 9864 oomAdj = Integer.toString(r.setAdj); 9865 } 9866 String schedGroup; 9867 switch (r.setSchedGroup) { 9868 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 9869 schedGroup = "B"; 9870 break; 9871 case Process.THREAD_GROUP_DEFAULT: 9872 schedGroup = "F"; 9873 break; 9874 default: 9875 schedGroup = Integer.toString(r.setSchedGroup); 9876 break; 9877 } 9878 pw.println(String.format("%s%s #%2d: adj=%s/%s %s (%s)", 9879 prefix, (r.persistent ? persistentLabel : normalLabel), 9880 i, oomAdj, schedGroup, r.toShortString(), r.adjType)); 9881 if (r.adjSource != null || r.adjTarget != null) { 9882 pw.println(prefix + " " + r.adjTarget 9883 + "<=" + r.adjSource); 9884 } 9885 } else { 9886 pw.println(String.format("%s%s #%2d: %s", 9887 prefix, (r.persistent ? persistentLabel : normalLabel), 9888 i, r.toString())); 9889 } 9890 if (r.persistent) { 9891 numPers++; 9892 } 9893 } 9894 return numPers; 9895 } 9896 9897 private static final void dumpApplicationMemoryUsage(FileDescriptor fd, 9898 PrintWriter pw, List list, String prefix, String[] args) { 9899 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 9900 long uptime = SystemClock.uptimeMillis(); 9901 long realtime = SystemClock.elapsedRealtime(); 9902 9903 if (isCheckinRequest) { 9904 // short checkin version 9905 pw.println(uptime + "," + realtime); 9906 pw.flush(); 9907 } else { 9908 pw.println("Applications Memory Usage (kB):"); 9909 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 9910 } 9911 for (int i = list.size() - 1 ; i >= 0 ; i--) { 9912 ProcessRecord r = (ProcessRecord)list.get(i); 9913 if (r.thread != null) { 9914 if (!isCheckinRequest) { 9915 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 9916 pw.flush(); 9917 } 9918 try { 9919 r.thread.asBinder().dump(fd, args); 9920 } catch (RemoteException e) { 9921 if (!isCheckinRequest) { 9922 pw.println("Got RemoteException!"); 9923 pw.flush(); 9924 } 9925 } 9926 } 9927 } 9928 } 9929 9930 /** 9931 * Searches array of arguments for the specified string 9932 * @param args array of argument strings 9933 * @param value value to search for 9934 * @return true if the value is contained in the array 9935 */ 9936 private static boolean scanArgs(String[] args, String value) { 9937 if (args != null) { 9938 for (String arg : args) { 9939 if (value.equals(arg)) { 9940 return true; 9941 } 9942 } 9943 } 9944 return false; 9945 } 9946 9947 private final int indexOfTokenLocked(IBinder token) { 9948 int count = mHistory.size(); 9949 9950 // convert the token to an entry in the history. 9951 HistoryRecord r = null; 9952 int index = -1; 9953 for (int i=count-1; i>=0; i--) { 9954 Object o = mHistory.get(i); 9955 if (o == token) { 9956 r = (HistoryRecord)o; 9957 index = i; 9958 break; 9959 } 9960 } 9961 9962 return index; 9963 } 9964 9965 private final void killServicesLocked(ProcessRecord app, 9966 boolean allowRestart) { 9967 // Report disconnected services. 9968 if (false) { 9969 // XXX we are letting the client link to the service for 9970 // death notifications. 9971 if (app.services.size() > 0) { 9972 Iterator it = app.services.iterator(); 9973 while (it.hasNext()) { 9974 ServiceRecord r = (ServiceRecord)it.next(); 9975 if (r.connections.size() > 0) { 9976 Iterator<ConnectionRecord> jt 9977 = r.connections.values().iterator(); 9978 while (jt.hasNext()) { 9979 ConnectionRecord c = jt.next(); 9980 if (c.binding.client != app) { 9981 try { 9982 //c.conn.connected(r.className, null); 9983 } catch (Exception e) { 9984 // todo: this should be asynchronous! 9985 Log.w(TAG, "Exception thrown disconnected servce " 9986 + r.shortName 9987 + " from app " + app.processName, e); 9988 } 9989 } 9990 } 9991 } 9992 } 9993 } 9994 } 9995 9996 // Clean up any connections this application has to other services. 9997 if (app.connections.size() > 0) { 9998 Iterator<ConnectionRecord> it = app.connections.iterator(); 9999 while (it.hasNext()) { 10000 ConnectionRecord r = it.next(); 10001 removeConnectionLocked(r, app, null); 10002 } 10003 } 10004 app.connections.clear(); 10005 10006 if (app.services.size() != 0) { 10007 // Any services running in the application need to be placed 10008 // back in the pending list. 10009 Iterator it = app.services.iterator(); 10010 while (it.hasNext()) { 10011 ServiceRecord sr = (ServiceRecord)it.next(); 10012 synchronized (sr.stats.getBatteryStats()) { 10013 sr.stats.stopLaunchedLocked(); 10014 } 10015 sr.app = null; 10016 sr.executeNesting = 0; 10017 mStoppingServices.remove(sr); 10018 10019 boolean hasClients = sr.bindings.size() > 0; 10020 if (hasClients) { 10021 Iterator<IntentBindRecord> bindings 10022 = sr.bindings.values().iterator(); 10023 while (bindings.hasNext()) { 10024 IntentBindRecord b = bindings.next(); 10025 if (DEBUG_SERVICE) Log.v(TAG, "Killing binding " + b 10026 + ": shouldUnbind=" + b.hasBound); 10027 b.binder = null; 10028 b.requested = b.received = b.hasBound = false; 10029 } 10030 } 10031 10032 if (sr.crashCount >= 2) { 10033 Log.w(TAG, "Service crashed " + sr.crashCount 10034 + " times, stopping: " + sr); 10035 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH, 10036 sr.crashCount, sr.shortName, app.pid); 10037 bringDownServiceLocked(sr, true); 10038 } else if (!allowRestart) { 10039 bringDownServiceLocked(sr, true); 10040 } else { 10041 boolean canceled = scheduleServiceRestartLocked(sr, true); 10042 10043 // Should the service remain running? Note that in the 10044 // extreme case of so many attempts to deliver a command 10045 // that it failed, that we also will stop it here. 10046 if (sr.startRequested && (sr.stopIfKilled || canceled)) { 10047 if (sr.pendingStarts.size() == 0) { 10048 sr.startRequested = false; 10049 if (!hasClients) { 10050 // Whoops, no reason to restart! 10051 bringDownServiceLocked(sr, true); 10052 } 10053 } 10054 } 10055 } 10056 } 10057 10058 if (!allowRestart) { 10059 app.services.clear(); 10060 } 10061 } 10062 10063 // Make sure we have no more records on the stopping list. 10064 int i = mStoppingServices.size(); 10065 while (i > 0) { 10066 i--; 10067 ServiceRecord sr = mStoppingServices.get(i); 10068 if (sr.app == app) { 10069 mStoppingServices.remove(i); 10070 } 10071 } 10072 10073 app.executingServices.clear(); 10074 } 10075 10076 private final void removeDyingProviderLocked(ProcessRecord proc, 10077 ContentProviderRecord cpr) { 10078 synchronized (cpr) { 10079 cpr.launchingApp = null; 10080 cpr.notifyAll(); 10081 } 10082 10083 mProvidersByClass.remove(cpr.info.name); 10084 String names[] = cpr.info.authority.split(";"); 10085 for (int j = 0; j < names.length; j++) { 10086 mProvidersByName.remove(names[j]); 10087 } 10088 10089 Iterator<ProcessRecord> cit = cpr.clients.iterator(); 10090 while (cit.hasNext()) { 10091 ProcessRecord capp = cit.next(); 10092 if (!capp.persistent && capp.thread != null 10093 && capp.pid != 0 10094 && capp.pid != MY_PID) { 10095 Log.i(TAG, "Killing app " + capp.processName 10096 + " (pid " + capp.pid 10097 + ") because provider " + cpr.info.name 10098 + " is in dying process " + proc.processName); 10099 Process.killProcess(capp.pid); 10100 } 10101 } 10102 10103 mLaunchingProviders.remove(cpr); 10104 } 10105 10106 /** 10107 * Main code for cleaning up a process when it has gone away. This is 10108 * called both as a result of the process dying, or directly when stopping 10109 * a process when running in single process mode. 10110 */ 10111 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10112 boolean restarting, int index) { 10113 if (index >= 0) { 10114 mLruProcesses.remove(index); 10115 } 10116 10117 mProcessesToGc.remove(app); 10118 10119 // Dismiss any open dialogs. 10120 if (app.crashDialog != null) { 10121 app.crashDialog.dismiss(); 10122 app.crashDialog = null; 10123 } 10124 if (app.anrDialog != null) { 10125 app.anrDialog.dismiss(); 10126 app.anrDialog = null; 10127 } 10128 if (app.waitDialog != null) { 10129 app.waitDialog.dismiss(); 10130 app.waitDialog = null; 10131 } 10132 10133 app.crashing = false; 10134 app.notResponding = false; 10135 10136 app.resetPackageList(); 10137 app.thread = null; 10138 app.forcingToForeground = null; 10139 app.foregroundServices = false; 10140 10141 killServicesLocked(app, true); 10142 10143 boolean restart = false; 10144 10145 int NL = mLaunchingProviders.size(); 10146 10147 // Remove published content providers. 10148 if (!app.pubProviders.isEmpty()) { 10149 Iterator it = app.pubProviders.values().iterator(); 10150 while (it.hasNext()) { 10151 ContentProviderRecord cpr = (ContentProviderRecord)it.next(); 10152 cpr.provider = null; 10153 cpr.app = null; 10154 10155 // See if someone is waiting for this provider... in which 10156 // case we don't remove it, but just let it restart. 10157 int i = 0; 10158 if (!app.bad) { 10159 for (; i<NL; i++) { 10160 if (mLaunchingProviders.get(i) == cpr) { 10161 restart = true; 10162 break; 10163 } 10164 } 10165 } else { 10166 i = NL; 10167 } 10168 10169 if (i >= NL) { 10170 removeDyingProviderLocked(app, cpr); 10171 NL = mLaunchingProviders.size(); 10172 } 10173 } 10174 app.pubProviders.clear(); 10175 } 10176 10177 // Take care of any launching providers waiting for this process. 10178 if (checkAppInLaunchingProvidersLocked(app, false)) { 10179 restart = true; 10180 } 10181 10182 // Unregister from connected content providers. 10183 if (!app.conProviders.isEmpty()) { 10184 Iterator it = app.conProviders.keySet().iterator(); 10185 while (it.hasNext()) { 10186 ContentProviderRecord cpr = (ContentProviderRecord)it.next(); 10187 cpr.clients.remove(app); 10188 } 10189 app.conProviders.clear(); 10190 } 10191 10192 // At this point there may be remaining entries in mLaunchingProviders 10193 // where we were the only one waiting, so they are no longer of use. 10194 // Look for these and clean up if found. 10195 // XXX Commented out for now. Trying to figure out a way to reproduce 10196 // the actual situation to identify what is actually going on. 10197 if (false) { 10198 for (int i=0; i<NL; i++) { 10199 ContentProviderRecord cpr = (ContentProviderRecord) 10200 mLaunchingProviders.get(i); 10201 if (cpr.clients.size() <= 0 && cpr.externals <= 0) { 10202 synchronized (cpr) { 10203 cpr.launchingApp = null; 10204 cpr.notifyAll(); 10205 } 10206 } 10207 } 10208 } 10209 10210 skipCurrentReceiverLocked(app); 10211 10212 // Unregister any receivers. 10213 if (app.receivers.size() > 0) { 10214 Iterator<ReceiverList> it = app.receivers.iterator(); 10215 while (it.hasNext()) { 10216 removeReceiverLocked(it.next()); 10217 } 10218 app.receivers.clear(); 10219 } 10220 10221 // If the app is undergoing backup, tell the backup manager about it 10222 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10223 if (DEBUG_BACKUP) Log.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10224 try { 10225 IBackupManager bm = IBackupManager.Stub.asInterface( 10226 ServiceManager.getService(Context.BACKUP_SERVICE)); 10227 bm.agentDisconnected(app.info.packageName); 10228 } catch (RemoteException e) { 10229 // can't happen; backup manager is local 10230 } 10231 } 10232 10233 // If the caller is restarting this app, then leave it in its 10234 // current lists and let the caller take care of it. 10235 if (restarting) { 10236 return; 10237 } 10238 10239 if (!app.persistent) { 10240 if (DEBUG_PROCESSES) Log.v(TAG, 10241 "Removing non-persistent process during cleanup: " + app); 10242 mProcessNames.remove(app.processName, app.info.uid); 10243 } else if (!app.removed) { 10244 // This app is persistent, so we need to keep its record around. 10245 // If it is not already on the pending app list, add it there 10246 // and start a new process for it. 10247 app.thread = null; 10248 app.forcingToForeground = null; 10249 app.foregroundServices = false; 10250 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10251 mPersistentStartingProcesses.add(app); 10252 restart = true; 10253 } 10254 } 10255 mProcessesOnHold.remove(app); 10256 10257 if (app == mHomeProcess) { 10258 mHomeProcess = null; 10259 } 10260 10261 if (restart) { 10262 // We have components that still need to be running in the 10263 // process, so re-launch it. 10264 mProcessNames.put(app.processName, app.info.uid, app); 10265 startProcessLocked(app, "restart", app.processName); 10266 } else if (app.pid > 0 && app.pid != MY_PID) { 10267 // Goodbye! 10268 synchronized (mPidsSelfLocked) { 10269 mPidsSelfLocked.remove(app.pid); 10270 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10271 } 10272 app.setPid(0); 10273 } 10274 } 10275 10276 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10277 // Look through the content providers we are waiting to have launched, 10278 // and if any run in this process then either schedule a restart of 10279 // the process or kill the client waiting for it if this process has 10280 // gone bad. 10281 int NL = mLaunchingProviders.size(); 10282 boolean restart = false; 10283 for (int i=0; i<NL; i++) { 10284 ContentProviderRecord cpr = (ContentProviderRecord) 10285 mLaunchingProviders.get(i); 10286 if (cpr.launchingApp == app) { 10287 if (!alwaysBad && !app.bad) { 10288 restart = true; 10289 } else { 10290 removeDyingProviderLocked(app, cpr); 10291 NL = mLaunchingProviders.size(); 10292 } 10293 } 10294 } 10295 return restart; 10296 } 10297 10298 // ========================================================= 10299 // SERVICES 10300 // ========================================================= 10301 10302 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) { 10303 ActivityManager.RunningServiceInfo info = 10304 new ActivityManager.RunningServiceInfo(); 10305 info.service = r.name; 10306 if (r.app != null) { 10307 info.pid = r.app.pid; 10308 } 10309 info.uid = r.appInfo.uid; 10310 info.process = r.processName; 10311 info.foreground = r.isForeground; 10312 info.activeSince = r.createTime; 10313 info.started = r.startRequested; 10314 info.clientCount = r.connections.size(); 10315 info.crashCount = r.crashCount; 10316 info.lastActivityTime = r.lastActivity; 10317 if (r.isForeground) { 10318 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND; 10319 } 10320 if (r.startRequested) { 10321 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED; 10322 } 10323 if (r.app != null && r.app.pid == Process.myPid()) { 10324 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS; 10325 } 10326 if (r.app != null && r.app.persistent) { 10327 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS; 10328 } 10329 for (ConnectionRecord conn : r.connections.values()) { 10330 if (conn.clientLabel != 0) { 10331 info.clientPackage = conn.binding.client.info.packageName; 10332 info.clientLabel = conn.clientLabel; 10333 break; 10334 } 10335 } 10336 return info; 10337 } 10338 10339 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10340 int flags) { 10341 synchronized (this) { 10342 ArrayList<ActivityManager.RunningServiceInfo> res 10343 = new ArrayList<ActivityManager.RunningServiceInfo>(); 10344 10345 if (mServices.size() > 0) { 10346 Iterator<ServiceRecord> it = mServices.values().iterator(); 10347 while (it.hasNext() && res.size() < maxNum) { 10348 res.add(makeRunningServiceInfoLocked(it.next())); 10349 } 10350 } 10351 10352 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) { 10353 ServiceRecord r = mRestartingServices.get(i); 10354 ActivityManager.RunningServiceInfo info = 10355 makeRunningServiceInfoLocked(r); 10356 info.restarting = r.nextRestartTime; 10357 res.add(info); 10358 } 10359 10360 return res; 10361 } 10362 } 10363 10364 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10365 synchronized (this) { 10366 ServiceRecord r = mServices.get(name); 10367 if (r != null) { 10368 for (ConnectionRecord conn : r.connections.values()) { 10369 if (conn.clientIntent != null) { 10370 return conn.clientIntent; 10371 } 10372 } 10373 } 10374 } 10375 return null; 10376 } 10377 10378 private final ServiceRecord findServiceLocked(ComponentName name, 10379 IBinder token) { 10380 ServiceRecord r = mServices.get(name); 10381 return r == token ? r : null; 10382 } 10383 10384 private final class ServiceLookupResult { 10385 final ServiceRecord record; 10386 final String permission; 10387 10388 ServiceLookupResult(ServiceRecord _record, String _permission) { 10389 record = _record; 10390 permission = _permission; 10391 } 10392 }; 10393 10394 private ServiceLookupResult findServiceLocked(Intent service, 10395 String resolvedType) { 10396 ServiceRecord r = null; 10397 if (service.getComponent() != null) { 10398 r = mServices.get(service.getComponent()); 10399 } 10400 if (r == null) { 10401 Intent.FilterComparison filter = new Intent.FilterComparison(service); 10402 r = mServicesByIntent.get(filter); 10403 } 10404 10405 if (r == null) { 10406 try { 10407 ResolveInfo rInfo = 10408 ActivityThread.getPackageManager().resolveService( 10409 service, resolvedType, 0); 10410 ServiceInfo sInfo = 10411 rInfo != null ? rInfo.serviceInfo : null; 10412 if (sInfo == null) { 10413 return null; 10414 } 10415 10416 ComponentName name = new ComponentName( 10417 sInfo.applicationInfo.packageName, sInfo.name); 10418 r = mServices.get(name); 10419 } catch (RemoteException ex) { 10420 // pm is in same process, this will never happen. 10421 } 10422 } 10423 if (r != null) { 10424 int callingPid = Binder.getCallingPid(); 10425 int callingUid = Binder.getCallingUid(); 10426 if (checkComponentPermission(r.permission, 10427 callingPid, callingUid, r.exported ? -1 : r.appInfo.uid) 10428 != PackageManager.PERMISSION_GRANTED) { 10429 Log.w(TAG, "Permission Denial: Accessing service " + r.name 10430 + " from pid=" + callingPid 10431 + ", uid=" + callingUid 10432 + " requires " + r.permission); 10433 return new ServiceLookupResult(null, r.permission); 10434 } 10435 return new ServiceLookupResult(r, null); 10436 } 10437 return null; 10438 } 10439 10440 private class ServiceRestarter implements Runnable { 10441 private ServiceRecord mService; 10442 10443 void setService(ServiceRecord service) { 10444 mService = service; 10445 } 10446 10447 public void run() { 10448 synchronized(ActivityManagerService.this) { 10449 performServiceRestartLocked(mService); 10450 } 10451 } 10452 } 10453 10454 private ServiceLookupResult retrieveServiceLocked(Intent service, 10455 String resolvedType, int callingPid, int callingUid) { 10456 ServiceRecord r = null; 10457 if (service.getComponent() != null) { 10458 r = mServices.get(service.getComponent()); 10459 } 10460 Intent.FilterComparison filter = new Intent.FilterComparison(service); 10461 r = mServicesByIntent.get(filter); 10462 if (r == null) { 10463 try { 10464 ResolveInfo rInfo = 10465 ActivityThread.getPackageManager().resolveService( 10466 service, resolvedType, STOCK_PM_FLAGS); 10467 ServiceInfo sInfo = 10468 rInfo != null ? rInfo.serviceInfo : null; 10469 if (sInfo == null) { 10470 Log.w(TAG, "Unable to start service " + service + 10471 ": not found"); 10472 return null; 10473 } 10474 10475 ComponentName name = new ComponentName( 10476 sInfo.applicationInfo.packageName, sInfo.name); 10477 r = mServices.get(name); 10478 if (r == null) { 10479 filter = new Intent.FilterComparison(service.cloneFilter()); 10480 ServiceRestarter res = new ServiceRestarter(); 10481 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10482 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10483 synchronized (stats) { 10484 ss = stats.getServiceStatsLocked( 10485 sInfo.applicationInfo.uid, sInfo.packageName, 10486 sInfo.name); 10487 } 10488 r = new ServiceRecord(ss, name, filter, sInfo, res); 10489 res.setService(r); 10490 mServices.put(name, r); 10491 mServicesByIntent.put(filter, r); 10492 10493 // Make sure this component isn't in the pending list. 10494 int N = mPendingServices.size(); 10495 for (int i=0; i<N; i++) { 10496 ServiceRecord pr = mPendingServices.get(i); 10497 if (pr.name.equals(name)) { 10498 mPendingServices.remove(i); 10499 i--; 10500 N--; 10501 } 10502 } 10503 } 10504 } catch (RemoteException ex) { 10505 // pm is in same process, this will never happen. 10506 } 10507 } 10508 if (r != null) { 10509 if (checkComponentPermission(r.permission, 10510 callingPid, callingUid, r.exported ? -1 : r.appInfo.uid) 10511 != PackageManager.PERMISSION_GRANTED) { 10512 Log.w(TAG, "Permission Denial: Accessing service " + r.name 10513 + " from pid=" + Binder.getCallingPid() 10514 + ", uid=" + Binder.getCallingUid() 10515 + " requires " + r.permission); 10516 return new ServiceLookupResult(null, r.permission); 10517 } 10518 return new ServiceLookupResult(r, null); 10519 } 10520 return null; 10521 } 10522 10523 private final void bumpServiceExecutingLocked(ServiceRecord r) { 10524 long now = SystemClock.uptimeMillis(); 10525 if (r.executeNesting == 0 && r.app != null) { 10526 if (r.app.executingServices.size() == 0) { 10527 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 10528 msg.obj = r.app; 10529 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT); 10530 } 10531 r.app.executingServices.add(r); 10532 } 10533 r.executeNesting++; 10534 r.executingStart = now; 10535 } 10536 10537 private final void sendServiceArgsLocked(ServiceRecord r, 10538 boolean oomAdjusted) { 10539 final int N = r.pendingStarts.size(); 10540 if (N == 0) { 10541 return; 10542 } 10543 10544 int i = 0; 10545 while (i < N) { 10546 try { 10547 ServiceRecord.StartItem si = r.pendingStarts.get(i); 10548 if (DEBUG_SERVICE) Log.v(TAG, "Sending arguments to service: " 10549 + r.name + " " + r.intent + " args=" + si.intent); 10550 if (si.intent == null && N > 1) { 10551 // If somehow we got a dummy start at the front, then 10552 // just drop it here. 10553 i++; 10554 continue; 10555 } 10556 bumpServiceExecutingLocked(r); 10557 if (!oomAdjusted) { 10558 oomAdjusted = true; 10559 updateOomAdjLocked(r.app); 10560 } 10561 int flags = 0; 10562 if (si.deliveryCount > 0) { 10563 flags |= Service.START_FLAG_RETRY; 10564 } 10565 if (si.doneExecutingCount > 0) { 10566 flags |= Service.START_FLAG_REDELIVERY; 10567 } 10568 r.app.thread.scheduleServiceArgs(r, si.id, flags, si.intent); 10569 si.deliveredTime = SystemClock.uptimeMillis(); 10570 r.deliveredStarts.add(si); 10571 si.deliveryCount++; 10572 i++; 10573 } catch (RemoteException e) { 10574 // Remote process gone... we'll let the normal cleanup take 10575 // care of this. 10576 break; 10577 } catch (Exception e) { 10578 Log.w(TAG, "Unexpected exception", e); 10579 break; 10580 } 10581 } 10582 if (i == N) { 10583 r.pendingStarts.clear(); 10584 } else { 10585 while (i > 0) { 10586 i--; 10587 r.pendingStarts.remove(i); 10588 } 10589 } 10590 } 10591 10592 private final boolean requestServiceBindingLocked(ServiceRecord r, 10593 IntentBindRecord i, boolean rebind) { 10594 if (r.app == null || r.app.thread == null) { 10595 // If service is not currently running, can't yet bind. 10596 return false; 10597 } 10598 if ((!i.requested || rebind) && i.apps.size() > 0) { 10599 try { 10600 bumpServiceExecutingLocked(r); 10601 if (DEBUG_SERVICE) Log.v(TAG, "Connecting binding " + i 10602 + ": shouldUnbind=" + i.hasBound); 10603 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind); 10604 if (!rebind) { 10605 i.requested = true; 10606 } 10607 i.hasBound = true; 10608 i.doRebind = false; 10609 } catch (RemoteException e) { 10610 return false; 10611 } 10612 } 10613 return true; 10614 } 10615 10616 private final void requestServiceBindingsLocked(ServiceRecord r) { 10617 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator(); 10618 while (bindings.hasNext()) { 10619 IntentBindRecord i = bindings.next(); 10620 if (!requestServiceBindingLocked(r, i, false)) { 10621 break; 10622 } 10623 } 10624 } 10625 10626 private final void realStartServiceLocked(ServiceRecord r, 10627 ProcessRecord app) throws RemoteException { 10628 if (app.thread == null) { 10629 throw new RemoteException(); 10630 } 10631 10632 r.app = app; 10633 r.restartTime = r.lastActivity = SystemClock.uptimeMillis(); 10634 10635 app.services.add(r); 10636 bumpServiceExecutingLocked(r); 10637 updateLruProcessLocked(app, true, true); 10638 10639 boolean created = false; 10640 try { 10641 if (DEBUG_SERVICE) Log.v(TAG, "Scheduling start service: " 10642 + r.name + " " + r.intent); 10643 mStringBuilder.setLength(0); 10644 r.intent.getIntent().toShortString(mStringBuilder, false, true); 10645 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE, 10646 System.identityHashCode(r), r.shortName, 10647 mStringBuilder.toString(), r.app.pid); 10648 synchronized (r.stats.getBatteryStats()) { 10649 r.stats.startLaunchedLocked(); 10650 } 10651 ensurePackageDexOpt(r.serviceInfo.packageName); 10652 app.thread.scheduleCreateService(r, r.serviceInfo); 10653 r.postNotification(); 10654 created = true; 10655 } finally { 10656 if (!created) { 10657 app.services.remove(r); 10658 scheduleServiceRestartLocked(r, false); 10659 } 10660 } 10661 10662 requestServiceBindingsLocked(r); 10663 10664 // If the service is in the started state, and there are no 10665 // pending arguments, then fake up one so its onStartCommand() will 10666 // be called. 10667 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) { 10668 r.lastStartId++; 10669 if (r.lastStartId < 1) { 10670 r.lastStartId = 1; 10671 } 10672 r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, null)); 10673 } 10674 10675 sendServiceArgsLocked(r, true); 10676 } 10677 10678 private final boolean scheduleServiceRestartLocked(ServiceRecord r, 10679 boolean allowCancel) { 10680 boolean canceled = false; 10681 10682 final long now = SystemClock.uptimeMillis(); 10683 long minDuration = SERVICE_RESTART_DURATION; 10684 long resetTime = SERVICE_RESET_RUN_DURATION; 10685 10686 // Any delivered but not yet finished starts should be put back 10687 // on the pending list. 10688 final int N = r.deliveredStarts.size(); 10689 if (N > 0) { 10690 for (int i=N-1; i>=0; i--) { 10691 ServiceRecord.StartItem si = r.deliveredStarts.get(i); 10692 if (si.intent == null) { 10693 // We'll generate this again if needed. 10694 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT 10695 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) { 10696 r.pendingStarts.add(0, si); 10697 long dur = SystemClock.uptimeMillis() - si.deliveredTime; 10698 dur *= 2; 10699 if (minDuration < dur) minDuration = dur; 10700 if (resetTime < dur) resetTime = dur; 10701 } else { 10702 Log.w(TAG, "Canceling start item " + si.intent + " in service " 10703 + r.name); 10704 canceled = true; 10705 } 10706 } 10707 r.deliveredStarts.clear(); 10708 } 10709 10710 r.totalRestartCount++; 10711 if (r.restartDelay == 0) { 10712 r.restartCount++; 10713 r.restartDelay = minDuration; 10714 } else { 10715 // If it has been a "reasonably long time" since the service 10716 // was started, then reset our restart duration back to 10717 // the beginning, so we don't infinitely increase the duration 10718 // on a service that just occasionally gets killed (which is 10719 // a normal case, due to process being killed to reclaim memory). 10720 if (now > (r.restartTime+resetTime)) { 10721 r.restartCount = 1; 10722 r.restartDelay = minDuration; 10723 } else { 10724 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR; 10725 if (r.restartDelay < minDuration) { 10726 r.restartDelay = minDuration; 10727 } 10728 } 10729 } 10730 10731 r.nextRestartTime = now + r.restartDelay; 10732 10733 // Make sure that we don't end up restarting a bunch of services 10734 // all at the same time. 10735 boolean repeat; 10736 do { 10737 repeat = false; 10738 for (int i=mRestartingServices.size()-1; i>=0; i--) { 10739 ServiceRecord r2 = mRestartingServices.get(i); 10740 if (r2 != r && r.nextRestartTime 10741 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN) 10742 && r.nextRestartTime 10743 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) { 10744 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN; 10745 r.restartDelay = r.nextRestartTime - now; 10746 repeat = true; 10747 break; 10748 } 10749 } 10750 } while (repeat); 10751 10752 if (!mRestartingServices.contains(r)) { 10753 mRestartingServices.add(r); 10754 } 10755 10756 r.cancelNotification(); 10757 10758 mHandler.removeCallbacks(r.restarter); 10759 mHandler.postAtTime(r.restarter, r.nextRestartTime); 10760 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay; 10761 Log.w(TAG, "Scheduling restart of crashed service " 10762 + r.shortName + " in " + r.restartDelay + "ms"); 10763 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART, 10764 r.shortName, r.restartDelay); 10765 10766 Message msg = Message.obtain(); 10767 msg.what = SERVICE_ERROR_MSG; 10768 msg.obj = r; 10769 mHandler.sendMessage(msg); 10770 10771 return canceled; 10772 } 10773 10774 final void performServiceRestartLocked(ServiceRecord r) { 10775 if (!mRestartingServices.contains(r)) { 10776 return; 10777 } 10778 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true); 10779 } 10780 10781 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) { 10782 if (r.restartDelay == 0) { 10783 return false; 10784 } 10785 r.resetRestartCounter(); 10786 mRestartingServices.remove(r); 10787 mHandler.removeCallbacks(r.restarter); 10788 return true; 10789 } 10790 10791 private final boolean bringUpServiceLocked(ServiceRecord r, 10792 int intentFlags, boolean whileRestarting) { 10793 //Log.i(TAG, "Bring up service:"); 10794 //r.dump(" "); 10795 10796 if (r.app != null && r.app.thread != null) { 10797 sendServiceArgsLocked(r, false); 10798 return true; 10799 } 10800 10801 if (!whileRestarting && r.restartDelay > 0) { 10802 // If waiting for a restart, then do nothing. 10803 return true; 10804 } 10805 10806 if (DEBUG_SERVICE) Log.v(TAG, "Bringing up service " + r.name 10807 + " " + r.intent); 10808 10809 // We are now bringing the service up, so no longer in the 10810 // restarting state. 10811 mRestartingServices.remove(r); 10812 10813 final String appName = r.processName; 10814 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid); 10815 if (app != null && app.thread != null) { 10816 try { 10817 realStartServiceLocked(r, app); 10818 return true; 10819 } catch (RemoteException e) { 10820 Log.w(TAG, "Exception when starting service " + r.shortName, e); 10821 } 10822 10823 // If a dead object exception was thrown -- fall through to 10824 // restart the application. 10825 } 10826 10827 // Not running -- get it started, and enqueue this service record 10828 // to be executed when the app comes up. 10829 if (startProcessLocked(appName, r.appInfo, true, intentFlags, 10830 "service", r.name, false) == null) { 10831 Log.w(TAG, "Unable to launch app " 10832 + r.appInfo.packageName + "/" 10833 + r.appInfo.uid + " for service " 10834 + r.intent.getIntent() + ": process is bad"); 10835 bringDownServiceLocked(r, true); 10836 return false; 10837 } 10838 10839 if (!mPendingServices.contains(r)) { 10840 mPendingServices.add(r); 10841 } 10842 10843 return true; 10844 } 10845 10846 private final void bringDownServiceLocked(ServiceRecord r, boolean force) { 10847 //Log.i(TAG, "Bring down service:"); 10848 //r.dump(" "); 10849 10850 // Does it still need to run? 10851 if (!force && r.startRequested) { 10852 return; 10853 } 10854 if (r.connections.size() > 0) { 10855 if (!force) { 10856 // XXX should probably keep a count of the number of auto-create 10857 // connections directly in the service. 10858 Iterator<ConnectionRecord> it = r.connections.values().iterator(); 10859 while (it.hasNext()) { 10860 ConnectionRecord cr = it.next(); 10861 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) { 10862 return; 10863 } 10864 } 10865 } 10866 10867 // Report to all of the connections that the service is no longer 10868 // available. 10869 Iterator<ConnectionRecord> it = r.connections.values().iterator(); 10870 while (it.hasNext()) { 10871 ConnectionRecord c = it.next(); 10872 try { 10873 // todo: shouldn't be a synchronous call! 10874 c.conn.connected(r.name, null); 10875 } catch (Exception e) { 10876 Log.w(TAG, "Failure disconnecting service " + r.name + 10877 " to connection " + c.conn.asBinder() + 10878 " (in " + c.binding.client.processName + ")", e); 10879 } 10880 } 10881 } 10882 10883 // Tell the service that it has been unbound. 10884 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) { 10885 Iterator<IntentBindRecord> it = r.bindings.values().iterator(); 10886 while (it.hasNext()) { 10887 IntentBindRecord ibr = it.next(); 10888 if (DEBUG_SERVICE) Log.v(TAG, "Bringing down binding " + ibr 10889 + ": hasBound=" + ibr.hasBound); 10890 if (r.app != null && r.app.thread != null && ibr.hasBound) { 10891 try { 10892 bumpServiceExecutingLocked(r); 10893 updateOomAdjLocked(r.app); 10894 ibr.hasBound = false; 10895 r.app.thread.scheduleUnbindService(r, 10896 ibr.intent.getIntent()); 10897 } catch (Exception e) { 10898 Log.w(TAG, "Exception when unbinding service " 10899 + r.shortName, e); 10900 serviceDoneExecutingLocked(r, true); 10901 } 10902 } 10903 } 10904 } 10905 10906 if (DEBUG_SERVICE) Log.v(TAG, "Bringing down service " + r.name 10907 + " " + r.intent); 10908 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE, 10909 System.identityHashCode(r), r.shortName, 10910 (r.app != null) ? r.app.pid : -1); 10911 10912 mServices.remove(r.name); 10913 mServicesByIntent.remove(r.intent); 10914 if (localLOGV) Log.v(TAG, "BRING DOWN SERVICE: " + r.shortName); 10915 r.totalRestartCount = 0; 10916 unscheduleServiceRestartLocked(r); 10917 10918 // Also make sure it is not on the pending list. 10919 int N = mPendingServices.size(); 10920 for (int i=0; i<N; i++) { 10921 if (mPendingServices.get(i) == r) { 10922 mPendingServices.remove(i); 10923 if (DEBUG_SERVICE) Log.v( 10924 TAG, "Removed pending service: " + r.shortName); 10925 i--; 10926 N--; 10927 } 10928 } 10929 10930 r.cancelNotification(); 10931 r.isForeground = false; 10932 r.foregroundId = 0; 10933 r.foregroundNoti = null; 10934 10935 // Clear start entries. 10936 r.deliveredStarts.clear(); 10937 r.pendingStarts.clear(); 10938 10939 if (r.app != null) { 10940 synchronized (r.stats.getBatteryStats()) { 10941 r.stats.stopLaunchedLocked(); 10942 } 10943 r.app.services.remove(r); 10944 if (r.app.thread != null) { 10945 try { 10946 if (DEBUG_SERVICE) Log.v(TAG, 10947 "Stopping service: " + r.shortName); 10948 bumpServiceExecutingLocked(r); 10949 mStoppingServices.add(r); 10950 updateOomAdjLocked(r.app); 10951 r.app.thread.scheduleStopService(r); 10952 } catch (Exception e) { 10953 Log.w(TAG, "Exception when stopping service " 10954 + r.shortName, e); 10955 serviceDoneExecutingLocked(r, true); 10956 } 10957 updateServiceForegroundLocked(r.app, false); 10958 } else { 10959 if (DEBUG_SERVICE) Log.v( 10960 TAG, "Removed service that has no process: " + r.shortName); 10961 } 10962 } else { 10963 if (DEBUG_SERVICE) Log.v( 10964 TAG, "Removed service that is not running: " + r.shortName); 10965 } 10966 } 10967 10968 ComponentName startServiceLocked(IApplicationThread caller, 10969 Intent service, String resolvedType, 10970 int callingPid, int callingUid) { 10971 synchronized(this) { 10972 if (DEBUG_SERVICE) Log.v(TAG, "startService: " + service 10973 + " type=" + resolvedType + " args=" + service.getExtras()); 10974 10975 if (caller != null) { 10976 final ProcessRecord callerApp = getRecordForAppLocked(caller); 10977 if (callerApp == null) { 10978 throw new SecurityException( 10979 "Unable to find app for caller " + caller 10980 + " (pid=" + Binder.getCallingPid() 10981 + ") when starting service " + service); 10982 } 10983 } 10984 10985 ServiceLookupResult res = 10986 retrieveServiceLocked(service, resolvedType, 10987 callingPid, callingUid); 10988 if (res == null) { 10989 return null; 10990 } 10991 if (res.record == null) { 10992 return new ComponentName("!", res.permission != null 10993 ? res.permission : "private to package"); 10994 } 10995 ServiceRecord r = res.record; 10996 if (unscheduleServiceRestartLocked(r)) { 10997 if (DEBUG_SERVICE) Log.v(TAG, "START SERVICE WHILE RESTART PENDING: " 10998 + r.shortName); 10999 } 11000 r.startRequested = true; 11001 r.callStart = false; 11002 r.lastStartId++; 11003 if (r.lastStartId < 1) { 11004 r.lastStartId = 1; 11005 } 11006 r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, service)); 11007 r.lastActivity = SystemClock.uptimeMillis(); 11008 synchronized (r.stats.getBatteryStats()) { 11009 r.stats.startRunningLocked(); 11010 } 11011 if (!bringUpServiceLocked(r, service.getFlags(), false)) { 11012 return new ComponentName("!", "Service process is bad"); 11013 } 11014 return r.name; 11015 } 11016 } 11017 11018 public ComponentName startService(IApplicationThread caller, Intent service, 11019 String resolvedType) { 11020 // Refuse possible leaked file descriptors 11021 if (service != null && service.hasFileDescriptors() == true) { 11022 throw new IllegalArgumentException("File descriptors passed in Intent"); 11023 } 11024 11025 synchronized(this) { 11026 final int callingPid = Binder.getCallingPid(); 11027 final int callingUid = Binder.getCallingUid(); 11028 final long origId = Binder.clearCallingIdentity(); 11029 ComponentName res = startServiceLocked(caller, service, 11030 resolvedType, callingPid, callingUid); 11031 Binder.restoreCallingIdentity(origId); 11032 return res; 11033 } 11034 } 11035 11036 ComponentName startServiceInPackage(int uid, 11037 Intent service, String resolvedType) { 11038 synchronized(this) { 11039 final long origId = Binder.clearCallingIdentity(); 11040 ComponentName res = startServiceLocked(null, service, 11041 resolvedType, -1, uid); 11042 Binder.restoreCallingIdentity(origId); 11043 return res; 11044 } 11045 } 11046 11047 public int stopService(IApplicationThread caller, Intent service, 11048 String resolvedType) { 11049 // Refuse possible leaked file descriptors 11050 if (service != null && service.hasFileDescriptors() == true) { 11051 throw new IllegalArgumentException("File descriptors passed in Intent"); 11052 } 11053 11054 synchronized(this) { 11055 if (DEBUG_SERVICE) Log.v(TAG, "stopService: " + service 11056 + " type=" + resolvedType); 11057 11058 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11059 if (caller != null && callerApp == null) { 11060 throw new SecurityException( 11061 "Unable to find app for caller " + caller 11062 + " (pid=" + Binder.getCallingPid() 11063 + ") when stopping service " + service); 11064 } 11065 11066 // If this service is active, make sure it is stopped. 11067 ServiceLookupResult r = findServiceLocked(service, resolvedType); 11068 if (r != null) { 11069 if (r.record != null) { 11070 synchronized (r.record.stats.getBatteryStats()) { 11071 r.record.stats.stopRunningLocked(); 11072 } 11073 r.record.startRequested = false; 11074 r.record.callStart = false; 11075 final long origId = Binder.clearCallingIdentity(); 11076 bringDownServiceLocked(r.record, false); 11077 Binder.restoreCallingIdentity(origId); 11078 return 1; 11079 } 11080 return -1; 11081 } 11082 } 11083 11084 return 0; 11085 } 11086 11087 public IBinder peekService(Intent service, String resolvedType) { 11088 // Refuse possible leaked file descriptors 11089 if (service != null && service.hasFileDescriptors() == true) { 11090 throw new IllegalArgumentException("File descriptors passed in Intent"); 11091 } 11092 11093 IBinder ret = null; 11094 11095 synchronized(this) { 11096 ServiceLookupResult r = findServiceLocked(service, resolvedType); 11097 11098 if (r != null) { 11099 // r.record is null if findServiceLocked() failed the caller permission check 11100 if (r.record == null) { 11101 throw new SecurityException( 11102 "Permission Denial: Accessing service " + r.record.name 11103 + " from pid=" + Binder.getCallingPid() 11104 + ", uid=" + Binder.getCallingUid() 11105 + " requires " + r.permission); 11106 } 11107 IntentBindRecord ib = r.record.bindings.get(r.record.intent); 11108 if (ib != null) { 11109 ret = ib.binder; 11110 } 11111 } 11112 } 11113 11114 return ret; 11115 } 11116 11117 public boolean stopServiceToken(ComponentName className, IBinder token, 11118 int startId) { 11119 synchronized(this) { 11120 if (DEBUG_SERVICE) Log.v(TAG, "stopServiceToken: " + className 11121 + " " + token + " startId=" + startId); 11122 ServiceRecord r = findServiceLocked(className, token); 11123 if (r != null) { 11124 if (startId >= 0) { 11125 // Asked to only stop if done with all work. Note that 11126 // to avoid leaks, we will take this as dropping all 11127 // start items up to and including this one. 11128 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 11129 if (si != null) { 11130 while (r.deliveredStarts.size() > 0) { 11131 if (r.deliveredStarts.remove(0) == si) { 11132 break; 11133 } 11134 } 11135 } 11136 11137 if (r.lastStartId != startId) { 11138 return false; 11139 } 11140 11141 if (r.deliveredStarts.size() > 0) { 11142 Log.w(TAG, "stopServiceToken startId " + startId 11143 + " is last, but have " + r.deliveredStarts.size() 11144 + " remaining args"); 11145 } 11146 } 11147 11148 synchronized (r.stats.getBatteryStats()) { 11149 r.stats.stopRunningLocked(); 11150 r.startRequested = false; 11151 r.callStart = false; 11152 } 11153 final long origId = Binder.clearCallingIdentity(); 11154 bringDownServiceLocked(r, false); 11155 Binder.restoreCallingIdentity(origId); 11156 return true; 11157 } 11158 } 11159 return false; 11160 } 11161 11162 public void setServiceForeground(ComponentName className, IBinder token, 11163 int id, Notification notification, boolean removeNotification) { 11164 final long origId = Binder.clearCallingIdentity(); 11165 try { 11166 synchronized(this) { 11167 ServiceRecord r = findServiceLocked(className, token); 11168 if (r != null) { 11169 if (id != 0) { 11170 if (notification == null) { 11171 throw new IllegalArgumentException("null notification"); 11172 } 11173 if (r.foregroundId != id) { 11174 r.cancelNotification(); 11175 r.foregroundId = id; 11176 } 11177 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE; 11178 r.foregroundNoti = notification; 11179 r.isForeground = true; 11180 r.postNotification(); 11181 if (r.app != null) { 11182 updateServiceForegroundLocked(r.app, true); 11183 } 11184 } else { 11185 if (r.isForeground) { 11186 r.isForeground = false; 11187 if (r.app != null) { 11188 updateServiceForegroundLocked(r.app, true); 11189 } 11190 } 11191 if (removeNotification) { 11192 r.cancelNotification(); 11193 r.foregroundId = 0; 11194 r.foregroundNoti = null; 11195 } 11196 } 11197 } 11198 } 11199 } finally { 11200 Binder.restoreCallingIdentity(origId); 11201 } 11202 } 11203 11204 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) { 11205 boolean anyForeground = false; 11206 for (ServiceRecord sr : (HashSet<ServiceRecord>)proc.services) { 11207 if (sr.isForeground) { 11208 anyForeground = true; 11209 break; 11210 } 11211 } 11212 if (anyForeground != proc.foregroundServices) { 11213 proc.foregroundServices = anyForeground; 11214 if (oomAdj) { 11215 updateOomAdjLocked(); 11216 } 11217 } 11218 } 11219 11220 public int bindService(IApplicationThread caller, IBinder token, 11221 Intent service, String resolvedType, 11222 IServiceConnection connection, int flags) { 11223 // Refuse possible leaked file descriptors 11224 if (service != null && service.hasFileDescriptors() == true) { 11225 throw new IllegalArgumentException("File descriptors passed in Intent"); 11226 } 11227 11228 synchronized(this) { 11229 if (DEBUG_SERVICE) Log.v(TAG, "bindService: " + service 11230 + " type=" + resolvedType + " conn=" + connection.asBinder() 11231 + " flags=0x" + Integer.toHexString(flags)); 11232 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11233 if (callerApp == null) { 11234 throw new SecurityException( 11235 "Unable to find app for caller " + caller 11236 + " (pid=" + Binder.getCallingPid() 11237 + ") when binding service " + service); 11238 } 11239 11240 HistoryRecord activity = null; 11241 if (token != null) { 11242 int aindex = indexOfTokenLocked(token); 11243 if (aindex < 0) { 11244 Log.w(TAG, "Binding with unknown activity: " + token); 11245 return 0; 11246 } 11247 activity = (HistoryRecord)mHistory.get(aindex); 11248 } 11249 11250 int clientLabel = 0; 11251 PendingIntent clientIntent = null; 11252 11253 if (callerApp.info.uid == Process.SYSTEM_UID) { 11254 // Hacky kind of thing -- allow system stuff to tell us 11255 // what they are, so we can report this elsewhere for 11256 // others to know why certain services are running. 11257 try { 11258 clientIntent = (PendingIntent)service.getParcelableExtra( 11259 Intent.EXTRA_CLIENT_INTENT); 11260 } catch (RuntimeException e) { 11261 } 11262 if (clientIntent != null) { 11263 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0); 11264 if (clientLabel != 0) { 11265 // There are no useful extras in the intent, trash them. 11266 // System code calling with this stuff just needs to know 11267 // this will happen. 11268 service = service.cloneFilter(); 11269 } 11270 } 11271 } 11272 11273 ServiceLookupResult res = 11274 retrieveServiceLocked(service, resolvedType, 11275 Binder.getCallingPid(), Binder.getCallingUid()); 11276 if (res == null) { 11277 return 0; 11278 } 11279 if (res.record == null) { 11280 return -1; 11281 } 11282 ServiceRecord s = res.record; 11283 11284 final long origId = Binder.clearCallingIdentity(); 11285 11286 if (unscheduleServiceRestartLocked(s)) { 11287 if (DEBUG_SERVICE) Log.v(TAG, "BIND SERVICE WHILE RESTART PENDING: " 11288 + s.shortName); 11289 } 11290 11291 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp); 11292 ConnectionRecord c = new ConnectionRecord(b, activity, 11293 connection, flags, clientLabel, clientIntent); 11294 11295 IBinder binder = connection.asBinder(); 11296 s.connections.put(binder, c); 11297 b.connections.add(c); 11298 if (activity != null) { 11299 if (activity.connections == null) { 11300 activity.connections = new HashSet<ConnectionRecord>(); 11301 } 11302 activity.connections.add(c); 11303 } 11304 b.client.connections.add(c); 11305 mServiceConnections.put(binder, c); 11306 11307 if ((flags&Context.BIND_AUTO_CREATE) != 0) { 11308 s.lastActivity = SystemClock.uptimeMillis(); 11309 if (!bringUpServiceLocked(s, service.getFlags(), false)) { 11310 return 0; 11311 } 11312 } 11313 11314 if (s.app != null) { 11315 // This could have made the service more important. 11316 updateOomAdjLocked(s.app); 11317 } 11318 11319 if (DEBUG_SERVICE) Log.v(TAG, "Bind " + s + " with " + b 11320 + ": received=" + b.intent.received 11321 + " apps=" + b.intent.apps.size() 11322 + " doRebind=" + b.intent.doRebind); 11323 11324 if (s.app != null && b.intent.received) { 11325 // Service is already running, so we can immediately 11326 // publish the connection. 11327 try { 11328 c.conn.connected(s.name, b.intent.binder); 11329 } catch (Exception e) { 11330 Log.w(TAG, "Failure sending service " + s.shortName 11331 + " to connection " + c.conn.asBinder() 11332 + " (in " + c.binding.client.processName + ")", e); 11333 } 11334 11335 // If this is the first app connected back to this binding, 11336 // and the service had previously asked to be told when 11337 // rebound, then do so. 11338 if (b.intent.apps.size() == 1 && b.intent.doRebind) { 11339 requestServiceBindingLocked(s, b.intent, true); 11340 } 11341 } else if (!b.intent.requested) { 11342 requestServiceBindingLocked(s, b.intent, false); 11343 } 11344 11345 Binder.restoreCallingIdentity(origId); 11346 } 11347 11348 return 1; 11349 } 11350 11351 private void removeConnectionLocked( 11352 ConnectionRecord c, ProcessRecord skipApp, HistoryRecord skipAct) { 11353 IBinder binder = c.conn.asBinder(); 11354 AppBindRecord b = c.binding; 11355 ServiceRecord s = b.service; 11356 s.connections.remove(binder); 11357 b.connections.remove(c); 11358 if (c.activity != null && c.activity != skipAct) { 11359 if (c.activity.connections != null) { 11360 c.activity.connections.remove(c); 11361 } 11362 } 11363 if (b.client != skipApp) { 11364 b.client.connections.remove(c); 11365 } 11366 mServiceConnections.remove(binder); 11367 11368 if (b.connections.size() == 0) { 11369 b.intent.apps.remove(b.client); 11370 } 11371 11372 if (DEBUG_SERVICE) Log.v(TAG, "Disconnecting binding " + b.intent 11373 + ": shouldUnbind=" + b.intent.hasBound); 11374 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0 11375 && b.intent.hasBound) { 11376 try { 11377 bumpServiceExecutingLocked(s); 11378 updateOomAdjLocked(s.app); 11379 b.intent.hasBound = false; 11380 // Assume the client doesn't want to know about a rebind; 11381 // we will deal with that later if it asks for one. 11382 b.intent.doRebind = false; 11383 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent()); 11384 } catch (Exception e) { 11385 Log.w(TAG, "Exception when unbinding service " + s.shortName, e); 11386 serviceDoneExecutingLocked(s, true); 11387 } 11388 } 11389 11390 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) { 11391 bringDownServiceLocked(s, false); 11392 } 11393 } 11394 11395 public boolean unbindService(IServiceConnection connection) { 11396 synchronized (this) { 11397 IBinder binder = connection.asBinder(); 11398 if (DEBUG_SERVICE) Log.v(TAG, "unbindService: conn=" + binder); 11399 ConnectionRecord r = mServiceConnections.get(binder); 11400 if (r == null) { 11401 Log.w(TAG, "Unbind failed: could not find connection for " 11402 + connection.asBinder()); 11403 return false; 11404 } 11405 11406 final long origId = Binder.clearCallingIdentity(); 11407 11408 removeConnectionLocked(r, null, null); 11409 11410 if (r.binding.service.app != null) { 11411 // This could have made the service less important. 11412 updateOomAdjLocked(r.binding.service.app); 11413 } 11414 11415 Binder.restoreCallingIdentity(origId); 11416 } 11417 11418 return true; 11419 } 11420 11421 public void publishService(IBinder token, Intent intent, IBinder service) { 11422 // Refuse possible leaked file descriptors 11423 if (intent != null && intent.hasFileDescriptors() == true) { 11424 throw new IllegalArgumentException("File descriptors passed in Intent"); 11425 } 11426 11427 synchronized(this) { 11428 if (!(token instanceof ServiceRecord)) { 11429 throw new IllegalArgumentException("Invalid service token"); 11430 } 11431 ServiceRecord r = (ServiceRecord)token; 11432 11433 final long origId = Binder.clearCallingIdentity(); 11434 11435 if (DEBUG_SERVICE) Log.v(TAG, "PUBLISHING SERVICE " + r.name 11436 + " " + intent + ": " + service); 11437 if (r != null) { 11438 Intent.FilterComparison filter 11439 = new Intent.FilterComparison(intent); 11440 IntentBindRecord b = r.bindings.get(filter); 11441 if (b != null && !b.received) { 11442 b.binder = service; 11443 b.requested = true; 11444 b.received = true; 11445 if (r.connections.size() > 0) { 11446 Iterator<ConnectionRecord> it 11447 = r.connections.values().iterator(); 11448 while (it.hasNext()) { 11449 ConnectionRecord c = it.next(); 11450 if (!filter.equals(c.binding.intent.intent)) { 11451 if (DEBUG_SERVICE) Log.v( 11452 TAG, "Not publishing to: " + c); 11453 if (DEBUG_SERVICE) Log.v( 11454 TAG, "Bound intent: " + c.binding.intent.intent); 11455 if (DEBUG_SERVICE) Log.v( 11456 TAG, "Published intent: " + intent); 11457 continue; 11458 } 11459 if (DEBUG_SERVICE) Log.v(TAG, "Publishing to: " + c); 11460 try { 11461 c.conn.connected(r.name, service); 11462 } catch (Exception e) { 11463 Log.w(TAG, "Failure sending service " + r.name + 11464 " to connection " + c.conn.asBinder() + 11465 " (in " + c.binding.client.processName + ")", e); 11466 } 11467 } 11468 } 11469 } 11470 11471 serviceDoneExecutingLocked(r, mStoppingServices.contains(r)); 11472 11473 Binder.restoreCallingIdentity(origId); 11474 } 11475 } 11476 } 11477 11478 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 11479 // Refuse possible leaked file descriptors 11480 if (intent != null && intent.hasFileDescriptors() == true) { 11481 throw new IllegalArgumentException("File descriptors passed in Intent"); 11482 } 11483 11484 synchronized(this) { 11485 if (!(token instanceof ServiceRecord)) { 11486 throw new IllegalArgumentException("Invalid service token"); 11487 } 11488 ServiceRecord r = (ServiceRecord)token; 11489 11490 final long origId = Binder.clearCallingIdentity(); 11491 11492 if (r != null) { 11493 Intent.FilterComparison filter 11494 = new Intent.FilterComparison(intent); 11495 IntentBindRecord b = r.bindings.get(filter); 11496 if (DEBUG_SERVICE) Log.v(TAG, "unbindFinished in " + r 11497 + " at " + b + ": apps=" 11498 + (b != null ? b.apps.size() : 0)); 11499 if (b != null) { 11500 if (b.apps.size() > 0) { 11501 // Applications have already bound since the last 11502 // unbind, so just rebind right here. 11503 requestServiceBindingLocked(r, b, true); 11504 } else { 11505 // Note to tell the service the next time there is 11506 // a new client. 11507 b.doRebind = true; 11508 } 11509 } 11510 11511 serviceDoneExecutingLocked(r, mStoppingServices.contains(r)); 11512 11513 Binder.restoreCallingIdentity(origId); 11514 } 11515 } 11516 } 11517 11518 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 11519 synchronized(this) { 11520 if (!(token instanceof ServiceRecord)) { 11521 throw new IllegalArgumentException("Invalid service token"); 11522 } 11523 ServiceRecord r = (ServiceRecord)token; 11524 boolean inStopping = mStoppingServices.contains(token); 11525 if (r != null) { 11526 if (DEBUG_SERVICE) Log.v(TAG, "DONE EXECUTING SERVICE " + r.name 11527 + ": nesting=" + r.executeNesting 11528 + ", inStopping=" + inStopping); 11529 if (r != token) { 11530 Log.w(TAG, "Done executing service " + r.name 11531 + " with incorrect token: given " + token 11532 + ", expected " + r); 11533 return; 11534 } 11535 11536 if (type == 1) { 11537 // This is a call from a service start... take care of 11538 // book-keeping. 11539 r.callStart = true; 11540 switch (res) { 11541 case Service.START_STICKY_COMPATIBILITY: 11542 case Service.START_STICKY: { 11543 // We are done with the associated start arguments. 11544 r.findDeliveredStart(startId, true); 11545 // Don't stop if killed. 11546 r.stopIfKilled = false; 11547 break; 11548 } 11549 case Service.START_NOT_STICKY: { 11550 // We are done with the associated start arguments. 11551 r.findDeliveredStart(startId, true); 11552 if (r.lastStartId == startId) { 11553 // There is no more work, and this service 11554 // doesn't want to hang around if killed. 11555 r.stopIfKilled = true; 11556 } 11557 break; 11558 } 11559 case Service.START_REDELIVER_INTENT: { 11560 // We'll keep this item until they explicitly 11561 // call stop for it, but keep track of the fact 11562 // that it was delivered. 11563 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 11564 if (si != null) { 11565 si.deliveryCount = 0; 11566 si.doneExecutingCount++; 11567 // Don't stop if killed. 11568 r.stopIfKilled = true; 11569 } 11570 break; 11571 } 11572 default: 11573 throw new IllegalArgumentException( 11574 "Unknown service start result: " + res); 11575 } 11576 if (res == Service.START_STICKY_COMPATIBILITY) { 11577 r.callStart = false; 11578 } 11579 } 11580 11581 final long origId = Binder.clearCallingIdentity(); 11582 serviceDoneExecutingLocked(r, inStopping); 11583 Binder.restoreCallingIdentity(origId); 11584 } else { 11585 Log.w(TAG, "Done executing unknown service " + r.name 11586 + " with token " + token); 11587 } 11588 } 11589 } 11590 11591 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) { 11592 r.executeNesting--; 11593 if (r.executeNesting <= 0 && r.app != null) { 11594 r.app.executingServices.remove(r); 11595 if (r.app.executingServices.size() == 0) { 11596 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app); 11597 } 11598 if (inStopping) { 11599 mStoppingServices.remove(r); 11600 } 11601 updateOomAdjLocked(r.app); 11602 } 11603 } 11604 11605 void serviceTimeout(ProcessRecord proc) { 11606 synchronized(this) { 11607 if (proc.executingServices.size() == 0 || proc.thread == null) { 11608 return; 11609 } 11610 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT; 11611 Iterator<ServiceRecord> it = proc.executingServices.iterator(); 11612 ServiceRecord timeout = null; 11613 long nextTime = 0; 11614 while (it.hasNext()) { 11615 ServiceRecord sr = it.next(); 11616 if (sr.executingStart < maxTime) { 11617 timeout = sr; 11618 break; 11619 } 11620 if (sr.executingStart > nextTime) { 11621 nextTime = sr.executingStart; 11622 } 11623 } 11624 if (timeout != null && mLruProcesses.contains(proc)) { 11625 Log.w(TAG, "Timeout executing service: " + timeout); 11626 appNotRespondingLocked(proc, null, null, "Executing service " + timeout.name); 11627 } else { 11628 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 11629 msg.obj = proc; 11630 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT); 11631 } 11632 } 11633 } 11634 11635 // ========================================================= 11636 // BACKUP AND RESTORE 11637 // ========================================================= 11638 11639 // Cause the target app to be launched if necessary and its backup agent 11640 // instantiated. The backup agent will invoke backupAgentCreated() on the 11641 // activity manager to announce its creation. 11642 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 11643 if (DEBUG_BACKUP) Log.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 11644 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 11645 11646 synchronized(this) { 11647 // !!! TODO: currently no check here that we're already bound 11648 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 11649 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 11650 synchronized (stats) { 11651 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 11652 } 11653 11654 BackupRecord r = new BackupRecord(ss, app, backupMode); 11655 ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName); 11656 // startProcessLocked() returns existing proc's record if it's already running 11657 ProcessRecord proc = startProcessLocked(app.processName, app, 11658 false, 0, "backup", hostingName, false); 11659 if (proc == null) { 11660 Log.e(TAG, "Unable to start backup agent process " + r); 11661 return false; 11662 } 11663 11664 r.app = proc; 11665 mBackupTarget = r; 11666 mBackupAppName = app.packageName; 11667 11668 // Try not to kill the process during backup 11669 updateOomAdjLocked(proc); 11670 11671 // If the process is already attached, schedule the creation of the backup agent now. 11672 // If it is not yet live, this will be done when it attaches to the framework. 11673 if (proc.thread != null) { 11674 if (DEBUG_BACKUP) Log.v(TAG, "Agent proc already running: " + proc); 11675 try { 11676 proc.thread.scheduleCreateBackupAgent(app, backupMode); 11677 } catch (RemoteException e) { 11678 // Will time out on the backup manager side 11679 } 11680 } else { 11681 if (DEBUG_BACKUP) Log.v(TAG, "Agent proc not running, waiting for attach"); 11682 } 11683 // Invariants: at this point, the target app process exists and the application 11684 // is either already running or in the process of coming up. mBackupTarget and 11685 // mBackupAppName describe the app, so that when it binds back to the AM we 11686 // know that it's scheduled for a backup-agent operation. 11687 } 11688 11689 return true; 11690 } 11691 11692 // A backup agent has just come up 11693 public void backupAgentCreated(String agentPackageName, IBinder agent) { 11694 if (DEBUG_BACKUP) Log.v(TAG, "backupAgentCreated: " + agentPackageName 11695 + " = " + agent); 11696 11697 synchronized(this) { 11698 if (!agentPackageName.equals(mBackupAppName)) { 11699 Log.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 11700 return; 11701 } 11702 11703 long oldIdent = Binder.clearCallingIdentity(); 11704 try { 11705 IBackupManager bm = IBackupManager.Stub.asInterface( 11706 ServiceManager.getService(Context.BACKUP_SERVICE)); 11707 bm.agentConnected(agentPackageName, agent); 11708 } catch (RemoteException e) { 11709 // can't happen; the backup manager service is local 11710 } catch (Exception e) { 11711 Log.w(TAG, "Exception trying to deliver BackupAgent binding: "); 11712 e.printStackTrace(); 11713 } finally { 11714 Binder.restoreCallingIdentity(oldIdent); 11715 } 11716 } 11717 } 11718 11719 // done with this agent 11720 public void unbindBackupAgent(ApplicationInfo appInfo) { 11721 if (DEBUG_BACKUP) Log.v(TAG, "unbindBackupAgent: " + appInfo); 11722 if (appInfo == null) { 11723 Log.w(TAG, "unbind backup agent for null app"); 11724 return; 11725 } 11726 11727 synchronized(this) { 11728 if (mBackupAppName == null) { 11729 Log.w(TAG, "Unbinding backup agent with no active backup"); 11730 return; 11731 } 11732 11733 if (!mBackupAppName.equals(appInfo.packageName)) { 11734 Log.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 11735 return; 11736 } 11737 11738 ProcessRecord proc = mBackupTarget.app; 11739 mBackupTarget = null; 11740 mBackupAppName = null; 11741 11742 // Not backing this app up any more; reset its OOM adjustment 11743 updateOomAdjLocked(proc); 11744 11745 // If the app crashed during backup, 'thread' will be null here 11746 if (proc.thread != null) { 11747 try { 11748 proc.thread.scheduleDestroyBackupAgent(appInfo); 11749 } catch (Exception e) { 11750 Log.e(TAG, "Exception when unbinding backup agent:"); 11751 e.printStackTrace(); 11752 } 11753 } 11754 } 11755 } 11756 // ========================================================= 11757 // BROADCASTS 11758 // ========================================================= 11759 11760 private final List getStickies(String action, IntentFilter filter, 11761 List cur) { 11762 final ContentResolver resolver = mContext.getContentResolver(); 11763 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 11764 if (list == null) { 11765 return cur; 11766 } 11767 int N = list.size(); 11768 for (int i=0; i<N; i++) { 11769 Intent intent = list.get(i); 11770 if (filter.match(resolver, intent, true, TAG) >= 0) { 11771 if (cur == null) { 11772 cur = new ArrayList<Intent>(); 11773 } 11774 cur.add(intent); 11775 } 11776 } 11777 return cur; 11778 } 11779 11780 private final void scheduleBroadcastsLocked() { 11781 if (DEBUG_BROADCAST) Log.v(TAG, "Schedule broadcasts: current=" 11782 + mBroadcastsScheduled); 11783 11784 if (mBroadcastsScheduled) { 11785 return; 11786 } 11787 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG); 11788 mBroadcastsScheduled = true; 11789 } 11790 11791 public Intent registerReceiver(IApplicationThread caller, 11792 IIntentReceiver receiver, IntentFilter filter, String permission) { 11793 synchronized(this) { 11794 ProcessRecord callerApp = null; 11795 if (caller != null) { 11796 callerApp = getRecordForAppLocked(caller); 11797 if (callerApp == null) { 11798 throw new SecurityException( 11799 "Unable to find app for caller " + caller 11800 + " (pid=" + Binder.getCallingPid() 11801 + ") when registering receiver " + receiver); 11802 } 11803 } 11804 11805 List allSticky = null; 11806 11807 // Look for any matching sticky broadcasts... 11808 Iterator actions = filter.actionsIterator(); 11809 if (actions != null) { 11810 while (actions.hasNext()) { 11811 String action = (String)actions.next(); 11812 allSticky = getStickies(action, filter, allSticky); 11813 } 11814 } else { 11815 allSticky = getStickies(null, filter, allSticky); 11816 } 11817 11818 // The first sticky in the list is returned directly back to 11819 // the client. 11820 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 11821 11822 if (DEBUG_BROADCAST) Log.v(TAG, "Register receiver " + filter 11823 + ": " + sticky); 11824 11825 if (receiver == null) { 11826 return sticky; 11827 } 11828 11829 ReceiverList rl 11830 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11831 if (rl == null) { 11832 rl = new ReceiverList(this, callerApp, 11833 Binder.getCallingPid(), 11834 Binder.getCallingUid(), receiver); 11835 if (rl.app != null) { 11836 rl.app.receivers.add(rl); 11837 } else { 11838 try { 11839 receiver.asBinder().linkToDeath(rl, 0); 11840 } catch (RemoteException e) { 11841 return sticky; 11842 } 11843 rl.linkedToDeath = true; 11844 } 11845 mRegisteredReceivers.put(receiver.asBinder(), rl); 11846 } 11847 BroadcastFilter bf = new BroadcastFilter(filter, rl, permission); 11848 rl.add(bf); 11849 if (!bf.debugCheck()) { 11850 Log.w(TAG, "==> For Dynamic broadast"); 11851 } 11852 mReceiverResolver.addFilter(bf); 11853 11854 // Enqueue broadcasts for all existing stickies that match 11855 // this filter. 11856 if (allSticky != null) { 11857 ArrayList receivers = new ArrayList(); 11858 receivers.add(bf); 11859 11860 int N = allSticky.size(); 11861 for (int i=0; i<N; i++) { 11862 Intent intent = (Intent)allSticky.get(i); 11863 BroadcastRecord r = new BroadcastRecord(intent, null, 11864 null, -1, -1, null, receivers, null, 0, null, null, 11865 false, true, true); 11866 if (mParallelBroadcasts.size() == 0) { 11867 scheduleBroadcastsLocked(); 11868 } 11869 mParallelBroadcasts.add(r); 11870 } 11871 } 11872 11873 return sticky; 11874 } 11875 } 11876 11877 public void unregisterReceiver(IIntentReceiver receiver) { 11878 if (DEBUG_BROADCAST) Log.v(TAG, "Unregister receiver: " + receiver); 11879 11880 boolean doNext = false; 11881 11882 synchronized(this) { 11883 ReceiverList rl 11884 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 11885 if (rl != null) { 11886 if (rl.curBroadcast != null) { 11887 BroadcastRecord r = rl.curBroadcast; 11888 doNext = finishReceiverLocked( 11889 receiver.asBinder(), r.resultCode, r.resultData, 11890 r.resultExtras, r.resultAbort, true); 11891 } 11892 11893 if (rl.app != null) { 11894 rl.app.receivers.remove(rl); 11895 } 11896 removeReceiverLocked(rl); 11897 if (rl.linkedToDeath) { 11898 rl.linkedToDeath = false; 11899 rl.receiver.asBinder().unlinkToDeath(rl, 0); 11900 } 11901 } 11902 } 11903 11904 if (!doNext) { 11905 return; 11906 } 11907 11908 final long origId = Binder.clearCallingIdentity(); 11909 processNextBroadcast(false); 11910 trimApplications(); 11911 Binder.restoreCallingIdentity(origId); 11912 } 11913 11914 void removeReceiverLocked(ReceiverList rl) { 11915 mRegisteredReceivers.remove(rl.receiver.asBinder()); 11916 int N = rl.size(); 11917 for (int i=0; i<N; i++) { 11918 mReceiverResolver.removeFilter(rl.get(i)); 11919 } 11920 } 11921 11922 private final int broadcastIntentLocked(ProcessRecord callerApp, 11923 String callerPackage, Intent intent, String resolvedType, 11924 IIntentReceiver resultTo, int resultCode, String resultData, 11925 Bundle map, String requiredPermission, 11926 boolean ordered, boolean sticky, int callingPid, int callingUid) { 11927 intent = new Intent(intent); 11928 11929 if (DEBUG_BROADCAST_LIGHT) Log.v( 11930 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 11931 + " ordered=" + ordered); 11932 if ((resultTo != null) && !ordered) { 11933 Log.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 11934 } 11935 11936 // Handle special intents: if this broadcast is from the package 11937 // manager about a package being removed, we need to remove all of 11938 // its activities from the history stack. 11939 final boolean uidRemoved = intent.ACTION_UID_REMOVED.equals( 11940 intent.getAction()); 11941 if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 11942 || intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 11943 || uidRemoved) { 11944 if (checkComponentPermission( 11945 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 11946 callingPid, callingUid, -1) 11947 == PackageManager.PERMISSION_GRANTED) { 11948 if (uidRemoved) { 11949 final Bundle intentExtras = intent.getExtras(); 11950 final int uid = intentExtras != null 11951 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 11952 if (uid >= 0) { 11953 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 11954 synchronized (bs) { 11955 bs.removeUidStatsLocked(uid); 11956 } 11957 } 11958 } else { 11959 Uri data = intent.getData(); 11960 String ssp; 11961 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 11962 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 11963 forceStopPackageLocked(ssp, 11964 intent.getIntExtra(Intent.EXTRA_UID, -1), false); 11965 AttributeCache ac = AttributeCache.instance(); 11966 if (ac != null) { 11967 ac.removePackage(ssp); 11968 } 11969 } 11970 } 11971 } 11972 } else { 11973 String msg = "Permission Denial: " + intent.getAction() 11974 + " broadcast from " + callerPackage + " (pid=" + callingPid 11975 + ", uid=" + callingUid + ")" 11976 + " requires " 11977 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 11978 Log.w(TAG, msg); 11979 throw new SecurityException(msg); 11980 } 11981 } 11982 11983 /* 11984 * If this is the time zone changed action, queue up a message that will reset the timezone 11985 * of all currently running processes. This message will get queued up before the broadcast 11986 * happens. 11987 */ 11988 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 11989 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 11990 } 11991 11992 /* 11993 * Prevent non-system code (defined here to be non-persistent 11994 * processes) from sending protected broadcasts. 11995 */ 11996 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 11997 || callingUid == Process.SHELL_UID || callingUid == 0) { 11998 // Always okay. 11999 } else if (callerApp == null || !callerApp.persistent) { 12000 try { 12001 if (ActivityThread.getPackageManager().isProtectedBroadcast( 12002 intent.getAction())) { 12003 String msg = "Permission Denial: not allowed to send broadcast " 12004 + intent.getAction() + " from pid=" 12005 + callingPid + ", uid=" + callingUid; 12006 Log.w(TAG, msg); 12007 throw new SecurityException(msg); 12008 } 12009 } catch (RemoteException e) { 12010 Log.w(TAG, "Remote exception", e); 12011 return BROADCAST_SUCCESS; 12012 } 12013 } 12014 12015 // Add to the sticky list if requested. 12016 if (sticky) { 12017 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 12018 callingPid, callingUid) 12019 != PackageManager.PERMISSION_GRANTED) { 12020 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 12021 + callingPid + ", uid=" + callingUid 12022 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 12023 Log.w(TAG, msg); 12024 throw new SecurityException(msg); 12025 } 12026 if (requiredPermission != null) { 12027 Log.w(TAG, "Can't broadcast sticky intent " + intent 12028 + " and enforce permission " + requiredPermission); 12029 return BROADCAST_STICKY_CANT_HAVE_PERMISSION; 12030 } 12031 if (intent.getComponent() != null) { 12032 throw new SecurityException( 12033 "Sticky broadcasts can't target a specific component"); 12034 } 12035 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 12036 if (list == null) { 12037 list = new ArrayList<Intent>(); 12038 mStickyBroadcasts.put(intent.getAction(), list); 12039 } 12040 int N = list.size(); 12041 int i; 12042 for (i=0; i<N; i++) { 12043 if (intent.filterEquals(list.get(i))) { 12044 // This sticky already exists, replace it. 12045 list.set(i, new Intent(intent)); 12046 break; 12047 } 12048 } 12049 if (i >= N) { 12050 list.add(new Intent(intent)); 12051 } 12052 } 12053 12054 // Figure out who all will receive this broadcast. 12055 List receivers = null; 12056 List<BroadcastFilter> registeredReceivers = null; 12057 try { 12058 if (intent.getComponent() != null) { 12059 // Broadcast is going to one specific receiver class... 12060 ActivityInfo ai = ActivityThread.getPackageManager(). 12061 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS); 12062 if (ai != null) { 12063 receivers = new ArrayList(); 12064 ResolveInfo ri = new ResolveInfo(); 12065 ri.activityInfo = ai; 12066 receivers.add(ri); 12067 } 12068 } else { 12069 // Need to resolve the intent to interested receivers... 12070 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 12071 == 0) { 12072 receivers = 12073 ActivityThread.getPackageManager().queryIntentReceivers( 12074 intent, resolvedType, STOCK_PM_FLAGS); 12075 } 12076 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false); 12077 } 12078 } catch (RemoteException ex) { 12079 // pm is in same process, this will never happen. 12080 } 12081 12082 final boolean replacePending = 12083 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 12084 12085 if (DEBUG_BROADCAST) Log.v(TAG, "Enqueing broadcast: " + intent.getAction() 12086 + " replacePending=" + replacePending); 12087 12088 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 12089 if (!ordered && NR > 0) { 12090 // If we are not serializing this broadcast, then send the 12091 // registered receivers separately so they don't wait for the 12092 // components to be launched. 12093 BroadcastRecord r = new BroadcastRecord(intent, callerApp, 12094 callerPackage, callingPid, callingUid, requiredPermission, 12095 registeredReceivers, resultTo, resultCode, resultData, map, 12096 ordered, sticky, false); 12097 if (DEBUG_BROADCAST) Log.v( 12098 TAG, "Enqueueing parallel broadcast " + r 12099 + ": prev had " + mParallelBroadcasts.size()); 12100 boolean replaced = false; 12101 if (replacePending) { 12102 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) { 12103 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) { 12104 if (DEBUG_BROADCAST) Log.v(TAG, 12105 "***** DROPPING PARALLEL: " + intent); 12106 mParallelBroadcasts.set(i, r); 12107 replaced = true; 12108 break; 12109 } 12110 } 12111 } 12112 if (!replaced) { 12113 mParallelBroadcasts.add(r); 12114 scheduleBroadcastsLocked(); 12115 } 12116 registeredReceivers = null; 12117 NR = 0; 12118 } 12119 12120 // Merge into one list. 12121 int ir = 0; 12122 if (receivers != null) { 12123 // A special case for PACKAGE_ADDED: do not allow the package 12124 // being added to see this broadcast. This prevents them from 12125 // using this as a back door to get run as soon as they are 12126 // installed. Maybe in the future we want to have a special install 12127 // broadcast or such for apps, but we'd like to deliberately make 12128 // this decision. 12129 boolean skip = false; 12130 if (intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 12131 skip = true; 12132 } else if (intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())) { 12133 skip = true; 12134 } else if (intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 12135 skip = true; 12136 } 12137 String skipPackage = (skip && intent.getData() != null) 12138 ? intent.getData().getSchemeSpecificPart() 12139 : null; 12140 if (skipPackage != null && receivers != null) { 12141 int NT = receivers.size(); 12142 for (int it=0; it<NT; it++) { 12143 ResolveInfo curt = (ResolveInfo)receivers.get(it); 12144 if (curt.activityInfo.packageName.equals(skipPackage)) { 12145 receivers.remove(it); 12146 it--; 12147 NT--; 12148 } 12149 } 12150 } 12151 12152 int NT = receivers != null ? receivers.size() : 0; 12153 int it = 0; 12154 ResolveInfo curt = null; 12155 BroadcastFilter curr = null; 12156 while (it < NT && ir < NR) { 12157 if (curt == null) { 12158 curt = (ResolveInfo)receivers.get(it); 12159 } 12160 if (curr == null) { 12161 curr = registeredReceivers.get(ir); 12162 } 12163 if (curr.getPriority() >= curt.priority) { 12164 // Insert this broadcast record into the final list. 12165 receivers.add(it, curr); 12166 ir++; 12167 curr = null; 12168 it++; 12169 NT++; 12170 } else { 12171 // Skip to the next ResolveInfo in the final list. 12172 it++; 12173 curt = null; 12174 } 12175 } 12176 } 12177 while (ir < NR) { 12178 if (receivers == null) { 12179 receivers = new ArrayList(); 12180 } 12181 receivers.add(registeredReceivers.get(ir)); 12182 ir++; 12183 } 12184 12185 if ((receivers != null && receivers.size() > 0) 12186 || resultTo != null) { 12187 BroadcastRecord r = new BroadcastRecord(intent, callerApp, 12188 callerPackage, callingPid, callingUid, requiredPermission, 12189 receivers, resultTo, resultCode, resultData, map, ordered, 12190 sticky, false); 12191 if (DEBUG_BROADCAST) Log.v( 12192 TAG, "Enqueueing ordered broadcast " + r 12193 + ": prev had " + mOrderedBroadcasts.size()); 12194 if (DEBUG_BROADCAST) { 12195 int seq = r.intent.getIntExtra("seq", -1); 12196 Log.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 12197 } 12198 boolean replaced = false; 12199 if (replacePending) { 12200 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) { 12201 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) { 12202 if (DEBUG_BROADCAST) Log.v(TAG, 12203 "***** DROPPING ORDERED: " + intent); 12204 mOrderedBroadcasts.set(i, r); 12205 replaced = true; 12206 break; 12207 } 12208 } 12209 } 12210 if (!replaced) { 12211 mOrderedBroadcasts.add(r); 12212 scheduleBroadcastsLocked(); 12213 } 12214 } 12215 12216 return BROADCAST_SUCCESS; 12217 } 12218 12219 public final int broadcastIntent(IApplicationThread caller, 12220 Intent intent, String resolvedType, IIntentReceiver resultTo, 12221 int resultCode, String resultData, Bundle map, 12222 String requiredPermission, boolean serialized, boolean sticky) { 12223 // Refuse possible leaked file descriptors 12224 if (intent != null && intent.hasFileDescriptors() == true) { 12225 throw new IllegalArgumentException("File descriptors passed in Intent"); 12226 } 12227 12228 synchronized(this) { 12229 int flags = intent.getFlags(); 12230 12231 if (!mSystemReady) { 12232 // if the caller really truly claims to know what they're doing, go 12233 // ahead and allow the broadcast without launching any receivers 12234 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 12235 intent = new Intent(intent); 12236 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 12237 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0){ 12238 Log.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 12239 + " before boot completion"); 12240 throw new IllegalStateException("Cannot broadcast before boot completed"); 12241 } 12242 } 12243 12244 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 12245 throw new IllegalArgumentException( 12246 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 12247 } 12248 12249 final ProcessRecord callerApp = getRecordForAppLocked(caller); 12250 final int callingPid = Binder.getCallingPid(); 12251 final int callingUid = Binder.getCallingUid(); 12252 final long origId = Binder.clearCallingIdentity(); 12253 int res = broadcastIntentLocked(callerApp, 12254 callerApp != null ? callerApp.info.packageName : null, 12255 intent, resolvedType, resultTo, 12256 resultCode, resultData, map, requiredPermission, serialized, 12257 sticky, callingPid, callingUid); 12258 Binder.restoreCallingIdentity(origId); 12259 return res; 12260 } 12261 } 12262 12263 int broadcastIntentInPackage(String packageName, int uid, 12264 Intent intent, String resolvedType, IIntentReceiver resultTo, 12265 int resultCode, String resultData, Bundle map, 12266 String requiredPermission, boolean serialized, boolean sticky) { 12267 synchronized(this) { 12268 final long origId = Binder.clearCallingIdentity(); 12269 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 12270 resultTo, resultCode, resultData, map, requiredPermission, 12271 serialized, sticky, -1, uid); 12272 Binder.restoreCallingIdentity(origId); 12273 return res; 12274 } 12275 } 12276 12277 public final void unbroadcastIntent(IApplicationThread caller, 12278 Intent intent) { 12279 // Refuse possible leaked file descriptors 12280 if (intent != null && intent.hasFileDescriptors() == true) { 12281 throw new IllegalArgumentException("File descriptors passed in Intent"); 12282 } 12283 12284 synchronized(this) { 12285 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 12286 != PackageManager.PERMISSION_GRANTED) { 12287 String msg = "Permission Denial: unbroadcastIntent() from pid=" 12288 + Binder.getCallingPid() 12289 + ", uid=" + Binder.getCallingUid() 12290 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 12291 Log.w(TAG, msg); 12292 throw new SecurityException(msg); 12293 } 12294 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 12295 if (list != null) { 12296 int N = list.size(); 12297 int i; 12298 for (i=0; i<N; i++) { 12299 if (intent.filterEquals(list.get(i))) { 12300 list.remove(i); 12301 break; 12302 } 12303 } 12304 } 12305 } 12306 } 12307 12308 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 12309 String resultData, Bundle resultExtras, boolean resultAbort, 12310 boolean explicit) { 12311 if (mOrderedBroadcasts.size() == 0) { 12312 if (explicit) { 12313 Log.w(TAG, "finishReceiver called but no pending broadcasts"); 12314 } 12315 return false; 12316 } 12317 BroadcastRecord r = mOrderedBroadcasts.get(0); 12318 if (r.receiver == null) { 12319 if (explicit) { 12320 Log.w(TAG, "finishReceiver called but none active"); 12321 } 12322 return false; 12323 } 12324 if (r.receiver != receiver) { 12325 Log.w(TAG, "finishReceiver called but active receiver is different"); 12326 return false; 12327 } 12328 int state = r.state; 12329 r.state = r.IDLE; 12330 if (state == r.IDLE) { 12331 if (explicit) { 12332 Log.w(TAG, "finishReceiver called but state is IDLE"); 12333 } 12334 } 12335 r.receiver = null; 12336 r.intent.setComponent(null); 12337 if (r.curApp != null) { 12338 r.curApp.curReceiver = null; 12339 } 12340 if (r.curFilter != null) { 12341 r.curFilter.receiverList.curBroadcast = null; 12342 } 12343 r.curFilter = null; 12344 r.curApp = null; 12345 r.curComponent = null; 12346 r.curReceiver = null; 12347 mPendingBroadcast = null; 12348 12349 r.resultCode = resultCode; 12350 r.resultData = resultData; 12351 r.resultExtras = resultExtras; 12352 r.resultAbort = resultAbort; 12353 12354 // We will process the next receiver right now if this is finishing 12355 // an app receiver (which is always asynchronous) or after we have 12356 // come back from calling a receiver. 12357 return state == BroadcastRecord.APP_RECEIVE 12358 || state == BroadcastRecord.CALL_DONE_RECEIVE; 12359 } 12360 12361 public void finishReceiver(IBinder who, int resultCode, String resultData, 12362 Bundle resultExtras, boolean resultAbort) { 12363 if (DEBUG_BROADCAST) Log.v(TAG, "Finish receiver: " + who); 12364 12365 // Refuse possible leaked file descriptors 12366 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 12367 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12368 } 12369 12370 boolean doNext; 12371 12372 final long origId = Binder.clearCallingIdentity(); 12373 12374 synchronized(this) { 12375 doNext = finishReceiverLocked( 12376 who, resultCode, resultData, resultExtras, resultAbort, true); 12377 } 12378 12379 if (doNext) { 12380 processNextBroadcast(false); 12381 } 12382 trimApplications(); 12383 12384 Binder.restoreCallingIdentity(origId); 12385 } 12386 12387 private final void logBroadcastReceiverDiscard(BroadcastRecord r) { 12388 if (r.nextReceiver > 0) { 12389 Object curReceiver = r.receivers.get(r.nextReceiver-1); 12390 if (curReceiver instanceof BroadcastFilter) { 12391 BroadcastFilter bf = (BroadcastFilter) curReceiver; 12392 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER, 12393 System.identityHashCode(r), 12394 r.intent.getAction(), 12395 r.nextReceiver - 1, 12396 System.identityHashCode(bf)); 12397 } else { 12398 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP, 12399 System.identityHashCode(r), 12400 r.intent.getAction(), 12401 r.nextReceiver - 1, 12402 ((ResolveInfo)curReceiver).toString()); 12403 } 12404 } else { 12405 Log.w(TAG, "Discarding broadcast before first receiver is invoked: " 12406 + r); 12407 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP, 12408 System.identityHashCode(r), 12409 r.intent.getAction(), 12410 r.nextReceiver, 12411 "NONE"); 12412 } 12413 } 12414 12415 private final void broadcastTimeout() { 12416 synchronized (this) { 12417 if (mOrderedBroadcasts.size() == 0) { 12418 return; 12419 } 12420 long now = SystemClock.uptimeMillis(); 12421 BroadcastRecord r = mOrderedBroadcasts.get(0); 12422 if ((r.receiverTime+BROADCAST_TIMEOUT) > now) { 12423 if (DEBUG_BROADCAST) Log.v(TAG, 12424 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for " 12425 + (r.receiverTime + BROADCAST_TIMEOUT)); 12426 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG); 12427 mHandler.sendMessageAtTime(msg, r.receiverTime+BROADCAST_TIMEOUT); 12428 return; 12429 } 12430 12431 Log.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver); 12432 r.receiverTime = now; 12433 r.anrCount++; 12434 12435 // Current receiver has passed its expiration date. 12436 if (r.nextReceiver <= 0) { 12437 Log.w(TAG, "Timeout on receiver with nextReceiver <= 0"); 12438 return; 12439 } 12440 12441 ProcessRecord app = null; 12442 12443 Object curReceiver = r.receivers.get(r.nextReceiver-1); 12444 Log.w(TAG, "Receiver during timeout: " + curReceiver); 12445 logBroadcastReceiverDiscard(r); 12446 if (curReceiver instanceof BroadcastFilter) { 12447 BroadcastFilter bf = (BroadcastFilter)curReceiver; 12448 if (bf.receiverList.pid != 0 12449 && bf.receiverList.pid != MY_PID) { 12450 synchronized (this.mPidsSelfLocked) { 12451 app = this.mPidsSelfLocked.get( 12452 bf.receiverList.pid); 12453 } 12454 } 12455 } else { 12456 app = r.curApp; 12457 } 12458 12459 if (app != null) { 12460 appNotRespondingLocked(app, null, null, "Broadcast of " + r.intent.toString()); 12461 } 12462 12463 if (mPendingBroadcast == r) { 12464 mPendingBroadcast = null; 12465 } 12466 12467 // Move on to the next receiver. 12468 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 12469 r.resultExtras, r.resultAbort, true); 12470 scheduleBroadcastsLocked(); 12471 } 12472 } 12473 12474 private final void processCurBroadcastLocked(BroadcastRecord r, 12475 ProcessRecord app) throws RemoteException { 12476 if (app.thread == null) { 12477 throw new RemoteException(); 12478 } 12479 r.receiver = app.thread.asBinder(); 12480 r.curApp = app; 12481 app.curReceiver = r; 12482 updateLruProcessLocked(app, true, true); 12483 12484 // Tell the application to launch this receiver. 12485 r.intent.setComponent(r.curComponent); 12486 12487 boolean started = false; 12488 try { 12489 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, 12490 "Delivering to component " + r.curComponent 12491 + ": " + r); 12492 ensurePackageDexOpt(r.intent.getComponent().getPackageName()); 12493 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver, 12494 r.resultCode, r.resultData, r.resultExtras, r.ordered); 12495 started = true; 12496 } finally { 12497 if (!started) { 12498 r.receiver = null; 12499 r.curApp = null; 12500 app.curReceiver = null; 12501 } 12502 } 12503 12504 } 12505 12506 static void performReceive(ProcessRecord app, IIntentReceiver receiver, 12507 Intent intent, int resultCode, String data, Bundle extras, 12508 boolean ordered, boolean sticky) throws RemoteException { 12509 if (app != null && app.thread != null) { 12510 // If we have an app thread, do the call through that so it is 12511 // correctly ordered with other one-way calls. 12512 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode, 12513 data, extras, ordered, sticky); 12514 } else { 12515 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky); 12516 } 12517 } 12518 12519 private final void deliverToRegisteredReceiver(BroadcastRecord r, 12520 BroadcastFilter filter, boolean ordered) { 12521 boolean skip = false; 12522 if (filter.requiredPermission != null) { 12523 int perm = checkComponentPermission(filter.requiredPermission, 12524 r.callingPid, r.callingUid, -1); 12525 if (perm != PackageManager.PERMISSION_GRANTED) { 12526 Log.w(TAG, "Permission Denial: broadcasting " 12527 + r.intent.toString() 12528 + " from " + r.callerPackage + " (pid=" 12529 + r.callingPid + ", uid=" + r.callingUid + ")" 12530 + " requires " + filter.requiredPermission 12531 + " due to registered receiver " + filter); 12532 skip = true; 12533 } 12534 } 12535 if (r.requiredPermission != null) { 12536 int perm = checkComponentPermission(r.requiredPermission, 12537 filter.receiverList.pid, filter.receiverList.uid, -1); 12538 if (perm != PackageManager.PERMISSION_GRANTED) { 12539 Log.w(TAG, "Permission Denial: receiving " 12540 + r.intent.toString() 12541 + " to " + filter.receiverList.app 12542 + " (pid=" + filter.receiverList.pid 12543 + ", uid=" + filter.receiverList.uid + ")" 12544 + " requires " + r.requiredPermission 12545 + " due to sender " + r.callerPackage 12546 + " (uid " + r.callingUid + ")"); 12547 skip = true; 12548 } 12549 } 12550 12551 if (!skip) { 12552 // If this is not being sent as an ordered broadcast, then we 12553 // don't want to touch the fields that keep track of the current 12554 // state of ordered broadcasts. 12555 if (ordered) { 12556 r.receiver = filter.receiverList.receiver.asBinder(); 12557 r.curFilter = filter; 12558 filter.receiverList.curBroadcast = r; 12559 r.state = BroadcastRecord.CALL_IN_RECEIVE; 12560 if (filter.receiverList.app != null) { 12561 // Bump hosting application to no longer be in background 12562 // scheduling class. Note that we can't do that if there 12563 // isn't an app... but we can only be in that case for 12564 // things that directly call the IActivityManager API, which 12565 // are already core system stuff so don't matter for this. 12566 r.curApp = filter.receiverList.app; 12567 filter.receiverList.app.curReceiver = r; 12568 updateOomAdjLocked(); 12569 } 12570 } 12571 try { 12572 if (DEBUG_BROADCAST_LIGHT) { 12573 int seq = r.intent.getIntExtra("seq", -1); 12574 Log.i(TAG, "Delivering to " + filter.receiverList.app 12575 + " (seq=" + seq + "): " + r); 12576 } 12577 performReceive(filter.receiverList.app, filter.receiverList.receiver, 12578 new Intent(r.intent), r.resultCode, 12579 r.resultData, r.resultExtras, r.ordered, r.initialSticky); 12580 if (ordered) { 12581 r.state = BroadcastRecord.CALL_DONE_RECEIVE; 12582 } 12583 } catch (RemoteException e) { 12584 Log.w(TAG, "Failure sending broadcast " + r.intent, e); 12585 if (ordered) { 12586 r.receiver = null; 12587 r.curFilter = null; 12588 filter.receiverList.curBroadcast = null; 12589 if (filter.receiverList.app != null) { 12590 filter.receiverList.app.curReceiver = null; 12591 } 12592 } 12593 } 12594 } 12595 } 12596 12597 private final void addBroadcastToHistoryLocked(BroadcastRecord r) { 12598 if (r.callingUid < 0) { 12599 // This was from a registerReceiver() call; ignore it. 12600 return; 12601 } 12602 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1, 12603 MAX_BROADCAST_HISTORY-1); 12604 r.finishTime = SystemClock.uptimeMillis(); 12605 mBroadcastHistory[0] = r; 12606 } 12607 12608 private final void processNextBroadcast(boolean fromMsg) { 12609 synchronized(this) { 12610 BroadcastRecord r; 12611 12612 if (DEBUG_BROADCAST) Log.v(TAG, "processNextBroadcast: " 12613 + mParallelBroadcasts.size() + " broadcasts, " 12614 + mOrderedBroadcasts.size() + " serialized broadcasts"); 12615 12616 updateCpuStats(); 12617 12618 if (fromMsg) { 12619 mBroadcastsScheduled = false; 12620 } 12621 12622 // First, deliver any non-serialized broadcasts right away. 12623 while (mParallelBroadcasts.size() > 0) { 12624 r = mParallelBroadcasts.remove(0); 12625 r.dispatchTime = SystemClock.uptimeMillis(); 12626 final int N = r.receivers.size(); 12627 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Processing parallel broadcast " 12628 + r); 12629 for (int i=0; i<N; i++) { 12630 Object target = r.receivers.get(i); 12631 if (DEBUG_BROADCAST) Log.v(TAG, 12632 "Delivering non-serialized to registered " 12633 + target + ": " + r); 12634 deliverToRegisteredReceiver(r, (BroadcastFilter)target, false); 12635 } 12636 addBroadcastToHistoryLocked(r); 12637 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Done with parallel broadcast " 12638 + r); 12639 } 12640 12641 // Now take care of the next serialized one... 12642 12643 // If we are waiting for a process to come up to handle the next 12644 // broadcast, then do nothing at this point. Just in case, we 12645 // check that the process we're waiting for still exists. 12646 if (mPendingBroadcast != null) { 12647 if (DEBUG_BROADCAST_LIGHT) { 12648 Log.v(TAG, "processNextBroadcast: waiting for " 12649 + mPendingBroadcast.curApp); 12650 } 12651 12652 boolean isDead; 12653 synchronized (mPidsSelfLocked) { 12654 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null); 12655 } 12656 if (!isDead) { 12657 // It's still alive, so keep waiting 12658 return; 12659 } else { 12660 Log.w(TAG, "pending app " + mPendingBroadcast.curApp 12661 + " died before responding to broadcast"); 12662 mPendingBroadcast = null; 12663 } 12664 } 12665 12666 boolean looped = false; 12667 12668 do { 12669 if (mOrderedBroadcasts.size() == 0) { 12670 // No more broadcasts pending, so all done! 12671 scheduleAppGcsLocked(); 12672 if (looped) { 12673 // If we had finished the last ordered broadcast, then 12674 // make sure all processes have correct oom and sched 12675 // adjustments. 12676 updateOomAdjLocked(); 12677 } 12678 return; 12679 } 12680 r = mOrderedBroadcasts.get(0); 12681 boolean forceReceive = false; 12682 12683 // Ensure that even if something goes awry with the timeout 12684 // detection, we catch "hung" broadcasts here, discard them, 12685 // and continue to make progress. 12686 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0; 12687 long now = SystemClock.uptimeMillis(); 12688 if (r.dispatchTime > 0) { 12689 if ((numReceivers > 0) && 12690 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) { 12691 Log.w(TAG, "Hung broadcast discarded after timeout failure:" 12692 + " now=" + now 12693 + " dispatchTime=" + r.dispatchTime 12694 + " startTime=" + r.receiverTime 12695 + " intent=" + r.intent 12696 + " numReceivers=" + numReceivers 12697 + " nextReceiver=" + r.nextReceiver 12698 + " state=" + r.state); 12699 broadcastTimeout(); // forcibly finish this broadcast 12700 forceReceive = true; 12701 r.state = BroadcastRecord.IDLE; 12702 } 12703 } 12704 12705 if (r.state != BroadcastRecord.IDLE) { 12706 if (DEBUG_BROADCAST) Log.d(TAG, 12707 "processNextBroadcast() called when not idle (state=" 12708 + r.state + ")"); 12709 return; 12710 } 12711 12712 if (r.receivers == null || r.nextReceiver >= numReceivers 12713 || r.resultAbort || forceReceive) { 12714 // No more receivers for this broadcast! Send the final 12715 // result if requested... 12716 if (r.resultTo != null) { 12717 try { 12718 if (DEBUG_BROADCAST) { 12719 int seq = r.intent.getIntExtra("seq", -1); 12720 Log.i(TAG, "Finishing broadcast " + r.intent.getAction() 12721 + " seq=" + seq + " app=" + r.callerApp); 12722 } 12723 performReceive(r.callerApp, r.resultTo, 12724 new Intent(r.intent), r.resultCode, 12725 r.resultData, r.resultExtras, false, false); 12726 } catch (RemoteException e) { 12727 Log.w(TAG, "Failure sending broadcast result of " + r.intent, e); 12728 } 12729 } 12730 12731 if (DEBUG_BROADCAST) Log.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG"); 12732 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG); 12733 12734 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Finished with ordered broadcast " 12735 + r); 12736 12737 // ... and on to the next... 12738 addBroadcastToHistoryLocked(r); 12739 mOrderedBroadcasts.remove(0); 12740 r = null; 12741 looped = true; 12742 continue; 12743 } 12744 } while (r == null); 12745 12746 // Get the next receiver... 12747 int recIdx = r.nextReceiver++; 12748 12749 // Keep track of when this receiver started, and make sure there 12750 // is a timeout message pending to kill it if need be. 12751 r.receiverTime = SystemClock.uptimeMillis(); 12752 if (recIdx == 0) { 12753 r.dispatchTime = r.receiverTime; 12754 12755 if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Processing ordered broadcast " 12756 + r); 12757 if (DEBUG_BROADCAST) Log.v(TAG, 12758 "Submitting BROADCAST_TIMEOUT_MSG for " 12759 + (r.receiverTime + BROADCAST_TIMEOUT)); 12760 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG); 12761 mHandler.sendMessageAtTime(msg, r.receiverTime+BROADCAST_TIMEOUT); 12762 } 12763 12764 Object nextReceiver = r.receivers.get(recIdx); 12765 if (nextReceiver instanceof BroadcastFilter) { 12766 // Simple case: this is a registered receiver who gets 12767 // a direct call. 12768 BroadcastFilter filter = (BroadcastFilter)nextReceiver; 12769 if (DEBUG_BROADCAST) Log.v(TAG, 12770 "Delivering serialized to registered " 12771 + filter + ": " + r); 12772 deliverToRegisteredReceiver(r, filter, r.ordered); 12773 if (r.receiver == null || !r.ordered) { 12774 // The receiver has already finished, so schedule to 12775 // process the next one. 12776 r.state = BroadcastRecord.IDLE; 12777 scheduleBroadcastsLocked(); 12778 } 12779 return; 12780 } 12781 12782 // Hard case: need to instantiate the receiver, possibly 12783 // starting its application process to host it. 12784 12785 ResolveInfo info = 12786 (ResolveInfo)nextReceiver; 12787 12788 boolean skip = false; 12789 int perm = checkComponentPermission(info.activityInfo.permission, 12790 r.callingPid, r.callingUid, 12791 info.activityInfo.exported 12792 ? -1 : info.activityInfo.applicationInfo.uid); 12793 if (perm != PackageManager.PERMISSION_GRANTED) { 12794 Log.w(TAG, "Permission Denial: broadcasting " 12795 + r.intent.toString() 12796 + " from " + r.callerPackage + " (pid=" + r.callingPid 12797 + ", uid=" + r.callingUid + ")" 12798 + " requires " + info.activityInfo.permission 12799 + " due to receiver " + info.activityInfo.packageName 12800 + "/" + info.activityInfo.name); 12801 skip = true; 12802 } 12803 if (r.callingUid != Process.SYSTEM_UID && 12804 r.requiredPermission != null) { 12805 try { 12806 perm = ActivityThread.getPackageManager(). 12807 checkPermission(r.requiredPermission, 12808 info.activityInfo.applicationInfo.packageName); 12809 } catch (RemoteException e) { 12810 perm = PackageManager.PERMISSION_DENIED; 12811 } 12812 if (perm != PackageManager.PERMISSION_GRANTED) { 12813 Log.w(TAG, "Permission Denial: receiving " 12814 + r.intent + " to " 12815 + info.activityInfo.applicationInfo.packageName 12816 + " requires " + r.requiredPermission 12817 + " due to sender " + r.callerPackage 12818 + " (uid " + r.callingUid + ")"); 12819 skip = true; 12820 } 12821 } 12822 if (r.curApp != null && r.curApp.crashing) { 12823 // If the target process is crashing, just skip it. 12824 skip = true; 12825 } 12826 12827 if (skip) { 12828 r.receiver = null; 12829 r.curFilter = null; 12830 r.state = BroadcastRecord.IDLE; 12831 scheduleBroadcastsLocked(); 12832 return; 12833 } 12834 12835 r.state = BroadcastRecord.APP_RECEIVE; 12836 String targetProcess = info.activityInfo.processName; 12837 r.curComponent = new ComponentName( 12838 info.activityInfo.applicationInfo.packageName, 12839 info.activityInfo.name); 12840 r.curReceiver = info.activityInfo; 12841 12842 // Is this receiver's application already running? 12843 ProcessRecord app = getProcessRecordLocked(targetProcess, 12844 info.activityInfo.applicationInfo.uid); 12845 if (app != null && app.thread != null) { 12846 try { 12847 processCurBroadcastLocked(r, app); 12848 return; 12849 } catch (RemoteException e) { 12850 Log.w(TAG, "Exception when sending broadcast to " 12851 + r.curComponent, e); 12852 } 12853 12854 // If a dead object exception was thrown -- fall through to 12855 // restart the application. 12856 } 12857 12858 // Not running -- get it started, to be executed when the app comes up. 12859 if ((r.curApp=startProcessLocked(targetProcess, 12860 info.activityInfo.applicationInfo, true, 12861 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND, 12862 "broadcast", r.curComponent, 12863 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0)) 12864 == null) { 12865 // Ah, this recipient is unavailable. Finish it if necessary, 12866 // and mark the broadcast record as ready for the next. 12867 Log.w(TAG, "Unable to launch app " 12868 + info.activityInfo.applicationInfo.packageName + "/" 12869 + info.activityInfo.applicationInfo.uid + " for broadcast " 12870 + r.intent + ": process is bad"); 12871 logBroadcastReceiverDiscard(r); 12872 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 12873 r.resultExtras, r.resultAbort, true); 12874 scheduleBroadcastsLocked(); 12875 r.state = BroadcastRecord.IDLE; 12876 return; 12877 } 12878 12879 mPendingBroadcast = r; 12880 } 12881 } 12882 12883 // ========================================================= 12884 // INSTRUMENTATION 12885 // ========================================================= 12886 12887 public boolean startInstrumentation(ComponentName className, 12888 String profileFile, int flags, Bundle arguments, 12889 IInstrumentationWatcher watcher) { 12890 // Refuse possible leaked file descriptors 12891 if (arguments != null && arguments.hasFileDescriptors()) { 12892 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12893 } 12894 12895 synchronized(this) { 12896 InstrumentationInfo ii = null; 12897 ApplicationInfo ai = null; 12898 try { 12899 ii = mContext.getPackageManager().getInstrumentationInfo( 12900 className, STOCK_PM_FLAGS); 12901 ai = mContext.getPackageManager().getApplicationInfo( 12902 ii.targetPackage, STOCK_PM_FLAGS); 12903 } catch (PackageManager.NameNotFoundException e) { 12904 } 12905 if (ii == null) { 12906 reportStartInstrumentationFailure(watcher, className, 12907 "Unable to find instrumentation info for: " + className); 12908 return false; 12909 } 12910 if (ai == null) { 12911 reportStartInstrumentationFailure(watcher, className, 12912 "Unable to find instrumentation target package: " + ii.targetPackage); 12913 return false; 12914 } 12915 12916 int match = mContext.getPackageManager().checkSignatures( 12917 ii.targetPackage, ii.packageName); 12918 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 12919 String msg = "Permission Denial: starting instrumentation " 12920 + className + " from pid=" 12921 + Binder.getCallingPid() 12922 + ", uid=" + Binder.getCallingPid() 12923 + " not allowed because package " + ii.packageName 12924 + " does not have a signature matching the target " 12925 + ii.targetPackage; 12926 reportStartInstrumentationFailure(watcher, className, msg); 12927 throw new SecurityException(msg); 12928 } 12929 12930 final long origId = Binder.clearCallingIdentity(); 12931 forceStopPackageLocked(ii.targetPackage, -1, true); 12932 ProcessRecord app = addAppLocked(ai); 12933 app.instrumentationClass = className; 12934 app.instrumentationInfo = ai; 12935 app.instrumentationProfileFile = profileFile; 12936 app.instrumentationArguments = arguments; 12937 app.instrumentationWatcher = watcher; 12938 app.instrumentationResultClass = className; 12939 Binder.restoreCallingIdentity(origId); 12940 } 12941 12942 return true; 12943 } 12944 12945 /** 12946 * Report errors that occur while attempting to start Instrumentation. Always writes the 12947 * error to the logs, but if somebody is watching, send the report there too. This enables 12948 * the "am" command to report errors with more information. 12949 * 12950 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 12951 * @param cn The component name of the instrumentation. 12952 * @param report The error report. 12953 */ 12954 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 12955 ComponentName cn, String report) { 12956 Log.w(TAG, report); 12957 try { 12958 if (watcher != null) { 12959 Bundle results = new Bundle(); 12960 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 12961 results.putString("Error", report); 12962 watcher.instrumentationStatus(cn, -1, results); 12963 } 12964 } catch (RemoteException e) { 12965 Log.w(TAG, e); 12966 } 12967 } 12968 12969 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 12970 if (app.instrumentationWatcher != null) { 12971 try { 12972 // NOTE: IInstrumentationWatcher *must* be oneway here 12973 app.instrumentationWatcher.instrumentationFinished( 12974 app.instrumentationClass, 12975 resultCode, 12976 results); 12977 } catch (RemoteException e) { 12978 } 12979 } 12980 app.instrumentationWatcher = null; 12981 app.instrumentationClass = null; 12982 app.instrumentationInfo = null; 12983 app.instrumentationProfileFile = null; 12984 app.instrumentationArguments = null; 12985 12986 forceStopPackageLocked(app.processName, -1, false); 12987 } 12988 12989 public void finishInstrumentation(IApplicationThread target, 12990 int resultCode, Bundle results) { 12991 // Refuse possible leaked file descriptors 12992 if (results != null && results.hasFileDescriptors()) { 12993 throw new IllegalArgumentException("File descriptors passed in Intent"); 12994 } 12995 12996 synchronized(this) { 12997 ProcessRecord app = getRecordForAppLocked(target); 12998 if (app == null) { 12999 Log.w(TAG, "finishInstrumentation: no app for " + target); 13000 return; 13001 } 13002 final long origId = Binder.clearCallingIdentity(); 13003 finishInstrumentationLocked(app, resultCode, results); 13004 Binder.restoreCallingIdentity(origId); 13005 } 13006 } 13007 13008 // ========================================================= 13009 // CONFIGURATION 13010 // ========================================================= 13011 13012 public ConfigurationInfo getDeviceConfigurationInfo() { 13013 ConfigurationInfo config = new ConfigurationInfo(); 13014 synchronized (this) { 13015 config.reqTouchScreen = mConfiguration.touchscreen; 13016 config.reqKeyboardType = mConfiguration.keyboard; 13017 config.reqNavigation = mConfiguration.navigation; 13018 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13019 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13020 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13021 } 13022 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13023 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13024 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13025 } 13026 config.reqGlEsVersion = GL_ES_VERSION; 13027 } 13028 return config; 13029 } 13030 13031 public Configuration getConfiguration() { 13032 Configuration ci; 13033 synchronized(this) { 13034 ci = new Configuration(mConfiguration); 13035 } 13036 return ci; 13037 } 13038 13039 public void updateConfiguration(Configuration values) { 13040 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13041 "updateConfiguration()"); 13042 13043 synchronized(this) { 13044 if (values == null && mWindowManager != null) { 13045 // sentinel: fetch the current configuration from the window manager 13046 values = mWindowManager.computeNewConfiguration(); 13047 } 13048 13049 final long origId = Binder.clearCallingIdentity(); 13050 updateConfigurationLocked(values, null); 13051 Binder.restoreCallingIdentity(origId); 13052 } 13053 } 13054 13055 /** 13056 * Do either or both things: (1) change the current configuration, and (2) 13057 * make sure the given activity is running with the (now) current 13058 * configuration. Returns true if the activity has been left running, or 13059 * false if <var>starting</var> is being destroyed to match the new 13060 * configuration. 13061 */ 13062 public boolean updateConfigurationLocked(Configuration values, 13063 HistoryRecord starting) { 13064 int changes = 0; 13065 13066 boolean kept = true; 13067 13068 if (values != null) { 13069 Configuration newConfig = new Configuration(mConfiguration); 13070 changes = newConfig.updateFrom(values); 13071 if (changes != 0) { 13072 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13073 Log.i(TAG, "Updating configuration to: " + values); 13074 } 13075 13076 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 13077 13078 if (values.locale != null) { 13079 saveLocaleLocked(values.locale, 13080 !values.locale.equals(mConfiguration.locale), 13081 values.userSetLocale); 13082 } 13083 13084 mConfiguration = newConfig; 13085 Log.i(TAG, "Config changed: " + newConfig); 13086 13087 AttributeCache ac = AttributeCache.instance(); 13088 if (ac != null) { 13089 ac.updateConfiguration(mConfiguration); 13090 } 13091 13092 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 13093 msg.obj = new Configuration(mConfiguration); 13094 mHandler.sendMessage(msg); 13095 13096 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13097 ProcessRecord app = mLruProcesses.get(i); 13098 try { 13099 if (app.thread != null) { 13100 if (DEBUG_CONFIGURATION) Log.v(TAG, "Sending to proc " 13101 + app.processName + " new config " + mConfiguration); 13102 app.thread.scheduleConfigurationChanged(mConfiguration); 13103 } 13104 } catch (Exception e) { 13105 } 13106 } 13107 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 13108 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 13109 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 13110 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 13111 null, false, false, MY_PID, Process.SYSTEM_UID); 13112 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 13113 broadcastIntentLocked(null, null, 13114 new Intent(Intent.ACTION_LOCALE_CHANGED), 13115 null, null, 0, null, null, 13116 null, false, false, MY_PID, Process.SYSTEM_UID); 13117 } 13118 } 13119 } 13120 13121 if (changes != 0 && starting == null) { 13122 // If the configuration changed, and the caller is not already 13123 // in the process of starting an activity, then find the top 13124 // activity to check if its configuration needs to change. 13125 starting = topRunningActivityLocked(null); 13126 } 13127 13128 if (starting != null) { 13129 kept = ensureActivityConfigurationLocked(starting, changes); 13130 if (kept) { 13131 // If this didn't result in the starting activity being 13132 // destroyed, then we need to make sure at this point that all 13133 // other activities are made visible. 13134 if (DEBUG_SWITCH) Log.i(TAG, "Config didn't destroy " + starting 13135 + ", ensuring others are correct."); 13136 ensureActivitiesVisibleLocked(starting, changes); 13137 } 13138 } 13139 13140 return kept; 13141 } 13142 13143 private final boolean relaunchActivityLocked(HistoryRecord r, 13144 int changes, boolean andResume) { 13145 List<ResultInfo> results = null; 13146 List<Intent> newIntents = null; 13147 if (andResume) { 13148 results = r.results; 13149 newIntents = r.newIntents; 13150 } 13151 if (DEBUG_SWITCH) Log.v(TAG, "Relaunching: " + r 13152 + " with results=" + results + " newIntents=" + newIntents 13153 + " andResume=" + andResume); 13154 EventLog.writeEvent(andResume ? EventLogTags.AM_RELAUNCH_RESUME_ACTIVITY 13155 : EventLogTags.AM_RELAUNCH_ACTIVITY, System.identityHashCode(r), 13156 r.task.taskId, r.shortComponentName); 13157 13158 r.startFreezingScreenLocked(r.app, 0); 13159 13160 try { 13161 if (DEBUG_SWITCH) Log.i(TAG, "Switch is restarting resumed " + r); 13162 r.app.thread.scheduleRelaunchActivity(r, results, newIntents, 13163 changes, !andResume, mConfiguration); 13164 // Note: don't need to call pauseIfSleepingLocked() here, because 13165 // the caller will only pass in 'andResume' if this activity is 13166 // currently resumed, which implies we aren't sleeping. 13167 } catch (RemoteException e) { 13168 return false; 13169 } 13170 13171 if (andResume) { 13172 r.results = null; 13173 r.newIntents = null; 13174 reportResumedActivityLocked(r); 13175 } 13176 13177 return true; 13178 } 13179 13180 /** 13181 * Make sure the given activity matches the current configuration. Returns 13182 * false if the activity had to be destroyed. Returns true if the 13183 * configuration is the same, or the activity will remain running as-is 13184 * for whatever reason. Ensures the HistoryRecord is updated with the 13185 * correct configuration and all other bookkeeping is handled. 13186 */ 13187 private final boolean ensureActivityConfigurationLocked(HistoryRecord r, 13188 int globalChanges) { 13189 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 13190 "Ensuring correct configuration: " + r); 13191 13192 // Short circuit: if the two configurations are the exact same 13193 // object (the common case), then there is nothing to do. 13194 Configuration newConfig = mConfiguration; 13195 if (r.configuration == newConfig) { 13196 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 13197 "Configuration unchanged in " + r); 13198 return true; 13199 } 13200 13201 // We don't worry about activities that are finishing. 13202 if (r.finishing) { 13203 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 13204 "Configuration doesn't matter in finishing " + r); 13205 r.stopFreezingScreenLocked(false); 13206 return true; 13207 } 13208 13209 // Okay we now are going to make this activity have the new config. 13210 // But then we need to figure out how it needs to deal with that. 13211 Configuration oldConfig = r.configuration; 13212 r.configuration = newConfig; 13213 13214 // If the activity isn't currently running, just leave the new 13215 // configuration and it will pick that up next time it starts. 13216 if (r.app == null || r.app.thread == null) { 13217 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 13218 "Configuration doesn't matter not running " + r); 13219 r.stopFreezingScreenLocked(false); 13220 return true; 13221 } 13222 13223 // If the activity isn't persistent, there is a chance we will 13224 // need to restart it. 13225 if (!r.persistent) { 13226 13227 // Figure out what has changed between the two configurations. 13228 int changes = oldConfig.diff(newConfig); 13229 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13230 Log.v(TAG, "Checking to restart " + r.info.name + ": changed=0x" 13231 + Integer.toHexString(changes) + ", handles=0x" 13232 + Integer.toHexString(r.info.configChanges) 13233 + ", newConfig=" + newConfig); 13234 } 13235 if ((changes&(~r.info.configChanges)) != 0) { 13236 // Aha, the activity isn't handling the change, so DIE DIE DIE. 13237 r.configChangeFlags |= changes; 13238 r.startFreezingScreenLocked(r.app, globalChanges); 13239 if (r.app == null || r.app.thread == null) { 13240 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 13241 "Switch is destroying non-running " + r); 13242 destroyActivityLocked(r, true); 13243 } else if (r.state == ActivityState.PAUSING) { 13244 // A little annoying: we are waiting for this activity to 13245 // finish pausing. Let's not do anything now, but just 13246 // flag that it needs to be restarted when done pausing. 13247 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 13248 "Switch is skipping already pausing " + r); 13249 r.configDestroy = true; 13250 return true; 13251 } else if (r.state == ActivityState.RESUMED) { 13252 // Try to optimize this case: the configuration is changing 13253 // and we need to restart the top, resumed activity. 13254 // Instead of doing the normal handshaking, just say 13255 // "restart!". 13256 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 13257 "Switch is restarting resumed " + r); 13258 relaunchActivityLocked(r, r.configChangeFlags, true); 13259 r.configChangeFlags = 0; 13260 } else { 13261 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG, 13262 "Switch is restarting non-resumed " + r); 13263 relaunchActivityLocked(r, r.configChangeFlags, false); 13264 r.configChangeFlags = 0; 13265 } 13266 13267 // All done... tell the caller we weren't able to keep this 13268 // activity around. 13269 return false; 13270 } 13271 } 13272 13273 // Default case: the activity can handle this new configuration, so 13274 // hand it over. Note that we don't need to give it the new 13275 // configuration, since we always send configuration changes to all 13276 // process when they happen so it can just use whatever configuration 13277 // it last got. 13278 if (r.app != null && r.app.thread != null) { 13279 try { 13280 if (DEBUG_CONFIGURATION) Log.v(TAG, "Sending new config to " + r); 13281 r.app.thread.scheduleActivityConfigurationChanged(r); 13282 } catch (RemoteException e) { 13283 // If process died, whatever. 13284 } 13285 } 13286 r.stopFreezingScreenLocked(false); 13287 13288 return true; 13289 } 13290 13291 /** 13292 * Save the locale. You must be inside a synchronized (this) block. 13293 */ 13294 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 13295 if(isDiff) { 13296 SystemProperties.set("user.language", l.getLanguage()); 13297 SystemProperties.set("user.region", l.getCountry()); 13298 } 13299 13300 if(isPersist) { 13301 SystemProperties.set("persist.sys.language", l.getLanguage()); 13302 SystemProperties.set("persist.sys.country", l.getCountry()); 13303 SystemProperties.set("persist.sys.localevar", l.getVariant()); 13304 } 13305 } 13306 13307 // ========================================================= 13308 // LIFETIME MANAGEMENT 13309 // ========================================================= 13310 13311 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 13312 ProcessRecord TOP_APP, boolean recursed) { 13313 if (mAdjSeq == app.adjSeq) { 13314 // This adjustment has already been computed. If we are calling 13315 // from the top, we may have already computed our adjustment with 13316 // an earlier hidden adjustment that isn't really for us... if 13317 // so, use the new hidden adjustment. 13318 if (!recursed && app.hidden) { 13319 app.curAdj = hiddenAdj; 13320 } 13321 return app.curAdj; 13322 } 13323 13324 if (app.thread == null) { 13325 app.adjSeq = mAdjSeq; 13326 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13327 return (app.curAdj=EMPTY_APP_ADJ); 13328 } 13329 13330 if (app.maxAdj <= FOREGROUND_APP_ADJ) { 13331 // The max adjustment doesn't allow this app to be anything 13332 // below foreground, so it is not worth doing work for it. 13333 app.adjType = "fixed"; 13334 app.adjSeq = mAdjSeq; 13335 app.curRawAdj = app.maxAdj; 13336 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 13337 return (app.curAdj=app.maxAdj); 13338 } 13339 13340 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 13341 app.adjSource = null; 13342 app.adjTarget = null; 13343 app.empty = false; 13344 app.hidden = false; 13345 13346 // Determine the importance of the process, starting with most 13347 // important to least, and assign an appropriate OOM adjustment. 13348 int adj; 13349 int schedGroup; 13350 int N; 13351 if (app == TOP_APP) { 13352 // The last app on the list is the foreground app. 13353 adj = FOREGROUND_APP_ADJ; 13354 schedGroup = Process.THREAD_GROUP_DEFAULT; 13355 app.adjType = "top-activity"; 13356 } else if (app.instrumentationClass != null) { 13357 // Don't want to kill running instrumentation. 13358 adj = FOREGROUND_APP_ADJ; 13359 schedGroup = Process.THREAD_GROUP_DEFAULT; 13360 app.adjType = "instrumentation"; 13361 } else if (app.persistentActivities > 0) { 13362 // Special persistent activities... shouldn't be used these days. 13363 adj = FOREGROUND_APP_ADJ; 13364 schedGroup = Process.THREAD_GROUP_DEFAULT; 13365 app.adjType = "persistent"; 13366 } else if (app.curReceiver != null || 13367 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) { 13368 // An app that is currently receiving a broadcast also 13369 // counts as being in the foreground. 13370 adj = FOREGROUND_APP_ADJ; 13371 schedGroup = Process.THREAD_GROUP_DEFAULT; 13372 app.adjType = "broadcast"; 13373 } else if (app.executingServices.size() > 0) { 13374 // An app that is currently executing a service callback also 13375 // counts as being in the foreground. 13376 adj = FOREGROUND_APP_ADJ; 13377 schedGroup = Process.THREAD_GROUP_DEFAULT; 13378 app.adjType = "exec-service"; 13379 } else if (app.foregroundServices) { 13380 // The user is aware of this app, so make it visible. 13381 adj = VISIBLE_APP_ADJ; 13382 schedGroup = Process.THREAD_GROUP_DEFAULT; 13383 app.adjType = "foreground-service"; 13384 } else if (app.forcingToForeground != null) { 13385 // The user is aware of this app, so make it visible. 13386 adj = VISIBLE_APP_ADJ; 13387 schedGroup = Process.THREAD_GROUP_DEFAULT; 13388 app.adjType = "force-foreground"; 13389 app.adjSource = app.forcingToForeground; 13390 } else if (app == mHomeProcess) { 13391 // This process is hosting what we currently consider to be the 13392 // home app, so we don't want to let it go into the background. 13393 adj = HOME_APP_ADJ; 13394 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13395 app.adjType = "home"; 13396 } else if ((N=app.activities.size()) != 0) { 13397 // This app is in the background with paused activities. 13398 app.hidden = true; 13399 adj = hiddenAdj; 13400 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13401 app.adjType = "bg-activities"; 13402 N = app.activities.size(); 13403 for (int j=0; j<N; j++) { 13404 if (((HistoryRecord)app.activities.get(j)).visible) { 13405 // This app has a visible activity! 13406 app.hidden = false; 13407 adj = VISIBLE_APP_ADJ; 13408 schedGroup = Process.THREAD_GROUP_DEFAULT; 13409 app.adjType = "visible"; 13410 break; 13411 } 13412 } 13413 } else { 13414 // A very not-needed process. If this is lower in the lru list, 13415 // we will push it in to the empty bucket. 13416 app.hidden = true; 13417 app.empty = true; 13418 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13419 adj = hiddenAdj; 13420 app.adjType = "bg-empty"; 13421 } 13422 13423 //Log.i(TAG, "OOM " + app + ": initial adj=" + adj); 13424 13425 // By default, we use the computed adjustment. It may be changed if 13426 // there are applications dependent on our services or providers, but 13427 // this gives us a baseline and makes sure we don't get into an 13428 // infinite recursion. 13429 app.adjSeq = mAdjSeq; 13430 app.curRawAdj = adj; 13431 13432 if (mBackupTarget != null && app == mBackupTarget.app) { 13433 // If possible we want to avoid killing apps while they're being backed up 13434 if (adj > BACKUP_APP_ADJ) { 13435 if (DEBUG_BACKUP) Log.v(TAG, "oom BACKUP_APP_ADJ for " + app); 13436 adj = BACKUP_APP_ADJ; 13437 app.adjType = "backup"; 13438 app.hidden = false; 13439 } 13440 } 13441 13442 if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ 13443 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13444 final long now = SystemClock.uptimeMillis(); 13445 // This process is more important if the top activity is 13446 // bound to the service. 13447 Iterator jt = app.services.iterator(); 13448 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) { 13449 ServiceRecord s = (ServiceRecord)jt.next(); 13450 if (s.startRequested) { 13451 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) { 13452 // This service has seen some activity within 13453 // recent memory, so we will keep its process ahead 13454 // of the background processes. 13455 if (adj > SECONDARY_SERVER_ADJ) { 13456 adj = SECONDARY_SERVER_ADJ; 13457 app.adjType = "started-services"; 13458 app.hidden = false; 13459 } 13460 } 13461 } 13462 if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ 13463 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13464 Iterator<ConnectionRecord> kt 13465 = s.connections.values().iterator(); 13466 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) { 13467 // XXX should compute this based on the max of 13468 // all connected clients. 13469 ConnectionRecord cr = kt.next(); 13470 if (cr.binding.client == app) { 13471 // Binding to ourself is not interesting. 13472 continue; 13473 } 13474 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) { 13475 ProcessRecord client = cr.binding.client; 13476 int myHiddenAdj = hiddenAdj; 13477 if (myHiddenAdj > client.hiddenAdj) { 13478 if (client.hiddenAdj > VISIBLE_APP_ADJ) { 13479 myHiddenAdj = client.hiddenAdj; 13480 } else { 13481 myHiddenAdj = VISIBLE_APP_ADJ; 13482 } 13483 } 13484 int clientAdj = computeOomAdjLocked( 13485 client, myHiddenAdj, TOP_APP, true); 13486 if (adj > clientAdj) { 13487 adj = clientAdj > VISIBLE_APP_ADJ 13488 ? clientAdj : VISIBLE_APP_ADJ; 13489 if (!client.hidden) { 13490 app.hidden = false; 13491 } 13492 app.adjType = "service"; 13493 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13494 .REASON_SERVICE_IN_USE; 13495 app.adjSource = cr.binding.client; 13496 app.adjTarget = s.serviceInfo.name; 13497 } 13498 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 13499 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 13500 schedGroup = Process.THREAD_GROUP_DEFAULT; 13501 } 13502 } 13503 } 13504 HistoryRecord a = cr.activity; 13505 //if (a != null) { 13506 // Log.i(TAG, "Connection to " + a ": state=" + a.state); 13507 //} 13508 if (a != null && adj > FOREGROUND_APP_ADJ && 13509 (a.state == ActivityState.RESUMED 13510 || a.state == ActivityState.PAUSING)) { 13511 adj = FOREGROUND_APP_ADJ; 13512 schedGroup = Process.THREAD_GROUP_DEFAULT; 13513 app.hidden = false; 13514 app.adjType = "service"; 13515 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13516 .REASON_SERVICE_IN_USE; 13517 app.adjSource = a; 13518 app.adjTarget = s.serviceInfo.name; 13519 } 13520 } 13521 } 13522 } 13523 13524 // Finally, f this process has active services running in it, we 13525 // would like to avoid killing it unless it would prevent the current 13526 // application from running. By default we put the process in 13527 // with the rest of the background processes; as we scan through 13528 // its services we may bump it up from there. 13529 if (adj > hiddenAdj) { 13530 adj = hiddenAdj; 13531 app.hidden = false; 13532 app.adjType = "bg-services"; 13533 } 13534 } 13535 13536 if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ 13537 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13538 Iterator jt = app.pubProviders.values().iterator(); 13539 while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ 13540 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13541 ContentProviderRecord cpr = (ContentProviderRecord)jt.next(); 13542 if (cpr.clients.size() != 0) { 13543 Iterator<ProcessRecord> kt = cpr.clients.iterator(); 13544 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) { 13545 ProcessRecord client = kt.next(); 13546 if (client == app) { 13547 // Being our own client is not interesting. 13548 continue; 13549 } 13550 int myHiddenAdj = hiddenAdj; 13551 if (myHiddenAdj > client.hiddenAdj) { 13552 if (client.hiddenAdj > FOREGROUND_APP_ADJ) { 13553 myHiddenAdj = client.hiddenAdj; 13554 } else { 13555 myHiddenAdj = FOREGROUND_APP_ADJ; 13556 } 13557 } 13558 int clientAdj = computeOomAdjLocked( 13559 client, myHiddenAdj, TOP_APP, true); 13560 if (adj > clientAdj) { 13561 adj = clientAdj > FOREGROUND_APP_ADJ 13562 ? clientAdj : FOREGROUND_APP_ADJ; 13563 if (!client.hidden) { 13564 app.hidden = false; 13565 } 13566 app.adjType = "provider"; 13567 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13568 .REASON_PROVIDER_IN_USE; 13569 app.adjSource = client; 13570 app.adjTarget = cpr.info.name; 13571 } 13572 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 13573 schedGroup = Process.THREAD_GROUP_DEFAULT; 13574 } 13575 } 13576 } 13577 // If the provider has external (non-framework) process 13578 // dependencies, ensure that its adjustment is at least 13579 // FOREGROUND_APP_ADJ. 13580 if (cpr.externals != 0) { 13581 if (adj > FOREGROUND_APP_ADJ) { 13582 adj = FOREGROUND_APP_ADJ; 13583 schedGroup = Process.THREAD_GROUP_DEFAULT; 13584 app.hidden = false; 13585 app.adjType = "provider"; 13586 app.adjTarget = cpr.info.name; 13587 } 13588 } 13589 } 13590 } 13591 13592 app.curRawAdj = adj; 13593 13594 //Log.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 13595 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 13596 if (adj > app.maxAdj) { 13597 adj = app.maxAdj; 13598 if (app.maxAdj <= VISIBLE_APP_ADJ) { 13599 schedGroup = Process.THREAD_GROUP_DEFAULT; 13600 } 13601 } 13602 13603 app.curAdj = adj; 13604 app.curSchedGroup = schedGroup; 13605 13606 return adj; 13607 } 13608 13609 /** 13610 * Ask a given process to GC right now. 13611 */ 13612 final void performAppGcLocked(ProcessRecord app) { 13613 try { 13614 app.lastRequestedGc = SystemClock.uptimeMillis(); 13615 if (app.thread != null) { 13616 if (app.reportLowMemory) { 13617 app.reportLowMemory = false; 13618 app.thread.scheduleLowMemory(); 13619 } else { 13620 app.thread.processInBackground(); 13621 } 13622 } 13623 } catch (Exception e) { 13624 // whatever. 13625 } 13626 } 13627 13628 /** 13629 * Returns true if things are idle enough to perform GCs. 13630 */ 13631 private final boolean canGcNow() { 13632 return mParallelBroadcasts.size() == 0 13633 && mOrderedBroadcasts.size() == 0 13634 && (mSleeping || (mResumedActivity != null && 13635 mResumedActivity.idle)); 13636 } 13637 13638 /** 13639 * Perform GCs on all processes that are waiting for it, but only 13640 * if things are idle. 13641 */ 13642 final void performAppGcsLocked() { 13643 final int N = mProcessesToGc.size(); 13644 if (N <= 0) { 13645 return; 13646 } 13647 if (canGcNow()) { 13648 while (mProcessesToGc.size() > 0) { 13649 ProcessRecord proc = mProcessesToGc.remove(0); 13650 if (proc.curRawAdj > VISIBLE_APP_ADJ || proc.reportLowMemory) { 13651 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 13652 <= SystemClock.uptimeMillis()) { 13653 // To avoid spamming the system, we will GC processes one 13654 // at a time, waiting a few seconds between each. 13655 performAppGcLocked(proc); 13656 scheduleAppGcsLocked(); 13657 return; 13658 } else { 13659 // It hasn't been long enough since we last GCed this 13660 // process... put it in the list to wait for its time. 13661 addProcessToGcListLocked(proc); 13662 break; 13663 } 13664 } 13665 } 13666 13667 scheduleAppGcsLocked(); 13668 } 13669 } 13670 13671 /** 13672 * If all looks good, perform GCs on all processes waiting for them. 13673 */ 13674 final void performAppGcsIfAppropriateLocked() { 13675 if (canGcNow()) { 13676 performAppGcsLocked(); 13677 return; 13678 } 13679 // Still not idle, wait some more. 13680 scheduleAppGcsLocked(); 13681 } 13682 13683 /** 13684 * Schedule the execution of all pending app GCs. 13685 */ 13686 final void scheduleAppGcsLocked() { 13687 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 13688 13689 if (mProcessesToGc.size() > 0) { 13690 // Schedule a GC for the time to the next process. 13691 ProcessRecord proc = mProcessesToGc.get(0); 13692 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 13693 13694 long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL; 13695 long now = SystemClock.uptimeMillis(); 13696 if (when < (now+GC_TIMEOUT)) { 13697 when = now + GC_TIMEOUT; 13698 } 13699 mHandler.sendMessageAtTime(msg, when); 13700 } 13701 } 13702 13703 /** 13704 * Add a process to the array of processes waiting to be GCed. Keeps the 13705 * list in sorted order by the last GC time. The process can't already be 13706 * on the list. 13707 */ 13708 final void addProcessToGcListLocked(ProcessRecord proc) { 13709 boolean added = false; 13710 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 13711 if (mProcessesToGc.get(i).lastRequestedGc < 13712 proc.lastRequestedGc) { 13713 added = true; 13714 mProcessesToGc.add(i+1, proc); 13715 break; 13716 } 13717 } 13718 if (!added) { 13719 mProcessesToGc.add(0, proc); 13720 } 13721 } 13722 13723 /** 13724 * Set up to ask a process to GC itself. This will either do it 13725 * immediately, or put it on the list of processes to gc the next 13726 * time things are idle. 13727 */ 13728 final void scheduleAppGcLocked(ProcessRecord app) { 13729 long now = SystemClock.uptimeMillis(); 13730 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 13731 return; 13732 } 13733 if (!mProcessesToGc.contains(app)) { 13734 addProcessToGcListLocked(app); 13735 scheduleAppGcsLocked(); 13736 } 13737 } 13738 13739 private final boolean updateOomAdjLocked( 13740 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) { 13741 app.hiddenAdj = hiddenAdj; 13742 13743 if (app.thread == null) { 13744 return true; 13745 } 13746 13747 int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false); 13748 13749 if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) { 13750 if (app.curRawAdj != app.setRawAdj) { 13751 if (app.curRawAdj > FOREGROUND_APP_ADJ 13752 && app.setRawAdj <= FOREGROUND_APP_ADJ) { 13753 // If this app is transitioning from foreground to 13754 // non-foreground, have it do a gc. 13755 scheduleAppGcLocked(app); 13756 } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ 13757 && app.setRawAdj < HIDDEN_APP_MIN_ADJ) { 13758 // Likewise do a gc when an app is moving in to the 13759 // background (such as a service stopping). 13760 scheduleAppGcLocked(app); 13761 } 13762 app.setRawAdj = app.curRawAdj; 13763 } 13764 if (adj != app.setAdj) { 13765 if (Process.setOomAdj(app.pid, adj)) { 13766 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v( 13767 TAG, "Set app " + app.processName + 13768 " oom adj to " + adj); 13769 app.setAdj = adj; 13770 } else { 13771 return false; 13772 } 13773 } 13774 if (app.setSchedGroup != app.curSchedGroup) { 13775 app.setSchedGroup = app.curSchedGroup; 13776 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v(TAG, 13777 "Setting process group of " + app.processName 13778 + " to " + app.curSchedGroup); 13779 if (true) { 13780 long oldId = Binder.clearCallingIdentity(); 13781 try { 13782 Process.setProcessGroup(app.pid, app.curSchedGroup); 13783 } catch (Exception e) { 13784 Log.w(TAG, "Failed setting process group of " + app.pid 13785 + " to " + app.curSchedGroup); 13786 e.printStackTrace(); 13787 } finally { 13788 Binder.restoreCallingIdentity(oldId); 13789 } 13790 } 13791 if (false) { 13792 if (app.thread != null) { 13793 try { 13794 app.thread.setSchedulingGroup(app.curSchedGroup); 13795 } catch (RemoteException e) { 13796 } 13797 } 13798 } 13799 } 13800 } 13801 13802 return true; 13803 } 13804 13805 private final HistoryRecord resumedAppLocked() { 13806 HistoryRecord resumedActivity = mResumedActivity; 13807 if (resumedActivity == null || resumedActivity.app == null) { 13808 resumedActivity = mPausingActivity; 13809 if (resumedActivity == null || resumedActivity.app == null) { 13810 resumedActivity = topRunningActivityLocked(null); 13811 } 13812 } 13813 return resumedActivity; 13814 } 13815 13816 private final boolean updateOomAdjLocked(ProcessRecord app) { 13817 final HistoryRecord TOP_ACT = resumedAppLocked(); 13818 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13819 int curAdj = app.curAdj; 13820 final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ 13821 && app.curAdj <= HIDDEN_APP_MAX_ADJ; 13822 13823 mAdjSeq++; 13824 13825 final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP); 13826 if (res) { 13827 final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ 13828 && app.curAdj <= HIDDEN_APP_MAX_ADJ; 13829 if (nowHidden != wasHidden) { 13830 // Changed to/from hidden state, so apps after it in the LRU 13831 // list may also be changed. 13832 updateOomAdjLocked(); 13833 } 13834 } 13835 return res; 13836 } 13837 13838 private final boolean updateOomAdjLocked() { 13839 boolean didOomAdj = true; 13840 final HistoryRecord TOP_ACT = resumedAppLocked(); 13841 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 13842 13843 if (false) { 13844 RuntimeException e = new RuntimeException(); 13845 e.fillInStackTrace(); 13846 Log.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 13847 } 13848 13849 mAdjSeq++; 13850 13851 // First try updating the OOM adjustment for each of the 13852 // application processes based on their current state. 13853 int i = mLruProcesses.size(); 13854 int curHiddenAdj = HIDDEN_APP_MIN_ADJ; 13855 while (i > 0) { 13856 i--; 13857 ProcessRecord app = mLruProcesses.get(i); 13858 //Log.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj); 13859 if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) { 13860 if (curHiddenAdj < EMPTY_APP_ADJ 13861 && app.curAdj == curHiddenAdj) { 13862 curHiddenAdj++; 13863 } 13864 } else { 13865 didOomAdj = false; 13866 } 13867 } 13868 13869 // If we return false, we will fall back on killing processes to 13870 // have a fixed limit. Do this if a limit has been requested; else 13871 // only return false if one of the adjustments failed. 13872 return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj; 13873 } 13874 13875 private final void trimApplications() { 13876 synchronized (this) { 13877 int i; 13878 13879 // First remove any unused application processes whose package 13880 // has been removed. 13881 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 13882 final ProcessRecord app = mRemovedProcesses.get(i); 13883 if (app.activities.size() == 0 13884 && app.curReceiver == null && app.services.size() == 0) { 13885 Log.i( 13886 TAG, "Exiting empty application process " 13887 + app.processName + " (" 13888 + (app.thread != null ? app.thread.asBinder() : null) 13889 + ")\n"); 13890 if (app.pid > 0 && app.pid != MY_PID) { 13891 Process.killProcess(app.pid); 13892 } else { 13893 try { 13894 app.thread.scheduleExit(); 13895 } catch (Exception e) { 13896 // Ignore exceptions. 13897 } 13898 } 13899 cleanUpApplicationRecordLocked(app, false, -1); 13900 mRemovedProcesses.remove(i); 13901 13902 if (app.persistent) { 13903 if (app.persistent) { 13904 addAppLocked(app.info); 13905 } 13906 } 13907 } 13908 } 13909 13910 // Now try updating the OOM adjustment for each of the 13911 // application processes based on their current state. 13912 // If the setOomAdj() API is not supported, then go with our 13913 // back-up plan... 13914 if (!updateOomAdjLocked()) { 13915 13916 // Count how many processes are running services. 13917 int numServiceProcs = 0; 13918 for (i=mLruProcesses.size()-1; i>=0; i--) { 13919 final ProcessRecord app = mLruProcesses.get(i); 13920 13921 if (app.persistent || app.services.size() != 0 13922 || app.curReceiver != null 13923 || app.persistentActivities > 0) { 13924 // Don't count processes holding services against our 13925 // maximum process count. 13926 if (localLOGV) Log.v( 13927 TAG, "Not trimming app " + app + " with services: " 13928 + app.services); 13929 numServiceProcs++; 13930 } 13931 } 13932 13933 int curMaxProcs = mProcessLimit; 13934 if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES; 13935 if (mAlwaysFinishActivities) { 13936 curMaxProcs = 1; 13937 } 13938 curMaxProcs += numServiceProcs; 13939 13940 // Quit as many processes as we can to get down to the desired 13941 // process count. First remove any processes that no longer 13942 // have activites running in them. 13943 for ( i=0; 13944 i<mLruProcesses.size() 13945 && mLruProcesses.size() > curMaxProcs; 13946 i++) { 13947 final ProcessRecord app = mLruProcesses.get(i); 13948 // Quit an application only if it is not currently 13949 // running any activities. 13950 if (!app.persistent && app.activities.size() == 0 13951 && app.curReceiver == null && app.services.size() == 0) { 13952 Log.i( 13953 TAG, "Exiting empty application process " 13954 + app.processName + " (" 13955 + (app.thread != null ? app.thread.asBinder() : null) 13956 + ")\n"); 13957 if (app.pid > 0 && app.pid != MY_PID) { 13958 Process.killProcess(app.pid); 13959 } else { 13960 try { 13961 app.thread.scheduleExit(); 13962 } catch (Exception e) { 13963 // Ignore exceptions. 13964 } 13965 } 13966 // todo: For now we assume the application is not buggy 13967 // or evil, and will quit as a result of our request. 13968 // Eventually we need to drive this off of the death 13969 // notification, and kill the process if it takes too long. 13970 cleanUpApplicationRecordLocked(app, false, i); 13971 i--; 13972 } 13973 } 13974 13975 // If we still have too many processes, now from the least 13976 // recently used process we start finishing activities. 13977 if (Config.LOGV) Log.v( 13978 TAG, "*** NOW HAVE " + mLruProcesses.size() + 13979 " of " + curMaxProcs + " processes"); 13980 for ( i=0; 13981 i<mLruProcesses.size() 13982 && mLruProcesses.size() > curMaxProcs; 13983 i++) { 13984 final ProcessRecord app = mLruProcesses.get(i); 13985 // Quit the application only if we have a state saved for 13986 // all of its activities. 13987 boolean canQuit = !app.persistent && app.curReceiver == null 13988 && app.services.size() == 0 13989 && app.persistentActivities == 0; 13990 int NUMA = app.activities.size(); 13991 int j; 13992 if (Config.LOGV) Log.v( 13993 TAG, "Looking to quit " + app.processName); 13994 for (j=0; j<NUMA && canQuit; j++) { 13995 HistoryRecord r = (HistoryRecord)app.activities.get(j); 13996 if (Config.LOGV) Log.v( 13997 TAG, " " + r.intent.getComponent().flattenToShortString() 13998 + ": frozen=" + r.haveState + ", visible=" + r.visible); 13999 canQuit = (r.haveState || !r.stateNotNeeded) 14000 && !r.visible && r.stopped; 14001 } 14002 if (canQuit) { 14003 // Finish all of the activities, and then the app itself. 14004 for (j=0; j<NUMA; j++) { 14005 HistoryRecord r = (HistoryRecord)app.activities.get(j); 14006 if (!r.finishing) { 14007 destroyActivityLocked(r, false); 14008 } 14009 r.resultTo = null; 14010 } 14011 Log.i(TAG, "Exiting application process " 14012 + app.processName + " (" 14013 + (app.thread != null ? app.thread.asBinder() : null) 14014 + ")\n"); 14015 if (app.pid > 0 && app.pid != MY_PID) { 14016 Process.killProcess(app.pid); 14017 } else { 14018 try { 14019 app.thread.scheduleExit(); 14020 } catch (Exception e) { 14021 // Ignore exceptions. 14022 } 14023 } 14024 // todo: For now we assume the application is not buggy 14025 // or evil, and will quit as a result of our request. 14026 // Eventually we need to drive this off of the death 14027 // notification, and kill the process if it takes too long. 14028 cleanUpApplicationRecordLocked(app, false, i); 14029 i--; 14030 //dump(); 14031 } 14032 } 14033 14034 } 14035 14036 int curMaxActivities = MAX_ACTIVITIES; 14037 if (mAlwaysFinishActivities) { 14038 curMaxActivities = 1; 14039 } 14040 14041 // Finally, if there are too many activities now running, try to 14042 // finish as many as we can to get back down to the limit. 14043 for ( i=0; 14044 i<mLRUActivities.size() 14045 && mLRUActivities.size() > curMaxActivities; 14046 i++) { 14047 final HistoryRecord r 14048 = (HistoryRecord)mLRUActivities.get(i); 14049 14050 // We can finish this one if we have its icicle saved and 14051 // it is not persistent. 14052 if ((r.haveState || !r.stateNotNeeded) && !r.visible 14053 && r.stopped && !r.persistent && !r.finishing) { 14054 final int origSize = mLRUActivities.size(); 14055 destroyActivityLocked(r, true); 14056 14057 // This will remove it from the LRU list, so keep 14058 // our index at the same value. Note that this check to 14059 // see if the size changes is just paranoia -- if 14060 // something unexpected happens, we don't want to end up 14061 // in an infinite loop. 14062 if (origSize > mLRUActivities.size()) { 14063 i--; 14064 } 14065 } 14066 } 14067 } 14068 } 14069 14070 /** This method sends the specified signal to each of the persistent apps */ 14071 public void signalPersistentProcesses(int sig) throws RemoteException { 14072 if (sig != Process.SIGNAL_USR1) { 14073 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 14074 } 14075 14076 synchronized (this) { 14077 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 14078 != PackageManager.PERMISSION_GRANTED) { 14079 throw new SecurityException("Requires permission " 14080 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 14081 } 14082 14083 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 14084 ProcessRecord r = mLruProcesses.get(i); 14085 if (r.thread != null && r.persistent) { 14086 Process.sendSignal(r.pid, sig); 14087 } 14088 } 14089 } 14090 } 14091 14092 public boolean profileControl(String process, boolean start, 14093 String path, ParcelFileDescriptor fd) throws RemoteException { 14094 14095 try { 14096 synchronized (this) { 14097 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 14098 // its own permission. 14099 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 14100 != PackageManager.PERMISSION_GRANTED) { 14101 throw new SecurityException("Requires permission " 14102 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 14103 } 14104 14105 if (start && fd == null) { 14106 throw new IllegalArgumentException("null fd"); 14107 } 14108 14109 ProcessRecord proc = null; 14110 try { 14111 int pid = Integer.parseInt(process); 14112 synchronized (mPidsSelfLocked) { 14113 proc = mPidsSelfLocked.get(pid); 14114 } 14115 } catch (NumberFormatException e) { 14116 } 14117 14118 if (proc == null) { 14119 HashMap<String, SparseArray<ProcessRecord>> all 14120 = mProcessNames.getMap(); 14121 SparseArray<ProcessRecord> procs = all.get(process); 14122 if (procs != null && procs.size() > 0) { 14123 proc = procs.valueAt(0); 14124 } 14125 } 14126 14127 if (proc == null || proc.thread == null) { 14128 throw new IllegalArgumentException("Unknown process: " + process); 14129 } 14130 14131 boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0")); 14132 if (isSecure) { 14133 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 14134 throw new SecurityException("Process not debuggable: " + proc); 14135 } 14136 } 14137 14138 proc.thread.profilerControl(start, path, fd); 14139 fd = null; 14140 return true; 14141 } 14142 } catch (RemoteException e) { 14143 throw new IllegalStateException("Process disappeared"); 14144 } finally { 14145 if (fd != null) { 14146 try { 14147 fd.close(); 14148 } catch (IOException e) { 14149 } 14150 } 14151 } 14152 } 14153 14154 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 14155 public void monitor() { 14156 synchronized (this) { } 14157 } 14158} 14159