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 17 package com.android.server.am; 18 19 import com.android.internal.os.BatteryStatsImpl; 20 import com.android.server.AttributeCache; 21 import com.android.server.IntentResolver; 22 import com.android.server.ProcessMap; 23 import com.android.server.ProcessStats; 24 import com.android.server.SystemServer; 25 import com.android.server.Watchdog; 26 import com.android.server.WindowManagerService; 27 28 import dalvik.system.Zygote; 29 30 import android.app.Activity; 31 import android.app.ActivityManager; 32 import android.app.ActivityManagerNative; 33 import android.app.ActivityThread; 34 import android.app.AlertDialog; 35 import android.app.ApplicationErrorReport; 36 import android.app.Dialog; 37 import android.app.IActivityController; 38 import android.app.IActivityManager; 39 import android.app.IActivityWatcher; 40 import android.app.IApplicationThread; 41 import android.app.IInstrumentationWatcher; 42 import android.app.IServiceConnection; 43 import android.app.IThumbnailReceiver; 44 import android.app.Instrumentation; 45 import android.app.Notification; 46 import android.app.PendingIntent; 47 import android.app.ResultInfo; 48 import android.app.Service; 49 import android.app.backup.IBackupManager; 50 import android.content.ActivityNotFoundException; 51 import android.content.BroadcastReceiver; 52 import android.content.ComponentName; 53 import android.content.ContentResolver; 54 import android.content.Context; 55 import android.content.Intent; 56 import android.content.IntentFilter; 57 import android.content.IIntentReceiver; 58 import android.content.IIntentSender; 59 import android.content.IntentSender; 60 import android.content.pm.ActivityInfo; 61 import android.content.pm.ApplicationInfo; 62 import android.content.pm.ConfigurationInfo; 63 import android.content.pm.IPackageDataObserver; 64 import android.content.pm.IPackageManager; 65 import android.content.pm.InstrumentationInfo; 66 import android.content.pm.PackageInfo; 67 import android.content.pm.PackageManager; 68 import android.content.pm.PathPermission; 69 import android.content.pm.ProviderInfo; 70 import android.content.pm.ResolveInfo; 71 import android.content.pm.ServiceInfo; 72 import android.content.res.Configuration; 73 import android.graphics.Bitmap; 74 import android.net.Uri; 75 import android.os.Binder; 76 import android.os.Build; 77 import android.os.Bundle; 78 import android.os.Debug; 79 import android.os.DropBoxManager; 80 import android.os.Environment; 81 import android.os.FileObserver; 82 import android.os.FileUtils; 83 import android.os.Handler; 84 import android.os.IBinder; 85 import android.os.IPermissionController; 86 import android.os.Looper; 87 import android.os.Message; 88 import android.os.Parcel; 89 import android.os.ParcelFileDescriptor; 90 import android.os.PowerManager; 91 import android.os.Process; 92 import android.os.RemoteCallbackList; 93 import android.os.RemoteException; 94 import android.os.ServiceManager; 95 import android.os.SystemClock; 96 import android.os.SystemProperties; 97 import android.provider.Settings; 98 import android.util.Config; 99 import android.util.EventLog; 100 import android.util.Slog; 101 import android.util.Log; 102 import android.util.PrintWriterPrinter; 103 import android.util.SparseArray; 104 import android.view.Gravity; 105 import android.view.LayoutInflater; 106 import android.view.View; 107 import android.view.WindowManager; 108 import android.view.WindowManagerPolicy; 109 110 import java.io.File; 111 import java.io.FileDescriptor; 112 import java.io.FileNotFoundException; 113 import java.io.IOException; 114 import java.io.InputStreamReader; 115 import java.io.PrintWriter; 116 import java.lang.IllegalStateException; 117 import java.lang.ref.WeakReference; 118 import java.util.ArrayList; 119 import java.util.HashMap; 120 import java.util.HashSet; 121 import java.util.Iterator; 122 import java.util.List; 123 import java.util.Locale; 124 import java.util.Map; 125 import java.util.Set; 126 import java.util.concurrent.atomic.AtomicBoolean; 127 import java.util.concurrent.atomic.AtomicLong; 128 129 public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor { 130 static final String TAG = "ActivityManager"; 131 static final boolean DEBUG = false; 132 static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV; 133 static final boolean DEBUG_SWITCH = localLOGV || false; 134 static final boolean DEBUG_TASKS = localLOGV || false; 135 static final boolean DEBUG_PAUSE = localLOGV || false; 136 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 137 static final boolean DEBUG_TRANSITION = localLOGV || false; 138 static final boolean DEBUG_BROADCAST = localLOGV || false; 139 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 140 static final boolean DEBUG_SERVICE = localLOGV || false; 141 static final boolean DEBUG_VISBILITY = localLOGV || false; 142 static final boolean DEBUG_PROCESSES = localLOGV || false; 143 static final boolean DEBUG_PROVIDER = localLOGV || false; 144 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 145 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 146 static final boolean DEBUG_RESULTS = localLOGV || false; 147 static final boolean DEBUG_BACKUP = localLOGV || false; 148 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 149 static final boolean VALIDATE_TOKENS = false; 150 static final boolean SHOW_ACTIVITY_START_TIME = true; 151 152 // Control over CPU and battery monitoring. 153 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 154 static final boolean MONITOR_CPU_USAGE = true; 155 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 156 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 157 static final boolean MONITOR_THREAD_CPU_USAGE = false; 158 159 // The flags that are set for all calls we make to the package manager. 160 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 161 162 private static final String SYSTEM_SECURE = "ro.secure"; 163 164 // This is the maximum number of application processes we would like 165 // to have running. Due to the asynchronous nature of things, we can 166 // temporarily go beyond this limit. 167 static final int MAX_PROCESSES = 2; 168 169 // Set to false to leave processes running indefinitely, relying on 170 // the kernel killing them as resources are required. 171 static final boolean ENFORCE_PROCESS_LIMIT = false; 172 173 // This is the maximum number of activities that we would like to have 174 // running at a given time. 175 static final int MAX_ACTIVITIES = 20; 176 177 // Maximum number of recent tasks that we can remember. 178 static final int MAX_RECENT_TASKS = 20; 179 180 // Amount of time after a call to stopAppSwitches() during which we will 181 // prevent further untrusted switches from happening. 182 static final long APP_SWITCH_DELAY_TIME = 5*1000; 183 184 // How long until we reset a task when the user returns to it. Currently 185 // 30 minutes. 186 static final long ACTIVITY_INACTIVE_RESET_TIME = 1000*60*30; 187 188 // Set to true to disable the icon that is shown while a new activity 189 // is being started. 190 static final boolean SHOW_APP_STARTING_ICON = true; 191 192 // How long we wait until giving up on the last activity to pause. This 193 // is short because it directly impacts the responsiveness of starting the 194 // next activity. 195 static final int PAUSE_TIMEOUT = 500; 196 197 /** 198 * How long we can hold the launch wake lock before giving up. 199 */ 200 static final int LAUNCH_TIMEOUT = 10*1000; 201 202 // How long we wait for a launched process to attach to the activity manager 203 // before we decide it's never going to come up for real. 204 static final int PROC_START_TIMEOUT = 10*1000; 205 206 // How long we wait until giving up on the last activity telling us it 207 // is idle. 208 static final int IDLE_TIMEOUT = 10*1000; 209 210 // How long to wait after going idle before forcing apps to GC. 211 static final int GC_TIMEOUT = 5*1000; 212 213 // The minimum amount of time between successive GC requests for a process. 214 static final int GC_MIN_INTERVAL = 60*1000; 215 216 // How long we wait until giving up on an activity telling us it has 217 // finished destroying itself. 218 static final int DESTROY_TIMEOUT = 10*1000; 219 220 // How long we allow a receiver to run before giving up on it. 221 static final int BROADCAST_TIMEOUT = 10*1000; 222 223 // How long we wait for a service to finish executing. 224 static final int SERVICE_TIMEOUT = 20*1000; 225 226 // How long a service needs to be running until restarting its process 227 // is no longer considered to be a relaunch of the service. 228 static final int SERVICE_RESTART_DURATION = 5*1000; 229 230 // How long a service needs to be running until it will start back at 231 // SERVICE_RESTART_DURATION after being killed. 232 static final int SERVICE_RESET_RUN_DURATION = 60*1000; 233 234 // Multiplying factor to increase restart duration time by, for each time 235 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION. 236 static final int SERVICE_RESTART_DURATION_FACTOR = 4; 237 238 // The minimum amount of time between restarting services that we allow. 239 // That is, when multiple services are restarting, we won't allow each 240 // to restart less than this amount of time from the last one. 241 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000; 242 243 // Maximum amount of time for there to be no activity on a service before 244 // we consider it non-essential and allow its process to go on the 245 // LRU background list. 246 static final int MAX_SERVICE_INACTIVITY = 30*60*1000; 247 248 // How long we wait until we timeout on key dispatching. 249 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 250 251 // The minimum time we allow between crashes, for us to consider this 252 // application to be bad and stop and its services and reject broadcasts. 253 static final int MIN_CRASH_INTERVAL = 60*1000; 254 255 // How long we wait until we timeout on key dispatching during instrumentation. 256 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 257 258 // OOM adjustments for processes in various states: 259 260 // This is a process without anything currently running in it. Definitely 261 // the first to go! Value set in system/rootdir/init.rc on startup. 262 // This value is initalized in the constructor, careful when refering to 263 // this static variable externally. 264 static final int EMPTY_APP_ADJ; 265 266 // This is a process only hosting activities that are not visible, 267 // so it can be killed without any disruption. Value set in 268 // system/rootdir/init.rc on startup. 269 static final int HIDDEN_APP_MAX_ADJ; 270 static int HIDDEN_APP_MIN_ADJ; 271 272 // This is a process holding the home application -- we want to try 273 // avoiding killing it, even if it would normally be in the background, 274 // because the user interacts with it so much. 275 static final int HOME_APP_ADJ; 276 277 // This is a process currently hosting a backup operation. Killing it 278 // is not entirely fatal but is generally a bad idea. 279 static final int BACKUP_APP_ADJ; 280 281 // This is a process holding a secondary server -- killing it will not 282 // have much of an impact as far as the user is concerned. Value set in 283 // system/rootdir/init.rc on startup. 284 static final int SECONDARY_SERVER_ADJ; 285 286 // This is a process only hosting activities that are visible to the 287 // user, so we'd prefer they don't disappear. Value set in 288 // system/rootdir/init.rc on startup. 289 static final int VISIBLE_APP_ADJ; 290 291 // This is the process running the current foreground app. We'd really 292 // rather not kill it! Value set in system/rootdir/init.rc on startup. 293 static final int FOREGROUND_APP_ADJ; 294 295 // This is a process running a core server, such as telephony. Definitely 296 // don't want to kill it, but doing so is not completely fatal. 297 static final int CORE_SERVER_ADJ = -12; 298 299 // The system process runs at the default adjustment. 300 static final int SYSTEM_ADJ = -16; 301 302 // Memory pages are 4K. 303 static final int PAGE_SIZE = 4*1024; 304 305 // Corresponding memory levels for above adjustments. 306 static final int EMPTY_APP_MEM; 307 static final int HIDDEN_APP_MEM; 308 static final int HOME_APP_MEM; 309 static final int BACKUP_APP_MEM; 310 static final int SECONDARY_SERVER_MEM; 311 static final int VISIBLE_APP_MEM; 312 static final int FOREGROUND_APP_MEM; 313 314 // The minimum number of hidden apps we want to be able to keep around, 315 // without empty apps being able to push them out of memory. 316 static final int MIN_HIDDEN_APPS = 2; 317 318 // The maximum number of hidden processes we will keep around before 319 // killing them; this is just a control to not let us go too crazy with 320 // keeping around processes on devices with large amounts of RAM. 321 static final int MAX_HIDDEN_APPS = 15; 322 323 // We put empty content processes after any hidden processes that have 324 // been idle for less than 15 seconds. 325 static final long CONTENT_APP_IDLE_OFFSET = 15*1000; 326 327 // We put empty content processes after any hidden processes that have 328 // been idle for less than 120 seconds. 329 static final long EMPTY_APP_IDLE_OFFSET = 120*1000; 330 331 static { 332 // These values are set in system/rootdir/init.rc on startup. 333 FOREGROUND_APP_ADJ = 334 Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_ADJ")); 335 VISIBLE_APP_ADJ = 336 Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_ADJ")); 337 SECONDARY_SERVER_ADJ = 338 Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_ADJ")); 339 BACKUP_APP_ADJ = 340 Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_ADJ")); 341 HOME_APP_ADJ = 342 Integer.valueOf(SystemProperties.get("ro.HOME_APP_ADJ")); 343 HIDDEN_APP_MIN_ADJ = 344 Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MIN_ADJ")); 345 EMPTY_APP_ADJ = 346 Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_ADJ")); 347 HIDDEN_APP_MAX_ADJ = EMPTY_APP_ADJ-1; 348 FOREGROUND_APP_MEM = 349 Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_MEM"))*PAGE_SIZE; 350 VISIBLE_APP_MEM = 351 Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_MEM"))*PAGE_SIZE; 352 SECONDARY_SERVER_MEM = 353 Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_MEM"))*PAGE_SIZE; 354 BACKUP_APP_MEM = 355 Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_MEM"))*PAGE_SIZE; 356 HOME_APP_MEM = 357 Integer.valueOf(SystemProperties.get("ro.HOME_APP_MEM"))*PAGE_SIZE; 358 HIDDEN_APP_MEM = 359 Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MEM"))*PAGE_SIZE; 360 EMPTY_APP_MEM = 361 Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_MEM"))*PAGE_SIZE; 362 } 363 364 static final int MY_PID = Process.myPid(); 365 366 static final String[] EMPTY_STRING_ARRAY = new String[0]; 367 368 enum ActivityState { 369 INITIALIZING, 370 RESUMED, 371 PAUSING, 372 PAUSED, 373 STOPPING, 374 STOPPED, 375 FINISHING, 376 DESTROYING, 377 DESTROYED 378 } 379 380 /** 381 * The back history of all previous (and possibly still 382 * running) activities. It contains HistoryRecord objects. 383 */ 384 final ArrayList mHistory = new ArrayList(); 385 386 /** 387 * Description of a request to start a new activity, which has been held 388 * due to app switches being disabled. 389 */ 390 class PendingActivityLaunch { 391 HistoryRecord r; 392 HistoryRecord sourceRecord; 393 Uri[] grantedUriPermissions; 394 int grantedMode; 395 boolean onlyIfNeeded; 396 } 397 398 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 399 = new ArrayList<PendingActivityLaunch>(); 400 401 /** 402 * List of people waiting to find out about the next launched activity. 403 */ 404 final ArrayList<IActivityManager.WaitResult> mWaitingActivityLaunched 405 = new ArrayList<IActivityManager.WaitResult>(); 406 407 /** 408 * List of people waiting to find out about the next visible activity. 409 */ 410 final ArrayList<IActivityManager.WaitResult> mWaitingActivityVisible 411 = new ArrayList<IActivityManager.WaitResult>(); 412 413 /** 414 * List of all active broadcasts that are to be executed immediately 415 * (without waiting for another broadcast to finish). Currently this only 416 * contains broadcasts to registered receivers, to avoid spinning up 417 * a bunch of processes to execute IntentReceiver components. 418 */ 419 final ArrayList<BroadcastRecord> mParallelBroadcasts 420 = new ArrayList<BroadcastRecord>(); 421 422 /** 423 * List of all active broadcasts that are to be executed one at a time. 424 * The object at the top of the list is the currently activity broadcasts; 425 * those after it are waiting for the top to finish.. 426 */ 427 final ArrayList<BroadcastRecord> mOrderedBroadcasts 428 = new ArrayList<BroadcastRecord>(); 429 430 /** 431 * Historical data of past broadcasts, for debugging. 432 */ 433 static final int MAX_BROADCAST_HISTORY = 100; 434 final BroadcastRecord[] mBroadcastHistory 435 = new BroadcastRecord[MAX_BROADCAST_HISTORY]; 436 437 /** 438 * Set when we current have a BROADCAST_INTENT_MSG in flight. 439 */ 440 boolean mBroadcastsScheduled = false; 441 442 /** 443 * Set to indicate whether to issue an onUserLeaving callback when a 444 * newly launched activity is being brought in front of us. 445 */ 446 boolean mUserLeaving = false; 447 448 /** 449 * When we are in the process of pausing an activity, before starting the 450 * next one, this variable holds the activity that is currently being paused. 451 */ 452 HistoryRecord mPausingActivity = null; 453 454 /** 455 * Current activity that is resumed, or null if there is none. 456 */ 457 HistoryRecord mResumedActivity = null; 458 459 /** 460 * Activity we have told the window manager to have key focus. 461 */ 462 HistoryRecord mFocusedActivity = null; 463 464 /** 465 * This is the last activity that we put into the paused state. This is 466 * used to determine if we need to do an activity transition while sleeping, 467 * when we normally hold the top activity paused. 468 */ 469 HistoryRecord mLastPausedActivity = null; 470 471 /** 472 * List of activities that are waiting for a new activity 473 * to become visible before completing whatever operation they are 474 * supposed to do. 475 */ 476 final ArrayList mWaitingVisibleActivities = new ArrayList(); 477 478 /** 479 * List of activities that are ready to be stopped, but waiting 480 * for the next activity to settle down before doing so. It contains 481 * HistoryRecord objects. 482 */ 483 final ArrayList<HistoryRecord> mStoppingActivities 484 = new ArrayList<HistoryRecord>(); 485 486 /** 487 * Animations that for the current transition have requested not to 488 * be considered for the transition animation. 489 */ 490 final ArrayList<HistoryRecord> mNoAnimActivities 491 = new ArrayList<HistoryRecord>(); 492 493 /** 494 * List of intents that were used to start the most recent tasks. 495 */ 496 final ArrayList<TaskRecord> mRecentTasks 497 = new ArrayList<TaskRecord>(); 498 499 /** 500 * List of activities that are ready to be finished, but waiting 501 * for the previous activity to settle down before doing so. It contains 502 * HistoryRecord objects. 503 */ 504 final ArrayList mFinishingActivities = new ArrayList(); 505 506 /** 507 * All of the applications we currently have running organized by name. 508 * The keys are strings of the application package name (as 509 * returned by the package manager), and the keys are ApplicationRecord 510 * objects. 511 */ 512 final ProcessMap<ProcessRecord> mProcessNames 513 = new ProcessMap<ProcessRecord>(); 514 515 /** 516 * The last time that various processes have crashed. 517 */ 518 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 519 520 /** 521 * Set of applications that we consider to be bad, and will reject 522 * incoming broadcasts from (which the user has no control over). 523 * Processes are added to this set when they have crashed twice within 524 * a minimum amount of time; they are removed from it when they are 525 * later restarted (hopefully due to some user action). The value is the 526 * time it was added to the list. 527 */ 528 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>(); 529 530 /** 531 * All of the processes we currently have running organized by pid. 532 * The keys are the pid running the application. 533 * 534 * <p>NOTE: This object is protected by its own lock, NOT the global 535 * activity manager lock! 536 */ 537 final SparseArray<ProcessRecord> mPidsSelfLocked 538 = new SparseArray<ProcessRecord>(); 539 540 /** 541 * All of the processes that have been forced to be foreground. The key 542 * is the pid of the caller who requested it (we hold a death 543 * link on it). 544 */ 545 abstract class ForegroundToken implements IBinder.DeathRecipient { 546 int pid; 547 IBinder token; 548 } 549 final SparseArray<ForegroundToken> mForegroundProcesses 550 = new SparseArray<ForegroundToken>(); 551 552 /** 553 * List of records for processes that someone had tried to start before the 554 * system was ready. We don't start them at that point, but ensure they 555 * are started by the time booting is complete. 556 */ 557 final ArrayList<ProcessRecord> mProcessesOnHold 558 = new ArrayList<ProcessRecord>(); 559 560 /** 561 * List of records for processes that we have started and are waiting 562 * for them to call back. This is really only needed when running in 563 * single processes mode, in which case we do not have a unique pid for 564 * each process. 565 */ 566 final ArrayList<ProcessRecord> mStartingProcesses 567 = new ArrayList<ProcessRecord>(); 568 569 /** 570 * List of persistent applications that are in the process 571 * of being started. 572 */ 573 final ArrayList<ProcessRecord> mPersistentStartingProcesses 574 = new ArrayList<ProcessRecord>(); 575 576 /** 577 * Processes that are being forcibly torn down. 578 */ 579 final ArrayList<ProcessRecord> mRemovedProcesses 580 = new ArrayList<ProcessRecord>(); 581 582 /** 583 * List of running applications, sorted by recent usage. 584 * The first entry in the list is the least recently used. 585 * It contains ApplicationRecord objects. This list does NOT include 586 * any persistent application records (since we never want to exit them). 587 */ 588 final ArrayList<ProcessRecord> mLruProcesses 589 = new ArrayList<ProcessRecord>(); 590 591 /** 592 * List of processes that should gc as soon as things are idle. 593 */ 594 final ArrayList<ProcessRecord> mProcessesToGc 595 = new ArrayList<ProcessRecord>(); 596 597 /** 598 * This is the process holding what we currently consider to be 599 * the "home" activity. 600 */ 601 private ProcessRecord mHomeProcess; 602 603 /** 604 * List of running activities, sorted by recent usage. 605 * The first entry in the list is the least recently used. 606 * It contains HistoryRecord objects. 607 */ 608 private final ArrayList mLRUActivities = new ArrayList(); 609 610 /** 611 * Set of PendingResultRecord objects that are currently active. 612 */ 613 final HashSet mPendingResultRecords = new HashSet(); 614 615 /** 616 * Set of IntentSenderRecord objects that are currently active. 617 */ 618 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 619 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 620 621 /** 622 * Intent broadcast that we have tried to start, but are 623 * waiting for its application's process to be created. We only 624 * need one (instead of a list) because we always process broadcasts 625 * one at a time, so no others can be started while waiting for this 626 * one. 627 */ 628 BroadcastRecord mPendingBroadcast = null; 629 630 /** 631 * Keeps track of all IIntentReceivers that have been registered for 632 * broadcasts. Hash keys are the receiver IBinder, hash value is 633 * a ReceiverList. 634 */ 635 final HashMap mRegisteredReceivers = new HashMap(); 636 637 /** 638 * Resolver for broadcast intents to registered receivers. 639 * Holds BroadcastFilter (subclass of IntentFilter). 640 */ 641 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 642 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 643 @Override 644 protected boolean allowFilterResult( 645 BroadcastFilter filter, List<BroadcastFilter> dest) { 646 IBinder target = filter.receiverList.receiver.asBinder(); 647 for (int i=dest.size()-1; i>=0; i--) { 648 if (dest.get(i).receiverList.receiver.asBinder() == target) { 649 return false; 650 } 651 } 652 return true; 653 } 654 }; 655 656 /** 657 * State of all active sticky broadcasts. Keys are the action of the 658 * sticky Intent, values are an ArrayList of all broadcasted intents with 659 * that action (which should usually be one). 660 */ 661 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts = 662 new HashMap<String, ArrayList<Intent>>(); 663 664 /** 665 * All currently running services. 666 */ 667 final HashMap<ComponentName, ServiceRecord> mServices = 668 new HashMap<ComponentName, ServiceRecord>(); 669 670 /** 671 * All currently running services indexed by the Intent used to start them. 672 */ 673 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent = 674 new HashMap<Intent.FilterComparison, ServiceRecord>(); 675 676 /** 677 * All currently bound service connections. Keys are the IBinder of 678 * the client's IServiceConnection. 679 */ 680 final HashMap<IBinder, ConnectionRecord> mServiceConnections 681 = new HashMap<IBinder, ConnectionRecord>(); 682 683 /** 684 * List of services that we have been asked to start, 685 * but haven't yet been able to. It is used to hold start requests 686 * while waiting for their corresponding application thread to get 687 * going. 688 */ 689 final ArrayList<ServiceRecord> mPendingServices 690 = new ArrayList<ServiceRecord>(); 691 692 /** 693 * List of services that are scheduled to restart following a crash. 694 */ 695 final ArrayList<ServiceRecord> mRestartingServices 696 = new ArrayList<ServiceRecord>(); 697 698 /** 699 * List of services that are in the process of being stopped. 700 */ 701 final ArrayList<ServiceRecord> mStoppingServices 702 = new ArrayList<ServiceRecord>(); 703 704 /** 705 * Backup/restore process management 706 */ 707 String mBackupAppName = null; 708 BackupRecord mBackupTarget = null; 709 710 /** 711 * List of PendingThumbnailsRecord objects of clients who are still 712 * waiting to receive all of the thumbnails for a task. 713 */ 714 final ArrayList mPendingThumbnails = new ArrayList(); 715 716 /** 717 * List of HistoryRecord objects that have been finished and must 718 * still report back to a pending thumbnail receiver. 719 */ 720 final ArrayList mCancelledThumbnails = new ArrayList(); 721 722 /** 723 * All of the currently running global content providers. Keys are a 724 * string containing the provider name and values are a 725 * ContentProviderRecord object containing the data about it. Note 726 * that a single provider may be published under multiple names, so 727 * there may be multiple entries here for a single one in mProvidersByClass. 728 */ 729 final HashMap mProvidersByName = new HashMap(); 730 731 /** 732 * All of the currently running global content providers. Keys are a 733 * string containing the provider's implementation class and values are a 734 * ContentProviderRecord object containing the data about it. 735 */ 736 final HashMap mProvidersByClass = new HashMap(); 737 738 /** 739 * List of content providers who have clients waiting for them. The 740 * application is currently being launched and the provider will be 741 * removed from this list once it is published. 742 */ 743 final ArrayList mLaunchingProviders = new ArrayList(); 744 745 /** 746 * Global set of specific Uri permissions that have been granted. 747 */ 748 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions 749 = new SparseArray<HashMap<Uri, UriPermission>>(); 750 751 /** 752 * Thread-local storage used to carry caller permissions over through 753 * indirect content-provider access. 754 * @see #ActivityManagerService.openContentUri() 755 */ 756 private class Identity { 757 public int pid; 758 public int uid; 759 760 Identity(int _pid, int _uid) { 761 pid = _pid; 762 uid = _uid; 763 } 764 } 765 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 766 767 /** 768 * All information we have collected about the runtime performance of 769 * any user id that can impact battery performance. 770 */ 771 final BatteryStatsService mBatteryStatsService; 772 773 /** 774 * information about component usage 775 */ 776 final UsageStatsService mUsageStatsService; 777 778 /** 779 * Current configuration information. HistoryRecord objects are given 780 * a reference to this object to indicate which configuration they are 781 * currently running in, so this object must be kept immutable. 782 */ 783 Configuration mConfiguration = new Configuration(); 784 785 /** 786 * Current sequencing integer of the configuration, for skipping old 787 * configurations. 788 */ 789 int mConfigurationSeq = 0; 790 791 /** 792 * Set when we know we are going to be calling updateConfiguration() 793 * soon, so want to skip intermediate config checks. 794 */ 795 boolean mConfigWillChange; 796 797 /** 798 * Hardware-reported OpenGLES version. 799 */ 800 final int GL_ES_VERSION; 801 802 /** 803 * List of initialization arguments to pass to all processes when binding applications to them. 804 * For example, references to the commonly used services. 805 */ 806 HashMap<String, IBinder> mAppBindArgs; 807 808 /** 809 * Temporary to avoid allocations. Protected by main lock. 810 */ 811 final StringBuilder mStringBuilder = new StringBuilder(256); 812 813 /** 814 * Used to control how we initialize the service. 815 */ 816 boolean mStartRunning = false; 817 ComponentName mTopComponent; 818 String mTopAction; 819 String mTopData; 820 boolean mSystemReady = false; 821 boolean mBooting = false; 822 boolean mWaitingUpdate = false; 823 boolean mDidUpdate = false; 824 825 Context mContext; 826 827 int mFactoryTest; 828 829 boolean mCheckedForSetup; 830 831 /** 832 * The time at which we will allow normal application switches again, 833 * after a call to {@link #stopAppSwitches()}. 834 */ 835 long mAppSwitchesAllowedTime; 836 837 /** 838 * This is set to true after the first switch after mAppSwitchesAllowedTime 839 * is set; any switches after that will clear the time. 840 */ 841 boolean mDidAppSwitch; 842 843 /** 844 * Set while we are wanting to sleep, to prevent any 845 * activities from being started/resumed. 846 */ 847 boolean mSleeping = false; 848 849 /** 850 * Set if we are shutting down the system, similar to sleeping. 851 */ 852 boolean mShuttingDown = false; 853 854 /** 855 * Set when the system is going to sleep, until we have 856 * successfully paused the current activity and released our wake lock. 857 * At that point the system is allowed to actually sleep. 858 */ 859 PowerManager.WakeLock mGoingToSleep; 860 861 /** 862 * We don't want to allow the device to go to sleep while in the process 863 * of launching an activity. This is primarily to allow alarm intent 864 * receivers to launch an activity and get that to run before the device 865 * goes back to sleep. 866 */ 867 PowerManager.WakeLock mLaunchingActivity; 868 869 /** 870 * Task identifier that activities are currently being started 871 * in. Incremented each time a new task is created. 872 * todo: Replace this with a TokenSpace class that generates non-repeating 873 * integers that won't wrap. 874 */ 875 int mCurTask = 1; 876 877 /** 878 * Current sequence id for oom_adj computation traversal. 879 */ 880 int mAdjSeq = 0; 881 882 /** 883 * Current sequence id for process LRU updating. 884 */ 885 int mLruSeq = 0; 886 887 /** 888 * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar 889 * is set, indicating the user wants processes started in such a way 890 * that they can use ANDROID_PROCESS_WRAPPER and know what will be 891 * running in each process (thus no pre-initialized process, etc). 892 */ 893 boolean mSimpleProcessManagement = false; 894 895 /** 896 * System monitoring: number of processes that died since the last 897 * N procs were started. 898 */ 899 int[] mProcDeaths = new int[20]; 900 901 /** 902 * This is set if we had to do a delayed dexopt of an app before launching 903 * it, to increasing the ANR timeouts in that case. 904 */ 905 boolean mDidDexOpt; 906 907 String mDebugApp = null; 908 boolean mWaitForDebugger = false; 909 boolean mDebugTransient = false; 910 String mOrigDebugApp = null; 911 boolean mOrigWaitForDebugger = false; 912 boolean mAlwaysFinishActivities = false; 913 IActivityController mController = null; 914 915 final RemoteCallbackList<IActivityWatcher> mWatchers 916 = new RemoteCallbackList<IActivityWatcher>(); 917 918 /** 919 * Callback of last caller to {@link #requestPss}. 920 */ 921 Runnable mRequestPssCallback; 922 923 /** 924 * Remaining processes for which we are waiting results from the last 925 * call to {@link #requestPss}. 926 */ 927 final ArrayList<ProcessRecord> mRequestPssList 928 = new ArrayList<ProcessRecord>(); 929 930 /** 931 * Runtime statistics collection thread. This object's lock is used to 932 * protect all related state. 933 */ 934 final Thread mProcessStatsThread; 935 936 /** 937 * Used to collect process stats when showing not responding dialog. 938 * Protected by mProcessStatsThread. 939 */ 940 final ProcessStats mProcessStats = new ProcessStats( 941 MONITOR_THREAD_CPU_USAGE); 942 final AtomicLong mLastCpuTime = new AtomicLong(0); 943 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true); 944 945 long mLastWriteTime = 0; 946 947 long mInitialStartTime = 0; 948 949 /** 950 * Set to true after the system has finished booting. 951 */ 952 boolean mBooted = false; 953 954 int mProcessLimit = 0; 955 956 WindowManagerService mWindowManager; 957 958 static ActivityManagerService mSelf; 959 static ActivityThread mSystemThread; 960 961 private final class AppDeathRecipient implements IBinder.DeathRecipient { 962 final ProcessRecord mApp; 963 final int mPid; 964 final IApplicationThread mAppThread; 965 966 AppDeathRecipient(ProcessRecord app, int pid, 967 IApplicationThread thread) { 968 if (localLOGV) Slog.v( 969 TAG, "New death recipient " + this 970 + " for thread " + thread.asBinder()); 971 mApp = app; 972 mPid = pid; 973 mAppThread = thread; 974 } 975 976 public void binderDied() { 977 if (localLOGV) Slog.v( 978 TAG, "Death received in " + this 979 + " for thread " + mAppThread.asBinder()); 980 removeRequestedPss(mApp); 981 synchronized(ActivityManagerService.this) { 982 appDiedLocked(mApp, mPid, mAppThread); 983 } 984 } 985 } 986 987 static final int SHOW_ERROR_MSG = 1; 988 static final int SHOW_NOT_RESPONDING_MSG = 2; 989 static final int SHOW_FACTORY_ERROR_MSG = 3; 990 static final int UPDATE_CONFIGURATION_MSG = 4; 991 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 992 static final int WAIT_FOR_DEBUGGER_MSG = 6; 993 static final int BROADCAST_INTENT_MSG = 7; 994 static final int BROADCAST_TIMEOUT_MSG = 8; 995 static final int PAUSE_TIMEOUT_MSG = 9; 996 static final int IDLE_TIMEOUT_MSG = 10; 997 static final int IDLE_NOW_MSG = 11; 998 static final int SERVICE_TIMEOUT_MSG = 12; 999 static final int UPDATE_TIME_ZONE = 13; 1000 static final int SHOW_UID_ERROR_MSG = 14; 1001 static final int IM_FEELING_LUCKY_MSG = 15; 1002 static final int LAUNCH_TIMEOUT_MSG = 16; 1003 static final int DESTROY_TIMEOUT_MSG = 17; 1004 static final int RESUME_TOP_ACTIVITY_MSG = 19; 1005 static final int PROC_START_TIMEOUT_MSG = 20; 1006 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1007 static final int KILL_APPLICATION_MSG = 22; 1008 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1009 1010 AlertDialog mUidAlert; 1011 1012 final Handler mHandler = new Handler() { 1013 //public Handler() { 1014 // if (localLOGV) Slog.v(TAG, "Handler started!"); 1015 //} 1016 1017 public void handleMessage(Message msg) { 1018 switch (msg.what) { 1019 case SHOW_ERROR_MSG: { 1020 HashMap data = (HashMap) msg.obj; 1021 synchronized (ActivityManagerService.this) { 1022 ProcessRecord proc = (ProcessRecord)data.get("app"); 1023 if (proc != null && proc.crashDialog != null) { 1024 Slog.e(TAG, "App already has crash dialog: " + proc); 1025 return; 1026 } 1027 AppErrorResult res = (AppErrorResult) data.get("result"); 1028 if (!mSleeping && !mShuttingDown) { 1029 Dialog d = new AppErrorDialog(mContext, res, proc); 1030 d.show(); 1031 proc.crashDialog = d; 1032 } else { 1033 // The device is asleep, so just pretend that the user 1034 // saw a crash dialog and hit "force quit". 1035 res.set(0); 1036 } 1037 } 1038 1039 ensureBootCompleted(); 1040 } break; 1041 case SHOW_NOT_RESPONDING_MSG: { 1042 synchronized (ActivityManagerService.this) { 1043 HashMap data = (HashMap) msg.obj; 1044 ProcessRecord proc = (ProcessRecord)data.get("app"); 1045 if (proc != null && proc.anrDialog != null) { 1046 Slog.e(TAG, "App already has anr dialog: " + proc); 1047 return; 1048 } 1049 1050 broadcastIntentLocked(null, null, new Intent("android.intent.action.ANR"), 1051 null, null, 0, null, null, null, 1052 false, false, MY_PID, Process.SYSTEM_UID); 1053 1054 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1055 mContext, proc, (HistoryRecord)data.get("activity")); 1056 d.show(); 1057 proc.anrDialog = d; 1058 } 1059 1060 ensureBootCompleted(); 1061 } break; 1062 case SHOW_FACTORY_ERROR_MSG: { 1063 Dialog d = new FactoryErrorDialog( 1064 mContext, msg.getData().getCharSequence("msg")); 1065 d.show(); 1066 ensureBootCompleted(); 1067 } break; 1068 case UPDATE_CONFIGURATION_MSG: { 1069 final ContentResolver resolver = mContext.getContentResolver(); 1070 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1071 } break; 1072 case GC_BACKGROUND_PROCESSES_MSG: { 1073 synchronized (ActivityManagerService.this) { 1074 performAppGcsIfAppropriateLocked(); 1075 } 1076 } break; 1077 case WAIT_FOR_DEBUGGER_MSG: { 1078 synchronized (ActivityManagerService.this) { 1079 ProcessRecord app = (ProcessRecord)msg.obj; 1080 if (msg.arg1 != 0) { 1081 if (!app.waitedForDebugger) { 1082 Dialog d = new AppWaitingForDebuggerDialog( 1083 ActivityManagerService.this, 1084 mContext, app); 1085 app.waitDialog = d; 1086 app.waitedForDebugger = true; 1087 d.show(); 1088 } 1089 } else { 1090 if (app.waitDialog != null) { 1091 app.waitDialog.dismiss(); 1092 app.waitDialog = null; 1093 } 1094 } 1095 } 1096 } break; 1097 case BROADCAST_INTENT_MSG: { 1098 if (DEBUG_BROADCAST) Slog.v( 1099 TAG, "Received BROADCAST_INTENT_MSG"); 1100 processNextBroadcast(true); 1101 } break; 1102 case BROADCAST_TIMEOUT_MSG: { 1103 if (mDidDexOpt) { 1104 mDidDexOpt = false; 1105 Message nmsg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG); 1106 mHandler.sendMessageDelayed(nmsg, BROADCAST_TIMEOUT); 1107 return; 1108 } 1109 // Only process broadcast timeouts if the system is ready. That way 1110 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended 1111 // to do heavy lifting for system up 1112 if (mSystemReady) { 1113 broadcastTimeout(); 1114 } 1115 } break; 1116 case PAUSE_TIMEOUT_MSG: { 1117 IBinder token = (IBinder)msg.obj; 1118 // We don't at this point know if the activity is fullscreen, 1119 // so we need to be conservative and assume it isn't. 1120 Slog.w(TAG, "Activity pause timeout for " + token); 1121 activityPaused(token, null, true); 1122 } break; 1123 case IDLE_TIMEOUT_MSG: { 1124 if (mDidDexOpt) { 1125 mDidDexOpt = false; 1126 Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 1127 nmsg.obj = msg.obj; 1128 mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT); 1129 return; 1130 } 1131 // We don't at this point know if the activity is fullscreen, 1132 // so we need to be conservative and assume it isn't. 1133 IBinder token = (IBinder)msg.obj; 1134 Slog.w(TAG, "Activity idle timeout for " + token); 1135 activityIdleInternal(token, true, null); 1136 } break; 1137 case DESTROY_TIMEOUT_MSG: { 1138 IBinder token = (IBinder)msg.obj; 1139 // We don't at this point know if the activity is fullscreen, 1140 // so we need to be conservative and assume it isn't. 1141 Slog.w(TAG, "Activity destroy timeout for " + token); 1142 activityDestroyed(token); 1143 } break; 1144 case IDLE_NOW_MSG: { 1145 IBinder token = (IBinder)msg.obj; 1146 activityIdle(token, null); 1147 } break; 1148 case SERVICE_TIMEOUT_MSG: { 1149 if (mDidDexOpt) { 1150 mDidDexOpt = false; 1151 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1152 nmsg.obj = msg.obj; 1153 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT); 1154 return; 1155 } 1156 serviceTimeout((ProcessRecord)msg.obj); 1157 } break; 1158 case UPDATE_TIME_ZONE: { 1159 synchronized (ActivityManagerService.this) { 1160 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1161 ProcessRecord r = mLruProcesses.get(i); 1162 if (r.thread != null) { 1163 try { 1164 r.thread.updateTimeZone(); 1165 } catch (RemoteException ex) { 1166 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1167 } 1168 } 1169 } 1170 } 1171 } break; 1172 case SHOW_UID_ERROR_MSG: { 1173 // XXX This is a temporary dialog, no need to localize. 1174 AlertDialog d = new BaseErrorDialog(mContext); 1175 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1176 d.setCancelable(false); 1177 d.setTitle("System UIDs Inconsistent"); 1178 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable."); 1179 d.setButton("I'm Feeling Lucky", 1180 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1181 mUidAlert = d; 1182 d.show(); 1183 } break; 1184 case IM_FEELING_LUCKY_MSG: { 1185 if (mUidAlert != null) { 1186 mUidAlert.dismiss(); 1187 mUidAlert = null; 1188 } 1189 } break; 1190 case LAUNCH_TIMEOUT_MSG: { 1191 if (mDidDexOpt) { 1192 mDidDexOpt = false; 1193 Message nmsg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG); 1194 mHandler.sendMessageDelayed(nmsg, LAUNCH_TIMEOUT); 1195 return; 1196 } 1197 synchronized (ActivityManagerService.this) { 1198 if (mLaunchingActivity.isHeld()) { 1199 Slog.w(TAG, "Launch timeout has expired, giving up wake lock!"); 1200 mLaunchingActivity.release(); 1201 } 1202 } 1203 } break; 1204 case RESUME_TOP_ACTIVITY_MSG: { 1205 synchronized (ActivityManagerService.this) { 1206 resumeTopActivityLocked(null); 1207 } 1208 } break; 1209 case PROC_START_TIMEOUT_MSG: { 1210 if (mDidDexOpt) { 1211 mDidDexOpt = false; 1212 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1213 nmsg.obj = msg.obj; 1214 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1215 return; 1216 } 1217 ProcessRecord app = (ProcessRecord)msg.obj; 1218 synchronized (ActivityManagerService.this) { 1219 processStartTimedOutLocked(app); 1220 } 1221 } break; 1222 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1223 synchronized (ActivityManagerService.this) { 1224 doPendingActivityLaunchesLocked(true); 1225 } 1226 } break; 1227 case KILL_APPLICATION_MSG: { 1228 synchronized (ActivityManagerService.this) { 1229 int uid = msg.arg1; 1230 boolean restart = (msg.arg2 == 1); 1231 String pkg = (String) msg.obj; 1232 forceStopPackageLocked(pkg, uid, restart, false, true); 1233 } 1234 } break; 1235 case FINALIZE_PENDING_INTENT_MSG: { 1236 ((PendingIntentRecord)msg.obj).completeFinalize(); 1237 } break; 1238 } 1239 } 1240 }; 1241 1242 public static void setSystemProcess() { 1243 try { 1244 ActivityManagerService m = mSelf; 1245 1246 ServiceManager.addService("activity", m); 1247 ServiceManager.addService("meminfo", new MemBinder(m)); 1248 if (MONITOR_CPU_USAGE) { 1249 ServiceManager.addService("cpuinfo", new CpuBinder(m)); 1250 } 1251 ServiceManager.addService("permission", new PermissionController(m)); 1252 1253 ApplicationInfo info = 1254 mSelf.mContext.getPackageManager().getApplicationInfo( 1255 "android", STOCK_PM_FLAGS); 1256 mSystemThread.installSystemApplicationInfo(info); 1257 1258 synchronized (mSelf) { 1259 ProcessRecord app = mSelf.newProcessRecordLocked( 1260 mSystemThread.getApplicationThread(), info, 1261 info.processName); 1262 app.persistent = true; 1263 app.pid = MY_PID; 1264 app.maxAdj = SYSTEM_ADJ; 1265 mSelf.mProcessNames.put(app.processName, app.info.uid, app); 1266 synchronized (mSelf.mPidsSelfLocked) { 1267 mSelf.mPidsSelfLocked.put(app.pid, app); 1268 } 1269 mSelf.updateLruProcessLocked(app, true, true); 1270 } 1271 } catch (PackageManager.NameNotFoundException e) { 1272 throw new RuntimeException( 1273 "Unable to find android system package", e); 1274 } 1275 } 1276 1277 public void setWindowManager(WindowManagerService wm) { 1278 mWindowManager = wm; 1279 } 1280 1281 public static final Context main(int factoryTest) { 1282 AThread thr = new AThread(); 1283 thr.start(); 1284 1285 synchronized (thr) { 1286 while (thr.mService == null) { 1287 try { 1288 thr.wait(); 1289 } catch (InterruptedException e) { 1290 } 1291 } 1292 } 1293 1294 ActivityManagerService m = thr.mService; 1295 mSelf = m; 1296 ActivityThread at = ActivityThread.systemMain(); 1297 mSystemThread = at; 1298 Context context = at.getSystemContext(); 1299 m.mContext = context; 1300 m.mFactoryTest = factoryTest; 1301 PowerManager pm = 1302 (PowerManager)context.getSystemService(Context.POWER_SERVICE); 1303 m.mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep"); 1304 m.mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch"); 1305 m.mLaunchingActivity.setReferenceCounted(false); 1306 1307 m.mBatteryStatsService.publish(context); 1308 m.mUsageStatsService.publish(context); 1309 1310 synchronized (thr) { 1311 thr.mReady = true; 1312 thr.notifyAll(); 1313 } 1314 1315 m.startRunning(null, null, null, null); 1316 1317 return context; 1318 } 1319 1320 public static ActivityManagerService self() { 1321 return mSelf; 1322 } 1323 1324 static class AThread extends Thread { 1325 ActivityManagerService mService; 1326 boolean mReady = false; 1327 1328 public AThread() { 1329 super("ActivityManager"); 1330 } 1331 1332 public void run() { 1333 Looper.prepare(); 1334 1335 android.os.Process.setThreadPriority( 1336 android.os.Process.THREAD_PRIORITY_FOREGROUND); 1337 1338 ActivityManagerService m = new ActivityManagerService(); 1339 1340 synchronized (this) { 1341 mService = m; 1342 notifyAll(); 1343 } 1344 1345 synchronized (this) { 1346 while (!mReady) { 1347 try { 1348 wait(); 1349 } catch (InterruptedException e) { 1350 } 1351 } 1352 } 1353 1354 Looper.loop(); 1355 } 1356 } 1357 1358 static class MemBinder extends Binder { 1359 ActivityManagerService mActivityManagerService; 1360 MemBinder(ActivityManagerService activityManagerService) { 1361 mActivityManagerService = activityManagerService; 1362 } 1363 1364 @Override 1365 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1366 ActivityManagerService service = mActivityManagerService; 1367 ArrayList<ProcessRecord> procs; 1368 synchronized (mActivityManagerService) { 1369 if (args != null && args.length > 0 1370 && args[0].charAt(0) != '-') { 1371 procs = new ArrayList<ProcessRecord>(); 1372 int pid = -1; 1373 try { 1374 pid = Integer.parseInt(args[0]); 1375 } catch (NumberFormatException e) { 1376 1377 } 1378 for (int i=service.mLruProcesses.size()-1; i>=0; i--) { 1379 ProcessRecord proc = service.mLruProcesses.get(i); 1380 if (proc.pid == pid) { 1381 procs.add(proc); 1382 } else if (proc.processName.equals(args[0])) { 1383 procs.add(proc); 1384 } 1385 } 1386 if (procs.size() <= 0) { 1387 pw.println("No process found for: " + args[0]); 1388 return; 1389 } 1390 } else { 1391 procs = new ArrayList<ProcessRecord>(service.mLruProcesses); 1392 } 1393 } 1394 dumpApplicationMemoryUsage(fd, pw, procs, " ", args); 1395 } 1396 } 1397 1398 static class CpuBinder extends Binder { 1399 ActivityManagerService mActivityManagerService; 1400 CpuBinder(ActivityManagerService activityManagerService) { 1401 mActivityManagerService = activityManagerService; 1402 } 1403 1404 @Override 1405 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1406 synchronized (mActivityManagerService.mProcessStatsThread) { 1407 pw.print(mActivityManagerService.mProcessStats.printCurrentState()); 1408 } 1409 } 1410 } 1411 1412 private ActivityManagerService() { 1413 String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT"); 1414 if (v != null && Integer.getInteger(v) != 0) { 1415 mSimpleProcessManagement = true; 1416 } 1417 v = System.getenv("ANDROID_DEBUG_APP"); 1418 if (v != null) { 1419 mSimpleProcessManagement = true; 1420 } 1421 1422 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1423 1424 File dataDir = Environment.getDataDirectory(); 1425 File systemDir = new File(dataDir, "system"); 1426 systemDir.mkdirs(); 1427 mBatteryStatsService = new BatteryStatsService(new File( 1428 systemDir, "batterystats.bin").toString()); 1429 mBatteryStatsService.getActiveStatistics().readLocked(); 1430 mBatteryStatsService.getActiveStatistics().writeLocked(); 1431 1432 mUsageStatsService = new UsageStatsService( new File( 1433 systemDir, "usagestats").toString()); 1434 1435 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1436 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1437 1438 mConfiguration.setToDefaults(); 1439 mConfiguration.locale = Locale.getDefault(); 1440 mProcessStats.init(); 1441 1442 // Add ourself to the Watchdog monitors. 1443 Watchdog.getInstance().addMonitor(this); 1444 1445 mProcessStatsThread = new Thread("ProcessStats") { 1446 public void run() { 1447 while (true) { 1448 try { 1449 try { 1450 synchronized(this) { 1451 final long now = SystemClock.uptimeMillis(); 1452 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1453 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1454 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1455 // + ", write delay=" + nextWriteDelay); 1456 if (nextWriteDelay < nextCpuDelay) { 1457 nextCpuDelay = nextWriteDelay; 1458 } 1459 if (nextCpuDelay > 0) { 1460 mProcessStatsMutexFree.set(true); 1461 this.wait(nextCpuDelay); 1462 } 1463 } 1464 } catch (InterruptedException e) { 1465 } 1466 updateCpuStatsNow(); 1467 } catch (Exception e) { 1468 Slog.e(TAG, "Unexpected exception collecting process stats", e); 1469 } 1470 } 1471 } 1472 }; 1473 mProcessStatsThread.start(); 1474 } 1475 1476 @Override 1477 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1478 throws RemoteException { 1479 try { 1480 return super.onTransact(code, data, reply, flags); 1481 } catch (RuntimeException e) { 1482 // The activity manager only throws security exceptions, so let's 1483 // log all others. 1484 if (!(e instanceof SecurityException)) { 1485 Slog.e(TAG, "Activity Manager Crash", e); 1486 } 1487 throw e; 1488 } 1489 } 1490 1491 void updateCpuStats() { 1492 final long now = SystemClock.uptimeMillis(); 1493 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 1494 return; 1495 } 1496 if (mProcessStatsMutexFree.compareAndSet(true, false)) { 1497 synchronized (mProcessStatsThread) { 1498 mProcessStatsThread.notify(); 1499 } 1500 } 1501 } 1502 1503 void updateCpuStatsNow() { 1504 synchronized (mProcessStatsThread) { 1505 mProcessStatsMutexFree.set(false); 1506 final long now = SystemClock.uptimeMillis(); 1507 boolean haveNewCpuStats = false; 1508 1509 if (MONITOR_CPU_USAGE && 1510 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 1511 mLastCpuTime.set(now); 1512 haveNewCpuStats = true; 1513 mProcessStats.update(); 1514 //Slog.i(TAG, mProcessStats.printCurrentState()); 1515 //Slog.i(TAG, "Total CPU usage: " 1516 // + mProcessStats.getTotalCpuPercent() + "%"); 1517 1518 // Slog the cpu usage if the property is set. 1519 if ("true".equals(SystemProperties.get("events.cpu"))) { 1520 int user = mProcessStats.getLastUserTime(); 1521 int system = mProcessStats.getLastSystemTime(); 1522 int iowait = mProcessStats.getLastIoWaitTime(); 1523 int irq = mProcessStats.getLastIrqTime(); 1524 int softIrq = mProcessStats.getLastSoftIrqTime(); 1525 int idle = mProcessStats.getLastIdleTime(); 1526 1527 int total = user + system + iowait + irq + softIrq + idle; 1528 if (total == 0) total = 1; 1529 1530 EventLog.writeEvent(EventLogTags.CPU, 1531 ((user+system+iowait+irq+softIrq) * 100) / total, 1532 (user * 100) / total, 1533 (system * 100) / total, 1534 (iowait * 100) / total, 1535 (irq * 100) / total, 1536 (softIrq * 100) / total); 1537 } 1538 } 1539 1540 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes(); 1541 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 1542 synchronized(bstats) { 1543 synchronized(mPidsSelfLocked) { 1544 if (haveNewCpuStats) { 1545 if (mBatteryStatsService.isOnBattery()) { 1546 final int N = mProcessStats.countWorkingStats(); 1547 for (int i=0; i<N; i++) { 1548 ProcessStats.Stats st 1549 = mProcessStats.getWorkingStats(i); 1550 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 1551 if (pr != null) { 1552 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; 1553 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); 1554 ps.addSpeedStepTimes(cpuSpeedTimes); 1555 } else { 1556 BatteryStatsImpl.Uid.Proc ps = 1557 bstats.getProcessStatsLocked(st.name, st.pid); 1558 if (ps != null) { 1559 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); 1560 ps.addSpeedStepTimes(cpuSpeedTimes); 1561 } 1562 } 1563 } 1564 } 1565 } 1566 } 1567 1568 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 1569 mLastWriteTime = now; 1570 mBatteryStatsService.getActiveStatistics().writeLocked(); 1571 } 1572 } 1573 } 1574 } 1575 1576 /** 1577 * Initialize the application bind args. These are passed to each 1578 * process when the bindApplication() IPC is sent to the process. They're 1579 * lazily setup to make sure the services are running when they're asked for. 1580 */ 1581 private HashMap<String, IBinder> getCommonServicesLocked() { 1582 if (mAppBindArgs == null) { 1583 mAppBindArgs = new HashMap<String, IBinder>(); 1584 1585 // Setup the application init args 1586 mAppBindArgs.put("package", ServiceManager.getService("package")); 1587 mAppBindArgs.put("window", ServiceManager.getService("window")); 1588 mAppBindArgs.put(Context.ALARM_SERVICE, 1589 ServiceManager.getService(Context.ALARM_SERVICE)); 1590 } 1591 return mAppBindArgs; 1592 } 1593 1594 private final void setFocusedActivityLocked(HistoryRecord r) { 1595 if (mFocusedActivity != r) { 1596 mFocusedActivity = r; 1597 mWindowManager.setFocusedApp(r, true); 1598 } 1599 } 1600 1601 private final void updateLruProcessInternalLocked(ProcessRecord app, 1602 boolean oomAdj, boolean updateActivityTime, int bestPos) { 1603 // put it on the LRU to keep track of when it should be exited. 1604 int lrui = mLruProcesses.indexOf(app); 1605 if (lrui >= 0) mLruProcesses.remove(lrui); 1606 1607 int i = mLruProcesses.size()-1; 1608 int skipTop = 0; 1609 1610 app.lruSeq = mLruSeq; 1611 1612 // compute the new weight for this process. 1613 if (updateActivityTime) { 1614 app.lastActivityTime = SystemClock.uptimeMillis(); 1615 } 1616 if (app.activities.size() > 0) { 1617 // If this process has activities, we more strongly want to keep 1618 // it around. 1619 app.lruWeight = app.lastActivityTime; 1620 } else if (app.pubProviders.size() > 0) { 1621 // If this process contains content providers, we want to keep 1622 // it a little more strongly. 1623 app.lruWeight = app.lastActivityTime - CONTENT_APP_IDLE_OFFSET; 1624 // Also don't let it kick out the first few "real" hidden processes. 1625 skipTop = MIN_HIDDEN_APPS; 1626 } else { 1627 // If this process doesn't have activities, we less strongly 1628 // want to keep it around, and generally want to avoid getting 1629 // in front of any very recently used activities. 1630 app.lruWeight = app.lastActivityTime - EMPTY_APP_IDLE_OFFSET; 1631 // Also don't let it kick out the first few "real" hidden processes. 1632 skipTop = MIN_HIDDEN_APPS; 1633 } 1634 1635 while (i >= 0) { 1636 ProcessRecord p = mLruProcesses.get(i); 1637 // If this app shouldn't be in front of the first N background 1638 // apps, then skip over that many that are currently hidden. 1639 if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) { 1640 skipTop--; 1641 } 1642 if (p.lruWeight <= app.lruWeight || i < bestPos) { 1643 mLruProcesses.add(i+1, app); 1644 break; 1645 } 1646 i--; 1647 } 1648 if (i < 0) { 1649 mLruProcesses.add(0, app); 1650 } 1651 1652 // If the app is currently using a content provider or service, 1653 // bump those processes as well. 1654 if (app.connections.size() > 0) { 1655 for (ConnectionRecord cr : app.connections) { 1656 if (cr.binding != null && cr.binding.service != null 1657 && cr.binding.service.app != null 1658 && cr.binding.service.app.lruSeq != mLruSeq) { 1659 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj, 1660 updateActivityTime, i+1); 1661 } 1662 } 1663 } 1664 if (app.conProviders.size() > 0) { 1665 for (ContentProviderRecord cpr : app.conProviders.keySet()) { 1666 if (cpr.app != null && cpr.app.lruSeq != mLruSeq) { 1667 updateLruProcessInternalLocked(cpr.app, oomAdj, 1668 updateActivityTime, i+1); 1669 } 1670 } 1671 } 1672 1673 //Slog.i(TAG, "Putting proc to front: " + app.processName); 1674 if (oomAdj) { 1675 updateOomAdjLocked(); 1676 } 1677 } 1678 1679 private final void updateLruProcessLocked(ProcessRecord app, 1680 boolean oomAdj, boolean updateActivityTime) { 1681 mLruSeq++; 1682 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0); 1683 } 1684 1685 private final boolean updateLRUListLocked(HistoryRecord r) { 1686 final boolean hadit = mLRUActivities.remove(r); 1687 mLRUActivities.add(r); 1688 return hadit; 1689 } 1690 1691 private final HistoryRecord topRunningActivityLocked(HistoryRecord notTop) { 1692 int i = mHistory.size()-1; 1693 while (i >= 0) { 1694 HistoryRecord r = (HistoryRecord)mHistory.get(i); 1695 if (!r.finishing && r != notTop) { 1696 return r; 1697 } 1698 i--; 1699 } 1700 return null; 1701 } 1702 1703 private final HistoryRecord topRunningNonDelayedActivityLocked(HistoryRecord notTop) { 1704 int i = mHistory.size()-1; 1705 while (i >= 0) { 1706 HistoryRecord r = (HistoryRecord)mHistory.get(i); 1707 if (!r.finishing && !r.delayedResume && r != notTop) { 1708 return r; 1709 } 1710 i--; 1711 } 1712 return null; 1713 } 1714 1715 /** 1716 * This is a simplified version of topRunningActivityLocked that provides a number of 1717 * optional skip-over modes. It is intended for use with the ActivityController hook only. 1718 * 1719 * @param token If non-null, any history records matching this token will be skipped. 1720 * @param taskId If non-zero, we'll attempt to skip over records with the same task ID. 1721 * 1722 * @return Returns the HistoryRecord of the next activity on the stack. 1723 */ 1724 private final HistoryRecord topRunningActivityLocked(IBinder token, int taskId) { 1725 int i = mHistory.size()-1; 1726 while (i >= 0) { 1727 HistoryRecord r = (HistoryRecord)mHistory.get(i); 1728 // Note: the taskId check depends on real taskId fields being non-zero 1729 if (!r.finishing && (token != r) && (taskId != r.task.taskId)) { 1730 return r; 1731 } 1732 i--; 1733 } 1734 return null; 1735 } 1736 1737 private final ProcessRecord getProcessRecordLocked( 1738 String processName, int uid) { 1739 if (uid == Process.SYSTEM_UID) { 1740 // The system gets to run in any process. If there are multiple 1741 // processes with the same uid, just pick the first (this 1742 // should never happen). 1743 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get( 1744 processName); 1745 return procs != null ? procs.valueAt(0) : null; 1746 } 1747 ProcessRecord proc = mProcessNames.get(processName, uid); 1748 return proc; 1749 } 1750 1751 private void ensurePackageDexOpt(String packageName) { 1752 IPackageManager pm = ActivityThread.getPackageManager(); 1753 try { 1754 if (pm.performDexOpt(packageName)) { 1755 mDidDexOpt = true; 1756 } 1757 } catch (RemoteException e) { 1758 } 1759 } 1760 1761 private boolean isNextTransitionForward() { 1762 int transit = mWindowManager.getPendingAppTransition(); 1763 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 1764 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN 1765 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT; 1766 } 1767 1768 private final boolean realStartActivityLocked(HistoryRecord r, 1769 ProcessRecord app, boolean andResume, boolean checkConfig) 1770 throws RemoteException { 1771 1772 r.startFreezingScreenLocked(app, 0); 1773 mWindowManager.setAppVisibility(r, true); 1774 1775 // Have the window manager re-evaluate the orientation of 1776 // the screen based on the new activity order. Note that 1777 // as a result of this, it can call back into the activity 1778 // manager with a new orientation. We don't care about that, 1779 // because the activity is not currently running so we are 1780 // just restarting it anyway. 1781 if (checkConfig) { 1782 Configuration config = mWindowManager.updateOrientationFromAppTokens( 1783 mConfiguration, 1784 r.mayFreezeScreenLocked(app) ? r : null); 1785 updateConfigurationLocked(config, r); 1786 } 1787 1788 r.app = app; 1789 1790 if (localLOGV) Slog.v(TAG, "Launching: " + r); 1791 1792 int idx = app.activities.indexOf(r); 1793 if (idx < 0) { 1794 app.activities.add(r); 1795 } 1796 updateLruProcessLocked(app, true, true); 1797 1798 try { 1799 if (app.thread == null) { 1800 throw new RemoteException(); 1801 } 1802 List<ResultInfo> results = null; 1803 List<Intent> newIntents = null; 1804 if (andResume) { 1805 results = r.results; 1806 newIntents = r.newIntents; 1807 } 1808 if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r 1809 + " icicle=" + r.icicle 1810 + " with results=" + results + " newIntents=" + newIntents 1811 + " andResume=" + andResume); 1812 if (andResume) { 1813 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY, 1814 System.identityHashCode(r), 1815 r.task.taskId, r.shortComponentName); 1816 } 1817 if (r.isHomeActivity) { 1818 mHomeProcess = app; 1819 } 1820 ensurePackageDexOpt(r.intent.getComponent().getPackageName()); 1821 app.thread.scheduleLaunchActivity(new Intent(r.intent), r, 1822 System.identityHashCode(r), 1823 r.info, r.icicle, results, newIntents, !andResume, 1824 isNextTransitionForward()); 1825 } catch (RemoteException e) { 1826 if (r.launchFailed) { 1827 // This is the second time we failed -- finish activity 1828 // and give up. 1829 Slog.e(TAG, "Second failure launching " 1830 + r.intent.getComponent().flattenToShortString() 1831 + ", giving up", e); 1832 appDiedLocked(app, app.pid, app.thread); 1833 requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null, 1834 "2nd-crash"); 1835 return false; 1836 } 1837 1838 // This is the first time we failed -- restart process and 1839 // retry. 1840 app.activities.remove(r); 1841 throw e; 1842 } 1843 1844 r.launchFailed = false; 1845 if (updateLRUListLocked(r)) { 1846 Slog.w(TAG, "Activity " + r 1847 + " being launched, but already in LRU list"); 1848 } 1849 1850 if (andResume) { 1851 // As part of the process of launching, ActivityThread also performs 1852 // a resume. 1853 r.state = ActivityState.RESUMED; 1854 r.icicle = null; 1855 r.haveState = false; 1856 r.stopped = false; 1857 mResumedActivity = r; 1858 r.task.touchActiveTime(); 1859 completeResumeLocked(r); 1860 pauseIfSleepingLocked(); 1861 } else { 1862 // This activity is not starting in the resumed state... which 1863 // should look like we asked it to pause+stop (but remain visible), 1864 // and it has done so and reported back the current icicle and 1865 // other state. 1866 r.state = ActivityState.STOPPED; 1867 r.stopped = true; 1868 } 1869 1870 // Launch the new version setup screen if needed. We do this -after- 1871 // launching the initial activity (that is, home), so that it can have 1872 // a chance to initialize itself while in the background, making the 1873 // switch back to it faster and look better. 1874 startSetupActivityLocked(); 1875 1876 return true; 1877 } 1878 1879 private final void startSpecificActivityLocked(HistoryRecord r, 1880 boolean andResume, boolean checkConfig) { 1881 // Is this activity's application already running? 1882 ProcessRecord app = getProcessRecordLocked(r.processName, 1883 r.info.applicationInfo.uid); 1884 1885 if (r.startTime == 0) { 1886 r.startTime = SystemClock.uptimeMillis(); 1887 if (mInitialStartTime == 0) { 1888 mInitialStartTime = r.startTime; 1889 } 1890 } else if (mInitialStartTime == 0) { 1891 mInitialStartTime = SystemClock.uptimeMillis(); 1892 } 1893 1894 if (app != null && app.thread != null) { 1895 try { 1896 realStartActivityLocked(r, app, andResume, checkConfig); 1897 return; 1898 } catch (RemoteException e) { 1899 Slog.w(TAG, "Exception when starting activity " 1900 + r.intent.getComponent().flattenToShortString(), e); 1901 } 1902 1903 // If a dead object exception was thrown -- fall through to 1904 // restart the application. 1905 } 1906 1907 startProcessLocked(r.processName, r.info.applicationInfo, true, 0, 1908 "activity", r.intent.getComponent(), false); 1909 } 1910 1911 private final ProcessRecord startProcessLocked(String processName, 1912 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 1913 String hostingType, ComponentName hostingName, boolean allowWhileBooting) { 1914 ProcessRecord app = getProcessRecordLocked(processName, info.uid); 1915 // We don't have to do anything more if: 1916 // (1) There is an existing application record; and 1917 // (2) The caller doesn't think it is dead, OR there is no thread 1918 // object attached to it so we know it couldn't have crashed; and 1919 // (3) There is a pid assigned to it, so it is either starting or 1920 // already running. 1921 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 1922 + " app=" + app + " knownToBeDead=" + knownToBeDead 1923 + " thread=" + (app != null ? app.thread : null) 1924 + " pid=" + (app != null ? app.pid : -1)); 1925 if (app != null && app.pid > 0) { 1926 if (!knownToBeDead || app.thread == null) { 1927 // We already have the app running, or are waiting for it to 1928 // come up (we have a pid but not yet its thread), so keep it. 1929 return app; 1930 } else { 1931 // An application record is attached to a previous process, 1932 // clean it up now. 1933 handleAppDiedLocked(app, true); 1934 } 1935 } 1936 1937 String hostingNameStr = hostingName != null 1938 ? hostingName.flattenToShortString() : null; 1939 1940 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 1941 // If we are in the background, then check to see if this process 1942 // is bad. If so, we will just silently fail. 1943 if (mBadProcesses.get(info.processName, info.uid) != null) { 1944 return null; 1945 } 1946 } else { 1947 // When the user is explicitly starting a process, then clear its 1948 // crash count so that we won't make it bad until they see at 1949 // least one crash dialog again, and make the process good again 1950 // if it had been bad. 1951 mProcessCrashTimes.remove(info.processName, info.uid); 1952 if (mBadProcesses.get(info.processName, info.uid) != null) { 1953 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid, 1954 info.processName); 1955 mBadProcesses.remove(info.processName, info.uid); 1956 if (app != null) { 1957 app.bad = false; 1958 } 1959 } 1960 } 1961 1962 if (app == null) { 1963 app = newProcessRecordLocked(null, info, processName); 1964 mProcessNames.put(processName, info.uid, app); 1965 } else { 1966 // If this is a new package in the process, add the package to the list 1967 app.addPackage(info.packageName); 1968 } 1969 1970 // If the system is not ready yet, then hold off on starting this 1971 // process until it is. 1972 if (!mSystemReady 1973 && !isAllowedWhileBooting(info) 1974 && !allowWhileBooting) { 1975 if (!mProcessesOnHold.contains(app)) { 1976 mProcessesOnHold.add(app); 1977 } 1978 return app; 1979 } 1980 1981 startProcessLocked(app, hostingType, hostingNameStr); 1982 return (app.pid != 0) ? app : null; 1983 } 1984 1985 boolean isAllowedWhileBooting(ApplicationInfo ai) { 1986 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 1987 } 1988 1989 private final void startProcessLocked(ProcessRecord app, 1990 String hostingType, String hostingNameStr) { 1991 if (app.pid > 0 && app.pid != MY_PID) { 1992 synchronized (mPidsSelfLocked) { 1993 mPidsSelfLocked.remove(app.pid); 1994 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1995 } 1996 app.pid = 0; 1997 } 1998 1999 mProcessesOnHold.remove(app); 2000 2001 updateCpuStats(); 2002 2003 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1); 2004 mProcDeaths[0] = 0; 2005 2006 try { 2007 int uid = app.info.uid; 2008 int[] gids = null; 2009 try { 2010 gids = mContext.getPackageManager().getPackageGids( 2011 app.info.packageName); 2012 } catch (PackageManager.NameNotFoundException e) { 2013 Slog.w(TAG, "Unable to retrieve gids", e); 2014 } 2015 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) { 2016 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2017 && mTopComponent != null 2018 && app.processName.equals(mTopComponent.getPackageName())) { 2019 uid = 0; 2020 } 2021 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL 2022 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2023 uid = 0; 2024 } 2025 } 2026 int debugFlags = 0; 2027 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2028 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2029 } 2030 // Run the app in safe mode if its manifest requests so or the 2031 // system is booted in safe mode. 2032 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2033 Zygote.systemInSafeMode == true) { 2034 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2035 } 2036 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2037 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2038 } 2039 if ("1".equals(SystemProperties.get("debug.assert"))) { 2040 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2041 } 2042 int pid = Process.start("android.app.ActivityThread", 2043 mSimpleProcessManagement ? app.processName : null, uid, uid, 2044 gids, debugFlags, null); 2045 BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); 2046 synchronized (bs) { 2047 if (bs.isOnBattery()) { 2048 app.batteryStats.incStartsLocked(); 2049 } 2050 } 2051 2052 EventLog.writeEvent(EventLogTags.AM_PROC_START, pid, uid, 2053 app.processName, hostingType, 2054 hostingNameStr != null ? hostingNameStr : ""); 2055 2056 if (app.persistent) { 2057 Watchdog.getInstance().processStarted(app, app.processName, pid); 2058 } 2059 2060 StringBuilder buf = mStringBuilder; 2061 buf.setLength(0); 2062 buf.append("Start proc "); 2063 buf.append(app.processName); 2064 buf.append(" for "); 2065 buf.append(hostingType); 2066 if (hostingNameStr != null) { 2067 buf.append(" "); 2068 buf.append(hostingNameStr); 2069 } 2070 buf.append(": pid="); 2071 buf.append(pid); 2072 buf.append(" uid="); 2073 buf.append(uid); 2074 buf.append(" gids={"); 2075 if (gids != null) { 2076 for (int gi=0; gi<gids.length; gi++) { 2077 if (gi != 0) buf.append(", "); 2078 buf.append(gids[gi]); 2079 2080 } 2081 } 2082 buf.append("}"); 2083 Slog.i(TAG, buf.toString()); 2084 if (pid == 0 || pid == MY_PID) { 2085 // Processes are being emulated with threads. 2086 app.pid = MY_PID; 2087 app.removed = false; 2088 mStartingProcesses.add(app); 2089 } else if (pid > 0) { 2090 app.pid = pid; 2091 app.removed = false; 2092 synchronized (mPidsSelfLocked) { 2093 this.mPidsSelfLocked.put(pid, app); 2094 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2095 msg.obj = app; 2096 mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT); 2097 } 2098 } else { 2099 app.pid = 0; 2100 RuntimeException e = new RuntimeException( 2101 "Failure starting process " + app.processName 2102 + ": returned pid=" + pid); 2103 Slog.e(TAG, e.getMessage(), e); 2104 } 2105 } catch (RuntimeException e) { 2106 // XXX do better error recovery. 2107 app.pid = 0; 2108 Slog.e(TAG, "Failure starting process " + app.processName, e); 2109 } 2110 } 2111 2112 private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) { 2113 if (mPausingActivity != null) { 2114 RuntimeException e = new RuntimeException(); 2115 Slog.e(TAG, "Trying to pause when pause is already pending for " 2116 + mPausingActivity, e); 2117 } 2118 HistoryRecord prev = mResumedActivity; 2119 if (prev == null) { 2120 RuntimeException e = new RuntimeException(); 2121 Slog.e(TAG, "Trying to pause when nothing is resumed", e); 2122 resumeTopActivityLocked(null); 2123 return; 2124 } 2125 if (DEBUG_PAUSE) Slog.v(TAG, "Start pausing: " + prev); 2126 mResumedActivity = null; 2127 mPausingActivity = prev; 2128 mLastPausedActivity = prev; 2129 prev.state = ActivityState.PAUSING; 2130 prev.task.touchActiveTime(); 2131 2132 updateCpuStats(); 2133 2134 if (prev.app != null && prev.app.thread != null) { 2135 if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending pause: " + prev); 2136 try { 2137 EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY, 2138 System.identityHashCode(prev), 2139 prev.shortComponentName); 2140 prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving, 2141 prev.configChangeFlags); 2142 updateUsageStats(prev, false); 2143 } catch (Exception e) { 2144 // Ignore exception, if process died other code will cleanup. 2145 Slog.w(TAG, "Exception thrown during pause", e); 2146 mPausingActivity = null; 2147 mLastPausedActivity = null; 2148 } 2149 } else { 2150 mPausingActivity = null; 2151 mLastPausedActivity = null; 2152 } 2153 2154 // If we are not going to sleep, we want to ensure the device is 2155 // awake until the next activity is started. 2156 if (!mSleeping && !mShuttingDown) { 2157 mLaunchingActivity.acquire(); 2158 if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) { 2159 // To be safe, don't allow the wake lock to be held for too long. 2160 Message msg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG); 2161 mHandler.sendMessageDelayed(msg, LAUNCH_TIMEOUT); 2162 } 2163 } 2164 2165 2166 if (mPausingActivity != null) { 2167 // Have the window manager pause its key dispatching until the new 2168 // activity has started. If we're pausing the activity just because 2169 // the screen is being turned off and the UI is sleeping, don't interrupt 2170 // key dispatch; the same activity will pick it up again on wakeup. 2171 if (!uiSleeping) { 2172 prev.pauseKeyDispatchingLocked(); 2173 } else { 2174 if (DEBUG_PAUSE) Slog.v(TAG, "Key dispatch not paused for screen off"); 2175 } 2176 2177 // Schedule a pause timeout in case the app doesn't respond. 2178 // We don't give it much time because this directly impacts the 2179 // responsiveness seen by the user. 2180 Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG); 2181 msg.obj = prev; 2182 mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT); 2183 if (DEBUG_PAUSE) Slog.v(TAG, "Waiting for pause to complete..."); 2184 } else { 2185 // This activity failed to schedule the 2186 // pause, so just treat it as being paused now. 2187 if (DEBUG_PAUSE) Slog.v(TAG, "Activity not running, resuming next."); 2188 resumeTopActivityLocked(null); 2189 } 2190 } 2191 2192 private final void completePauseLocked() { 2193 HistoryRecord prev = mPausingActivity; 2194 if (DEBUG_PAUSE) Slog.v(TAG, "Complete pause: " + prev); 2195 2196 if (prev != null) { 2197 if (prev.finishing) { 2198 if (DEBUG_PAUSE) Slog.v(TAG, "Executing finish of activity: " + prev); 2199 prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE); 2200 } else if (prev.app != null) { 2201 if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending stop: " + prev); 2202 if (prev.waitingVisible) { 2203 prev.waitingVisible = false; 2204 mWaitingVisibleActivities.remove(prev); 2205 if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v( 2206 TAG, "Complete pause, no longer waiting: " + prev); 2207 } 2208 if (prev.configDestroy) { 2209 // The previous is being paused because the configuration 2210 // is changing, which means it is actually stopping... 2211 // To juggle the fact that we are also starting a new 2212 // instance right now, we need to first completely stop 2213 // the current instance before starting the new one. 2214 if (DEBUG_PAUSE) Slog.v(TAG, "Destroying after pause: " + prev); 2215 destroyActivityLocked(prev, true); 2216 } else { 2217 mStoppingActivities.add(prev); 2218 if (mStoppingActivities.size() > 3) { 2219 // If we already have a few activities waiting to stop, 2220 // then give up on things going idle and start clearing 2221 // them out. 2222 if (DEBUG_PAUSE) Slog.v(TAG, "To many pending stops, forcing idle"); 2223 Message msg = Message.obtain(); 2224 msg.what = ActivityManagerService.IDLE_NOW_MSG; 2225 mHandler.sendMessage(msg); 2226 } 2227 } 2228 } else { 2229 if (DEBUG_PAUSE) Slog.v(TAG, "App died during pause, not stopping: " + prev); 2230 prev = null; 2231 } 2232 mPausingActivity = null; 2233 } 2234 2235 if (!mSleeping && !mShuttingDown) { 2236 resumeTopActivityLocked(prev); 2237 } else { 2238 if (mGoingToSleep.isHeld()) { 2239 mGoingToSleep.release(); 2240 } 2241 if (mShuttingDown) { 2242 notifyAll(); 2243 } 2244 } 2245 2246 if (prev != null) { 2247 prev.resumeKeyDispatchingLocked(); 2248 } 2249 2250 if (prev.app != null && prev.cpuTimeAtResume > 0 && mBatteryStatsService.isOnBattery()) { 2251 long diff = 0; 2252 synchronized (mProcessStatsThread) { 2253 diff = mProcessStats.getCpuTimeForPid(prev.app.pid) - prev.cpuTimeAtResume; 2254 } 2255 if (diff > 0) { 2256 BatteryStatsImpl bsi = mBatteryStatsService.getActiveStatistics(); 2257 synchronized (bsi) { 2258 BatteryStatsImpl.Uid.Proc ps = 2259 bsi.getProcessStatsLocked(prev.info.applicationInfo.uid, 2260 prev.info.packageName); 2261 if (ps != null) { 2262 ps.addForegroundTimeLocked(diff); 2263 } 2264 } 2265 } 2266 } 2267 prev.cpuTimeAtResume = 0; // reset it 2268 } 2269 2270 /** 2271 * Once we know that we have asked an application to put an activity in 2272 * the resumed state (either by launching it or explicitly telling it), 2273 * this function updates the rest of our state to match that fact. 2274 */ 2275 private final void completeResumeLocked(HistoryRecord next) { 2276 next.idle = false; 2277 next.results = null; 2278 next.newIntents = null; 2279 2280 // schedule an idle timeout in case the app doesn't do it for us. 2281 Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG); 2282 msg.obj = next; 2283 mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); 2284 2285 if (false) { 2286 // The activity was never told to pause, so just keep 2287 // things going as-is. To maintain our own state, 2288 // we need to emulate it coming back and saying it is 2289 // idle. 2290 msg = mHandler.obtainMessage(IDLE_NOW_MSG); 2291 msg.obj = next; 2292 mHandler.sendMessage(msg); 2293 } 2294 2295 reportResumedActivityLocked(next); 2296 2297 next.thumbnail = null; 2298 setFocusedActivityLocked(next); 2299 next.resumeKeyDispatchingLocked(); 2300 ensureActivitiesVisibleLocked(null, 0); 2301 mWindowManager.executeAppTransition(); 2302 mNoAnimActivities.clear(); 2303 2304 // Mark the point when the activity is resuming 2305 // TODO: To be more accurate, the mark should be before the onCreate, 2306 // not after the onResume. But for subsequent starts, onResume is fine. 2307 if (next.app != null) { 2308 synchronized (mProcessStatsThread) { 2309 next.cpuTimeAtResume = mProcessStats.getCpuTimeForPid(next.app.pid); 2310 } 2311 } else { 2312 next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process 2313 } 2314 } 2315 2316 /** 2317 * Make sure that all activities that need to be visible (that is, they 2318 * currently can be seen by the user) actually are. 2319 */ 2320 private final void ensureActivitiesVisibleLocked(HistoryRecord top, 2321 HistoryRecord starting, String onlyThisProcess, int configChanges) { 2322 if (DEBUG_VISBILITY) Slog.v( 2323 TAG, "ensureActivitiesVisible behind " + top 2324 + " configChanges=0x" + Integer.toHexString(configChanges)); 2325 2326 // If the top activity is not fullscreen, then we need to 2327 // make sure any activities under it are now visible. 2328 final int count = mHistory.size(); 2329 int i = count-1; 2330 while (mHistory.get(i) != top) { 2331 i--; 2332 } 2333 HistoryRecord r; 2334 boolean behindFullscreen = false; 2335 for (; i>=0; i--) { 2336 r = (HistoryRecord)mHistory.get(i); 2337 if (DEBUG_VISBILITY) Slog.v( 2338 TAG, "Make visible? " + r + " finishing=" + r.finishing 2339 + " state=" + r.state); 2340 if (r.finishing) { 2341 continue; 2342 } 2343 2344 final boolean doThisProcess = onlyThisProcess == null 2345 || onlyThisProcess.equals(r.processName); 2346 2347 // First: if this is not the current activity being started, make 2348 // sure it matches the current configuration. 2349 if (r != starting && doThisProcess) { 2350 ensureActivityConfigurationLocked(r, 0); 2351 } 2352 2353 if (r.app == null || r.app.thread == null) { 2354 if (onlyThisProcess == null 2355 || onlyThisProcess.equals(r.processName)) { 2356 // This activity needs to be visible, but isn't even 2357 // running... get it started, but don't resume it 2358 // at this point. 2359 if (DEBUG_VISBILITY) Slog.v( 2360 TAG, "Start and freeze screen for " + r); 2361 if (r != starting) { 2362 r.startFreezingScreenLocked(r.app, configChanges); 2363 } 2364 if (!r.visible) { 2365 if (DEBUG_VISBILITY) Slog.v( 2366 TAG, "Starting and making visible: " + r); 2367 mWindowManager.setAppVisibility(r, true); 2368 } 2369 if (r != starting) { 2370 startSpecificActivityLocked(r, false, false); 2371 } 2372 } 2373 2374 } else if (r.visible) { 2375 // If this activity is already visible, then there is nothing 2376 // else to do here. 2377 if (DEBUG_VISBILITY) Slog.v( 2378 TAG, "Skipping: already visible at " + r); 2379 r.stopFreezingScreenLocked(false); 2380 2381 } else if (onlyThisProcess == null) { 2382 // This activity is not currently visible, but is running. 2383 // Tell it to become visible. 2384 r.visible = true; 2385 if (r.state != ActivityState.RESUMED && r != starting) { 2386 // If this activity is paused, tell it 2387 // to now show its window. 2388 if (DEBUG_VISBILITY) Slog.v( 2389 TAG, "Making visible and scheduling visibility: " + r); 2390 try { 2391 mWindowManager.setAppVisibility(r, true); 2392 r.app.thread.scheduleWindowVisibility(r, true); 2393 r.stopFreezingScreenLocked(false); 2394 } catch (Exception e) { 2395 // Just skip on any failure; we'll make it 2396 // visible when it next restarts. 2397 Slog.w(TAG, "Exception thrown making visibile: " 2398 + r.intent.getComponent(), e); 2399 } 2400 } 2401 } 2402 2403 // Aggregate current change flags. 2404 configChanges |= r.configChangeFlags; 2405 2406 if (r.fullscreen) { 2407 // At this point, nothing else needs to be shown 2408 if (DEBUG_VISBILITY) Slog.v( 2409 TAG, "Stopping: fullscreen at " + r); 2410 behindFullscreen = true; 2411 i--; 2412 break; 2413 } 2414 } 2415 2416 // Now for any activities that aren't visible to the user, make 2417 // sure they no longer are keeping the screen frozen. 2418 while (i >= 0) { 2419 r = (HistoryRecord)mHistory.get(i); 2420 if (DEBUG_VISBILITY) Slog.v( 2421 TAG, "Make invisible? " + r + " finishing=" + r.finishing 2422 + " state=" + r.state 2423 + " behindFullscreen=" + behindFullscreen); 2424 if (!r.finishing) { 2425 if (behindFullscreen) { 2426 if (r.visible) { 2427 if (DEBUG_VISBILITY) Slog.v( 2428 TAG, "Making invisible: " + r); 2429 r.visible = false; 2430 try { 2431 mWindowManager.setAppVisibility(r, false); 2432 if ((r.state == ActivityState.STOPPING 2433 || r.state == ActivityState.STOPPED) 2434 && r.app != null && r.app.thread != null) { 2435 if (DEBUG_VISBILITY) Slog.v( 2436 TAG, "Scheduling invisibility: " + r); 2437 r.app.thread.scheduleWindowVisibility(r, false); 2438 } 2439 } catch (Exception e) { 2440 // Just skip on any failure; we'll make it 2441 // visible when it next restarts. 2442 Slog.w(TAG, "Exception thrown making hidden: " 2443 + r.intent.getComponent(), e); 2444 } 2445 } else { 2446 if (DEBUG_VISBILITY) Slog.v( 2447 TAG, "Already invisible: " + r); 2448 } 2449 } else if (r.fullscreen) { 2450 if (DEBUG_VISBILITY) Slog.v( 2451 TAG, "Now behindFullscreen: " + r); 2452 behindFullscreen = true; 2453 } 2454 } 2455 i--; 2456 } 2457 } 2458 2459 /** 2460 * Version of ensureActivitiesVisible that can easily be called anywhere. 2461 */ 2462 private final void ensureActivitiesVisibleLocked(HistoryRecord starting, 2463 int configChanges) { 2464 HistoryRecord r = topRunningActivityLocked(null); 2465 if (r != null) { 2466 ensureActivitiesVisibleLocked(r, starting, null, configChanges); 2467 } 2468 } 2469 2470 private void updateUsageStats(HistoryRecord resumedComponent, boolean resumed) { 2471 if (resumed) { 2472 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity); 2473 } else { 2474 mUsageStatsService.notePauseComponent(resumedComponent.realActivity); 2475 } 2476 } 2477 2478 private boolean startHomeActivityLocked() { 2479 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL 2480 && mTopAction == null) { 2481 // We are running in factory test mode, but unable to find 2482 // the factory test app, so just sit around displaying the 2483 // error message and don't try to start anything. 2484 return false; 2485 } 2486 Intent intent = new Intent( 2487 mTopAction, 2488 mTopData != null ? Uri.parse(mTopData) : null); 2489 intent.setComponent(mTopComponent); 2490 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 2491 intent.addCategory(Intent.CATEGORY_HOME); 2492 } 2493 ActivityInfo aInfo = 2494 intent.resolveActivityInfo(mContext.getPackageManager(), 2495 STOCK_PM_FLAGS); 2496 if (aInfo != null) { 2497 intent.setComponent(new ComponentName( 2498 aInfo.applicationInfo.packageName, aInfo.name)); 2499 // Don't do this if the home app is currently being 2500 // instrumented. 2501 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2502 aInfo.applicationInfo.uid); 2503 if (app == null || app.instrumentationClass == null) { 2504 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2505 startActivityLocked(null, intent, null, null, 0, aInfo, 2506 null, null, 0, 0, 0, false, false); 2507 } 2508 } 2509 2510 2511 return true; 2512 } 2513 2514 /** 2515 * Starts the "new version setup screen" if appropriate. 2516 */ 2517 private void startSetupActivityLocked() { 2518 // Only do this once per boot. 2519 if (mCheckedForSetup) { 2520 return; 2521 } 2522 2523 // We will show this screen if the current one is a different 2524 // version than the last one shown, and we are not running in 2525 // low-level factory test mode. 2526 final ContentResolver resolver = mContext.getContentResolver(); 2527 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL && 2528 Settings.Secure.getInt(resolver, 2529 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) { 2530 mCheckedForSetup = true; 2531 2532 // See if we should be showing the platform update setup UI. 2533 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2534 List<ResolveInfo> ris = mSelf.mContext.getPackageManager() 2535 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2536 2537 // We don't allow third party apps to replace this. 2538 ResolveInfo ri = null; 2539 for (int i=0; ris != null && i<ris.size(); i++) { 2540 if ((ris.get(i).activityInfo.applicationInfo.flags 2541 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2542 ri = ris.get(i); 2543 break; 2544 } 2545 } 2546 2547 if (ri != null) { 2548 String vers = ri.activityInfo.metaData != null 2549 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2550 : null; 2551 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2552 vers = ri.activityInfo.applicationInfo.metaData.getString( 2553 Intent.METADATA_SETUP_VERSION); 2554 } 2555 String lastVers = Settings.Secure.getString( 2556 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2557 if (vers != null && !vers.equals(lastVers)) { 2558 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2559 intent.setComponent(new ComponentName( 2560 ri.activityInfo.packageName, ri.activityInfo.name)); 2561 startActivityLocked(null, intent, null, null, 0, ri.activityInfo, 2562 null, null, 0, 0, 0, false, false); 2563 } 2564 } 2565 } 2566 } 2567 2568 private void reportResumedActivityLocked(HistoryRecord r) { 2569 //Slog.i(TAG, "**** REPORT RESUME: " + r); 2570 2571 final int identHash = System.identityHashCode(r); 2572 updateUsageStats(r, true); 2573 2574 int i = mWatchers.beginBroadcast(); 2575 while (i > 0) { 2576 i--; 2577 IActivityWatcher w = mWatchers.getBroadcastItem(i); 2578 if (w != null) { 2579 try { 2580 w.activityResuming(identHash); 2581 } catch (RemoteException e) { 2582 } 2583 } 2584 } 2585 mWatchers.finishBroadcast(); 2586 } 2587 2588 /** 2589 * Ensure that the top activity in the stack is resumed. 2590 * 2591 * @param prev The previously resumed activity, for when in the process 2592 * of pausing; can be null to call from elsewhere. 2593 * 2594 * @return Returns true if something is being resumed, or false if 2595 * nothing happened. 2596 */ 2597 private final boolean resumeTopActivityLocked(HistoryRecord prev) { 2598 // Find the first activity that is not finishing. 2599 HistoryRecord next = topRunningActivityLocked(null); 2600 2601 // Remember how we'll process this pause/resume situation, and ensure 2602 // that the state is reset however we wind up proceeding. 2603 final boolean userLeaving = mUserLeaving; 2604 mUserLeaving = false; 2605 2606 if (next == null) { 2607 // There are no more activities! Let's just start up the 2608 // Launcher... 2609 return startHomeActivityLocked(); 2610 } 2611 2612 next.delayedResume = false; 2613 2614 // If the top activity is the resumed one, nothing to do. 2615 if (mResumedActivity == next && next.state == ActivityState.RESUMED) { 2616 // Make sure we have executed any pending transitions, since there 2617 // should be nothing left to do at this point. 2618 mWindowManager.executeAppTransition(); 2619 mNoAnimActivities.clear(); 2620 return false; 2621 } 2622 2623 // If we are sleeping, and there is no resumed activity, and the top 2624 // activity is paused, well that is the state we want. 2625 if ((mSleeping || mShuttingDown) 2626 && mLastPausedActivity == next && next.state == ActivityState.PAUSED) { 2627 // Make sure we have executed any pending transitions, since there 2628 // should be nothing left to do at this point. 2629 mWindowManager.executeAppTransition(); 2630 mNoAnimActivities.clear(); 2631 return false; 2632 } 2633 2634 // The activity may be waiting for stop, but that is no longer 2635 // appropriate for it. 2636 mStoppingActivities.remove(next); 2637 mWaitingVisibleActivities.remove(next); 2638 2639 if (DEBUG_SWITCH) Slog.v(TAG, "Resuming " + next); 2640 2641 // If we are currently pausing an activity, then don't do anything 2642 // until that is done. 2643 if (mPausingActivity != null) { 2644 if (DEBUG_SWITCH) Slog.v(TAG, "Skip resume: pausing=" + mPausingActivity); 2645 return false; 2646 } 2647 2648 // We need to start pausing the current activity so the top one 2649 // can be resumed... 2650 if (mResumedActivity != null) { 2651 if (DEBUG_SWITCH) Slog.v(TAG, "Skip resume: need to start pausing"); 2652 startPausingLocked(userLeaving, false); 2653 return true; 2654 } 2655 2656 if (prev != null && prev != next) { 2657 if (!prev.waitingVisible && next != null && !next.nowVisible) { 2658 prev.waitingVisible = true; 2659 mWaitingVisibleActivities.add(prev); 2660 if (DEBUG_SWITCH) Slog.v( 2661 TAG, "Resuming top, waiting visible to hide: " + prev); 2662 } else { 2663 // The next activity is already visible, so hide the previous 2664 // activity's windows right now so we can show the new one ASAP. 2665 // We only do this if the previous is finishing, which should mean 2666 // it is on top of the one being resumed so hiding it quickly 2667 // is good. Otherwise, we want to do the normal route of allowing 2668 // the resumed activity to be shown so we can decide if the 2669 // previous should actually be hidden depending on whether the 2670 // new one is found to be full-screen or not. 2671 if (prev.finishing) { 2672 mWindowManager.setAppVisibility(prev, false); 2673 if (DEBUG_SWITCH) Slog.v(TAG, "Not waiting for visible to hide: " 2674 + prev + ", waitingVisible=" 2675 + (prev != null ? prev.waitingVisible : null) 2676 + ", nowVisible=" + next.nowVisible); 2677 } else { 2678 if (DEBUG_SWITCH) Slog.v(TAG, "Previous already visible but still waiting to hide: " 2679 + prev + ", waitingVisible=" 2680 + (prev != null ? prev.waitingVisible : null) 2681 + ", nowVisible=" + next.nowVisible); 2682 } 2683 } 2684 } 2685 2686 // We are starting up the next activity, so tell the window manager 2687 // that the previous one will be hidden soon. This way it can know 2688 // to ignore it when computing the desired screen orientation. 2689 if (prev != null) { 2690 if (prev.finishing) { 2691 if (DEBUG_TRANSITION) Slog.v(TAG, 2692 "Prepare close transition: prev=" + prev); 2693 if (mNoAnimActivities.contains(prev)) { 2694 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 2695 } else { 2696 mWindowManager.prepareAppTransition(prev.task == next.task 2697 ? WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE 2698 : WindowManagerPolicy.TRANSIT_TASK_CLOSE); 2699 } 2700 mWindowManager.setAppWillBeHidden(prev); 2701 mWindowManager.setAppVisibility(prev, false); 2702 } else { 2703 if (DEBUG_TRANSITION) Slog.v(TAG, 2704 "Prepare open transition: prev=" + prev); 2705 if (mNoAnimActivities.contains(next)) { 2706 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 2707 } else { 2708 mWindowManager.prepareAppTransition(prev.task == next.task 2709 ? WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN 2710 : WindowManagerPolicy.TRANSIT_TASK_OPEN); 2711 } 2712 } 2713 if (false) { 2714 mWindowManager.setAppWillBeHidden(prev); 2715 mWindowManager.setAppVisibility(prev, false); 2716 } 2717 } else if (mHistory.size() > 1) { 2718 if (DEBUG_TRANSITION) Slog.v(TAG, 2719 "Prepare open transition: no previous"); 2720 if (mNoAnimActivities.contains(next)) { 2721 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 2722 } else { 2723 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN); 2724 } 2725 } 2726 2727 if (next.app != null && next.app.thread != null) { 2728 if (DEBUG_SWITCH) Slog.v(TAG, "Resume running: " + next); 2729 2730 // This activity is now becoming visible. 2731 mWindowManager.setAppVisibility(next, true); 2732 2733 HistoryRecord lastResumedActivity = mResumedActivity; 2734 ActivityState lastState = next.state; 2735 2736 updateCpuStats(); 2737 2738 next.state = ActivityState.RESUMED; 2739 mResumedActivity = next; 2740 next.task.touchActiveTime(); 2741 updateLruProcessLocked(next.app, true, true); 2742 updateLRUListLocked(next); 2743 2744 // Have the window manager re-evaluate the orientation of 2745 // the screen based on the new activity order. 2746 boolean updated; 2747 synchronized (this) { 2748 Configuration config = mWindowManager.updateOrientationFromAppTokens( 2749 mConfiguration, 2750 next.mayFreezeScreenLocked(next.app) ? next : null); 2751 if (config != null) { 2752 next.frozenBeforeDestroy = true; 2753 } 2754 updated = updateConfigurationLocked(config, next); 2755 } 2756 if (!updated) { 2757 // The configuration update wasn't able to keep the existing 2758 // instance of the activity, and instead started a new one. 2759 // We should be all done, but let's just make sure our activity 2760 // is still at the top and schedule another run if something 2761 // weird happened. 2762 HistoryRecord nextNext = topRunningActivityLocked(null); 2763 if (DEBUG_SWITCH) Slog.i(TAG, 2764 "Activity config changed during resume: " + next 2765 + ", new next: " + nextNext); 2766 if (nextNext != next) { 2767 // Do over! 2768 mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG); 2769 } 2770 setFocusedActivityLocked(next); 2771 ensureActivitiesVisibleLocked(null, 0); 2772 mWindowManager.executeAppTransition(); 2773 mNoAnimActivities.clear(); 2774 return true; 2775 } 2776 2777 try { 2778 // Deliver all pending results. 2779 ArrayList a = next.results; 2780 if (a != null) { 2781 final int N = a.size(); 2782 if (!next.finishing && N > 0) { 2783 if (DEBUG_RESULTS) Slog.v( 2784 TAG, "Delivering results to " + next 2785 + ": " + a); 2786 next.app.thread.scheduleSendResult(next, a); 2787 } 2788 } 2789 2790 if (next.newIntents != null) { 2791 next.app.thread.scheduleNewIntent(next.newIntents, next); 2792 } 2793 2794 EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, 2795 System.identityHashCode(next), 2796 next.task.taskId, next.shortComponentName); 2797 2798 next.app.thread.scheduleResumeActivity(next, 2799 isNextTransitionForward()); 2800 2801 pauseIfSleepingLocked(); 2802 2803 } catch (Exception e) { 2804 // Whoops, need to restart this activity! 2805 next.state = lastState; 2806 mResumedActivity = lastResumedActivity; 2807 Slog.i(TAG, "Restarting because process died: " + next); 2808 if (!next.hasBeenLaunched) { 2809 next.hasBeenLaunched = true; 2810 } else { 2811 if (SHOW_APP_STARTING_ICON) { 2812 mWindowManager.setAppStartingWindow( 2813 next, next.packageName, next.theme, 2814 next.nonLocalizedLabel, 2815 next.labelRes, next.icon, null, true); 2816 } 2817 } 2818 startSpecificActivityLocked(next, true, false); 2819 return true; 2820 } 2821 2822 // From this point on, if something goes wrong there is no way 2823 // to recover the activity. 2824 try { 2825 next.visible = true; 2826 completeResumeLocked(next); 2827 } catch (Exception e) { 2828 // If any exception gets thrown, toss away this 2829 // activity and try the next one. 2830 Slog.w(TAG, "Exception thrown during resume of " + next, e); 2831 requestFinishActivityLocked(next, Activity.RESULT_CANCELED, null, 2832 "resume-exception"); 2833 return true; 2834 } 2835 2836 // Didn't need to use the icicle, and it is now out of date. 2837 next.icicle = null; 2838 next.haveState = false; 2839 next.stopped = false; 2840 2841 } else { 2842 // Whoops, need to restart this activity! 2843 if (!next.hasBeenLaunched) { 2844 next.hasBeenLaunched = true; 2845 } else { 2846 if (SHOW_APP_STARTING_ICON) { 2847 mWindowManager.setAppStartingWindow( 2848 next, next.packageName, next.theme, 2849 next.nonLocalizedLabel, 2850 next.labelRes, next.icon, null, true); 2851 } 2852 if (DEBUG_SWITCH) Slog.v(TAG, "Restarting: " + next); 2853 } 2854 startSpecificActivityLocked(next, true, true); 2855 } 2856 2857 return true; 2858 } 2859 2860 private final void startActivityLocked(HistoryRecord r, boolean newTask, 2861 boolean doResume) { 2862 final int NH = mHistory.size(); 2863 2864 int addPos = -1; 2865 2866 if (!newTask) { 2867 // If starting in an existing task, find where that is... 2868 HistoryRecord next = null; 2869 boolean startIt = true; 2870 for (int i = NH-1; i >= 0; i--) { 2871 HistoryRecord p = (HistoryRecord)mHistory.get(i); 2872 if (p.finishing) { 2873 continue; 2874 } 2875 if (p.task == r.task) { 2876 // Here it is! Now, if this is not yet visible to the 2877 // user, then just add it without starting; it will 2878 // get started when the user navigates back to it. 2879 addPos = i+1; 2880 if (!startIt) { 2881 mHistory.add(addPos, r); 2882 r.inHistory = true; 2883 r.task.numActivities++; 2884 mWindowManager.addAppToken(addPos, r, r.task.taskId, 2885 r.info.screenOrientation, r.fullscreen); 2886 if (VALIDATE_TOKENS) { 2887 mWindowManager.validateAppTokens(mHistory); 2888 } 2889 return; 2890 } 2891 break; 2892 } 2893 if (p.fullscreen) { 2894 startIt = false; 2895 } 2896 next = p; 2897 } 2898 } 2899 2900 // Place a new activity at top of stack, so it is next to interact 2901 // with the user. 2902 if (addPos < 0) { 2903 addPos = mHistory.size(); 2904 } 2905 2906 // If we are not placing the new activity frontmost, we do not want 2907 // to deliver the onUserLeaving callback to the actual frontmost 2908 // activity 2909 if (addPos < NH) { 2910 mUserLeaving = false; 2911 if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() behind front, mUserLeaving=false"); 2912 } 2913 2914 // Slot the activity into the history stack and proceed 2915 mHistory.add(addPos, r); 2916 r.inHistory = true; 2917 r.frontOfTask = newTask; 2918 r.task.numActivities++; 2919 if (NH > 0) { 2920 // We want to show the starting preview window if we are 2921 // switching to a new task, or the next activity's process is 2922 // not currently running. 2923 boolean showStartingIcon = newTask; 2924 ProcessRecord proc = r.app; 2925 if (proc == null) { 2926 proc = mProcessNames.get(r.processName, r.info.applicationInfo.uid); 2927 } 2928 if (proc == null || proc.thread == null) { 2929 showStartingIcon = true; 2930 } 2931 if (DEBUG_TRANSITION) Slog.v(TAG, 2932 "Prepare open transition: starting " + r); 2933 if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { 2934 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 2935 mNoAnimActivities.add(r); 2936 } else if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) { 2937 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_OPEN); 2938 mNoAnimActivities.remove(r); 2939 } else { 2940 mWindowManager.prepareAppTransition(newTask 2941 ? WindowManagerPolicy.TRANSIT_TASK_OPEN 2942 : WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN); 2943 mNoAnimActivities.remove(r); 2944 } 2945 mWindowManager.addAppToken( 2946 addPos, r, r.task.taskId, r.info.screenOrientation, r.fullscreen); 2947 boolean doShow = true; 2948 if (newTask) { 2949 // Even though this activity is starting fresh, we still need 2950 // to reset it to make sure we apply affinities to move any 2951 // existing activities from other tasks in to it. 2952 // If the caller has requested that the target task be 2953 // reset, then do so. 2954 if ((r.intent.getFlags() 2955 &Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 2956 resetTaskIfNeededLocked(r, r); 2957 doShow = topRunningNonDelayedActivityLocked(null) == r; 2958 } 2959 } 2960 if (SHOW_APP_STARTING_ICON && doShow) { 2961 // Figure out if we are transitioning from another activity that is 2962 // "has the same starting icon" as the next one. This allows the 2963 // window manager to keep the previous window it had previously 2964 // created, if it still had one. 2965 HistoryRecord prev = mResumedActivity; 2966 if (prev != null) { 2967 // We don't want to reuse the previous starting preview if: 2968 // (1) The current activity is in a different task. 2969 if (prev.task != r.task) prev = null; 2970 // (2) The current activity is already displayed. 2971 else if (prev.nowVisible) prev = null; 2972 } 2973 mWindowManager.setAppStartingWindow( 2974 r, r.packageName, r.theme, r.nonLocalizedLabel, 2975 r.labelRes, r.icon, prev, showStartingIcon); 2976 } 2977 } else { 2978 // If this is the first activity, don't do any fancy animations, 2979 // because there is nothing for it to animate on top of. 2980 mWindowManager.addAppToken(addPos, r, r.task.taskId, 2981 r.info.screenOrientation, r.fullscreen); 2982 } 2983 if (VALIDATE_TOKENS) { 2984 mWindowManager.validateAppTokens(mHistory); 2985 } 2986 2987 if (doResume) { 2988 resumeTopActivityLocked(null); 2989 } 2990 } 2991 2992 /** 2993 * Perform clear operation as requested by 2994 * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the 2995 * stack to the given task, then look for 2996 * an instance of that activity in the stack and, if found, finish all 2997 * activities on top of it and return the instance. 2998 * 2999 * @param newR Description of the new activity being started. 3000 * @return Returns the old activity that should be continue to be used, 3001 * or null if none was found. 3002 */ 3003 private final HistoryRecord performClearTaskLocked(int taskId, 3004 HistoryRecord newR, int launchFlags, boolean doClear) { 3005 int i = mHistory.size(); 3006 3007 // First find the requested task. 3008 while (i > 0) { 3009 i--; 3010 HistoryRecord r = (HistoryRecord)mHistory.get(i); 3011 if (r.task.taskId == taskId) { 3012 i++; 3013 break; 3014 } 3015 } 3016 3017 // Now clear it. 3018 while (i > 0) { 3019 i--; 3020 HistoryRecord r = (HistoryRecord)mHistory.get(i); 3021 if (r.finishing) { 3022 continue; 3023 } 3024 if (r.task.taskId != taskId) { 3025 return null; 3026 } 3027 if (r.realActivity.equals(newR.realActivity)) { 3028 // Here it is! Now finish everything in front... 3029 HistoryRecord ret = r; 3030 if (doClear) { 3031 while (i < (mHistory.size()-1)) { 3032 i++; 3033 r = (HistoryRecord)mHistory.get(i); 3034 if (r.finishing) { 3035 continue; 3036 } 3037 if (finishActivityLocked(r, i, Activity.RESULT_CANCELED, 3038 null, "clear")) { 3039 i--; 3040 } 3041 } 3042 } 3043 3044 // Finally, if this is a normal launch mode (that is, not 3045 // expecting onNewIntent()), then we will finish the current 3046 // instance of the activity so a new fresh one can be started. 3047 if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE 3048 && (launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) { 3049 if (!ret.finishing) { 3050 int index = indexOfTokenLocked(ret); 3051 if (index >= 0) { 3052 finishActivityLocked(ret, index, Activity.RESULT_CANCELED, 3053 null, "clear"); 3054 } 3055 return null; 3056 } 3057 } 3058 3059 return ret; 3060 } 3061 } 3062 3063 return null; 3064 } 3065 3066 /** 3067 * Find the activity in the history stack within the given task. Returns 3068 * the index within the history at which it's found, or < 0 if not found. 3069 */ 3070 private final int findActivityInHistoryLocked(HistoryRecord r, int task) { 3071 int i = mHistory.size(); 3072 while (i > 0) { 3073 i--; 3074 HistoryRecord candidate = (HistoryRecord)mHistory.get(i); 3075 if (candidate.task.taskId != task) { 3076 break; 3077 } 3078 if (candidate.realActivity.equals(r.realActivity)) { 3079 return i; 3080 } 3081 } 3082 3083 return -1; 3084 } 3085 3086 /** 3087 * Reorder the history stack so that the activity at the given index is 3088 * brought to the front. 3089 */ 3090 private final HistoryRecord moveActivityToFrontLocked(int where) { 3091 HistoryRecord newTop = (HistoryRecord)mHistory.remove(where); 3092 int top = mHistory.size(); 3093 HistoryRecord oldTop = (HistoryRecord)mHistory.get(top-1); 3094 mHistory.add(top, newTop); 3095 oldTop.frontOfTask = false; 3096 newTop.frontOfTask = true; 3097 return newTop; 3098 } 3099 3100 /** 3101 * Deliver a new Intent to an existing activity, so that its onNewIntent() 3102 * method will be called at the proper time. 3103 */ 3104 private final void deliverNewIntentLocked(HistoryRecord r, Intent intent) { 3105 boolean sent = false; 3106 if (r.state == ActivityState.RESUMED 3107 && r.app != null && r.app.thread != null) { 3108 try { 3109 ArrayList<Intent> ar = new ArrayList<Intent>(); 3110 ar.add(new Intent(intent)); 3111 r.app.thread.scheduleNewIntent(ar, r); 3112 sent = true; 3113 } catch (Exception e) { 3114 Slog.w(TAG, "Exception thrown sending new intent to " + r, e); 3115 } 3116 } 3117 if (!sent) { 3118 r.addNewIntentLocked(new Intent(intent)); 3119 } 3120 } 3121 3122 private final void logStartActivity(int tag, HistoryRecord r, 3123 TaskRecord task) { 3124 EventLog.writeEvent(tag, 3125 System.identityHashCode(r), task.taskId, 3126 r.shortComponentName, r.intent.getAction(), 3127 r.intent.getType(), r.intent.getDataString(), 3128 r.intent.getFlags()); 3129 } 3130 3131 private final int startActivityLocked(IApplicationThread caller, 3132 Intent intent, String resolvedType, 3133 Uri[] grantedUriPermissions, 3134 int grantedMode, ActivityInfo aInfo, IBinder resultTo, 3135 String resultWho, int requestCode, 3136 int callingPid, int callingUid, boolean onlyIfNeeded, 3137 boolean componentSpecified) { 3138 Slog.i(TAG, "Starting activity: " + intent); 3139 3140 HistoryRecord sourceRecord = null; 3141 HistoryRecord resultRecord = null; 3142 if (resultTo != null) { 3143 int index = indexOfTokenLocked(resultTo); 3144 if (DEBUG_RESULTS) Slog.v( 3145 TAG, "Sending result to " + resultTo + " (index " + index + ")"); 3146 if (index >= 0) { 3147 sourceRecord = (HistoryRecord)mHistory.get(index); 3148 if (requestCode >= 0 && !sourceRecord.finishing) { 3149 resultRecord = sourceRecord; 3150 } 3151 } 3152 } 3153 3154 int launchFlags = intent.getFlags(); 3155 3156 if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 3157 && sourceRecord != null) { 3158 // Transfer the result target from the source activity to the new 3159 // one being started, including any failures. 3160 if (requestCode >= 0) { 3161 return START_FORWARD_AND_REQUEST_CONFLICT; 3162 } 3163 resultRecord = sourceRecord.resultTo; 3164 resultWho = sourceRecord.resultWho; 3165 requestCode = sourceRecord.requestCode; 3166 sourceRecord.resultTo = null; 3167 if (resultRecord != null) { 3168 resultRecord.removeResultsLocked( 3169 sourceRecord, resultWho, requestCode); 3170 } 3171 } 3172 3173 int err = START_SUCCESS; 3174 3175 if (intent.getComponent() == null) { 3176 // We couldn't find a class that can handle the given Intent. 3177 // That's the end of that! 3178 err = START_INTENT_NOT_RESOLVED; 3179 } 3180 3181 if (err == START_SUCCESS && aInfo == null) { 3182 // We couldn't find the specific class specified in the Intent. 3183 // Also the end of the line. 3184 err = START_CLASS_NOT_FOUND; 3185 } 3186 3187 ProcessRecord callerApp = null; 3188 if (err == START_SUCCESS && caller != null) { 3189 callerApp = getRecordForAppLocked(caller); 3190 if (callerApp != null) { 3191 callingPid = callerApp.pid; 3192 callingUid = callerApp.info.uid; 3193 } else { 3194 Slog.w(TAG, "Unable to find app for caller " + caller 3195 + " (pid=" + callingPid + ") when starting: " 3196 + intent.toString()); 3197 err = START_PERMISSION_DENIED; 3198 } 3199 } 3200 3201 if (err != START_SUCCESS) { 3202 if (resultRecord != null) { 3203 sendActivityResultLocked(-1, 3204 resultRecord, resultWho, requestCode, 3205 Activity.RESULT_CANCELED, null); 3206 } 3207 return err; 3208 } 3209 3210 final int perm = checkComponentPermission(aInfo.permission, callingPid, 3211 callingUid, aInfo.exported ? -1 : aInfo.applicationInfo.uid); 3212 if (perm != PackageManager.PERMISSION_GRANTED) { 3213 if (resultRecord != null) { 3214 sendActivityResultLocked(-1, 3215 resultRecord, resultWho, requestCode, 3216 Activity.RESULT_CANCELED, null); 3217 } 3218 String msg = "Permission Denial: starting " + intent.toString() 3219 + " from " + callerApp + " (pid=" + callingPid 3220 + ", uid=" + callingUid + ")" 3221 + " requires " + aInfo.permission; 3222 Slog.w(TAG, msg); 3223 throw new SecurityException(msg); 3224 } 3225 3226 if (mController != null) { 3227 boolean abort = false; 3228 try { 3229 // The Intent we give to the watcher has the extra data 3230 // stripped off, since it can contain private information. 3231 Intent watchIntent = intent.cloneFilter(); 3232 abort = !mController.activityStarting(watchIntent, 3233 aInfo.applicationInfo.packageName); 3234 } catch (RemoteException e) { 3235 mController = null; 3236 } 3237 3238 if (abort) { 3239 if (resultRecord != null) { 3240 sendActivityResultLocked(-1, 3241 resultRecord, resultWho, requestCode, 3242 Activity.RESULT_CANCELED, null); 3243 } 3244 // We pretend to the caller that it was really started, but 3245 // they will just get a cancel result. 3246 return START_SUCCESS; 3247 } 3248 } 3249 3250 HistoryRecord r = new HistoryRecord(this, callerApp, callingUid, 3251 intent, resolvedType, aInfo, mConfiguration, 3252 resultRecord, resultWho, requestCode, componentSpecified); 3253 3254 if (mResumedActivity == null 3255 || mResumedActivity.info.applicationInfo.uid != callingUid) { 3256 if (!checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) { 3257 PendingActivityLaunch pal = new PendingActivityLaunch(); 3258 pal.r = r; 3259 pal.sourceRecord = sourceRecord; 3260 pal.grantedUriPermissions = grantedUriPermissions; 3261 pal.grantedMode = grantedMode; 3262 pal.onlyIfNeeded = onlyIfNeeded; 3263 mPendingActivityLaunches.add(pal); 3264 return START_SWITCHES_CANCELED; 3265 } 3266 } 3267 3268 if (mDidAppSwitch) { 3269 // This is the second allowed switch since we stopped switches, 3270 // so now just generally allow switches. Use case: user presses 3271 // home (switches disabled, switch to home, mDidAppSwitch now true); 3272 // user taps a home icon (coming from home so allowed, we hit here 3273 // and now allow anyone to switch again). 3274 mAppSwitchesAllowedTime = 0; 3275 } else { 3276 mDidAppSwitch = true; 3277 } 3278 3279 doPendingActivityLaunchesLocked(false); 3280 3281 return startActivityUncheckedLocked(r, sourceRecord, 3282 grantedUriPermissions, grantedMode, onlyIfNeeded, true); 3283 } 3284 3285 private final void doPendingActivityLaunchesLocked(boolean doResume) { 3286 final int N = mPendingActivityLaunches.size(); 3287 if (N <= 0) { 3288 return; 3289 } 3290 for (int i=0; i<N; i++) { 3291 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3292 startActivityUncheckedLocked(pal.r, pal.sourceRecord, 3293 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded, 3294 doResume && i == (N-1)); 3295 } 3296 mPendingActivityLaunches.clear(); 3297 } 3298 3299 private final int startActivityUncheckedLocked(HistoryRecord r, 3300 HistoryRecord sourceRecord, Uri[] grantedUriPermissions, 3301 int grantedMode, boolean onlyIfNeeded, boolean doResume) { 3302 final Intent intent = r.intent; 3303 final int callingUid = r.launchedFromUid; 3304 3305 int launchFlags = intent.getFlags(); 3306 3307 // We'll invoke onUserLeaving before onPause only if the launching 3308 // activity did not explicitly state that this is an automated launch. 3309 mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0; 3310 if (DEBUG_USER_LEAVING) Slog.v(TAG, 3311 "startActivity() => mUserLeaving=" + mUserLeaving); 3312 3313 // If the caller has asked not to resume at this point, we make note 3314 // of this in the record so that we can skip it when trying to find 3315 // the top running activity. 3316 if (!doResume) { 3317 r.delayedResume = true; 3318 } 3319 3320 HistoryRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) 3321 != 0 ? r : null; 3322 3323 // If the onlyIfNeeded flag is set, then we can do this if the activity 3324 // being launched is the same as the one making the call... or, as 3325 // a special case, if we do not know the caller then we count the 3326 // current top activity as the caller. 3327 if (onlyIfNeeded) { 3328 HistoryRecord checkedCaller = sourceRecord; 3329 if (checkedCaller == null) { 3330 checkedCaller = topRunningNonDelayedActivityLocked(notTop); 3331 } 3332 if (!checkedCaller.realActivity.equals(r.realActivity)) { 3333 // Caller is not the same as launcher, so always needed. 3334 onlyIfNeeded = false; 3335 } 3336 } 3337 3338 if (grantedUriPermissions != null && callingUid > 0) { 3339 for (int i=0; i<grantedUriPermissions.length; i++) { 3340 grantUriPermissionLocked(callingUid, r.packageName, 3341 grantedUriPermissions[i], grantedMode, r); 3342 } 3343 } 3344 3345 grantUriPermissionFromIntentLocked(callingUid, r.packageName, 3346 intent, r); 3347 3348 if (sourceRecord == null) { 3349 // This activity is not being started from another... in this 3350 // case we -always- start a new task. 3351 if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 3352 Slog.w(TAG, "startActivity called from non-Activity context; forcing Intent.FLAG_ACTIVITY_NEW_TASK for: " 3353 + intent); 3354 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 3355 } 3356 } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 3357 // The original activity who is starting us is running as a single 3358 // instance... this new activity it is starting must go on its 3359 // own task. 3360 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 3361 } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE 3362 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 3363 // The activity being started is a single instance... it always 3364 // gets launched into its own task. 3365 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; 3366 } 3367 3368 if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 3369 // For whatever reason this activity is being launched into a new 3370 // task... yet the caller has requested a result back. Well, that 3371 // is pretty messed up, so instead immediately send back a cancel 3372 // and let the new task continue launched as normal without a 3373 // dependency on its originator. 3374 Slog.w(TAG, "Activity is launching as a new task, so cancelling activity result."); 3375 sendActivityResultLocked(-1, 3376 r.resultTo, r.resultWho, r.requestCode, 3377 Activity.RESULT_CANCELED, null); 3378 r.resultTo = null; 3379 } 3380 3381 boolean addingToTask = false; 3382 if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && 3383 (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) 3384 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 3385 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 3386 // If bring to front is requested, and no result is requested, and 3387 // we can find a task that was started with this same 3388 // component, then instead of launching bring that one to the front. 3389 if (r.resultTo == null) { 3390 // See if there is a task to bring to the front. If this is 3391 // a SINGLE_INSTANCE activity, there can be one and only one 3392 // instance of it in the history, and it is always in its own 3393 // unique task, so we do a special search. 3394 HistoryRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE 3395 ? findTaskLocked(intent, r.info) 3396 : findActivityLocked(intent, r.info); 3397 if (taskTop != null) { 3398 if (taskTop.task.intent == null) { 3399 // This task was started because of movement of 3400 // the activity based on affinity... now that we 3401 // are actually launching it, we can assign the 3402 // base intent. 3403 taskTop.task.setIntent(intent, r.info); 3404 } 3405 // If the target task is not in the front, then we need 3406 // to bring it to the front... except... well, with 3407 // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like 3408 // to have the same behavior as if a new instance was 3409 // being started, which means not bringing it to the front 3410 // if the caller is not itself in the front. 3411 HistoryRecord curTop = topRunningNonDelayedActivityLocked(notTop); 3412 if (curTop.task != taskTop.task) { 3413 r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); 3414 boolean callerAtFront = sourceRecord == null 3415 || curTop.task == sourceRecord.task; 3416 if (callerAtFront) { 3417 // We really do want to push this one into the 3418 // user's face, right now. 3419 moveTaskToFrontLocked(taskTop.task, r); 3420 } 3421 } 3422 // If the caller has requested that the target task be 3423 // reset, then do so. 3424 if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 3425 taskTop = resetTaskIfNeededLocked(taskTop, r); 3426 } 3427 if (onlyIfNeeded) { 3428 // We don't need to start a new activity, and 3429 // the client said not to do anything if that 3430 // is the case, so this is it! And for paranoia, make 3431 // sure we have correctly resumed the top activity. 3432 if (doResume) { 3433 resumeTopActivityLocked(null); 3434 } 3435 return START_RETURN_INTENT_TO_CALLER; 3436 } 3437 if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0 3438 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK 3439 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 3440 // In this situation we want to remove all activities 3441 // from the task up to the one being started. In most 3442 // cases this means we are resetting the task to its 3443 // initial state. 3444 HistoryRecord top = performClearTaskLocked( 3445 taskTop.task.taskId, r, launchFlags, true); 3446 if (top != null) { 3447 if (top.frontOfTask) { 3448 // Activity aliases may mean we use different 3449 // intents for the top activity, so make sure 3450 // the task now has the identity of the new 3451 // intent. 3452 top.task.setIntent(r.intent, r.info); 3453 } 3454 logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); 3455 deliverNewIntentLocked(top, r.intent); 3456 } else { 3457 // A special case: we need to 3458 // start the activity because it is not currently 3459 // running, and the caller has asked to clear the 3460 // current task to have this activity at the top. 3461 addingToTask = true; 3462 // Now pretend like this activity is being started 3463 // by the top of its task, so it is put in the 3464 // right place. 3465 sourceRecord = taskTop; 3466 } 3467 } else if (r.realActivity.equals(taskTop.task.realActivity)) { 3468 // In this case the top activity on the task is the 3469 // same as the one being launched, so we take that 3470 // as a request to bring the task to the foreground. 3471 // If the top activity in the task is the root 3472 // activity, deliver this new intent to it if it 3473 // desires. 3474 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 3475 && taskTop.realActivity.equals(r.realActivity)) { 3476 logStartActivity(EventLogTags.AM_NEW_INTENT, r, taskTop.task); 3477 if (taskTop.frontOfTask) { 3478 taskTop.task.setIntent(r.intent, r.info); 3479 } 3480 deliverNewIntentLocked(taskTop, r.intent); 3481 } else if (!r.intent.filterEquals(taskTop.task.intent)) { 3482 // In this case we are launching the root activity 3483 // of the task, but with a different intent. We 3484 // should start a new instance on top. 3485 addingToTask = true; 3486 sourceRecord = taskTop; 3487 } 3488 } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) { 3489 // In this case an activity is being launched in to an 3490 // existing task, without resetting that task. This 3491 // is typically the situation of launching an activity 3492 // from a notification or shortcut. We want to place 3493 // the new activity on top of the current task. 3494 addingToTask = true; 3495 sourceRecord = taskTop; 3496 } else if (!taskTop.task.rootWasReset) { 3497 // In this case we are launching in to an existing task 3498 // that has not yet been started from its front door. 3499 // The current task has been brought to the front. 3500 // Ideally, we'd probably like to place this new task 3501 // at the bottom of its stack, but that's a little hard 3502 // to do with the current organization of the code so 3503 // for now we'll just drop it. 3504 taskTop.task.setIntent(r.intent, r.info); 3505 } 3506 if (!addingToTask) { 3507 // We didn't do anything... but it was needed (a.k.a., client 3508 // don't use that intent!) And for paranoia, make 3509 // sure we have correctly resumed the top activity. 3510 if (doResume) { 3511 resumeTopActivityLocked(null); 3512 } 3513 return START_TASK_TO_FRONT; 3514 } 3515 } 3516 } 3517 } 3518 3519 //String uri = r.intent.toURI(); 3520 //Intent intent2 = new Intent(uri); 3521 //Slog.i(TAG, "Given intent: " + r.intent); 3522 //Slog.i(TAG, "URI is: " + uri); 3523 //Slog.i(TAG, "To intent: " + intent2); 3524 3525 if (r.packageName != null) { 3526 // If the activity being launched is the same as the one currently 3527 // at the top, then we need to check if it should only be launched 3528 // once. 3529 HistoryRecord top = topRunningNonDelayedActivityLocked(notTop); 3530 if (top != null && r.resultTo == null) { 3531 if (top.realActivity.equals(r.realActivity)) { 3532 if (top.app != null && top.app.thread != null) { 3533 if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 3534 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP 3535 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { 3536 logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task); 3537 // For paranoia, make sure we have correctly 3538 // resumed the top activity. 3539 if (doResume) { 3540 resumeTopActivityLocked(null); 3541 } 3542 if (onlyIfNeeded) { 3543 // We don't need to start a new activity, and 3544 // the client said not to do anything if that 3545 // is the case, so this is it! 3546 return START_RETURN_INTENT_TO_CALLER; 3547 } 3548 deliverNewIntentLocked(top, r.intent); 3549 return START_DELIVERED_TO_TOP; 3550 } 3551 } 3552 } 3553 } 3554 3555 } else { 3556 if (r.resultTo != null) { 3557 sendActivityResultLocked(-1, 3558 r.resultTo, r.resultWho, r.requestCode, 3559 Activity.RESULT_CANCELED, null); 3560 } 3561 return START_CLASS_NOT_FOUND; 3562 } 3563 3564 boolean newTask = false; 3565 3566 // Should this be considered a new task? 3567 if (r.resultTo == null && !addingToTask 3568 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 3569 // todo: should do better management of integers. 3570 mCurTask++; 3571 if (mCurTask <= 0) { 3572 mCurTask = 1; 3573 } 3574 r.task = new TaskRecord(mCurTask, r.info, intent, 3575 (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0); 3576 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 3577 + " in new task " + r.task); 3578 newTask = true; 3579 addRecentTaskLocked(r.task); 3580 3581 } else if (sourceRecord != null) { 3582 if (!addingToTask && 3583 (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { 3584 // In this case, we are adding the activity to an existing 3585 // task, but the caller has asked to clear that task if the 3586 // activity is already running. 3587 HistoryRecord top = performClearTaskLocked( 3588 sourceRecord.task.taskId, r, launchFlags, true); 3589 if (top != null) { 3590 logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); 3591 deliverNewIntentLocked(top, r.intent); 3592 // For paranoia, make sure we have correctly 3593 // resumed the top activity. 3594 if (doResume) { 3595 resumeTopActivityLocked(null); 3596 } 3597 return START_DELIVERED_TO_TOP; 3598 } 3599 } else if (!addingToTask && 3600 (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { 3601 // In this case, we are launching an activity in our own task 3602 // that may already be running somewhere in the history, and 3603 // we want to shuffle it to the front of the stack if so. 3604 int where = findActivityInHistoryLocked(r, sourceRecord.task.taskId); 3605 if (where >= 0) { 3606 HistoryRecord top = moveActivityToFrontLocked(where); 3607 logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); 3608 deliverNewIntentLocked(top, r.intent); 3609 if (doResume) { 3610 resumeTopActivityLocked(null); 3611 } 3612 return START_DELIVERED_TO_TOP; 3613 } 3614 } 3615 // An existing activity is starting this new activity, so we want 3616 // to keep the new one in the same task as the one that is starting 3617 // it. 3618 r.task = sourceRecord.task; 3619 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 3620 + " in existing task " + r.task); 3621 3622 } else { 3623 // This not being started from an existing activity, and not part 3624 // of a new task... just put it in the top task, though these days 3625 // this case should never happen. 3626 final int N = mHistory.size(); 3627 HistoryRecord prev = 3628 N > 0 ? (HistoryRecord)mHistory.get(N-1) : null; 3629 r.task = prev != null 3630 ? prev.task 3631 : new TaskRecord(mCurTask, r.info, intent, 3632 (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0); 3633 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r 3634 + " in new guessed " + r.task); 3635 } 3636 if (newTask) { 3637 EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.task.taskId); 3638 } 3639 logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task); 3640 startActivityLocked(r, newTask, doResume); 3641 return START_SUCCESS; 3642 } 3643 3644 void reportActivityLaunchedLocked(boolean timeout, HistoryRecord r, 3645 long thisTime, long totalTime) { 3646 for (int i=mWaitingActivityLaunched.size()-1; i>=0; i--) { 3647 WaitResult w = mWaitingActivityLaunched.get(i); 3648 w.timeout = timeout; 3649 if (r != null) { 3650 w.who = new ComponentName(r.info.packageName, r.info.name); 3651 } 3652 w.thisTime = thisTime; 3653 w.totalTime = totalTime; 3654 } 3655 notify(); 3656 } 3657 3658 void reportActivityVisibleLocked(HistoryRecord r) { 3659 for (int i=mWaitingActivityVisible.size()-1; i>=0; i--) { 3660 WaitResult w = mWaitingActivityVisible.get(i); 3661 w.timeout = false; 3662 if (r != null) { 3663 w.who = new ComponentName(r.info.packageName, r.info.name); 3664 } 3665 w.totalTime = SystemClock.uptimeMillis() - w.thisTime; 3666 w.thisTime = w.totalTime; 3667 } 3668 notify(); 3669 } 3670 3671 private final int startActivityMayWait(IApplicationThread caller, 3672 Intent intent, String resolvedType, Uri[] grantedUriPermissions, 3673 int grantedMode, IBinder resultTo, 3674 String resultWho, int requestCode, boolean onlyIfNeeded, 3675 boolean debug, WaitResult outResult, Configuration config) { 3676 // Refuse possible leaked file descriptors 3677 if (intent != null && intent.hasFileDescriptors()) { 3678 throw new IllegalArgumentException("File descriptors passed in Intent"); 3679 } 3680 3681 final boolean componentSpecified = intent.getComponent() != null; 3682 3683 // Don't modify the client's object! 3684 intent = new Intent(intent); 3685 3686 // Collect information about the target of the Intent. 3687 ActivityInfo aInfo; 3688 try { 3689 ResolveInfo rInfo = 3690 ActivityThread.getPackageManager().resolveIntent( 3691 intent, resolvedType, 3692 PackageManager.MATCH_DEFAULT_ONLY 3693 | STOCK_PM_FLAGS); 3694 aInfo = rInfo != null ? rInfo.activityInfo : null; 3695 } catch (RemoteException e) { 3696 aInfo = null; 3697 } 3698 3699 if (aInfo != null) { 3700 // Store the found target back into the intent, because now that 3701 // we have it we never want to do this again. For example, if the 3702 // user navigates back to this point in the history, we should 3703 // always restart the exact same activity. 3704 intent.setComponent(new ComponentName( 3705 aInfo.applicationInfo.packageName, aInfo.name)); 3706 3707 // Don't debug things in the system process 3708 if (debug) { 3709 if (!aInfo.processName.equals("system")) { 3710 setDebugApp(aInfo.processName, true, false); 3711 } 3712 } 3713 } 3714 3715 synchronized (this) { 3716 int callingPid; 3717 int callingUid; 3718 if (caller == null) { 3719 callingPid = Binder.getCallingPid(); 3720 callingUid = Binder.getCallingUid(); 3721 } else { 3722 callingPid = callingUid = -1; 3723 } 3724 3725 mConfigWillChange = config != null && mConfiguration.diff(config) != 0; 3726 if (DEBUG_CONFIGURATION) Slog.v(TAG, 3727 "Starting activity when config will change = " + mConfigWillChange); 3728 3729 final long origId = Binder.clearCallingIdentity(); 3730 3731 int res = startActivityLocked(caller, intent, resolvedType, 3732 grantedUriPermissions, grantedMode, aInfo, 3733 resultTo, resultWho, requestCode, callingPid, callingUid, 3734 onlyIfNeeded, componentSpecified); 3735 3736 if (mConfigWillChange) { 3737 // If the caller also wants to switch to a new configuration, 3738 // do so now. This allows a clean switch, as we are waiting 3739 // for the current activity to pause (so we will not destroy 3740 // it), and have not yet started the next activity. 3741 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 3742 "updateConfiguration()"); 3743 mConfigWillChange = false; 3744 if (DEBUG_CONFIGURATION) Slog.v(TAG, 3745 "Updating to new configuration after starting activity."); 3746 updateConfigurationLocked(config, null); 3747 } 3748 3749 Binder.restoreCallingIdentity(origId); 3750 3751 if (outResult != null) { 3752 outResult.result = res; 3753 if (res == IActivityManager.START_SUCCESS) { 3754 mWaitingActivityLaunched.add(outResult); 3755 do { 3756 try { 3757 wait(); 3758 } catch (InterruptedException e) { 3759 } 3760 } while (!outResult.timeout && outResult.who == null); 3761 } else if (res == IActivityManager.START_TASK_TO_FRONT) { 3762 HistoryRecord r = this.topRunningActivityLocked(null); 3763 if (r.nowVisible) { 3764 outResult.timeout = false; 3765 outResult.who = new ComponentName(r.info.packageName, r.info.name); 3766 outResult.totalTime = 0; 3767 outResult.thisTime = 0; 3768 } else { 3769 outResult.thisTime = SystemClock.uptimeMillis(); 3770 mWaitingActivityVisible.add(outResult); 3771 do { 3772 try { 3773 wait(); 3774 } catch (InterruptedException e) { 3775 } 3776 } while (!outResult.timeout && outResult.who == null); 3777 } 3778 } 3779 } 3780 3781 return res; 3782 } 3783 } 3784 3785 public final int startActivity(IApplicationThread caller, 3786 Intent intent, String resolvedType, Uri[] grantedUriPermissions, 3787 int grantedMode, IBinder resultTo, 3788 String resultWho, int requestCode, boolean onlyIfNeeded, 3789 boolean debug) { 3790 return startActivityMayWait(caller, intent, resolvedType, 3791 grantedUriPermissions, grantedMode, resultTo, resultWho, 3792 requestCode, onlyIfNeeded, debug, null, null); 3793 } 3794 3795 public final WaitResult startActivityAndWait(IApplicationThread caller, 3796 Intent intent, String resolvedType, Uri[] grantedUriPermissions, 3797 int grantedMode, IBinder resultTo, 3798 String resultWho, int requestCode, boolean onlyIfNeeded, 3799 boolean debug) { 3800 WaitResult res = new WaitResult(); 3801 startActivityMayWait(caller, intent, resolvedType, 3802 grantedUriPermissions, grantedMode, resultTo, resultWho, 3803 requestCode, onlyIfNeeded, debug, res, null); 3804 return res; 3805 } 3806 3807 public final int startActivityWithConfig(IApplicationThread caller, 3808 Intent intent, String resolvedType, Uri[] grantedUriPermissions, 3809 int grantedMode, IBinder resultTo, 3810 String resultWho, int requestCode, boolean onlyIfNeeded, 3811 boolean debug, Configuration config) { 3812 return startActivityMayWait(caller, intent, resolvedType, 3813 grantedUriPermissions, grantedMode, resultTo, resultWho, 3814 requestCode, onlyIfNeeded, debug, null, config); 3815 } 3816 3817 public int startActivityIntentSender(IApplicationThread caller, 3818 IntentSender intent, Intent fillInIntent, String resolvedType, 3819 IBinder resultTo, String resultWho, int requestCode, 3820 int flagsMask, int flagsValues) { 3821 // Refuse possible leaked file descriptors 3822 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3823 throw new IllegalArgumentException("File descriptors passed in Intent"); 3824 } 3825 3826 IIntentSender sender = intent.getTarget(); 3827 if (!(sender instanceof PendingIntentRecord)) { 3828 throw new IllegalArgumentException("Bad PendingIntent object"); 3829 } 3830 3831 PendingIntentRecord pir = (PendingIntentRecord)sender; 3832 3833 synchronized (this) { 3834 // If this is coming from the currently resumed activity, it is 3835 // effectively saying that app switches are allowed at this point. 3836 if (mResumedActivity != null 3837 && mResumedActivity.info.applicationInfo.uid == 3838 Binder.getCallingUid()) { 3839 mAppSwitchesAllowedTime = 0; 3840 } 3841 } 3842 3843 return pir.sendInner(0, fillInIntent, resolvedType, 3844 null, resultTo, resultWho, requestCode, flagsMask, flagsValues); 3845 } 3846 3847 public boolean startNextMatchingActivity(IBinder callingActivity, 3848 Intent intent) { 3849 // Refuse possible leaked file descriptors 3850 if (intent != null && intent.hasFileDescriptors() == true) { 3851 throw new IllegalArgumentException("File descriptors passed in Intent"); 3852 } 3853 3854 synchronized (this) { 3855 int index = indexOfTokenLocked(callingActivity); 3856 if (index < 0) { 3857 return false; 3858 } 3859 HistoryRecord r = (HistoryRecord)mHistory.get(index); 3860 if (r.app == null || r.app.thread == null) { 3861 // The caller is not running... d'oh! 3862 return false; 3863 } 3864 intent = new Intent(intent); 3865 // The caller is not allowed to change the data. 3866 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3867 // And we are resetting to find the next component... 3868 intent.setComponent(null); 3869 3870 ActivityInfo aInfo = null; 3871 try { 3872 List<ResolveInfo> resolves = 3873 ActivityThread.getPackageManager().queryIntentActivities( 3874 intent, r.resolvedType, 3875 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS); 3876 3877 // Look for the original activity in the list... 3878 final int N = resolves != null ? resolves.size() : 0; 3879 for (int i=0; i<N; i++) { 3880 ResolveInfo rInfo = resolves.get(i); 3881 if (rInfo.activityInfo.packageName.equals(r.packageName) 3882 && rInfo.activityInfo.name.equals(r.info.name)) { 3883 // We found the current one... the next matching is 3884 // after it. 3885 i++; 3886 if (i<N) { 3887 aInfo = resolves.get(i).activityInfo; 3888 } 3889 break; 3890 } 3891 } 3892 } catch (RemoteException e) { 3893 } 3894 3895 if (aInfo == null) { 3896 // Nobody who is next! 3897 return false; 3898 } 3899 3900 intent.setComponent(new ComponentName( 3901 aInfo.applicationInfo.packageName, aInfo.name)); 3902 intent.setFlags(intent.getFlags()&~( 3903 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3904 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3905 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3906 Intent.FLAG_ACTIVITY_NEW_TASK)); 3907 3908 // Okay now we need to start the new activity, replacing the 3909 // currently running activity. This is a little tricky because 3910 // we want to start the new one as if the current one is finished, 3911 // but not finish the current one first so that there is no flicker. 3912 // And thus... 3913 final boolean wasFinishing = r.finishing; 3914 r.finishing = true; 3915 3916 // Propagate reply information over to the new activity. 3917 final HistoryRecord resultTo = r.resultTo; 3918 final String resultWho = r.resultWho; 3919 final int requestCode = r.requestCode; 3920 r.resultTo = null; 3921 if (resultTo != null) { 3922 resultTo.removeResultsLocked(r, resultWho, requestCode); 3923 } 3924 3925 final long origId = Binder.clearCallingIdentity(); 3926 // XXX we are not dealing with propagating grantedUriPermissions... 3927 // those are not yet exposed to user code, so there is no need. 3928 int res = startActivityLocked(r.app.thread, intent, 3929 r.resolvedType, null, 0, aInfo, resultTo, resultWho, 3930 requestCode, -1, r.launchedFromUid, false, false); 3931 Binder.restoreCallingIdentity(origId); 3932 3933 r.finishing = wasFinishing; 3934 if (res != START_SUCCESS) { 3935 return false; 3936 } 3937 return true; 3938 } 3939 } 3940 3941 public final int startActivityInPackage(int uid, 3942 Intent intent, String resolvedType, IBinder resultTo, 3943 String resultWho, int requestCode, boolean onlyIfNeeded) { 3944 3945 // This is so super not safe, that only the system (or okay root) 3946 // can do it. 3947 final int callingUid = Binder.getCallingUid(); 3948 if (callingUid != 0 && callingUid != Process.myUid()) { 3949 throw new SecurityException( 3950 "startActivityInPackage only available to the system"); 3951 } 3952 3953 final boolean componentSpecified = intent.getComponent() != null; 3954 3955 // Don't modify the client's object! 3956 intent = new Intent(intent); 3957 3958 // Collect information about the target of the Intent. 3959 ActivityInfo aInfo; 3960 try { 3961 ResolveInfo rInfo = 3962 ActivityThread.getPackageManager().resolveIntent( 3963 intent, resolvedType, 3964 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS); 3965 aInfo = rInfo != null ? rInfo.activityInfo : null; 3966 } catch (RemoteException e) { 3967 aInfo = null; 3968 } 3969 3970 if (aInfo != null) { 3971 // Store the found target back into the intent, because now that 3972 // we have it we never want to do this again. For example, if the 3973 // user navigates back to this point in the history, we should 3974 // always restart the exact same activity. 3975 intent.setComponent(new ComponentName( 3976 aInfo.applicationInfo.packageName, aInfo.name)); 3977 } 3978 3979 synchronized(this) { 3980 return startActivityLocked(null, intent, resolvedType, 3981 null, 0, aInfo, resultTo, resultWho, requestCode, -1, uid, 3982 onlyIfNeeded, componentSpecified); 3983 } 3984 } 3985 3986 private final void addRecentTaskLocked(TaskRecord task) { 3987 // Remove any existing entries that are the same kind of task. 3988 int N = mRecentTasks.size(); 3989 for (int i=0; i<N; i++) { 3990 TaskRecord tr = mRecentTasks.get(i); 3991 if ((task.affinity != null && task.affinity.equals(tr.affinity)) 3992 || (task.intent != null && task.intent.filterEquals(tr.intent))) { 3993 mRecentTasks.remove(i); 3994 i--; 3995 N--; 3996 if (task.intent == null) { 3997 // If the new recent task we are adding is not fully 3998 // specified, then replace it with the existing recent task. 3999 task = tr; 4000 } 4001 } 4002 } 4003 if (N >= MAX_RECENT_TASKS) { 4004 mRecentTasks.remove(N-1); 4005 } 4006 mRecentTasks.add(0, task); 4007 } 4008 4009 public void setRequestedOrientation(IBinder token, 4010 int requestedOrientation) { 4011 synchronized (this) { 4012 int index = indexOfTokenLocked(token); 4013 if (index < 0) { 4014 return; 4015 } 4016 HistoryRecord r = (HistoryRecord)mHistory.get(index); 4017 final long origId = Binder.clearCallingIdentity(); 4018 mWindowManager.setAppOrientation(r, requestedOrientation); 4019 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4020 mConfiguration, 4021 r.mayFreezeScreenLocked(r.app) ? r : null); 4022 if (config != null) { 4023 r.frozenBeforeDestroy = true; 4024 if (!updateConfigurationLocked(config, r)) { 4025 resumeTopActivityLocked(null); 4026 } 4027 } 4028 Binder.restoreCallingIdentity(origId); 4029 } 4030 } 4031 4032 public int getRequestedOrientation(IBinder token) { 4033 synchronized (this) { 4034 int index = indexOfTokenLocked(token); 4035 if (index < 0) { 4036 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4037 } 4038 HistoryRecord r = (HistoryRecord)mHistory.get(index); 4039 return mWindowManager.getAppOrientation(r); 4040 } 4041 } 4042 4043 private final void stopActivityLocked(HistoryRecord r) { 4044 if (DEBUG_SWITCH) Slog.d(TAG, "Stopping: " + r); 4045 if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0 4046 || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) { 4047 if (!r.finishing) { 4048 requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null, 4049 "no-history"); 4050 } 4051 } else if (r.app != null && r.app.thread != null) { 4052 if (mFocusedActivity == r) { 4053 setFocusedActivityLocked(topRunningActivityLocked(null)); 4054 } 4055 r.resumeKeyDispatchingLocked(); 4056 try { 4057 r.stopped = false; 4058 r.state = ActivityState.STOPPING; 4059 if (DEBUG_VISBILITY) Slog.v( 4060 TAG, "Stopping visible=" + r.visible + " for " + r); 4061 if (!r.visible) { 4062 mWindowManager.setAppVisibility(r, false); 4063 } 4064 r.app.thread.scheduleStopActivity(r, r.visible, r.configChangeFlags); 4065 } catch (Exception e) { 4066 // Maybe just ignore exceptions here... if the process 4067 // has crashed, our death notification will clean things 4068 // up. 4069 Slog.w(TAG, "Exception thrown during pause", e); 4070 // Just in case, assume it to be stopped. 4071 r.stopped = true; 4072 r.state = ActivityState.STOPPED; 4073 if (r.configDestroy) { 4074 destroyActivityLocked(r, true); 4075 } 4076 } 4077 } 4078 } 4079 4080 /** 4081 * @return Returns true if the activity is being finished, false if for 4082 * some reason it is being left as-is. 4083 */ 4084 private final boolean requestFinishActivityLocked(IBinder token, int resultCode, 4085 Intent resultData, String reason) { 4086 if (DEBUG_RESULTS) Slog.v( 4087 TAG, "Finishing activity: token=" + token 4088 + ", result=" + resultCode + ", data=" + resultData); 4089 4090 int index = indexOfTokenLocked(token); 4091 if (index < 0) { 4092 return false; 4093 } 4094 HistoryRecord r = (HistoryRecord)mHistory.get(index); 4095 4096 // Is this the last activity left? 4097 boolean lastActivity = true; 4098 for (int i=mHistory.size()-1; i>=0; i--) { 4099 HistoryRecord p = (HistoryRecord)mHistory.get(i); 4100 if (!p.finishing && p != r) { 4101 lastActivity = false; 4102 break; 4103 } 4104 } 4105 4106 // If this is the last activity, but it is the home activity, then 4107 // just don't finish it. 4108 if (lastActivity) { 4109 if (r.intent.hasCategory(Intent.CATEGORY_HOME)) { 4110 return false; 4111 } 4112 } 4113 4114 finishActivityLocked(r, index, resultCode, resultData, reason); 4115 return true; 4116 } 4117 4118 /** 4119 * @return Returns true if this activity has been removed from the history 4120 * list, or false if it is still in the list and will be removed later. 4121 */ 4122 private final boolean finishActivityLocked(HistoryRecord r, int index, 4123 int resultCode, Intent resultData, String reason) { 4124 if (r.finishing) { 4125 Slog.w(TAG, "Duplicate finish request for " + r); 4126 return false; 4127 } 4128 4129 r.finishing = true; 4130 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, 4131 System.identityHashCode(r), 4132 r.task.taskId, r.shortComponentName, reason); 4133 r.task.numActivities--; 4134 if (index < (mHistory.size()-1)) { 4135 HistoryRecord next = (HistoryRecord)mHistory.get(index+1); 4136 if (next.task == r.task) { 4137 if (r.frontOfTask) { 4138 // The next activity is now the front of the task. 4139 next.frontOfTask = true; 4140 } 4141 if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) { 4142 // If the caller asked that this activity (and all above it) 4143 // be cleared when the task is reset, don't lose that information, 4144 // but propagate it up to the next activity. 4145 next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 4146 } 4147 } 4148 } 4149 4150 r.pauseKeyDispatchingLocked(); 4151 if (mFocusedActivity == r) { 4152 setFocusedActivityLocked(topRunningActivityLocked(null)); 4153 } 4154 4155 // send the result 4156 HistoryRecord resultTo = r.resultTo; 4157 if (resultTo != null) { 4158 if (DEBUG_RESULTS) Slog.v(TAG, "Adding result to " + resultTo 4159 + " who=" + r.resultWho + " req=" + r.requestCode 4160 + " res=" + resultCode + " data=" + resultData); 4161 if (r.info.applicationInfo.uid > 0) { 4162 grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid, 4163 r.packageName, resultData, r); 4164 } 4165 resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode, 4166 resultData); 4167 r.resultTo = null; 4168 } 4169 else if (DEBUG_RESULTS) Slog.v(TAG, "No result destination from " + r); 4170 4171 // Make sure this HistoryRecord is not holding on to other resources, 4172 // because clients have remote IPC references to this object so we 4173 // can't assume that will go away and want to avoid circular IPC refs. 4174 r.results = null; 4175 r.pendingResults = null; 4176 r.newIntents = null; 4177 r.icicle = null; 4178 4179 if (mPendingThumbnails.size() > 0) { 4180 // There are clients waiting to receive thumbnails so, in case 4181 // this is an activity that someone is waiting for, add it 4182 // to the pending list so we can correctly update the clients. 4183 mCancelledThumbnails.add(r); 4184 } 4185 4186 if (mResumedActivity == r) { 4187 boolean endTask = index <= 0 4188 || ((HistoryRecord)mHistory.get(index-1)).task != r.task; 4189 if (DEBUG_TRANSITION) Slog.v(TAG, 4190 "Prepare close transition: finishing " + r); 4191 mWindowManager.prepareAppTransition(endTask 4192 ? WindowManagerPolicy.TRANSIT_TASK_CLOSE 4193 : WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE); 4194 4195 // Tell window manager to prepare for this one to be removed. 4196 mWindowManager.setAppVisibility(r, false); 4197 4198 if (mPausingActivity == null) { 4199 if (DEBUG_PAUSE) Slog.v(TAG, "Finish needs to pause: " + r); 4200 if (DEBUG_USER_LEAVING) Slog.v(TAG, "finish() => pause with userLeaving=false"); 4201 startPausingLocked(false, false); 4202 } 4203 4204 } else if (r.state != ActivityState.PAUSING) { 4205 // If the activity is PAUSING, we will complete the finish once 4206 // it is done pausing; else we can just directly finish it here. 4207 if (DEBUG_PAUSE) Slog.v(TAG, "Finish not pausing: " + r); 4208 return finishCurrentActivityLocked(r, index, 4209 FINISH_AFTER_PAUSE) == null; 4210 } else { 4211 if (DEBUG_PAUSE) Slog.v(TAG, "Finish waiting for pause of: " + r); 4212 } 4213 4214 return false; 4215 } 4216 4217 private static final int FINISH_IMMEDIATELY = 0; 4218 private static final int FINISH_AFTER_PAUSE = 1; 4219 private static final int FINISH_AFTER_VISIBLE = 2; 4220 4221 private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r, 4222 int mode) { 4223 final int index = indexOfTokenLocked(r); 4224 if (index < 0) { 4225 return null; 4226 } 4227 4228 return finishCurrentActivityLocked(r, index, mode); 4229 } 4230 4231 private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r, 4232 int index, int mode) { 4233 // First things first: if this activity is currently visible, 4234 // and the resumed activity is not yet visible, then hold off on 4235 // finishing until the resumed one becomes visible. 4236 if (mode == FINISH_AFTER_VISIBLE && r.nowVisible) { 4237 if (!mStoppingActivities.contains(r)) { 4238 mStoppingActivities.add(r); 4239 if (mStoppingActivities.size() > 3) { 4240 // If we already have a few activities waiting to stop, 4241 // then give up on things going idle and start clearing 4242 // them out. 4243 Message msg = Message.obtain(); 4244 msg.what = ActivityManagerService.IDLE_NOW_MSG; 4245 mHandler.sendMessage(msg); 4246 } 4247 } 4248 r.state = ActivityState.STOPPING; 4249 updateOomAdjLocked(); 4250 return r; 4251 } 4252 4253 // make sure the record is cleaned out of other places. 4254 mStoppingActivities.remove(r); 4255 mWaitingVisibleActivities.remove(r); 4256 if (mResumedActivity == r) { 4257 mResumedActivity = null; 4258 } 4259 final ActivityState prevState = r.state; 4260 r.state = ActivityState.FINISHING; 4261 4262 if (mode == FINISH_IMMEDIATELY 4263 || prevState == ActivityState.STOPPED 4264 || prevState == ActivityState.INITIALIZING) { 4265 // If this activity is already stopped, we can just finish 4266 // it right now. 4267 return destroyActivityLocked(r, true) ? null : r; 4268 } else { 4269 // Need to go through the full pause cycle to get this 4270 // activity into the stopped state and then finish it. 4271 if (localLOGV) Slog.v(TAG, "Enqueueing pending finish: " + r); 4272 mFinishingActivities.add(r); 4273 resumeTopActivityLocked(null); 4274 } 4275 return r; 4276 } 4277 4278 /** 4279 * This is the internal entry point for handling Activity.finish(). 4280 * 4281 * @param token The Binder token referencing the Activity we want to finish. 4282 * @param resultCode Result code, if any, from this Activity. 4283 * @param resultData Result data (Intent), if any, from this Activity. 4284 * 4285 * @return Returns true if the activity successfully finished, or false if it is still running. 4286 */ 4287 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 4288 // Refuse possible leaked file descriptors 4289 if (resultData != null && resultData.hasFileDescriptors() == true) { 4290 throw new IllegalArgumentException("File descriptors passed in Intent"); 4291 } 4292 4293 synchronized(this) { 4294 if (mController != null) { 4295 // Find the first activity that is not finishing. 4296 HistoryRecord next = topRunningActivityLocked(token, 0); 4297 if (next != null) { 4298 // ask watcher if this is allowed 4299 boolean resumeOK = true; 4300 try { 4301 resumeOK = mController.activityResuming(next.packageName); 4302 } catch (RemoteException e) { 4303 mController = null; 4304 } 4305 4306 if (!resumeOK) { 4307 return false; 4308 } 4309 } 4310 } 4311 final long origId = Binder.clearCallingIdentity(); 4312 boolean res = requestFinishActivityLocked(token, resultCode, 4313 resultData, "app-request"); 4314 Binder.restoreCallingIdentity(origId); 4315 return res; 4316 } 4317 } 4318 4319 void sendActivityResultLocked(int callingUid, HistoryRecord r, 4320 String resultWho, int requestCode, int resultCode, Intent data) { 4321 4322 if (callingUid > 0) { 4323 grantUriPermissionFromIntentLocked(callingUid, r.packageName, 4324 data, r); 4325 } 4326 4327 if (DEBUG_RESULTS) Slog.v(TAG, "Send activity result to " + r 4328 + " : who=" + resultWho + " req=" + requestCode 4329 + " res=" + resultCode + " data=" + data); 4330 if (mResumedActivity == r && r.app != null && r.app.thread != null) { 4331 try { 4332 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>(); 4333 list.add(new ResultInfo(resultWho, requestCode, 4334 resultCode, data)); 4335 r.app.thread.scheduleSendResult(r, list); 4336 return; 4337 } catch (Exception e) { 4338 Slog.w(TAG, "Exception thrown sending result to " + r, e); 4339 } 4340 } 4341 4342 r.addResultLocked(null, resultWho, requestCode, resultCode, data); 4343 } 4344 4345 public final void finishSubActivity(IBinder token, String resultWho, 4346 int requestCode) { 4347 synchronized(this) { 4348 int index = indexOfTokenLocked(token); 4349 if (index < 0) { 4350 return; 4351 } 4352 HistoryRecord self = (HistoryRecord)mHistory.get(index); 4353 4354 final long origId = Binder.clearCallingIdentity(); 4355 4356 int i; 4357 for (i=mHistory.size()-1; i>=0; i--) { 4358 HistoryRecord r = (HistoryRecord)mHistory.get(i); 4359 if (r.resultTo == self && r.requestCode == requestCode) { 4360 if ((r.resultWho == null && resultWho == null) || 4361 (r.resultWho != null && r.resultWho.equals(resultWho))) { 4362 finishActivityLocked(r, i, 4363 Activity.RESULT_CANCELED, null, "request-sub"); 4364 } 4365 } 4366 } 4367 4368 Binder.restoreCallingIdentity(origId); 4369 } 4370 } 4371 4372 public boolean willActivityBeVisible(IBinder token) { 4373 synchronized(this) { 4374 int i; 4375 for (i=mHistory.size()-1; i>=0; i--) { 4376 HistoryRecord r = (HistoryRecord)mHistory.get(i); 4377 if (r == token) { 4378 return true; 4379 } 4380 if (r.fullscreen && !r.finishing) { 4381 return false; 4382 } 4383 } 4384 return true; 4385 } 4386 } 4387 4388 public void overridePendingTransition(IBinder token, String packageName, 4389 int enterAnim, int exitAnim) { 4390 synchronized(this) { 4391 int index = indexOfTokenLocked(token); 4392 if (index < 0) { 4393 return; 4394 } 4395 HistoryRecord self = (HistoryRecord)mHistory.get(index); 4396 4397 final long origId = Binder.clearCallingIdentity(); 4398 4399 if (self.state == ActivityState.RESUMED 4400 || self.state == ActivityState.PAUSING) { 4401 mWindowManager.overridePendingAppTransition(packageName, 4402 enterAnim, exitAnim); 4403 } 4404 4405 Binder.restoreCallingIdentity(origId); 4406 } 4407 } 4408 4409 /** 4410 * Perform clean-up of service connections in an activity record. 4411 */ 4412 private final void cleanUpActivityServicesLocked(HistoryRecord r) { 4413 // Throw away any services that have been bound by this activity. 4414 if (r.connections != null) { 4415 Iterator<ConnectionRecord> it = r.connections.iterator(); 4416 while (it.hasNext()) { 4417 ConnectionRecord c = it.next(); 4418 removeConnectionLocked(c, null, r); 4419 } 4420 r.connections = null; 4421 } 4422 } 4423 4424 /** 4425 * Perform the common clean-up of an activity record. This is called both 4426 * as part of destroyActivityLocked() (when destroying the client-side 4427 * representation) and cleaning things up as a result of its hosting 4428 * processing going away, in which case there is no remaining client-side 4429 * state to destroy so only the cleanup here is needed. 4430 */ 4431 private final void cleanUpActivityLocked(HistoryRecord r, boolean cleanServices) { 4432 if (mResumedActivity == r) { 4433 mResumedActivity = null; 4434 } 4435 if (mFocusedActivity == r) { 4436 mFocusedActivity = null; 4437 } 4438 4439 r.configDestroy = false; 4440 r.frozenBeforeDestroy = false; 4441 4442 // Make sure this record is no longer in the pending finishes list. 4443 // This could happen, for example, if we are trimming activities 4444 // down to the max limit while they are still waiting to finish. 4445 mFinishingActivities.remove(r); 4446 mWaitingVisibleActivities.remove(r); 4447 4448 // Remove any pending results. 4449 if (r.finishing && r.pendingResults != null) { 4450 for (WeakReference<PendingIntentRecord> apr : r.pendingResults) { 4451 PendingIntentRecord rec = apr.get(); 4452 if (rec != null) { 4453 cancelIntentSenderLocked(rec, false); 4454 } 4455 } 4456 r.pendingResults = null; 4457 } 4458 4459 if (cleanServices) { 4460 cleanUpActivityServicesLocked(r); 4461 } 4462 4463 if (mPendingThumbnails.size() > 0) { 4464 // There are clients waiting to receive thumbnails so, in case 4465 // this is an activity that someone is waiting for, add it 4466 // to the pending list so we can correctly update the clients. 4467 mCancelledThumbnails.add(r); 4468 } 4469 4470 // Get rid of any pending idle timeouts. 4471 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); 4472 mHandler.removeMessages(IDLE_TIMEOUT_MSG, r); 4473 } 4474 4475 private final void removeActivityFromHistoryLocked(HistoryRecord r) { 4476 if (r.state != ActivityState.DESTROYED) { 4477 mHistory.remove(r); 4478 r.inHistory = false; 4479 r.state = ActivityState.DESTROYED; 4480 mWindowManager.removeAppToken(r); 4481 if (VALIDATE_TOKENS) { 4482 mWindowManager.validateAppTokens(mHistory); 4483 } 4484 cleanUpActivityServicesLocked(r); 4485 removeActivityUriPermissionsLocked(r); 4486 } 4487 } 4488 4489 /** 4490 * Destroy the current CLIENT SIDE instance of an activity. This may be 4491 * called both when actually finishing an activity, or when performing 4492 * a configuration switch where we destroy the current client-side object 4493 * but then create a new client-side object for this same HistoryRecord. 4494 */ 4495 private final boolean destroyActivityLocked(HistoryRecord r, 4496 boolean removeFromApp) { 4497 if (DEBUG_SWITCH) Slog.v( 4498 TAG, "Removing activity: token=" + r 4499 + ", app=" + (r.app != null ? r.app.processName : "(null)")); 4500 EventLog.writeEvent(EventLogTags.AM_DESTROY_ACTIVITY, 4501 System.identityHashCode(r), 4502 r.task.taskId, r.shortComponentName); 4503 4504 boolean removedFromHistory = false; 4505 4506 cleanUpActivityLocked(r, false); 4507 4508 final boolean hadApp = r.app != null; 4509 4510 if (hadApp) { 4511 if (removeFromApp) { 4512 int idx = r.app.activities.indexOf(r); 4513 if (idx >= 0) { 4514 r.app.activities.remove(idx); 4515 } 4516 if (r.persistent) { 4517 decPersistentCountLocked(r.app); 4518 } 4519 if (r.app.activities.size() == 0) { 4520 // No longer have activities, so update location in 4521 // LRU list. 4522 updateLruProcessLocked(r.app, true, false); 4523 } 4524 } 4525 4526 boolean skipDestroy = false; 4527 4528 try { 4529 if (DEBUG_SWITCH) Slog.i(TAG, "Destroying: " + r); 4530 r.app.thread.scheduleDestroyActivity(r, r.finishing, 4531 r.configChangeFlags); 4532 } catch (Exception e) { 4533 // We can just ignore exceptions here... if the process 4534 // has crashed, our death notification will clean things 4535 // up. 4536 //Slog.w(TAG, "Exception thrown during finish", e); 4537 if (r.finishing) { 4538 removeActivityFromHistoryLocked(r); 4539 removedFromHistory = true; 4540 skipDestroy = true; 4541 } 4542 } 4543 4544 r.app = null; 4545 r.nowVisible = false; 4546 4547 if (r.finishing && !skipDestroy) { 4548 r.state = ActivityState.DESTROYING; 4549 Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG); 4550 msg.obj = r; 4551 mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT); 4552 } else { 4553 r.state = ActivityState.DESTROYED; 4554 } 4555 } else { 4556 // remove this record from the history. 4557 if (r.finishing) { 4558 removeActivityFromHistoryLocked(r); 4559 removedFromHistory = true; 4560 } else { 4561 r.state = ActivityState.DESTROYED; 4562 } 4563 } 4564 4565 r.configChangeFlags = 0; 4566 4567 if (!mLRUActivities.remove(r) && hadApp) { 4568 Slog.w(TAG, "Activity " + r + " being finished, but not in LRU list"); 4569 } 4570 4571 return removedFromHistory; 4572 } 4573 4574 private static void removeHistoryRecordsForAppLocked(ArrayList list, ProcessRecord app) { 4575 int i = list.size(); 4576 if (localLOGV) Slog.v( 4577 TAG, "Removing app " + app + " from list " + list 4578 + " with " + i + " entries"); 4579 while (i > 0) { 4580 i--; 4581 HistoryRecord r = (HistoryRecord)list.get(i); 4582 if (localLOGV) Slog.v( 4583 TAG, "Record #" + i + " " + r + ": app=" + r.app); 4584 if (r.app == app) { 4585 if (localLOGV) Slog.v(TAG, "Removing this entry!"); 4586 list.remove(i); 4587 } 4588 } 4589 } 4590 4591 /** 4592 * Main function for removing an existing process from the activity manager 4593 * as a result of that process going away. Clears out all connections 4594 * to the process. 4595 */ 4596 private final void handleAppDiedLocked(ProcessRecord app, 4597 boolean restarting) { 4598 cleanUpApplicationRecordLocked(app, restarting, -1); 4599 if (!restarting) { 4600 mLruProcesses.remove(app); 4601 } 4602 4603 // Just in case... 4604 if (mPausingActivity != null && mPausingActivity.app == app) { 4605 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " + mPausingActivity); 4606 mPausingActivity = null; 4607 } 4608 if (mLastPausedActivity != null && mLastPausedActivity.app == app) { 4609 mLastPausedActivity = null; 4610 } 4611 4612 // Remove this application's activities from active lists. 4613 removeHistoryRecordsForAppLocked(mLRUActivities, app); 4614 removeHistoryRecordsForAppLocked(mStoppingActivities, app); 4615 removeHistoryRecordsForAppLocked(mWaitingVisibleActivities, app); 4616 removeHistoryRecordsForAppLocked(mFinishingActivities, app); 4617 4618 boolean atTop = true; 4619 boolean hasVisibleActivities = false; 4620 4621 // Clean out the history list. 4622 int i = mHistory.size(); 4623 if (localLOGV) Slog.v( 4624 TAG, "Removing app " + app + " from history with " + i + " entries"); 4625 while (i > 0) { 4626 i--; 4627 HistoryRecord r = (HistoryRecord)mHistory.get(i); 4628 if (localLOGV) Slog.v( 4629 TAG, "Record #" + i + " " + r + ": app=" + r.app); 4630 if (r.app == app) { 4631 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { 4632 if (localLOGV) Slog.v( 4633 TAG, "Removing this entry! frozen=" + r.haveState 4634 + " finishing=" + r.finishing); 4635 mHistory.remove(i); 4636 4637 r.inHistory = false; 4638 mWindowManager.removeAppToken(r); 4639 if (VALIDATE_TOKENS) { 4640 mWindowManager.validateAppTokens(mHistory); 4641 } 4642 removeActivityUriPermissionsLocked(r); 4643 4644 } else { 4645 // We have the current state for this activity, so 4646 // it can be restarted later when needed. 4647 if (localLOGV) Slog.v( 4648 TAG, "Keeping entry, setting app to null"); 4649 if (r.visible) { 4650 hasVisibleActivities = true; 4651 } 4652 r.app = null; 4653 r.nowVisible = false; 4654 if (!r.haveState) { 4655 r.icicle = null; 4656 } 4657 } 4658 4659 cleanUpActivityLocked(r, true); 4660 r.state = ActivityState.STOPPED; 4661 } 4662 atTop = false; 4663 } 4664 4665 app.activities.clear(); 4666 4667 if (app.instrumentationClass != null) { 4668 Slog.w(TAG, "Crash of app " + app.processName 4669 + " running instrumentation " + app.instrumentationClass); 4670 Bundle info = new Bundle(); 4671 info.putString("shortMsg", "Process crashed."); 4672 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4673 } 4674 4675 if (!restarting) { 4676 if (!resumeTopActivityLocked(null)) { 4677 // If there was nothing to resume, and we are not already 4678 // restarting this process, but there is a visible activity that 4679 // is hosted by the process... then make sure all visible 4680 // activities are running, taking care of restarting this 4681 // process. 4682 if (hasVisibleActivities) { 4683 ensureActivitiesVisibleLocked(null, 0); 4684 } 4685 } 4686 } 4687 } 4688 4689 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4690 IBinder threadBinder = thread.asBinder(); 4691 4692 // Find the application record. 4693 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4694 ProcessRecord rec = mLruProcesses.get(i); 4695 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4696 return i; 4697 } 4698 } 4699 return -1; 4700 } 4701 4702 private final ProcessRecord getRecordForAppLocked( 4703 IApplicationThread thread) { 4704 if (thread == null) { 4705 return null; 4706 } 4707 4708 int appIndex = getLRURecordIndexForAppLocked(thread); 4709 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4710 } 4711 4712 private final void appDiedLocked(ProcessRecord app, int pid, 4713 IApplicationThread thread) { 4714 4715 mProcDeaths[0]++; 4716 4717 // Clean up already done if the process has been re-started. 4718 if (app.pid == pid && app.thread != null && 4719 app.thread.asBinder() == thread.asBinder()) { 4720 if (!app.killedBackground) { 4721 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4722 + ") has died."); 4723 } 4724 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 4725 if (localLOGV) Slog.v( 4726 TAG, "Dying app: " + app + ", pid: " + pid 4727 + ", thread: " + thread.asBinder()); 4728 boolean doLowMem = app.instrumentationClass == null; 4729 handleAppDiedLocked(app, false); 4730 4731 if (doLowMem) { 4732 // If there are no longer any background processes running, 4733 // and the app that died was not running instrumentation, 4734 // then tell everyone we are now low on memory. 4735 boolean haveBg = false; 4736 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4737 ProcessRecord rec = mLruProcesses.get(i); 4738 if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) { 4739 haveBg = true; 4740 break; 4741 } 4742 } 4743 4744 if (!haveBg) { 4745 Slog.i(TAG, "Low Memory: No more background processes."); 4746 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4747 long now = SystemClock.uptimeMillis(); 4748 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4749 ProcessRecord rec = mLruProcesses.get(i); 4750 if (rec != app && rec.thread != null && 4751 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4752 // The low memory report is overriding any current 4753 // state for a GC request. Make sure to do 4754 // visible/foreground processes first. 4755 if (rec.setAdj <= VISIBLE_APP_ADJ) { 4756 rec.lastRequestedGc = 0; 4757 } else { 4758 rec.lastRequestedGc = rec.lastLowMemory; 4759 } 4760 rec.reportLowMemory = true; 4761 rec.lastLowMemory = now; 4762 mProcessesToGc.remove(rec); 4763 addProcessToGcListLocked(rec); 4764 } 4765 } 4766 scheduleAppGcsLocked(); 4767 } 4768 } 4769 } else if (app.pid != pid) { 4770 // A new process has already been started. 4771 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4772 + ") has died and restarted (pid " + app.pid + ")."); 4773 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName); 4774 } else if (DEBUG_PROCESSES) { 4775 Slog.d(TAG, "Received spurious death notification for thread " 4776 + thread.asBinder()); 4777 } 4778 } 4779 4780 /** 4781 * If a stack trace dump file is configured, dump process stack traces. 4782 * @param clearTraces causes the dump file to be erased prior to the new 4783 * traces being written, if true; when false, the new traces will be 4784 * appended to any existing file content. 4785 * @param pids of dalvik VM processes to dump stack traces for 4786 * @return file containing stack traces, or null if no dump file is configured 4787 */ 4788 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> pids) { 4789 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4790 if (tracesPath == null || tracesPath.length() == 0) { 4791 return null; 4792 } 4793 4794 File tracesFile = new File(tracesPath); 4795 try { 4796 File tracesDir = tracesFile.getParentFile(); 4797 if (!tracesDir.exists()) tracesFile.mkdirs(); 4798 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4799 4800 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4801 tracesFile.createNewFile(); 4802 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4803 } catch (IOException e) { 4804 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4805 return null; 4806 } 4807 4808 // Use a FileObserver to detect when traces finish writing. 4809 // The order of traces is considered important to maintain for legibility. 4810 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4811 public synchronized void onEvent(int event, String path) { notify(); } 4812 }; 4813 4814 try { 4815 observer.startWatching(); 4816 int num = pids.size(); 4817 for (int i = 0; i < num; i++) { 4818 synchronized (observer) { 4819 Process.sendSignal(pids.get(i), Process.SIGNAL_QUIT); 4820 observer.wait(200); // Wait for write-close, give up after 200msec 4821 } 4822 } 4823 } catch (InterruptedException e) { 4824 Log.wtf(TAG, e); 4825 } finally { 4826 observer.stopWatching(); 4827 } 4828 4829 return tracesFile; 4830 } 4831 4832 final void appNotResponding(ProcessRecord app, HistoryRecord activity, 4833 HistoryRecord parent, final String annotation) { 4834 ArrayList<Integer> pids = new ArrayList<Integer>(20); 4835 4836 synchronized (this) { 4837 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4838 if (mShuttingDown) { 4839 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4840 return; 4841 } else if (app.notResponding) { 4842 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4843 return; 4844 } else if (app.crashing) { 4845 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4846 return; 4847 } 4848 4849 // In case we come through here for the same app before completing 4850 // this one, mark as anring now so we will bail out. 4851 app.notResponding = true; 4852 4853 // Log the ANR to the event log. 4854 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags, 4855 annotation); 4856 4857 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4858 pids.add(app.pid); 4859 4860 int parentPid = app.pid; 4861 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4862 if (parentPid != app.pid) pids.add(parentPid); 4863 4864 if (MY_PID != app.pid && MY_PID != parentPid) pids.add(MY_PID); 4865 4866 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4867 ProcessRecord r = mLruProcesses.get(i); 4868 if (r != null && r.thread != null) { 4869 int pid = r.pid; 4870 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) pids.add(pid); 4871 } 4872 } 4873 } 4874 4875 File tracesFile = dumpStackTraces(true, pids); 4876 4877 // Log the ANR to the main log. 4878 StringBuilder info = mStringBuilder; 4879 info.setLength(0); 4880 info.append("ANR in ").append(app.processName); 4881 if (activity != null && activity.shortComponentName != null) { 4882 info.append(" (").append(activity.shortComponentName).append(")"); 4883 } 4884 info.append("\n"); 4885 if (annotation != null) { 4886 info.append("Reason: ").append(annotation).append("\n"); 4887 } 4888 if (parent != null && parent != activity) { 4889 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4890 } 4891 4892 String cpuInfo = null; 4893 if (MONITOR_CPU_USAGE) { 4894 updateCpuStatsNow(); 4895 synchronized (mProcessStatsThread) { 4896 cpuInfo = mProcessStats.printCurrentState(); 4897 } 4898 info.append(cpuInfo); 4899 } 4900 4901 Slog.e(TAG, info.toString()); 4902 if (tracesFile == null) { 4903 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4904 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4905 } 4906 4907 addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null); 4908 4909 if (mController != null) { 4910 try { 4911 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4912 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4913 if (res != 0) { 4914 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4915 return; 4916 } 4917 } catch (RemoteException e) { 4918 mController = null; 4919 } 4920 } 4921 4922 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4923 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4924 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4925 4926 synchronized (this) { 4927 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4928 Process.killProcess(app.pid); 4929 return; 4930 } 4931 4932 // Set the app's notResponding state, and look up the errorReportReceiver 4933 makeAppNotRespondingLocked(app, 4934 activity != null ? activity.shortComponentName : null, 4935 annotation != null ? "ANR " + annotation : "ANR", 4936 info.toString()); 4937 4938 // Bring up the infamous App Not Responding dialog 4939 Message msg = Message.obtain(); 4940 HashMap map = new HashMap(); 4941 msg.what = SHOW_NOT_RESPONDING_MSG; 4942 msg.obj = map; 4943 map.put("app", app); 4944 if (activity != null) { 4945 map.put("activity", activity); 4946 } 4947 4948 mHandler.sendMessage(msg); 4949 } 4950 } 4951 4952 private final void decPersistentCountLocked(ProcessRecord app) 4953 { 4954 app.persistentActivities--; 4955 if (app.persistentActivities > 0) { 4956 // Still more of 'em... 4957 return; 4958 } 4959 if (app.persistent) { 4960 // Ah, but the application itself is persistent. Whatever! 4961 return; 4962 } 4963 4964 // App is no longer persistent... make sure it and the ones 4965 // following it in the LRU list have the correc oom_adj. 4966 updateOomAdjLocked(); 4967 } 4968 4969 public void setPersistent(IBinder token, boolean isPersistent) { 4970 if (checkCallingPermission(android.Manifest.permission.PERSISTENT_ACTIVITY) 4971 != PackageManager.PERMISSION_GRANTED) { 4972 String msg = "Permission Denial: setPersistent() from pid=" 4973 + Binder.getCallingPid() 4974 + ", uid=" + Binder.getCallingUid() 4975 + " requires " + android.Manifest.permission.PERSISTENT_ACTIVITY; 4976 Slog.w(TAG, msg); 4977 throw new SecurityException(msg); 4978 } 4979 4980 synchronized(this) { 4981 int index = indexOfTokenLocked(token); 4982 if (index < 0) { 4983 return; 4984 } 4985 HistoryRecord r = (HistoryRecord)mHistory.get(index); 4986 ProcessRecord app = r.app; 4987 4988 if (localLOGV) Slog.v( 4989 TAG, "Setting persistence " + isPersistent + ": " + r); 4990 4991 if (isPersistent) { 4992 if (r.persistent) { 4993 // Okay okay, I heard you already! 4994 if (localLOGV) Slog.v(TAG, "Already persistent!"); 4995 return; 4996 } 4997 r.persistent = true; 4998 app.persistentActivities++; 4999 if (localLOGV) Slog.v(TAG, "Num persistent now: " + app.persistentActivities); 5000 if (app.persistentActivities > 1) { 5001 // We aren't the first... 5002 if (localLOGV) Slog.v(TAG, "Not the first!"); 5003 return; 5004 } 5005 if (app.persistent) { 5006 // This would be redundant. 5007 if (localLOGV) Slog.v(TAG, "App is persistent!"); 5008 return; 5009 } 5010 5011 // App is now persistent... make sure it and the ones 5012 // following it now have the correct oom_adj. 5013 final long origId = Binder.clearCallingIdentity(); 5014 updateOomAdjLocked(); 5015 Binder.restoreCallingIdentity(origId); 5016 5017 } else { 5018 if (!r.persistent) { 5019 // Okay okay, I heard you already! 5020 return; 5021 } 5022 r.persistent = false; 5023 final long origId = Binder.clearCallingIdentity(); 5024 decPersistentCountLocked(app); 5025 Binder.restoreCallingIdentity(origId); 5026 5027 } 5028 } 5029 } 5030 5031 public boolean clearApplicationUserData(final String packageName, 5032 final IPackageDataObserver observer) { 5033 int uid = Binder.getCallingUid(); 5034 int pid = Binder.getCallingPid(); 5035 long callingId = Binder.clearCallingIdentity(); 5036 try { 5037 IPackageManager pm = ActivityThread.getPackageManager(); 5038 int pkgUid = -1; 5039 synchronized(this) { 5040 try { 5041 pkgUid = pm.getPackageUid(packageName); 5042 } catch (RemoteException e) { 5043 } 5044 if (pkgUid == -1) { 5045 Slog.w(TAG, "Invalid packageName:" + packageName); 5046 return false; 5047 } 5048 if (uid == pkgUid || checkComponentPermission( 5049 android.Manifest.permission.CLEAR_APP_USER_DATA, 5050 pid, uid, -1) 5051 == PackageManager.PERMISSION_GRANTED) { 5052 forceStopPackageLocked(packageName, pkgUid); 5053 } else { 5054 throw new SecurityException(pid+" does not have permission:"+ 5055 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" + 5056 "for process:"+packageName); 5057 } 5058 } 5059 5060 try { 5061 //clear application user data 5062 pm.clearApplicationUserData(packageName, observer); 5063 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5064 Uri.fromParts("package", packageName, null)); 5065 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5066 synchronized (this) { 5067 broadcastIntentLocked(null, null, intent, 5068 null, null, 0, null, null, null, 5069 false, false, MY_PID, Process.SYSTEM_UID); 5070 } 5071 } catch (RemoteException e) { 5072 } 5073 } finally { 5074 Binder.restoreCallingIdentity(callingId); 5075 } 5076 return true; 5077 } 5078 5079 public void killBackgroundProcesses(final String packageName) { 5080 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5081 != PackageManager.PERMISSION_GRANTED && 5082 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5083 != PackageManager.PERMISSION_GRANTED) { 5084 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5085 + Binder.getCallingPid() 5086 + ", uid=" + Binder.getCallingUid() 5087 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5088 Slog.w(TAG, msg); 5089 throw new SecurityException(msg); 5090 } 5091 5092 long callingId = Binder.clearCallingIdentity(); 5093 try { 5094 IPackageManager pm = ActivityThread.getPackageManager(); 5095 int pkgUid = -1; 5096 synchronized(this) { 5097 try { 5098 pkgUid = pm.getPackageUid(packageName); 5099 } catch (RemoteException e) { 5100 } 5101 if (pkgUid == -1) { 5102 Slog.w(TAG, "Invalid packageName: " + packageName); 5103 return; 5104 } 5105 killPackageProcessesLocked(packageName, pkgUid, 5106 SECONDARY_SERVER_ADJ, false, true); 5107 } 5108 } finally { 5109 Binder.restoreCallingIdentity(callingId); 5110 } 5111 } 5112 5113 public void forceStopPackage(final String packageName) { 5114 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5115 != PackageManager.PERMISSION_GRANTED) { 5116 String msg = "Permission Denial: forceStopPackage() from pid=" 5117 + Binder.getCallingPid() 5118 + ", uid=" + Binder.getCallingUid() 5119 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5120 Slog.w(TAG, msg); 5121 throw new SecurityException(msg); 5122 } 5123 5124 long callingId = Binder.clearCallingIdentity(); 5125 try { 5126 IPackageManager pm = ActivityThread.getPackageManager(); 5127 int pkgUid = -1; 5128 synchronized(this) { 5129 try { 5130 pkgUid = pm.getPackageUid(packageName); 5131 } catch (RemoteException e) { 5132 } 5133 if (pkgUid == -1) { 5134 Slog.w(TAG, "Invalid packageName: " + packageName); 5135 return; 5136 } 5137 forceStopPackageLocked(packageName, pkgUid); 5138 } 5139 } finally { 5140 Binder.restoreCallingIdentity(callingId); 5141 } 5142 } 5143 5144 /* 5145 * The pkg name and uid have to be specified. 5146 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int) 5147 */ 5148 public void killApplicationWithUid(String pkg, int uid) { 5149 if (pkg == null) { 5150 return; 5151 } 5152 // Make sure the uid is valid. 5153 if (uid < 0) { 5154 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg); 5155 return; 5156 } 5157 int callerUid = Binder.getCallingUid(); 5158 // Only the system server can kill an application 5159 if (callerUid == Process.SYSTEM_UID) { 5160 // Post an aysnc message to kill the application 5161 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5162 msg.arg1 = uid; 5163 msg.arg2 = 0; 5164 msg.obj = pkg; 5165 mHandler.sendMessage(msg); 5166 } else { 5167 throw new SecurityException(callerUid + " cannot kill pkg: " + 5168 pkg); 5169 } 5170 } 5171 5172 public void closeSystemDialogs(String reason) { 5173 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5174 if (reason != null) { 5175 intent.putExtra("reason", reason); 5176 } 5177 5178 final int uid = Binder.getCallingUid(); 5179 final long origId = Binder.clearCallingIdentity(); 5180 synchronized (this) { 5181 int i = mWatchers.beginBroadcast(); 5182 while (i > 0) { 5183 i--; 5184 IActivityWatcher w = mWatchers.getBroadcastItem(i); 5185 if (w != null) { 5186 try { 5187 w.closingSystemDialogs(reason); 5188 } catch (RemoteException e) { 5189 } 5190 } 5191 } 5192 mWatchers.finishBroadcast(); 5193 5194 mWindowManager.closeSystemDialogs(reason); 5195 5196 for (i=mHistory.size()-1; i>=0; i--) { 5197 HistoryRecord r = (HistoryRecord)mHistory.get(i); 5198 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { 5199 finishActivityLocked(r, i, 5200 Activity.RESULT_CANCELED, null, "close-sys"); 5201 } 5202 } 5203 5204 broadcastIntentLocked(null, null, intent, null, 5205 null, 0, null, null, null, false, false, -1, uid); 5206 } 5207 Binder.restoreCallingIdentity(origId); 5208 } 5209 5210 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) 5211 throws RemoteException { 5212 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5213 for (int i=pids.length-1; i>=0; i--) { 5214 infos[i] = new Debug.MemoryInfo(); 5215 Debug.getMemoryInfo(pids[i], infos[i]); 5216 } 5217 return infos; 5218 } 5219 5220 public void killApplicationProcess(String processName, int uid) { 5221 if (processName == null) { 5222 return; 5223 } 5224 5225 int callerUid = Binder.getCallingUid(); 5226 // Only the system server can kill an application 5227 if (callerUid == Process.SYSTEM_UID) { 5228 synchronized (this) { 5229 ProcessRecord app = getProcessRecordLocked(processName, uid); 5230 if (app != null) { 5231 try { 5232 app.thread.scheduleSuicide(); 5233 } catch (RemoteException e) { 5234 // If the other end already died, then our work here is done. 5235 } 5236 } else { 5237 Slog.w(TAG, "Process/uid not found attempting kill of " 5238 + processName + " / " + uid); 5239 } 5240 } 5241 } else { 5242 throw new SecurityException(callerUid + " cannot kill app process: " + 5243 processName); 5244 } 5245 } 5246 5247 private void forceStopPackageLocked(final String packageName, int uid) { 5248 forceStopPackageLocked(packageName, uid, false, false, true); 5249 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5250 Uri.fromParts("package", packageName, null)); 5251 intent.putExtra(Intent.EXTRA_UID, uid); 5252 broadcastIntentLocked(null, null, intent, 5253 null, null, 0, null, null, null, 5254 false, false, MY_PID, Process.SYSTEM_UID); 5255 } 5256 5257 private final boolean killPackageProcessesLocked(String packageName, int uid, 5258 int minOomAdj, boolean callerWillRestart, boolean doit) { 5259 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5260 5261 // Remove all processes this package may have touched: all with the 5262 // same UID (except for the system or root user), and all whose name 5263 // matches the package name. 5264 final String procNamePrefix = packageName + ":"; 5265 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 5266 final int NA = apps.size(); 5267 for (int ia=0; ia<NA; ia++) { 5268 ProcessRecord app = apps.valueAt(ia); 5269 if (app.removed) { 5270 if (doit) { 5271 procs.add(app); 5272 } 5273 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid) 5274 || app.processName.equals(packageName) 5275 || app.processName.startsWith(procNamePrefix)) { 5276 if (app.setAdj >= minOomAdj) { 5277 if (!doit) { 5278 return true; 5279 } 5280 app.removed = true; 5281 procs.add(app); 5282 } 5283 } 5284 } 5285 } 5286 5287 int N = procs.size(); 5288 for (int i=0; i<N; i++) { 5289 removeProcessLocked(procs.get(i), callerWillRestart); 5290 } 5291 return N > 0; 5292 } 5293 5294 private final boolean forceStopPackageLocked(String name, int uid, 5295 boolean callerWillRestart, boolean purgeCache, boolean doit) { 5296 int i, N; 5297 5298 if (uid < 0) { 5299 try { 5300 uid = ActivityThread.getPackageManager().getPackageUid(name); 5301 } catch (RemoteException e) { 5302 } 5303 } 5304 5305 if (doit) { 5306 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid); 5307 5308 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator(); 5309 while (badApps.hasNext()) { 5310 SparseArray<Long> ba = badApps.next(); 5311 if (ba.get(uid) != null) { 5312 badApps.remove(); 5313 } 5314 } 5315 } 5316 5317 boolean didSomething = killPackageProcessesLocked(name, uid, -100, 5318 callerWillRestart, doit); 5319 5320 for (i=mHistory.size()-1; i>=0; i--) { 5321 HistoryRecord r = (HistoryRecord)mHistory.get(i); 5322 if (r.packageName.equals(name)) { 5323 if (!doit) { 5324 return true; 5325 } 5326 didSomething = true; 5327 Slog.i(TAG, " Force finishing activity " + r); 5328 if (r.app != null) { 5329 r.app.removed = true; 5330 } 5331 r.app = null; 5332 finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall"); 5333 } 5334 } 5335 5336 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); 5337 for (ServiceRecord service : mServices.values()) { 5338 if (service.packageName.equals(name)) { 5339 if (!doit) { 5340 return true; 5341 } 5342 didSomething = true; 5343 Slog.i(TAG, " Force stopping service " + service); 5344 if (service.app != null) { 5345 service.app.removed = true; 5346 } 5347 service.app = null; 5348 services.add(service); 5349 } 5350 } 5351 5352 N = services.size(); 5353 for (i=0; i<N; i++) { 5354 bringDownServiceLocked(services.get(i), true); 5355 } 5356 5357 if (doit) { 5358 if (purgeCache) { 5359 AttributeCache ac = AttributeCache.instance(); 5360 if (ac != null) { 5361 ac.removePackage(name); 5362 } 5363 } 5364 resumeTopActivityLocked(null); 5365 } 5366 5367 return didSomething; 5368 } 5369 5370 private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) { 5371 final String name = app.processName; 5372 final int uid = app.info.uid; 5373 if (DEBUG_PROCESSES) Slog.d( 5374 TAG, "Force removing process " + app + " (" + name 5375 + "/" + uid + ")"); 5376 5377 mProcessNames.remove(name, uid); 5378 boolean needRestart = false; 5379 if (app.pid > 0 && app.pid != MY_PID) { 5380 int pid = app.pid; 5381 synchronized (mPidsSelfLocked) { 5382 mPidsSelfLocked.remove(pid); 5383 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5384 } 5385 handleAppDiedLocked(app, true); 5386 mLruProcesses.remove(app); 5387 Process.killProcess(pid); 5388 5389 if (app.persistent) { 5390 if (!callerWillRestart) { 5391 addAppLocked(app.info); 5392 } else { 5393 needRestart = true; 5394 } 5395 } 5396 } else { 5397 mRemovedProcesses.add(app); 5398 } 5399 5400 return needRestart; 5401 } 5402 5403 private final void processStartTimedOutLocked(ProcessRecord app) { 5404 final int pid = app.pid; 5405 boolean gone = false; 5406 synchronized (mPidsSelfLocked) { 5407 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5408 if (knownApp != null && knownApp.thread == null) { 5409 mPidsSelfLocked.remove(pid); 5410 gone = true; 5411 } 5412 } 5413 5414 if (gone) { 5415 Slog.w(TAG, "Process " + app + " failed to attach"); 5416 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid, 5417 app.processName); 5418 mProcessNames.remove(app.processName, app.info.uid); 5419 // Take care of any launching providers waiting for this process. 5420 checkAppInLaunchingProvidersLocked(app, true); 5421 // Take care of any services that are waiting for the process. 5422 for (int i=0; i<mPendingServices.size(); i++) { 5423 ServiceRecord sr = mPendingServices.get(i); 5424 if (app.info.uid == sr.appInfo.uid 5425 && app.processName.equals(sr.processName)) { 5426 Slog.w(TAG, "Forcing bringing down service: " + sr); 5427 mPendingServices.remove(i); 5428 i--; 5429 bringDownServiceLocked(sr, true); 5430 } 5431 } 5432 Process.killProcess(pid); 5433 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5434 Slog.w(TAG, "Unattached app died before backup, skipping"); 5435 try { 5436 IBackupManager bm = IBackupManager.Stub.asInterface( 5437 ServiceManager.getService(Context.BACKUP_SERVICE)); 5438 bm.agentDisconnected(app.info.packageName); 5439 } catch (RemoteException e) { 5440 // Can't happen; the backup manager is local 5441 } 5442 } 5443 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) { 5444 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5445 mPendingBroadcast = null; 5446 scheduleBroadcastsLocked(); 5447 } 5448 } else { 5449 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5450 } 5451 } 5452 5453 private final boolean attachApplicationLocked(IApplicationThread thread, 5454 int pid) { 5455 5456 // Find the application record that is being attached... either via 5457 // the pid if we are running in multiple processes, or just pull the 5458 // next app record if we are emulating process with anonymous threads. 5459 ProcessRecord app; 5460 if (pid != MY_PID && pid >= 0) { 5461 synchronized (mPidsSelfLocked) { 5462 app = mPidsSelfLocked.get(pid); 5463 } 5464 } else if (mStartingProcesses.size() > 0) { 5465 app = mStartingProcesses.remove(0); 5466 app.setPid(pid); 5467 } else { 5468 app = null; 5469 } 5470 5471 if (app == null) { 5472 Slog.w(TAG, "No pending application record for pid " + pid 5473 + " (IApplicationThread " + thread + "); dropping process"); 5474 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5475 if (pid > 0 && pid != MY_PID) { 5476 Process.killProcess(pid); 5477 } else { 5478 try { 5479 thread.scheduleExit(); 5480 } catch (Exception e) { 5481 // Ignore exceptions. 5482 } 5483 } 5484 return false; 5485 } 5486 5487 // If this application record is still attached to a previous 5488 // process, clean it up now. 5489 if (app.thread != null) { 5490 handleAppDiedLocked(app, true); 5491 } 5492 5493 // Tell the process all about itself. 5494 5495 if (localLOGV) Slog.v( 5496 TAG, "Binding process pid " + pid + " to record " + app); 5497 5498 String processName = app.processName; 5499 try { 5500 thread.asBinder().linkToDeath(new AppDeathRecipient( 5501 app, pid, thread), 0); 5502 } catch (RemoteException e) { 5503 app.resetPackageList(); 5504 startProcessLocked(app, "link fail", processName); 5505 return false; 5506 } 5507 5508 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName); 5509 5510 app.thread = thread; 5511 app.curAdj = app.setAdj = -100; 5512 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 5513 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 5514 app.forcingToForeground = null; 5515 app.foregroundServices = false; 5516 app.debugging = false; 5517 5518 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5519 5520 boolean normalMode = mSystemReady || isAllowedWhileBooting(app.info); 5521 List providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5522 5523 if (!normalMode) { 5524 Slog.i(TAG, "Launching preboot mode app: " + app); 5525 } 5526 5527 if (localLOGV) Slog.v( 5528 TAG, "New app record " + app 5529 + " thread=" + thread.asBinder() + " pid=" + pid); 5530 try { 5531 int testMode = IApplicationThread.DEBUG_OFF; 5532 if (mDebugApp != null && mDebugApp.equals(processName)) { 5533 testMode = mWaitForDebugger 5534 ? IApplicationThread.DEBUG_WAIT 5535 : IApplicationThread.DEBUG_ON; 5536 app.debugging = true; 5537 if (mDebugTransient) { 5538 mDebugApp = mOrigDebugApp; 5539 mWaitForDebugger = mOrigWaitForDebugger; 5540 } 5541 } 5542 5543 // If the app is being launched for restore or full backup, set it up specially 5544 boolean isRestrictedBackupMode = false; 5545 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5546 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5547 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5548 } 5549 5550 ensurePackageDexOpt(app.instrumentationInfo != null 5551 ? app.instrumentationInfo.packageName 5552 : app.info.packageName); 5553 if (app.instrumentationClass != null) { 5554 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5555 } 5556 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5557 + processName + " with config " + mConfiguration); 5558 thread.bindApplication(processName, app.instrumentationInfo != null 5559 ? app.instrumentationInfo : app.info, providers, 5560 app.instrumentationClass, app.instrumentationProfileFile, 5561 app.instrumentationArguments, app.instrumentationWatcher, testMode, 5562 isRestrictedBackupMode || !normalMode, 5563 mConfiguration, getCommonServicesLocked()); 5564 updateLruProcessLocked(app, false, true); 5565 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5566 } catch (Exception e) { 5567 // todo: Yikes! What should we do? For now we will try to 5568 // start another process, but that could easily get us in 5569 // an infinite loop of restarting processes... 5570 Slog.w(TAG, "Exception thrown during bind!", e); 5571 5572 app.resetPackageList(); 5573 startProcessLocked(app, "bind fail", processName); 5574 return false; 5575 } 5576 5577 // Remove this record from the list of starting applications. 5578 mPersistentStartingProcesses.remove(app); 5579 mProcessesOnHold.remove(app); 5580 5581 boolean badApp = false; 5582 boolean didSomething = false; 5583 5584 // See if the top visible activity is waiting to run in this process... 5585 HistoryRecord hr = topRunningActivityLocked(null); 5586 if (hr != null && normalMode) { 5587 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid 5588 && processName.equals(hr.processName)) { 5589 try { 5590 if (realStartActivityLocked(hr, app, true, true)) { 5591 didSomething = true; 5592 } 5593 } catch (Exception e) { 5594 Slog.w(TAG, "Exception in new application when starting activity " 5595 + hr.intent.getComponent().flattenToShortString(), e); 5596 badApp = true; 5597 } 5598 } else { 5599 ensureActivitiesVisibleLocked(hr, null, processName, 0); 5600 } 5601 } 5602 5603 // Find any services that should be running in this process... 5604 if (!badApp && mPendingServices.size() > 0) { 5605 ServiceRecord sr = null; 5606 try { 5607 for (int i=0; i<mPendingServices.size(); i++) { 5608 sr = mPendingServices.get(i); 5609 if (app.info.uid != sr.appInfo.uid 5610 || !processName.equals(sr.processName)) { 5611 continue; 5612 } 5613 5614 mPendingServices.remove(i); 5615 i--; 5616 realStartServiceLocked(sr, app); 5617 didSomething = true; 5618 } 5619 } catch (Exception e) { 5620 Slog.w(TAG, "Exception in new application when starting service " 5621 + sr.shortName, e); 5622 badApp = true; 5623 } 5624 } 5625 5626 // Check if the next broadcast receiver is in this process... 5627 BroadcastRecord br = mPendingBroadcast; 5628 if (!badApp && br != null && br.curApp == app) { 5629 try { 5630 mPendingBroadcast = null; 5631 processCurBroadcastLocked(br, app); 5632 didSomething = true; 5633 } catch (Exception e) { 5634 Slog.w(TAG, "Exception in new application when starting receiver " 5635 + br.curComponent.flattenToShortString(), e); 5636 badApp = true; 5637 logBroadcastReceiverDiscard(br); 5638 finishReceiverLocked(br.receiver, br.resultCode, br.resultData, 5639 br.resultExtras, br.resultAbort, true); 5640 scheduleBroadcastsLocked(); 5641 // We need to reset the state if we fails to start the receiver. 5642 br.state = BroadcastRecord.IDLE; 5643 } 5644 } 5645 5646 // Check whether the next backup agent is in this process... 5647 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) { 5648 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5649 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5650 try { 5651 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, mBackupTarget.backupMode); 5652 } catch (Exception e) { 5653 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5654 e.printStackTrace(); 5655 } 5656 } 5657 5658 if (badApp) { 5659 // todo: Also need to kill application to deal with all 5660 // kinds of exceptions. 5661 handleAppDiedLocked(app, false); 5662 return false; 5663 } 5664 5665 if (!didSomething) { 5666 updateOomAdjLocked(); 5667 } 5668 5669 return true; 5670 } 5671 5672 public final void attachApplication(IApplicationThread thread) { 5673 synchronized (this) { 5674 int callingPid = Binder.getCallingPid(); 5675 final long origId = Binder.clearCallingIdentity(); 5676 attachApplicationLocked(thread, callingPid); 5677 Binder.restoreCallingIdentity(origId); 5678 } 5679 } 5680 5681 public final void activityIdle(IBinder token, Configuration config) { 5682 final long origId = Binder.clearCallingIdentity(); 5683 activityIdleInternal(token, false, config); 5684 Binder.restoreCallingIdentity(origId); 5685 } 5686 5687 final ArrayList<HistoryRecord> processStoppingActivitiesLocked( 5688 boolean remove) { 5689 int N = mStoppingActivities.size(); 5690 if (N <= 0) return null; 5691 5692 ArrayList<HistoryRecord> stops = null; 5693 5694 final boolean nowVisible = mResumedActivity != null 5695 && mResumedActivity.nowVisible 5696 && !mResumedActivity.waitingVisible; 5697 for (int i=0; i<N; i++) { 5698 HistoryRecord s = mStoppingActivities.get(i); 5699 if (localLOGV) Slog.v(TAG, "Stopping " + s + ": nowVisible=" 5700 + nowVisible + " waitingVisible=" + s.waitingVisible 5701 + " finishing=" + s.finishing); 5702 if (s.waitingVisible && nowVisible) { 5703 mWaitingVisibleActivities.remove(s); 5704 s.waitingVisible = false; 5705 if (s.finishing) { 5706 // If this activity is finishing, it is sitting on top of 5707 // everyone else but we now know it is no longer needed... 5708 // so get rid of it. Otherwise, we need to go through the 5709 // normal flow and hide it once we determine that it is 5710 // hidden by the activities in front of it. 5711 if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s); 5712 mWindowManager.setAppVisibility(s, false); 5713 } 5714 } 5715 if (!s.waitingVisible && remove) { 5716 if (localLOGV) Slog.v(TAG, "Ready to stop: " + s); 5717 if (stops == null) { 5718 stops = new ArrayList<HistoryRecord>(); 5719 } 5720 stops.add(s); 5721 mStoppingActivities.remove(i); 5722 N--; 5723 i--; 5724 } 5725 } 5726 5727 return stops; 5728 } 5729 5730 void enableScreenAfterBoot() { 5731 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5732 SystemClock.uptimeMillis()); 5733 mWindowManager.enableScreenAfterBoot(); 5734 } 5735 5736 final void activityIdleInternal(IBinder token, boolean fromTimeout, 5737 Configuration config) { 5738 if (localLOGV) Slog.v(TAG, "Activity idle: " + token); 5739 5740 ArrayList<HistoryRecord> stops = null; 5741 ArrayList<HistoryRecord> finishes = null; 5742 ArrayList<HistoryRecord> thumbnails = null; 5743 int NS = 0; 5744 int NF = 0; 5745 int NT = 0; 5746 IApplicationThread sendThumbnail = null; 5747 boolean booting = false; 5748 boolean enableScreen = false; 5749 5750 synchronized (this) { 5751 if (token != null) { 5752 mHandler.removeMessages(IDLE_TIMEOUT_MSG, token); 5753 } 5754 5755 // Get the activity record. 5756 int index = indexOfTokenLocked(token); 5757 if (index >= 0) { 5758 HistoryRecord r = (HistoryRecord)mHistory.get(index); 5759 5760 if (fromTimeout) { 5761 reportActivityLaunchedLocked(fromTimeout, r, -1, -1); 5762 } 5763 5764 // This is a hack to semi-deal with a race condition 5765 // in the client where it can be constructed with a 5766 // newer configuration from when we asked it to launch. 5767 // We'll update with whatever configuration it now says 5768 // it used to launch. 5769 if (config != null) { 5770 r.configuration = config; 5771 } 5772 5773 // No longer need to keep the device awake. 5774 if (mResumedActivity == r && mLaunchingActivity.isHeld()) { 5775 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 5776 mLaunchingActivity.release(); 5777 } 5778 5779 // We are now idle. If someone is waiting for a thumbnail from 5780 // us, we can now deliver. 5781 r.idle = true; 5782 scheduleAppGcsLocked(); 5783 if (r.thumbnailNeeded && r.app != null && r.app.thread != null) { 5784 sendThumbnail = r.app.thread; 5785 r.thumbnailNeeded = false; 5786 } 5787 5788 // If this activity is fullscreen, set up to hide those under it. 5789 5790 if (DEBUG_VISBILITY) Slog.v(TAG, "Idle activity for " + r); 5791 ensureActivitiesVisibleLocked(null, 0); 5792 5793 //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout); 5794 if (!mBooted && !fromTimeout) { 5795 mBooted = true; 5796 enableScreen = true; 5797 } 5798 5799 } else if (fromTimeout) { 5800 reportActivityLaunchedLocked(fromTimeout, null, -1, -1); 5801 } 5802 5803 // Atomically retrieve all of the other things to do. 5804 stops = processStoppingActivitiesLocked(true); 5805 NS = stops != null ? stops.size() : 0; 5806 if ((NF=mFinishingActivities.size()) > 0) { 5807 finishes = new ArrayList<HistoryRecord>(mFinishingActivities); 5808 mFinishingActivities.clear(); 5809 } 5810 if ((NT=mCancelledThumbnails.size()) > 0) { 5811 thumbnails = new ArrayList<HistoryRecord>(mCancelledThumbnails); 5812 mCancelledThumbnails.clear(); 5813 } 5814 5815 booting = mBooting; 5816 mBooting = false; 5817 } 5818 5819 int i; 5820 5821 // Send thumbnail if requested. 5822 if (sendThumbnail != null) { 5823 try { 5824 sendThumbnail.requestThumbnail(token); 5825 } catch (Exception e) { 5826 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 5827 sendPendingThumbnail(null, token, null, null, true); 5828 } 5829 } 5830 5831 // Stop any activities that are scheduled to do so but have been 5832 // waiting for the next one to start. 5833 for (i=0; i<NS; i++) { 5834 HistoryRecord r = (HistoryRecord)stops.get(i); 5835 synchronized (this) { 5836 if (r.finishing) { 5837 finishCurrentActivityLocked(r, FINISH_IMMEDIATELY); 5838 } else { 5839 stopActivityLocked(r); 5840 } 5841 } 5842 } 5843 5844 // Finish any activities that are scheduled to do so but have been 5845 // waiting for the next one to start. 5846 for (i=0; i<NF; i++) { 5847 HistoryRecord r = (HistoryRecord)finishes.get(i); 5848 synchronized (this) { 5849 destroyActivityLocked(r, true); 5850 } 5851 } 5852 5853 // Report back to any thumbnail receivers. 5854 for (i=0; i<NT; i++) { 5855 HistoryRecord r = (HistoryRecord)thumbnails.get(i); 5856 sendPendingThumbnail(r, null, null, null, true); 5857 } 5858 5859 if (booting) { 5860 finishBooting(); 5861 } 5862 5863 trimApplications(); 5864 //dump(); 5865 //mWindowManager.dump(); 5866 5867 if (enableScreen) { 5868 enableScreenAfterBoot(); 5869 } 5870 } 5871 5872 final void finishBooting() { 5873 IntentFilter pkgFilter = new IntentFilter(); 5874 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5875 pkgFilter.addDataScheme("package"); 5876 mContext.registerReceiver(new BroadcastReceiver() { 5877 @Override 5878 public void onReceive(Context context, Intent intent) { 5879 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5880 if (pkgs != null) { 5881 for (String pkg : pkgs) { 5882 if (forceStopPackageLocked(pkg, -1, false, false, false)) { 5883 setResultCode(Activity.RESULT_OK); 5884 return; 5885 } 5886 } 5887 } 5888 } 5889 }, pkgFilter); 5890 5891 synchronized (this) { 5892 // Ensure that any processes we had put on hold are now started 5893 // up. 5894 final int NP = mProcessesOnHold.size(); 5895 if (NP > 0) { 5896 ArrayList<ProcessRecord> procs = 5897 new ArrayList<ProcessRecord>(mProcessesOnHold); 5898 for (int ip=0; ip<NP; ip++) { 5899 this.startProcessLocked(procs.get(ip), "on-hold", null); 5900 } 5901 } 5902 5903 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 5904 // Tell anyone interested that we are done booting! 5905 broadcastIntentLocked(null, null, 5906 new Intent(Intent.ACTION_BOOT_COMPLETED, null), 5907 null, null, 0, null, null, 5908 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5909 false, false, MY_PID, Process.SYSTEM_UID); 5910 } 5911 } 5912 } 5913 5914 final void ensureBootCompleted() { 5915 boolean booting; 5916 boolean enableScreen; 5917 synchronized (this) { 5918 booting = mBooting; 5919 mBooting = false; 5920 enableScreen = !mBooted; 5921 mBooted = true; 5922 } 5923 5924 if (booting) { 5925 finishBooting(); 5926 } 5927 5928 if (enableScreen) { 5929 enableScreenAfterBoot(); 5930 } 5931 } 5932 5933 public final void activityPaused(IBinder token, Bundle icicle) { 5934 // Refuse possible leaked file descriptors 5935 if (icicle != null && icicle.hasFileDescriptors()) { 5936 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5937 } 5938 5939 final long origId = Binder.clearCallingIdentity(); 5940 activityPaused(token, icicle, false); 5941 Binder.restoreCallingIdentity(origId); 5942 } 5943 5944 final void activityPaused(IBinder token, Bundle icicle, boolean timeout) { 5945 if (DEBUG_PAUSE) Slog.v( 5946 TAG, "Activity paused: token=" + token + ", icicle=" + icicle 5947 + ", timeout=" + timeout); 5948 5949 HistoryRecord r = null; 5950 5951 synchronized (this) { 5952 int index = indexOfTokenLocked(token); 5953 if (index >= 0) { 5954 r = (HistoryRecord)mHistory.get(index); 5955 if (!timeout) { 5956 r.icicle = icicle; 5957 r.haveState = true; 5958 } 5959 mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); 5960 if (mPausingActivity == r) { 5961 r.state = ActivityState.PAUSED; 5962 completePauseLocked(); 5963 } else { 5964 EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE, 5965 System.identityHashCode(r), r.shortComponentName, 5966 mPausingActivity != null 5967 ? mPausingActivity.shortComponentName : "(none)"); 5968 } 5969 } 5970 } 5971 } 5972 5973 public final void activityStopped(IBinder token, Bitmap thumbnail, 5974 CharSequence description) { 5975 if (localLOGV) Slog.v( 5976 TAG, "Activity stopped: token=" + token); 5977 5978 HistoryRecord r = null; 5979 5980 final long origId = Binder.clearCallingIdentity(); 5981 5982 synchronized (this) { 5983 int index = indexOfTokenLocked(token); 5984 if (index >= 0) { 5985 r = (HistoryRecord)mHistory.get(index); 5986 r.thumbnail = thumbnail; 5987 r.description = description; 5988 r.stopped = true; 5989 r.state = ActivityState.STOPPED; 5990 if (!r.finishing) { 5991 if (r.configDestroy) { 5992 destroyActivityLocked(r, true); 5993 resumeTopActivityLocked(null); 5994 } 5995 } 5996 } 5997 } 5998 5999 if (r != null) { 6000 sendPendingThumbnail(r, null, null, null, false); 6001 } 6002 6003 trimApplications(); 6004 6005 Binder.restoreCallingIdentity(origId); 6006 } 6007 6008 public final void activityDestroyed(IBinder token) { 6009 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6010 synchronized (this) { 6011 mHandler.removeMessages(DESTROY_TIMEOUT_MSG, token); 6012 6013 int index = indexOfTokenLocked(token); 6014 if (index >= 0) { 6015 HistoryRecord r = (HistoryRecord)mHistory.get(index); 6016 if (r.state == ActivityState.DESTROYING) { 6017 final long origId = Binder.clearCallingIdentity(); 6018 removeActivityFromHistoryLocked(r); 6019 Binder.restoreCallingIdentity(origId); 6020 } 6021 } 6022 } 6023 } 6024 6025 public String getCallingPackage(IBinder token) { 6026 synchronized (this) { 6027 HistoryRecord r = getCallingRecordLocked(token); 6028 return r != null && r.app != null ? r.info.packageName : null; 6029 } 6030 } 6031 6032 public ComponentName getCallingActivity(IBinder token) { 6033 synchronized (this) { 6034 HistoryRecord r = getCallingRecordLocked(token); 6035 return r != null ? r.intent.getComponent() : null; 6036 } 6037 } 6038 6039 private HistoryRecord getCallingRecordLocked(IBinder token) { 6040 int index = indexOfTokenLocked(token); 6041 if (index >= 0) { 6042 HistoryRecord r = (HistoryRecord)mHistory.get(index); 6043 if (r != null) { 6044 return r.resultTo; 6045 } 6046 } 6047 return null; 6048 } 6049 6050 public ComponentName getActivityClassForToken(IBinder token) { 6051 synchronized(this) { 6052 int index = indexOfTokenLocked(token); 6053 if (index >= 0) { 6054 HistoryRecord r = (HistoryRecord)mHistory.get(index); 6055 return r.intent.getComponent(); 6056 } 6057 return null; 6058 } 6059 } 6060 6061 public String getPackageForToken(IBinder token) { 6062 synchronized(this) { 6063 int index = indexOfTokenLocked(token); 6064 if (index >= 0) { 6065 HistoryRecord r = (HistoryRecord)mHistory.get(index); 6066 return r.packageName; 6067 } 6068 return null; 6069 } 6070 } 6071 6072 public IIntentSender getIntentSender(int type, 6073 String packageName, IBinder token, String resultWho, 6074 int requestCode, Intent intent, String resolvedType, int flags) { 6075 // Refuse possible leaked file descriptors 6076 if (intent != null && intent.hasFileDescriptors() == true) { 6077 throw new IllegalArgumentException("File descriptors passed in Intent"); 6078 } 6079 6080 if (type == INTENT_SENDER_BROADCAST) { 6081 if ((intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6082 throw new IllegalArgumentException( 6083 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6084 } 6085 } 6086 6087 synchronized(this) { 6088 int callingUid = Binder.getCallingUid(); 6089 try { 6090 if (callingUid != 0 && callingUid != Process.SYSTEM_UID && 6091 Process.supportsProcesses()) { 6092 int uid = ActivityThread.getPackageManager() 6093 .getPackageUid(packageName); 6094 if (uid != Binder.getCallingUid()) { 6095 String msg = "Permission Denial: getIntentSender() from pid=" 6096 + Binder.getCallingPid() 6097 + ", uid=" + Binder.getCallingUid() 6098 + ", (need uid=" + uid + ")" 6099 + " is not allowed to send as package " + packageName; 6100 Slog.w(TAG, msg); 6101 throw new SecurityException(msg); 6102 } 6103 } 6104 } catch (RemoteException e) { 6105 throw new SecurityException(e); 6106 } 6107 HistoryRecord activity = null; 6108 if (type == INTENT_SENDER_ACTIVITY_RESULT) { 6109 int index = indexOfTokenLocked(token); 6110 if (index < 0) { 6111 return null; 6112 } 6113 activity = (HistoryRecord)mHistory.get(index); 6114 if (activity.finishing) { 6115 return null; 6116 } 6117 } 6118 6119 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6120 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6121 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6122 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6123 |PendingIntent.FLAG_UPDATE_CURRENT); 6124 6125 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6126 type, packageName, activity, resultWho, 6127 requestCode, intent, resolvedType, flags); 6128 WeakReference<PendingIntentRecord> ref; 6129 ref = mIntentSenderRecords.get(key); 6130 PendingIntentRecord rec = ref != null ? ref.get() : null; 6131 if (rec != null) { 6132 if (!cancelCurrent) { 6133 if (updateCurrent) { 6134 rec.key.requestIntent.replaceExtras(intent); 6135 } 6136 return rec; 6137 } 6138 rec.canceled = true; 6139 mIntentSenderRecords.remove(key); 6140 } 6141 if (noCreate) { 6142 return rec; 6143 } 6144 rec = new PendingIntentRecord(this, key, callingUid); 6145 mIntentSenderRecords.put(key, rec.ref); 6146 if (type == INTENT_SENDER_ACTIVITY_RESULT) { 6147 if (activity.pendingResults == null) { 6148 activity.pendingResults 6149 = new HashSet<WeakReference<PendingIntentRecord>>(); 6150 } 6151 activity.pendingResults.add(rec.ref); 6152 } 6153 return rec; 6154 } 6155 } 6156 6157 public void cancelIntentSender(IIntentSender sender) { 6158 if (!(sender instanceof PendingIntentRecord)) { 6159 return; 6160 } 6161 synchronized(this) { 6162 PendingIntentRecord rec = (PendingIntentRecord)sender; 6163 try { 6164 int uid = ActivityThread.getPackageManager() 6165 .getPackageUid(rec.key.packageName); 6166 if (uid != Binder.getCallingUid()) { 6167 String msg = "Permission Denial: cancelIntentSender() from pid=" 6168 + Binder.getCallingPid() 6169 + ", uid=" + Binder.getCallingUid() 6170 + " is not allowed to cancel packges " 6171 + rec.key.packageName; 6172 Slog.w(TAG, msg); 6173 throw new SecurityException(msg); 6174 } 6175 } catch (RemoteException e) { 6176 throw new SecurityException(e); 6177 } 6178 cancelIntentSenderLocked(rec, true); 6179 } 6180 } 6181 6182 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6183 rec.canceled = true; 6184 mIntentSenderRecords.remove(rec.key); 6185 if (cleanActivity && rec.key.activity != null) { 6186 rec.key.activity.pendingResults.remove(rec.ref); 6187 } 6188 } 6189 6190 public String getPackageForIntentSender(IIntentSender pendingResult) { 6191 if (!(pendingResult instanceof PendingIntentRecord)) { 6192 return null; 6193 } 6194 try { 6195 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6196 return res.key.packageName; 6197 } catch (ClassCastException e) { 6198 } 6199 return null; 6200 } 6201 6202 public void setProcessLimit(int max) { 6203 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6204 "setProcessLimit()"); 6205 mProcessLimit = max; 6206 } 6207 6208 public int getProcessLimit() { 6209 return mProcessLimit; 6210 } 6211 6212 void foregroundTokenDied(ForegroundToken token) { 6213 synchronized (ActivityManagerService.this) { 6214 synchronized (mPidsSelfLocked) { 6215 ForegroundToken cur 6216 = mForegroundProcesses.get(token.pid); 6217 if (cur != token) { 6218 return; 6219 } 6220 mForegroundProcesses.remove(token.pid); 6221 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6222 if (pr == null) { 6223 return; 6224 } 6225 pr.forcingToForeground = null; 6226 pr.foregroundServices = false; 6227 } 6228 updateOomAdjLocked(); 6229 } 6230 } 6231 6232 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6233 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6234 "setProcessForeground()"); 6235 synchronized(this) { 6236 boolean changed = false; 6237 6238 synchronized (mPidsSelfLocked) { 6239 ProcessRecord pr = mPidsSelfLocked.get(pid); 6240 if (pr == null) { 6241 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6242 return; 6243 } 6244 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6245 if (oldToken != null) { 6246 oldToken.token.unlinkToDeath(oldToken, 0); 6247 mForegroundProcesses.remove(pid); 6248 pr.forcingToForeground = null; 6249 changed = true; 6250 } 6251 if (isForeground && token != null) { 6252 ForegroundToken newToken = new ForegroundToken() { 6253 public void binderDied() { 6254 foregroundTokenDied(this); 6255 } 6256 }; 6257 newToken.pid = pid; 6258 newToken.token = token; 6259 try { 6260 token.linkToDeath(newToken, 0); 6261 mForegroundProcesses.put(pid, newToken); 6262 pr.forcingToForeground = token; 6263 changed = true; 6264 } catch (RemoteException e) { 6265 // If the process died while doing this, we will later 6266 // do the cleanup with the process death link. 6267 } 6268 } 6269 } 6270 6271 if (changed) { 6272 updateOomAdjLocked(); 6273 } 6274 } 6275 } 6276 6277 // ========================================================= 6278 // PERMISSIONS 6279 // ========================================================= 6280 6281 static class PermissionController extends IPermissionController.Stub { 6282 ActivityManagerService mActivityManagerService; 6283 PermissionController(ActivityManagerService activityManagerService) { 6284 mActivityManagerService = activityManagerService; 6285 } 6286 6287 public boolean checkPermission(String permission, int pid, int uid) { 6288 return mActivityManagerService.checkPermission(permission, pid, 6289 uid) == PackageManager.PERMISSION_GRANTED; 6290 } 6291 } 6292 6293 /** 6294 * This can be called with or without the global lock held. 6295 */ 6296 int checkComponentPermission(String permission, int pid, int uid, 6297 int reqUid) { 6298 // We might be performing an operation on behalf of an indirect binder 6299 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6300 // client identity accordingly before proceeding. 6301 Identity tlsIdentity = sCallerIdentity.get(); 6302 if (tlsIdentity != null) { 6303 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6304 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6305 uid = tlsIdentity.uid; 6306 pid = tlsIdentity.pid; 6307 } 6308 6309 // Root, system server and our own process get to do everything. 6310 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID || 6311 !Process.supportsProcesses()) { 6312 return PackageManager.PERMISSION_GRANTED; 6313 } 6314 // If the target requires a specific UID, always fail for others. 6315 if (reqUid >= 0 && uid != reqUid) { 6316 Slog.w(TAG, "Permission denied: checkComponentPermission() reqUid=" + reqUid); 6317 return PackageManager.PERMISSION_DENIED; 6318 } 6319 if (permission == null) { 6320 return PackageManager.PERMISSION_GRANTED; 6321 } 6322 try { 6323 return ActivityThread.getPackageManager() 6324 .checkUidPermission(permission, uid); 6325 } catch (RemoteException e) { 6326 // Should never happen, but if it does... deny! 6327 Slog.e(TAG, "PackageManager is dead?!?", e); 6328 } 6329 return PackageManager.PERMISSION_DENIED; 6330 } 6331 6332 /** 6333 * As the only public entry point for permissions checking, this method 6334 * can enforce the semantic that requesting a check on a null global 6335 * permission is automatically denied. (Internally a null permission 6336 * string is used when calling {@link #checkComponentPermission} in cases 6337 * when only uid-based security is needed.) 6338 * 6339 * This can be called with or without the global lock held. 6340 */ 6341 public int checkPermission(String permission, int pid, int uid) { 6342 if (permission == null) { 6343 return PackageManager.PERMISSION_DENIED; 6344 } 6345 return checkComponentPermission(permission, pid, uid, -1); 6346 } 6347 6348 /** 6349 * Binder IPC calls go through the public entry point. 6350 * This can be called with or without the global lock held. 6351 */ 6352 int checkCallingPermission(String permission) { 6353 return checkPermission(permission, 6354 Binder.getCallingPid(), 6355 Binder.getCallingUid()); 6356 } 6357 6358 /** 6359 * This can be called with or without the global lock held. 6360 */ 6361 void enforceCallingPermission(String permission, String func) { 6362 if (checkCallingPermission(permission) 6363 == PackageManager.PERMISSION_GRANTED) { 6364 return; 6365 } 6366 6367 String msg = "Permission Denial: " + func + " from pid=" 6368 + Binder.getCallingPid() 6369 + ", uid=" + Binder.getCallingUid() 6370 + " requires " + permission; 6371 Slog.w(TAG, msg); 6372 throw new SecurityException(msg); 6373 } 6374 6375 private final boolean checkHoldingPermissionsLocked(IPackageManager pm, 6376 ProviderInfo pi, int uid, int modeFlags) { 6377 try { 6378 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6379 if ((pi.readPermission != null) && 6380 (pm.checkUidPermission(pi.readPermission, uid) 6381 != PackageManager.PERMISSION_GRANTED)) { 6382 return false; 6383 } 6384 } 6385 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6386 if ((pi.writePermission != null) && 6387 (pm.checkUidPermission(pi.writePermission, uid) 6388 != PackageManager.PERMISSION_GRANTED)) { 6389 return false; 6390 } 6391 } 6392 return true; 6393 } catch (RemoteException e) { 6394 return false; 6395 } 6396 } 6397 6398 private final boolean checkUriPermissionLocked(Uri uri, int uid, 6399 int modeFlags) { 6400 // Root gets to do everything. 6401 if (uid == 0 || !Process.supportsProcesses()) { 6402 return true; 6403 } 6404 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6405 if (perms == null) return false; 6406 UriPermission perm = perms.get(uri); 6407 if (perm == null) return false; 6408 return (modeFlags&perm.modeFlags) == modeFlags; 6409 } 6410 6411 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 6412 // Another redirected-binder-call permissions check as in 6413 // {@link checkComponentPermission}. 6414 Identity tlsIdentity = sCallerIdentity.get(); 6415 if (tlsIdentity != null) { 6416 uid = tlsIdentity.uid; 6417 pid = tlsIdentity.pid; 6418 } 6419 6420 // Our own process gets to do everything. 6421 if (pid == MY_PID) { 6422 return PackageManager.PERMISSION_GRANTED; 6423 } 6424 synchronized(this) { 6425 return checkUriPermissionLocked(uri, uid, modeFlags) 6426 ? PackageManager.PERMISSION_GRANTED 6427 : PackageManager.PERMISSION_DENIED; 6428 } 6429 } 6430 6431 private void grantUriPermissionLocked(int callingUid, 6432 String targetPkg, Uri uri, int modeFlags, HistoryRecord activity) { 6433 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6434 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6435 if (modeFlags == 0) { 6436 return; 6437 } 6438 6439 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6440 "Requested grant " + targetPkg + " permission to " + uri); 6441 6442 final IPackageManager pm = ActivityThread.getPackageManager(); 6443 6444 // If this is not a content: uri, we can't do anything with it. 6445 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 6446 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6447 "Can't grant URI permission for non-content URI: " + uri); 6448 return; 6449 } 6450 6451 String name = uri.getAuthority(); 6452 ProviderInfo pi = null; 6453 ContentProviderRecord cpr 6454 = (ContentProviderRecord)mProvidersByName.get(name); 6455 if (cpr != null) { 6456 pi = cpr.info; 6457 } else { 6458 try { 6459 pi = pm.resolveContentProvider(name, 6460 PackageManager.GET_URI_PERMISSION_PATTERNS); 6461 } catch (RemoteException ex) { 6462 } 6463 } 6464 if (pi == null) { 6465 Slog.w(TAG, "No content provider found for: " + name); 6466 return; 6467 } 6468 6469 int targetUid; 6470 try { 6471 targetUid = pm.getPackageUid(targetPkg); 6472 if (targetUid < 0) { 6473 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6474 "Can't grant URI permission no uid for: " + targetPkg); 6475 return; 6476 } 6477 } catch (RemoteException ex) { 6478 return; 6479 } 6480 6481 // First... does the target actually need this permission? 6482 if (checkHoldingPermissionsLocked(pm, pi, targetUid, modeFlags)) { 6483 // No need to grant the target this permission. 6484 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6485 "Target " + targetPkg + " already has full permission to " + uri); 6486 return; 6487 } 6488 6489 // Second... is the provider allowing granting of URI permissions? 6490 if (!pi.grantUriPermissions) { 6491 throw new SecurityException("Provider " + pi.packageName 6492 + "/" + pi.name 6493 + " does not allow granting of Uri permissions (uri " 6494 + uri + ")"); 6495 } 6496 if (pi.uriPermissionPatterns != null) { 6497 final int N = pi.uriPermissionPatterns.length; 6498 boolean allowed = false; 6499 for (int i=0; i<N; i++) { 6500 if (pi.uriPermissionPatterns[i] != null 6501 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6502 allowed = true; 6503 break; 6504 } 6505 } 6506 if (!allowed) { 6507 throw new SecurityException("Provider " + pi.packageName 6508 + "/" + pi.name 6509 + " does not allow granting of permission to path of Uri " 6510 + uri); 6511 } 6512 } 6513 6514 // Third... does the caller itself have permission to access 6515 // this uri? 6516 if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) { 6517 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6518 throw new SecurityException("Uid " + callingUid 6519 + " does not have permission to uri " + uri); 6520 } 6521 } 6522 6523 // Okay! So here we are: the caller has the assumed permission 6524 // to the uri, and the target doesn't. Let's now give this to 6525 // the target. 6526 6527 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6528 "Granting " + targetPkg + " permission to " + uri); 6529 6530 HashMap<Uri, UriPermission> targetUris 6531 = mGrantedUriPermissions.get(targetUid); 6532 if (targetUris == null) { 6533 targetUris = new HashMap<Uri, UriPermission>(); 6534 mGrantedUriPermissions.put(targetUid, targetUris); 6535 } 6536 6537 UriPermission perm = targetUris.get(uri); 6538 if (perm == null) { 6539 perm = new UriPermission(targetUid, uri); 6540 targetUris.put(uri, perm); 6541 6542 } 6543 perm.modeFlags |= modeFlags; 6544 if (activity == null) { 6545 perm.globalModeFlags |= modeFlags; 6546 } else if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6547 perm.readActivities.add(activity); 6548 if (activity.readUriPermissions == null) { 6549 activity.readUriPermissions = new HashSet<UriPermission>(); 6550 } 6551 activity.readUriPermissions.add(perm); 6552 } else if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6553 perm.writeActivities.add(activity); 6554 if (activity.writeUriPermissions == null) { 6555 activity.writeUriPermissions = new HashSet<UriPermission>(); 6556 } 6557 activity.writeUriPermissions.add(perm); 6558 } 6559 } 6560 6561 private void grantUriPermissionFromIntentLocked(int callingUid, 6562 String targetPkg, Intent intent, HistoryRecord activity) { 6563 if (intent == null) { 6564 return; 6565 } 6566 Uri data = intent.getData(); 6567 if (data == null) { 6568 return; 6569 } 6570 grantUriPermissionLocked(callingUid, targetPkg, data, 6571 intent.getFlags(), activity); 6572 } 6573 6574 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6575 Uri uri, int modeFlags) { 6576 synchronized(this) { 6577 final ProcessRecord r = getRecordForAppLocked(caller); 6578 if (r == null) { 6579 throw new SecurityException("Unable to find app for caller " 6580 + caller 6581 + " when granting permission to uri " + uri); 6582 } 6583 if (targetPkg == null) { 6584 Slog.w(TAG, "grantUriPermission: null target"); 6585 return; 6586 } 6587 if (uri == null) { 6588 Slog.w(TAG, "grantUriPermission: null uri"); 6589 return; 6590 } 6591 6592 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags, 6593 null); 6594 } 6595 } 6596 6597 private void removeUriPermissionIfNeededLocked(UriPermission perm) { 6598 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6599 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6600 HashMap<Uri, UriPermission> perms 6601 = mGrantedUriPermissions.get(perm.uid); 6602 if (perms != null) { 6603 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6604 "Removing " + perm.uid + " permission to " + perm.uri); 6605 perms.remove(perm.uri); 6606 if (perms.size() == 0) { 6607 mGrantedUriPermissions.remove(perm.uid); 6608 } 6609 } 6610 } 6611 } 6612 6613 private void removeActivityUriPermissionsLocked(HistoryRecord activity) { 6614 if (activity.readUriPermissions != null) { 6615 for (UriPermission perm : activity.readUriPermissions) { 6616 perm.readActivities.remove(activity); 6617 if (perm.readActivities.size() == 0 && (perm.globalModeFlags 6618 &Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0) { 6619 perm.modeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION; 6620 removeUriPermissionIfNeededLocked(perm); 6621 } 6622 } 6623 } 6624 if (activity.writeUriPermissions != null) { 6625 for (UriPermission perm : activity.writeUriPermissions) { 6626 perm.writeActivities.remove(activity); 6627 if (perm.writeActivities.size() == 0 && (perm.globalModeFlags 6628 &Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0) { 6629 perm.modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION; 6630 removeUriPermissionIfNeededLocked(perm); 6631 } 6632 } 6633 } 6634 } 6635 6636 private void revokeUriPermissionLocked(int callingUid, Uri uri, 6637 int modeFlags) { 6638 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6639 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6640 if (modeFlags == 0) { 6641 return; 6642 } 6643 6644 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6645 "Revoking all granted permissions to " + uri); 6646 6647 final IPackageManager pm = ActivityThread.getPackageManager(); 6648 6649 final String authority = uri.getAuthority(); 6650 ProviderInfo pi = null; 6651 ContentProviderRecord cpr 6652 = (ContentProviderRecord)mProvidersByName.get(authority); 6653 if (cpr != null) { 6654 pi = cpr.info; 6655 } else { 6656 try { 6657 pi = pm.resolveContentProvider(authority, 6658 PackageManager.GET_URI_PERMISSION_PATTERNS); 6659 } catch (RemoteException ex) { 6660 } 6661 } 6662 if (pi == null) { 6663 Slog.w(TAG, "No content provider found for: " + authority); 6664 return; 6665 } 6666 6667 // Does the caller have this permission on the URI? 6668 if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) { 6669 // Right now, if you are not the original owner of the permission, 6670 // you are not allowed to revoke it. 6671 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6672 throw new SecurityException("Uid " + callingUid 6673 + " does not have permission to uri " + uri); 6674 //} 6675 } 6676 6677 // Go through all of the permissions and remove any that match. 6678 final List<String> SEGMENTS = uri.getPathSegments(); 6679 if (SEGMENTS != null) { 6680 final int NS = SEGMENTS.size(); 6681 int N = mGrantedUriPermissions.size(); 6682 for (int i=0; i<N; i++) { 6683 HashMap<Uri, UriPermission> perms 6684 = mGrantedUriPermissions.valueAt(i); 6685 Iterator<UriPermission> it = perms.values().iterator(); 6686 toploop: 6687 while (it.hasNext()) { 6688 UriPermission perm = it.next(); 6689 Uri targetUri = perm.uri; 6690 if (!authority.equals(targetUri.getAuthority())) { 6691 continue; 6692 } 6693 List<String> targetSegments = targetUri.getPathSegments(); 6694 if (targetSegments == null) { 6695 continue; 6696 } 6697 if (targetSegments.size() < NS) { 6698 continue; 6699 } 6700 for (int j=0; j<NS; j++) { 6701 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6702 continue toploop; 6703 } 6704 } 6705 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6706 "Revoking " + perm.uid + " permission to " + perm.uri); 6707 perm.clearModes(modeFlags); 6708 if (perm.modeFlags == 0) { 6709 it.remove(); 6710 } 6711 } 6712 if (perms.size() == 0) { 6713 mGrantedUriPermissions.remove( 6714 mGrantedUriPermissions.keyAt(i)); 6715 N--; 6716 i--; 6717 } 6718 } 6719 } 6720 } 6721 6722 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6723 int modeFlags) { 6724 synchronized(this) { 6725 final ProcessRecord r = getRecordForAppLocked(caller); 6726 if (r == null) { 6727 throw new SecurityException("Unable to find app for caller " 6728 + caller 6729 + " when revoking permission to uri " + uri); 6730 } 6731 if (uri == null) { 6732 Slog.w(TAG, "revokeUriPermission: null uri"); 6733 return; 6734 } 6735 6736 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6737 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6738 if (modeFlags == 0) { 6739 return; 6740 } 6741 6742 final IPackageManager pm = ActivityThread.getPackageManager(); 6743 6744 final String authority = uri.getAuthority(); 6745 ProviderInfo pi = null; 6746 ContentProviderRecord cpr 6747 = (ContentProviderRecord)mProvidersByName.get(authority); 6748 if (cpr != null) { 6749 pi = cpr.info; 6750 } else { 6751 try { 6752 pi = pm.resolveContentProvider(authority, 6753 PackageManager.GET_URI_PERMISSION_PATTERNS); 6754 } catch (RemoteException ex) { 6755 } 6756 } 6757 if (pi == null) { 6758 Slog.w(TAG, "No content provider found for: " + authority); 6759 return; 6760 } 6761 6762 revokeUriPermissionLocked(r.info.uid, uri, modeFlags); 6763 } 6764 } 6765 6766 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6767 synchronized (this) { 6768 ProcessRecord app = 6769 who != null ? getRecordForAppLocked(who) : null; 6770 if (app == null) return; 6771 6772 Message msg = Message.obtain(); 6773 msg.what = WAIT_FOR_DEBUGGER_MSG; 6774 msg.obj = app; 6775 msg.arg1 = waiting ? 1 : 0; 6776 mHandler.sendMessage(msg); 6777 } 6778 } 6779 6780 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6781 outInfo.availMem = Process.getFreeMemory(); 6782 outInfo.threshold = HOME_APP_MEM; 6783 outInfo.lowMemory = outInfo.availMem < 6784 (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2)); 6785 } 6786 6787 // ========================================================= 6788 // TASK MANAGEMENT 6789 // ========================================================= 6790 6791 public List getTasks(int maxNum, int flags, 6792 IThumbnailReceiver receiver) { 6793 ArrayList list = new ArrayList(); 6794 6795 PendingThumbnailsRecord pending = null; 6796 IApplicationThread topThumbnail = null; 6797 HistoryRecord topRecord = null; 6798 6799 synchronized(this) { 6800 if (localLOGV) Slog.v( 6801 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6802 + ", receiver=" + receiver); 6803 6804 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6805 != PackageManager.PERMISSION_GRANTED) { 6806 if (receiver != null) { 6807 // If the caller wants to wait for pending thumbnails, 6808 // it ain't gonna get them. 6809 try { 6810 receiver.finished(); 6811 } catch (RemoteException ex) { 6812 } 6813 } 6814 String msg = "Permission Denial: getTasks() from pid=" 6815 + Binder.getCallingPid() 6816 + ", uid=" + Binder.getCallingUid() 6817 + " requires " + android.Manifest.permission.GET_TASKS; 6818 Slog.w(TAG, msg); 6819 throw new SecurityException(msg); 6820 } 6821 6822 int pos = mHistory.size()-1; 6823 HistoryRecord next = 6824 pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null; 6825 HistoryRecord top = null; 6826 CharSequence topDescription = null; 6827 TaskRecord curTask = null; 6828 int numActivities = 0; 6829 int numRunning = 0; 6830 while (pos >= 0 && maxNum > 0) { 6831 final HistoryRecord r = next; 6832 pos--; 6833 next = pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null; 6834 6835 // Initialize state for next task if needed. 6836 if (top == null || 6837 (top.state == ActivityState.INITIALIZING 6838 && top.task == r.task)) { 6839 top = r; 6840 topDescription = r.description; 6841 curTask = r.task; 6842 numActivities = numRunning = 0; 6843 } 6844 6845 // Add 'r' into the current task. 6846 numActivities++; 6847 if (r.app != null && r.app.thread != null) { 6848 numRunning++; 6849 } 6850 if (topDescription == null) { 6851 topDescription = r.description; 6852 } 6853 6854 if (localLOGV) Slog.v( 6855 TAG, r.intent.getComponent().flattenToShortString() 6856 + ": task=" + r.task); 6857 6858 // If the next one is a different task, generate a new 6859 // TaskInfo entry for what we have. 6860 if (next == null || next.task != curTask) { 6861 ActivityManager.RunningTaskInfo ci 6862 = new ActivityManager.RunningTaskInfo(); 6863 ci.id = curTask.taskId; 6864 ci.baseActivity = r.intent.getComponent(); 6865 ci.topActivity = top.intent.getComponent(); 6866 ci.thumbnail = top.thumbnail; 6867 ci.description = topDescription; 6868 ci.numActivities = numActivities; 6869 ci.numRunning = numRunning; 6870 //System.out.println( 6871 // "#" + maxNum + ": " + " descr=" + ci.description); 6872 if (ci.thumbnail == null && receiver != null) { 6873 if (localLOGV) Slog.v( 6874 TAG, "State=" + top.state + "Idle=" + top.idle 6875 + " app=" + top.app 6876 + " thr=" + (top.app != null ? top.app.thread : null)); 6877 if (top.state == ActivityState.RESUMED 6878 || top.state == ActivityState.PAUSING) { 6879 if (top.idle && top.app != null 6880 && top.app.thread != null) { 6881 topRecord = top; 6882 topThumbnail = top.app.thread; 6883 } else { 6884 top.thumbnailNeeded = true; 6885 } 6886 } 6887 if (pending == null) { 6888 pending = new PendingThumbnailsRecord(receiver); 6889 } 6890 pending.pendingRecords.add(top); 6891 } 6892 list.add(ci); 6893 maxNum--; 6894 top = null; 6895 } 6896 } 6897 6898 if (pending != null) { 6899 mPendingThumbnails.add(pending); 6900 } 6901 } 6902 6903 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6904 6905 if (topThumbnail != null) { 6906 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6907 try { 6908 topThumbnail.requestThumbnail(topRecord); 6909 } catch (Exception e) { 6910 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6911 sendPendingThumbnail(null, topRecord, null, null, true); 6912 } 6913 } 6914 6915 if (pending == null && receiver != null) { 6916 // In this case all thumbnails were available and the client 6917 // is being asked to be told when the remaining ones come in... 6918 // which is unusually, since the top-most currently running 6919 // activity should never have a canned thumbnail! Oh well. 6920 try { 6921 receiver.finished(); 6922 } catch (RemoteException ex) { 6923 } 6924 } 6925 6926 return list; 6927 } 6928 6929 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6930 int flags) { 6931 synchronized (this) { 6932 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6933 "getRecentTasks()"); 6934 6935 IPackageManager pm = ActivityThread.getPackageManager(); 6936 6937 final int N = mRecentTasks.size(); 6938 ArrayList<ActivityManager.RecentTaskInfo> res 6939 = new ArrayList<ActivityManager.RecentTaskInfo>( 6940 maxNum < N ? maxNum : N); 6941 for (int i=0; i<N && maxNum > 0; i++) { 6942 TaskRecord tr = mRecentTasks.get(i); 6943 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6944 || (tr.intent == null) 6945 || ((tr.intent.getFlags() 6946 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6947 ActivityManager.RecentTaskInfo rti 6948 = new ActivityManager.RecentTaskInfo(); 6949 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6950 rti.baseIntent = new Intent( 6951 tr.intent != null ? tr.intent : tr.affinityIntent); 6952 rti.origActivity = tr.origActivity; 6953 6954 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6955 // Check whether this activity is currently available. 6956 try { 6957 if (rti.origActivity != null) { 6958 if (pm.getActivityInfo(rti.origActivity, 0) == null) { 6959 continue; 6960 } 6961 } else if (rti.baseIntent != null) { 6962 if (pm.queryIntentActivities(rti.baseIntent, 6963 null, 0) == null) { 6964 continue; 6965 } 6966 } 6967 } catch (RemoteException e) { 6968 // Will never happen. 6969 } 6970 } 6971 6972 res.add(rti); 6973 maxNum--; 6974 } 6975 } 6976 return res; 6977 } 6978 } 6979 6980 private final int findAffinityTaskTopLocked(int startIndex, String affinity) { 6981 int j; 6982 TaskRecord startTask = ((HistoryRecord)mHistory.get(startIndex)).task; 6983 TaskRecord jt = startTask; 6984 6985 // First look backwards 6986 for (j=startIndex-1; j>=0; j--) { 6987 HistoryRecord r = (HistoryRecord)mHistory.get(j); 6988 if (r.task != jt) { 6989 jt = r.task; 6990 if (affinity.equals(jt.affinity)) { 6991 return j; 6992 } 6993 } 6994 } 6995 6996 // Now look forwards 6997 final int N = mHistory.size(); 6998 jt = startTask; 6999 for (j=startIndex+1; j<N; j++) { 7000 HistoryRecord r = (HistoryRecord)mHistory.get(j); 7001 if (r.task != jt) { 7002 if (affinity.equals(jt.affinity)) { 7003 return j; 7004 } 7005 jt = r.task; 7006 } 7007 } 7008 7009 // Might it be at the top? 7010 if (affinity.equals(((HistoryRecord)mHistory.get(N-1)).task.affinity)) { 7011 return N-1; 7012 } 7013 7014 return -1; 7015 } 7016 7017 /** 7018 * Perform a reset of the given task, if needed as part of launching it. 7019 * Returns the new HistoryRecord at the top of the task. 7020 */ 7021 private final HistoryRecord resetTaskIfNeededLocked(HistoryRecord taskTop, 7022 HistoryRecord newActivity) { 7023 boolean forceReset = (newActivity.info.flags 7024 &ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0; 7025 if (taskTop.task.getInactiveDuration() > ACTIVITY_INACTIVE_RESET_TIME) { 7026 if ((newActivity.info.flags 7027 &ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE) == 0) { 7028 forceReset = true; 7029 } 7030 } 7031 7032 final TaskRecord task = taskTop.task; 7033 7034 // We are going to move through the history list so that we can look 7035 // at each activity 'target' with 'below' either the interesting 7036 // activity immediately below it in the stack or null. 7037 HistoryRecord target = null; 7038 int targetI = 0; 7039 int taskTopI = -1; 7040 int replyChainEnd = -1; 7041 int lastReparentPos = -1; 7042 for (int i=mHistory.size()-1; i>=-1; i--) { 7043 HistoryRecord below = i >= 0 ? (HistoryRecord)mHistory.get(i) : null; 7044 7045 if (below != null && below.finishing) { 7046 continue; 7047 } 7048 if (target == null) { 7049 target = below; 7050 targetI = i; 7051 // If we were in the middle of a reply chain before this 7052 // task, it doesn't appear like the root of the chain wants 7053 // anything interesting, so drop it. 7054 replyChainEnd = -1; 7055 continue; 7056 } 7057 7058 final int flags = target.info.flags; 7059 7060 final boolean finishOnTaskLaunch = 7061 (flags&ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0; 7062 final boolean allowTaskReparenting = 7063 (flags&ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0; 7064 7065 if (target.task == task) { 7066 // We are inside of the task being reset... we'll either 7067 // finish this activity, push it out for another task, 7068 // or leave it as-is. We only do this 7069 // for activities that are not the root of the task (since 7070 // if we finish the root, we may no longer have the task!). 7071 if (taskTopI < 0) { 7072 taskTopI = targetI; 7073 } 7074 if (below != null && below.task == task) { 7075 final boolean clearWhenTaskReset = 7076 (target.intent.getFlags() 7077 &Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0; 7078 if (!finishOnTaskLaunch && !clearWhenTaskReset && target.resultTo != null) { 7079 // If this activity is sending a reply to a previous 7080 // activity, we can't do anything with it now until 7081 // we reach the start of the reply chain. 7082 // XXX note that we are assuming the result is always 7083 // to the previous activity, which is almost always 7084 // the case but we really shouldn't count on. 7085 if (replyChainEnd < 0) { 7086 replyChainEnd = targetI; 7087 } 7088 } else if (!finishOnTaskLaunch && !clearWhenTaskReset && allowTaskReparenting 7089 && target.taskAffinity != null 7090 && !target.taskAffinity.equals(task.affinity)) { 7091 // If this activity has an affinity for another 7092 // task, then we need to move it out of here. We will 7093 // move it as far out of the way as possible, to the 7094 // bottom of the activity stack. This also keeps it 7095 // correctly ordered with any activities we previously 7096 // moved. 7097 HistoryRecord p = (HistoryRecord)mHistory.get(0); 7098 if (target.taskAffinity != null 7099 && target.taskAffinity.equals(p.task.affinity)) { 7100 // If the activity currently at the bottom has the 7101 // same task affinity as the one we are moving, 7102 // then merge it into the same task. 7103 target.task = p.task; 7104 if (DEBUG_TASKS) Slog.v(TAG, "Start pushing activity " + target 7105 + " out to bottom task " + p.task); 7106 } else { 7107 mCurTask++; 7108 if (mCurTask <= 0) { 7109 mCurTask = 1; 7110 } 7111 target.task = new TaskRecord(mCurTask, target.info, null, 7112 (target.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0); 7113 target.task.affinityIntent = target.intent; 7114 if (DEBUG_TASKS) Slog.v(TAG, "Start pushing activity " + target 7115 + " out to new task " + target.task); 7116 } 7117 mWindowManager.setAppGroupId(target, task.taskId); 7118 if (replyChainEnd < 0) { 7119 replyChainEnd = targetI; 7120 } 7121 int dstPos = 0; 7122 for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) { 7123 p = (HistoryRecord)mHistory.get(srcPos); 7124 if (p.finishing) { 7125 continue; 7126 } 7127 if (DEBUG_TASKS) Slog.v(TAG, "Pushing next activity " + p 7128 + " out to target's task " + target.task); 7129 task.numActivities--; 7130 p.task = target.task; 7131 target.task.numActivities++; 7132 mHistory.remove(srcPos); 7133 mHistory.add(dstPos, p); 7134 mWindowManager.moveAppToken(dstPos, p); 7135 mWindowManager.setAppGroupId(p, p.task.taskId); 7136 dstPos++; 7137 if (VALIDATE_TOKENS) { 7138 mWindowManager.validateAppTokens(mHistory); 7139 } 7140 i++; 7141 } 7142 if (taskTop == p) { 7143 taskTop = below; 7144 } 7145 if (taskTopI == replyChainEnd) { 7146 taskTopI = -1; 7147 } 7148 replyChainEnd = -1; 7149 addRecentTaskLocked(target.task); 7150 } else if (forceReset || finishOnTaskLaunch 7151 || clearWhenTaskReset) { 7152 // If the activity should just be removed -- either 7153 // because it asks for it, or the task should be 7154 // cleared -- then finish it and anything that is 7155 // part of its reply chain. 7156 if (clearWhenTaskReset) { 7157 // In this case, we want to finish this activity 7158 // and everything above it, so be sneaky and pretend 7159 // like these are all in the reply chain. 7160 replyChainEnd = targetI+1; 7161 while (replyChainEnd < mHistory.size() && 7162 ((HistoryRecord)mHistory.get( 7163 replyChainEnd)).task == task) { 7164 replyChainEnd++; 7165 } 7166 replyChainEnd--; 7167 } else if (replyChainEnd < 0) { 7168 replyChainEnd = targetI; 7169 } 7170 HistoryRecord p = null; 7171 for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) { 7172 p = (HistoryRecord)mHistory.get(srcPos); 7173 if (p.finishing) { 7174 continue; 7175 } 7176 if (finishActivityLocked(p, srcPos, 7177 Activity.RESULT_CANCELED, null, "reset")) { 7178 replyChainEnd--; 7179 srcPos--; 7180 } 7181 } 7182 if (taskTop == p) { 7183 taskTop = below; 7184 } 7185 if (taskTopI == replyChainEnd) { 7186 taskTopI = -1; 7187 } 7188 replyChainEnd = -1; 7189 } else { 7190 // If we were in the middle of a chain, well the 7191 // activity that started it all doesn't want anything 7192 // special, so leave it all as-is. 7193 replyChainEnd = -1; 7194 } 7195 } else { 7196 // Reached the bottom of the task -- any reply chain 7197 // should be left as-is. 7198 replyChainEnd = -1; 7199 } 7200 7201 } else if (target.resultTo != null) { 7202 // If this activity is sending a reply to a previous 7203 // activity, we can't do anything with it now until 7204 // we reach the start of the reply chain. 7205 // XXX note that we are assuming the result is always 7206 // to the previous activity, which is almost always 7207 // the case but we really shouldn't count on. 7208 if (replyChainEnd < 0) { 7209 replyChainEnd = targetI; 7210 } 7211 7212 } else if (taskTopI >= 0 && allowTaskReparenting 7213 && task.affinity != null 7214 && task.affinity.equals(target.taskAffinity)) { 7215 // We are inside of another task... if this activity has 7216 // an affinity for our task, then either remove it if we are 7217 // clearing or move it over to our task. Note that 7218 // we currently punt on the case where we are resetting a 7219 // task that is not at the top but who has activities above 7220 // with an affinity to it... this is really not a normal 7221 // case, and we will need to later pull that task to the front 7222 // and usually at that point we will do the reset and pick 7223 // up those remaining activities. (This only happens if 7224 // someone starts an activity in a new task from an activity 7225 // in a task that is not currently on top.) 7226 if (forceReset || finishOnTaskLaunch) { 7227 if (replyChainEnd < 0) { 7228 replyChainEnd = targetI; 7229 } 7230 HistoryRecord p = null; 7231 for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) { 7232 p = (HistoryRecord)mHistory.get(srcPos); 7233 if (p.finishing) { 7234 continue; 7235 } 7236 if (finishActivityLocked(p, srcPos, 7237 Activity.RESULT_CANCELED, null, "reset")) { 7238 taskTopI--; 7239 lastReparentPos--; 7240 replyChainEnd--; 7241 srcPos--; 7242 } 7243 } 7244 replyChainEnd = -1; 7245 } else { 7246 if (replyChainEnd < 0) { 7247 replyChainEnd = targetI; 7248 } 7249 for (int srcPos=replyChainEnd; srcPos>=targetI; srcPos--) { 7250 HistoryRecord p = (HistoryRecord)mHistory.get(srcPos); 7251 if (p.finishing) { 7252 continue; 7253 } 7254 if (lastReparentPos < 0) { 7255 lastReparentPos = taskTopI; 7256 taskTop = p; 7257 } else { 7258 lastReparentPos--; 7259 } 7260 mHistory.remove(srcPos); 7261 p.task.numActivities--; 7262 p.task = task; 7263 mHistory.add(lastReparentPos, p); 7264 if (DEBUG_TASKS) Slog.v(TAG, "Pulling activity " + p 7265 + " in to resetting task " + task); 7266 task.numActivities++; 7267 mWindowManager.moveAppToken(lastReparentPos, p); 7268 mWindowManager.setAppGroupId(p, p.task.taskId); 7269 if (VALIDATE_TOKENS) { 7270 mWindowManager.validateAppTokens(mHistory); 7271 } 7272 } 7273 replyChainEnd = -1; 7274 7275 // Now we've moved it in to place... but what if this is 7276 // a singleTop activity and we have put it on top of another 7277 // instance of the same activity? Then we drop the instance 7278 // below so it remains singleTop. 7279 if (target.info.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) { 7280 for (int j=lastReparentPos-1; j>=0; j--) { 7281 HistoryRecord p = (HistoryRecord)mHistory.get(j); 7282 if (p.finishing) { 7283 continue; 7284 } 7285 if (p.intent.getComponent().equals(target.intent.getComponent())) { 7286 if (finishActivityLocked(p, j, 7287 Activity.RESULT_CANCELED, null, "replace")) { 7288 taskTopI--; 7289 lastReparentPos--; 7290 } 7291 } 7292 } 7293 } 7294 } 7295 } 7296 7297 target = below; 7298 targetI = i; 7299 } 7300 7301 return taskTop; 7302 } 7303 7304 /** 7305 * TODO: Add mController hook 7306 */ 7307 public void moveTaskToFront(int task) { 7308 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7309 "moveTaskToFront()"); 7310 7311 synchronized(this) { 7312 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7313 Binder.getCallingUid(), "Task to front")) { 7314 return; 7315 } 7316 final long origId = Binder.clearCallingIdentity(); 7317 try { 7318 int N = mRecentTasks.size(); 7319 for (int i=0; i<N; i++) { 7320 TaskRecord tr = mRecentTasks.get(i); 7321 if (tr.taskId == task) { 7322 moveTaskToFrontLocked(tr, null); 7323 return; 7324 } 7325 } 7326 for (int i=mHistory.size()-1; i>=0; i--) { 7327 HistoryRecord hr = (HistoryRecord)mHistory.get(i); 7328 if (hr.task.taskId == task) { 7329 moveTaskToFrontLocked(hr.task, null); 7330 return; 7331 } 7332 } 7333 } finally { 7334 Binder.restoreCallingIdentity(origId); 7335 } 7336 } 7337 } 7338 7339 private final void moveTaskToFrontLocked(TaskRecord tr, HistoryRecord reason) { 7340 if (DEBUG_SWITCH) Slog.v(TAG, "moveTaskToFront: " + tr); 7341 7342 final int task = tr.taskId; 7343 int top = mHistory.size()-1; 7344 7345 if (top < 0 || ((HistoryRecord)mHistory.get(top)).task.taskId == task) { 7346 // nothing to do! 7347 return; 7348 } 7349 7350 ArrayList moved = new ArrayList(); 7351 7352 // Applying the affinities may have removed entries from the history, 7353 // so get the size again. 7354 top = mHistory.size()-1; 7355 int pos = top; 7356 7357 // Shift all activities with this task up to the top 7358 // of the stack, keeping them in the same internal order. 7359 while (pos >= 0) { 7360 HistoryRecord r = (HistoryRecord)mHistory.get(pos); 7361 if (localLOGV) Slog.v( 7362 TAG, "At " + pos + " ckp " + r.task + ": " + r); 7363 boolean first = true; 7364 if (r.task.taskId == task) { 7365 if (localLOGV) Slog.v(TAG, "Removing and adding at " + top); 7366 mHistory.remove(pos); 7367 mHistory.add(top, r); 7368 moved.add(0, r); 7369 top--; 7370 if (first) { 7371 addRecentTaskLocked(r.task); 7372 first = false; 7373 } 7374 } 7375 pos--; 7376 } 7377 7378 if (DEBUG_TRANSITION) Slog.v(TAG, 7379 "Prepare to front transition: task=" + tr); 7380 if (reason != null && 7381 (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { 7382 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 7383 HistoryRecord r = topRunningActivityLocked(null); 7384 if (r != null) { 7385 mNoAnimActivities.add(r); 7386 } 7387 } else { 7388 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT); 7389 } 7390 7391 mWindowManager.moveAppTokensToTop(moved); 7392 if (VALIDATE_TOKENS) { 7393 mWindowManager.validateAppTokens(mHistory); 7394 } 7395 7396 finishTaskMoveLocked(task); 7397 EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, task); 7398 } 7399 7400 private final void finishTaskMoveLocked(int task) { 7401 resumeTopActivityLocked(null); 7402 } 7403 7404 public void moveTaskToBack(int task) { 7405 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7406 "moveTaskToBack()"); 7407 7408 synchronized(this) { 7409 if (mResumedActivity != null && mResumedActivity.task.taskId == task) { 7410 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7411 Binder.getCallingUid(), "Task to back")) { 7412 return; 7413 } 7414 } 7415 final long origId = Binder.clearCallingIdentity(); 7416 moveTaskToBackLocked(task, null); 7417 Binder.restoreCallingIdentity(origId); 7418 } 7419 } 7420 7421 /** 7422 * Moves an activity, and all of the other activities within the same task, to the bottom 7423 * of the history stack. The activity's order within the task is unchanged. 7424 * 7425 * @param token A reference to the activity we wish to move 7426 * @param nonRoot If false then this only works if the activity is the root 7427 * of a task; if true it will work for any activity in a task. 7428 * @return Returns true if the move completed, false if not. 7429 */ 7430 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7431 synchronized(this) { 7432 final long origId = Binder.clearCallingIdentity(); 7433 int taskId = getTaskForActivityLocked(token, !nonRoot); 7434 if (taskId >= 0) { 7435 return moveTaskToBackLocked(taskId, null); 7436 } 7437 Binder.restoreCallingIdentity(origId); 7438 } 7439 return false; 7440 } 7441 7442 /** 7443 * Worker method for rearranging history stack. Implements the function of moving all 7444 * activities for a specific task (gathering them if disjoint) into a single group at the 7445 * bottom of the stack. 7446 * 7447 * If a watcher is installed, the action is preflighted and the watcher has an opportunity 7448 * to premeptively cancel the move. 7449 * 7450 * @param task The taskId to collect and move to the bottom. 7451 * @return Returns true if the move completed, false if not. 7452 */ 7453 private final boolean moveTaskToBackLocked(int task, HistoryRecord reason) { 7454 Slog.i(TAG, "moveTaskToBack: " + task); 7455 7456 // If we have a watcher, preflight the move before committing to it. First check 7457 // for *other* available tasks, but if none are available, then try again allowing the 7458 // current task to be selected. 7459 if (mController != null) { 7460 HistoryRecord next = topRunningActivityLocked(null, task); 7461 if (next == null) { 7462 next = topRunningActivityLocked(null, 0); 7463 } 7464 if (next != null) { 7465 // ask watcher if this is allowed 7466 boolean moveOK = true; 7467 try { 7468 moveOK = mController.activityResuming(next.packageName); 7469 } catch (RemoteException e) { 7470 mController = null; 7471 } 7472 if (!moveOK) { 7473 return false; 7474 } 7475 } 7476 } 7477 7478 ArrayList moved = new ArrayList(); 7479 7480 if (DEBUG_TRANSITION) Slog.v(TAG, 7481 "Prepare to back transition: task=" + task); 7482 7483 final int N = mHistory.size(); 7484 int bottom = 0; 7485 int pos = 0; 7486 7487 // Shift all activities with this task down to the bottom 7488 // of the stack, keeping them in the same internal order. 7489 while (pos < N) { 7490 HistoryRecord r = (HistoryRecord)mHistory.get(pos); 7491 if (localLOGV) Slog.v( 7492 TAG, "At " + pos + " ckp " + r.task + ": " + r); 7493 if (r.task.taskId == task) { 7494 if (localLOGV) Slog.v(TAG, "Removing and adding at " + (N-1)); 7495 mHistory.remove(pos); 7496 mHistory.add(bottom, r); 7497 moved.add(r); 7498 bottom++; 7499 } 7500 pos++; 7501 } 7502 7503 if (reason != null && 7504 (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { 7505 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE); 7506 HistoryRecord r = topRunningActivityLocked(null); 7507 if (r != null) { 7508 mNoAnimActivities.add(r); 7509 } 7510 } else { 7511 mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_BACK); 7512 } 7513 mWindowManager.moveAppTokensToBottom(moved); 7514 if (VALIDATE_TOKENS) { 7515 mWindowManager.validateAppTokens(mHistory); 7516 } 7517 7518 finishTaskMoveLocked(task); 7519 return true; 7520 } 7521 7522 public void moveTaskBackwards(int task) { 7523 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7524 "moveTaskBackwards()"); 7525 7526 synchronized(this) { 7527 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7528 Binder.getCallingUid(), "Task backwards")) { 7529 return; 7530 } 7531 final long origId = Binder.clearCallingIdentity(); 7532 moveTaskBackwardsLocked(task); 7533 Binder.restoreCallingIdentity(origId); 7534 } 7535 } 7536 7537 private final void moveTaskBackwardsLocked(int task) { 7538 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7539 } 7540 7541 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7542 synchronized(this) { 7543 return getTaskForActivityLocked(token, onlyRoot); 7544 } 7545 } 7546 7547 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { 7548 final int N = mHistory.size(); 7549 TaskRecord lastTask = null; 7550 for (int i=0; i<N; i++) { 7551 HistoryRecord r = (HistoryRecord)mHistory.get(i); 7552 if (r == token) { 7553 if (!onlyRoot || lastTask != r.task) { 7554 return r.task.taskId; 7555 } 7556 return -1; 7557 } 7558 lastTask = r.task; 7559 } 7560 7561 return -1; 7562 } 7563 7564 /** 7565 * Returns the top activity in any existing task matching the given 7566 * Intent. Returns null if no such task is found. 7567 */ 7568 private HistoryRecord findTaskLocked(Intent intent, ActivityInfo info) { 7569 ComponentName cls = intent.getComponent(); 7570 if (info.targetActivity != null) { 7571 cls = new ComponentName(info.packageName, info.targetActivity); 7572 } 7573 7574 TaskRecord cp = null; 7575 7576 final int N = mHistory.size(); 7577 for (int i=(N-1); i>=0; i--) { 7578 HistoryRecord r = (HistoryRecord)mHistory.get(i); 7579 if (!r.finishing && r.task != cp 7580 && r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE) { 7581 cp = r.task; 7582 //Slog.i(TAG, "Comparing existing cls=" + r.task.intent.getComponent().flattenToShortString() 7583 // + "/aff=" + r.task.affinity + " to new cls=" 7584 // + intent.getComponent().flattenToShortString() + "/aff=" + taskAffinity); 7585 if (r.task.affinity != null) { 7586 if (r.task.affinity.equals(info.taskAffinity)) { 7587 //Slog.i(TAG, "Found matching affinity!"); 7588 return r; 7589 } 7590 } else if (r.task.intent != null 7591 && r.task.intent.getComponent().equals(cls)) { 7592 //Slog.i(TAG, "Found matching class!"); 7593 //dump(); 7594 //Slog.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent); 7595 return r; 7596 } else if (r.task.affinityIntent != null 7597 && r.task.affinityIntent.getComponent().equals(cls)) { 7598 //Slog.i(TAG, "Found matching class!"); 7599 //dump(); 7600 //Slog.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent); 7601 return r; 7602 } 7603 } 7604 } 7605 7606 return null; 7607 } 7608 7609 /** 7610 * Returns the first activity (starting from the top of the stack) that 7611 * is the same as the given activity. Returns null if no such activity 7612 * is found. 7613 */ 7614 private HistoryRecord findActivityLocked(Intent intent, ActivityInfo info) { 7615 ComponentName cls = intent.getComponent(); 7616 if (info.targetActivity != null) { 7617 cls = new ComponentName(info.packageName, info.targetActivity); 7618 } 7619 7620 final int N = mHistory.size(); 7621 for (int i=(N-1); i>=0; i--) { 7622 HistoryRecord r = (HistoryRecord)mHistory.get(i); 7623 if (!r.finishing) { 7624 if (r.intent.getComponent().equals(cls)) { 7625 //Slog.i(TAG, "Found matching class!"); 7626 //dump(); 7627 //Slog.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent); 7628 return r; 7629 } 7630 } 7631 } 7632 7633 return null; 7634 } 7635 7636 public void finishOtherInstances(IBinder token, ComponentName className) { 7637 synchronized(this) { 7638 final long origId = Binder.clearCallingIdentity(); 7639 7640 int N = mHistory.size(); 7641 TaskRecord lastTask = null; 7642 for (int i=0; i<N; i++) { 7643 HistoryRecord r = (HistoryRecord)mHistory.get(i); 7644 if (r.realActivity.equals(className) 7645 && r != token && lastTask != r.task) { 7646 if (finishActivityLocked(r, i, Activity.RESULT_CANCELED, 7647 null, "others")) { 7648 i--; 7649 N--; 7650 } 7651 } 7652 lastTask = r.task; 7653 } 7654 7655 Binder.restoreCallingIdentity(origId); 7656 } 7657 } 7658 7659 // ========================================================= 7660 // THUMBNAILS 7661 // ========================================================= 7662 7663 public void reportThumbnail(IBinder token, 7664 Bitmap thumbnail, CharSequence description) { 7665 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7666 final long origId = Binder.clearCallingIdentity(); 7667 sendPendingThumbnail(null, token, thumbnail, description, true); 7668 Binder.restoreCallingIdentity(origId); 7669 } 7670 7671 final void sendPendingThumbnail(HistoryRecord r, IBinder token, 7672 Bitmap thumbnail, CharSequence description, boolean always) { 7673 TaskRecord task = null; 7674 ArrayList receivers = null; 7675 7676 //System.out.println("Send pending thumbnail: " + r); 7677 7678 synchronized(this) { 7679 if (r == null) { 7680 int index = indexOfTokenLocked(token); 7681 if (index < 0) { 7682 return; 7683 } 7684 r = (HistoryRecord)mHistory.get(index); 7685 } 7686 if (thumbnail == null) { 7687 thumbnail = r.thumbnail; 7688 description = r.description; 7689 } 7690 if (thumbnail == null && !always) { 7691 // If there is no thumbnail, and this entry is not actually 7692 // going away, then abort for now and pick up the next 7693 // thumbnail we get. 7694 return; 7695 } 7696 task = r.task; 7697 7698 int N = mPendingThumbnails.size(); 7699 int i=0; 7700 while (i<N) { 7701 PendingThumbnailsRecord pr = 7702 (PendingThumbnailsRecord)mPendingThumbnails.get(i); 7703 //System.out.println("Looking in " + pr.pendingRecords); 7704 if (pr.pendingRecords.remove(r)) { 7705 if (receivers == null) { 7706 receivers = new ArrayList(); 7707 } 7708 receivers.add(pr); 7709 if (pr.pendingRecords.size() == 0) { 7710 pr.finished = true; 7711 mPendingThumbnails.remove(i); 7712 N--; 7713 continue; 7714 } 7715 } 7716 i++; 7717 } 7718 } 7719 7720 if (receivers != null) { 7721 final int N = receivers.size(); 7722 for (int i=0; i<N; i++) { 7723 try { 7724 PendingThumbnailsRecord pr = 7725 (PendingThumbnailsRecord)receivers.get(i); 7726 pr.receiver.newThumbnail( 7727 task != null ? task.taskId : -1, thumbnail, description); 7728 if (pr.finished) { 7729 pr.receiver.finished(); 7730 } 7731 } catch (Exception e) { 7732 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7733 } 7734 } 7735 } 7736 } 7737 7738 // ========================================================= 7739 // CONTENT PROVIDERS 7740 // ========================================================= 7741 7742 private final List generateApplicationProvidersLocked(ProcessRecord app) { 7743 List providers = null; 7744 try { 7745 providers = ActivityThread.getPackageManager(). 7746 queryContentProviders(app.processName, app.info.uid, 7747 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7748 } catch (RemoteException ex) { 7749 } 7750 if (providers != null) { 7751 final int N = providers.size(); 7752 for (int i=0; i<N; i++) { 7753 ProviderInfo cpi = 7754 (ProviderInfo)providers.get(i); 7755 ContentProviderRecord cpr = 7756 (ContentProviderRecord)mProvidersByClass.get(cpi.name); 7757 if (cpr == null) { 7758 cpr = new ContentProviderRecord(cpi, app.info); 7759 mProvidersByClass.put(cpi.name, cpr); 7760 } 7761 app.pubProviders.put(cpi.name, cpr); 7762 app.addPackage(cpi.applicationInfo.packageName); 7763 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7764 } 7765 } 7766 return providers; 7767 } 7768 7769 private final String checkContentProviderPermissionLocked( 7770 ProviderInfo cpi, ProcessRecord r, int mode) { 7771 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7772 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid(); 7773 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7774 cpi.exported ? -1 : cpi.applicationInfo.uid) 7775 == PackageManager.PERMISSION_GRANTED 7776 && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) { 7777 return null; 7778 } 7779 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7780 cpi.exported ? -1 : cpi.applicationInfo.uid) 7781 == PackageManager.PERMISSION_GRANTED) { 7782 return null; 7783 } 7784 7785 PathPermission[] pps = cpi.pathPermissions; 7786 if (pps != null) { 7787 int i = pps.length; 7788 while (i > 0) { 7789 i--; 7790 PathPermission pp = pps[i]; 7791 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7792 cpi.exported ? -1 : cpi.applicationInfo.uid) 7793 == PackageManager.PERMISSION_GRANTED 7794 && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) { 7795 return null; 7796 } 7797 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7798 cpi.exported ? -1 : cpi.applicationInfo.uid) 7799 == PackageManager.PERMISSION_GRANTED) { 7800 return null; 7801 } 7802 } 7803 } 7804 7805 String msg = "Permission Denial: opening provider " + cpi.name 7806 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7807 + ", uid=" + callingUid + ") requires " 7808 + cpi.readPermission + " or " + cpi.writePermission; 7809 Slog.w(TAG, msg); 7810 return msg; 7811 } 7812 7813 private final ContentProviderHolder getContentProviderImpl( 7814 IApplicationThread caller, String name) { 7815 ContentProviderRecord cpr; 7816 ProviderInfo cpi = null; 7817 7818 synchronized(this) { 7819 ProcessRecord r = null; 7820 if (caller != null) { 7821 r = getRecordForAppLocked(caller); 7822 if (r == null) { 7823 throw new SecurityException( 7824 "Unable to find app for caller " + caller 7825 + " (pid=" + Binder.getCallingPid() 7826 + ") when getting content provider " + name); 7827 } 7828 } 7829 7830 // First check if this content provider has been published... 7831 cpr = (ContentProviderRecord)mProvidersByName.get(name); 7832 if (cpr != null) { 7833 cpi = cpr.info; 7834 if (checkContentProviderPermissionLocked(cpi, r, -1) != null) { 7835 return new ContentProviderHolder(cpi, 7836 cpi.readPermission != null 7837 ? cpi.readPermission : cpi.writePermission); 7838 } 7839 7840 if (r != null && cpr.canRunHere(r)) { 7841 // This provider has been published or is in the process 7842 // of being published... but it is also allowed to run 7843 // in the caller's process, so don't make a connection 7844 // and just let the caller instantiate its own instance. 7845 if (cpr.provider != null) { 7846 // don't give caller the provider object, it needs 7847 // to make its own. 7848 cpr = new ContentProviderRecord(cpr); 7849 } 7850 return cpr; 7851 } 7852 7853 final long origId = Binder.clearCallingIdentity(); 7854 7855 // In this case the provider instance already exists, so we can 7856 // return it right away. 7857 if (r != null) { 7858 if (DEBUG_PROVIDER) Slog.v(TAG, 7859 "Adding provider requested by " 7860 + r.processName + " from process " 7861 + cpr.info.processName); 7862 Integer cnt = r.conProviders.get(cpr); 7863 if (cnt == null) { 7864 r.conProviders.put(cpr, new Integer(1)); 7865 } else { 7866 r.conProviders.put(cpr, new Integer(cnt.intValue()+1)); 7867 } 7868 cpr.clients.add(r); 7869 if (cpr.app != null && r.setAdj >= VISIBLE_APP_ADJ) { 7870 // If this is a visible app accessing the provider, 7871 // make sure to count it as being accessed and thus 7872 // back up on the LRU list. This is good because 7873 // content providers are often expensive to start. 7874 updateLruProcessLocked(cpr.app, false, true); 7875 } 7876 } else { 7877 cpr.externals++; 7878 } 7879 7880 if (cpr.app != null) { 7881 updateOomAdjLocked(cpr.app); 7882 } 7883 7884 Binder.restoreCallingIdentity(origId); 7885 7886 } else { 7887 try { 7888 cpi = ActivityThread.getPackageManager(). 7889 resolveContentProvider(name, 7890 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7891 } catch (RemoteException ex) { 7892 } 7893 if (cpi == null) { 7894 return null; 7895 } 7896 7897 if (checkContentProviderPermissionLocked(cpi, r, -1) != null) { 7898 return new ContentProviderHolder(cpi, 7899 cpi.readPermission != null 7900 ? cpi.readPermission : cpi.writePermission); 7901 } 7902 7903 if (!mSystemReady && !mDidUpdate && !mWaitingUpdate 7904 && !cpi.processName.equals("system")) { 7905 // If this content provider does not run in the system 7906 // process, and the system is not yet ready to run other 7907 // processes, then fail fast instead of hanging. 7908 throw new IllegalArgumentException( 7909 "Attempt to launch content provider before system ready"); 7910 } 7911 7912 cpr = (ContentProviderRecord)mProvidersByClass.get(cpi.name); 7913 final boolean firstClass = cpr == null; 7914 if (firstClass) { 7915 try { 7916 ApplicationInfo ai = 7917 ActivityThread.getPackageManager(). 7918 getApplicationInfo( 7919 cpi.applicationInfo.packageName, 7920 STOCK_PM_FLAGS); 7921 if (ai == null) { 7922 Slog.w(TAG, "No package info for content provider " 7923 + cpi.name); 7924 return null; 7925 } 7926 cpr = new ContentProviderRecord(cpi, ai); 7927 } catch (RemoteException ex) { 7928 // pm is in same process, this will never happen. 7929 } 7930 } 7931 7932 if (r != null && cpr.canRunHere(r)) { 7933 // If this is a multiprocess provider, then just return its 7934 // info and allow the caller to instantiate it. Only do 7935 // this if the provider is the same user as the caller's 7936 // process, or can run as root (so can be in any process). 7937 return cpr; 7938 } 7939 7940 if (DEBUG_PROVIDER) { 7941 RuntimeException e = new RuntimeException("here"); 7942 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid 7943 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7944 } 7945 7946 // This is single process, and our app is now connecting to it. 7947 // See if we are already in the process of launching this 7948 // provider. 7949 final int N = mLaunchingProviders.size(); 7950 int i; 7951 for (i=0; i<N; i++) { 7952 if (mLaunchingProviders.get(i) == cpr) { 7953 break; 7954 } 7955 } 7956 7957 // If the provider is not already being launched, then get it 7958 // started. 7959 if (i >= N) { 7960 final long origId = Binder.clearCallingIdentity(); 7961 ProcessRecord proc = startProcessLocked(cpi.processName, 7962 cpr.appInfo, false, 0, "content provider", 7963 new ComponentName(cpi.applicationInfo.packageName, 7964 cpi.name), false); 7965 if (proc == null) { 7966 Slog.w(TAG, "Unable to launch app " 7967 + cpi.applicationInfo.packageName + "/" 7968 + cpi.applicationInfo.uid + " for provider " 7969 + name + ": process is bad"); 7970 return null; 7971 } 7972 cpr.launchingApp = proc; 7973 mLaunchingProviders.add(cpr); 7974 Binder.restoreCallingIdentity(origId); 7975 } 7976 7977 // Make sure the provider is published (the same provider class 7978 // may be published under multiple names). 7979 if (firstClass) { 7980 mProvidersByClass.put(cpi.name, cpr); 7981 } 7982 mProvidersByName.put(name, cpr); 7983 7984 if (r != null) { 7985 if (DEBUG_PROVIDER) Slog.v(TAG, 7986 "Adding provider requested by " 7987 + r.processName + " from process " 7988 + cpr.info.processName); 7989 Integer cnt = r.conProviders.get(cpr); 7990 if (cnt == null) { 7991 r.conProviders.put(cpr, new Integer(1)); 7992 } else { 7993 r.conProviders.put(cpr, new Integer(cnt.intValue()+1)); 7994 } 7995 cpr.clients.add(r); 7996 } else { 7997 cpr.externals++; 7998 } 7999 } 8000 } 8001 8002 // Wait for the provider to be published... 8003 synchronized (cpr) { 8004 while (cpr.provider == null) { 8005 if (cpr.launchingApp == null) { 8006 Slog.w(TAG, "Unable to launch app " 8007 + cpi.applicationInfo.packageName + "/" 8008 + cpi.applicationInfo.uid + " for provider " 8009 + name + ": launching app became null"); 8010 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8011 cpi.applicationInfo.packageName, 8012 cpi.applicationInfo.uid, name); 8013 return null; 8014 } 8015 try { 8016 cpr.wait(); 8017 } catch (InterruptedException ex) { 8018 } 8019 } 8020 } 8021 return cpr; 8022 } 8023 8024 public final ContentProviderHolder getContentProvider( 8025 IApplicationThread caller, String name) { 8026 if (caller == null) { 8027 String msg = "null IApplicationThread when getting content provider " 8028 + name; 8029 Slog.w(TAG, msg); 8030 throw new SecurityException(msg); 8031 } 8032 8033 return getContentProviderImpl(caller, name); 8034 } 8035 8036 private ContentProviderHolder getContentProviderExternal(String name) { 8037 return getContentProviderImpl(null, name); 8038 } 8039 8040 /** 8041 * Drop a content provider from a ProcessRecord's bookkeeping 8042 * @param cpr 8043 */ 8044 public void removeContentProvider(IApplicationThread caller, String name) { 8045 synchronized (this) { 8046 ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name); 8047 if(cpr == null) { 8048 // remove from mProvidersByClass 8049 if (DEBUG_PROVIDER) Slog.v(TAG, name + 8050 " provider not found in providers list"); 8051 return; 8052 } 8053 final ProcessRecord r = getRecordForAppLocked(caller); 8054 if (r == null) { 8055 throw new SecurityException( 8056 "Unable to find app for caller " + caller + 8057 " when removing content provider " + name); 8058 } 8059 //update content provider record entry info 8060 ContentProviderRecord localCpr = (ContentProviderRecord) 8061 mProvidersByClass.get(cpr.info.name); 8062 if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by " 8063 + r.info.processName + " from process " 8064 + localCpr.appInfo.processName); 8065 if (localCpr.app == r) { 8066 //should not happen. taken care of as a local provider 8067 Slog.w(TAG, "removeContentProvider called on local provider: " 8068 + cpr.info.name + " in process " + r.processName); 8069 return; 8070 } else { 8071 Integer cnt = r.conProviders.get(localCpr); 8072 if (cnt == null || cnt.intValue() <= 1) { 8073 localCpr.clients.remove(r); 8074 r.conProviders.remove(localCpr); 8075 } else { 8076 r.conProviders.put(localCpr, new Integer(cnt.intValue()-1)); 8077 } 8078 } 8079 updateOomAdjLocked(); 8080 } 8081 } 8082 8083 private void removeContentProviderExternal(String name) { 8084 synchronized (this) { 8085 ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name); 8086 if(cpr == null) { 8087 //remove from mProvidersByClass 8088 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8089 return; 8090 } 8091 8092 //update content provider record entry info 8093 ContentProviderRecord localCpr = (ContentProviderRecord) mProvidersByClass.get(cpr.info.name); 8094 localCpr.externals--; 8095 if (localCpr.externals < 0) { 8096 Slog.e(TAG, "Externals < 0 for content provider " + localCpr); 8097 } 8098 updateOomAdjLocked(); 8099 } 8100 } 8101 8102 public final void publishContentProviders(IApplicationThread caller, 8103 List<ContentProviderHolder> providers) { 8104 if (providers == null) { 8105 return; 8106 } 8107 8108 synchronized(this) { 8109 final ProcessRecord r = getRecordForAppLocked(caller); 8110 if (r == null) { 8111 throw new SecurityException( 8112 "Unable to find app for caller " + caller 8113 + " (pid=" + Binder.getCallingPid() 8114 + ") when publishing content providers"); 8115 } 8116 8117 final long origId = Binder.clearCallingIdentity(); 8118 8119 final int N = providers.size(); 8120 for (int i=0; i<N; i++) { 8121 ContentProviderHolder src = providers.get(i); 8122 if (src == null || src.info == null || src.provider == null) { 8123 continue; 8124 } 8125 ContentProviderRecord dst = 8126 (ContentProviderRecord)r.pubProviders.get(src.info.name); 8127 if (dst != null) { 8128 mProvidersByClass.put(dst.info.name, dst); 8129 String names[] = dst.info.authority.split(";"); 8130 for (int j = 0; j < names.length; j++) { 8131 mProvidersByName.put(names[j], dst); 8132 } 8133 8134 int NL = mLaunchingProviders.size(); 8135 int j; 8136 for (j=0; j<NL; j++) { 8137 if (mLaunchingProviders.get(j) == dst) { 8138 mLaunchingProviders.remove(j); 8139 j--; 8140 NL--; 8141 } 8142 } 8143 synchronized (dst) { 8144 dst.provider = src.provider; 8145 dst.app = r; 8146 dst.notifyAll(); 8147 } 8148 updateOomAdjLocked(r); 8149 } 8150 } 8151 8152 Binder.restoreCallingIdentity(origId); 8153 } 8154 } 8155 8156 public static final void installSystemProviders() { 8157 List providers; 8158 synchronized (mSelf) { 8159 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID); 8160 providers = mSelf.generateApplicationProvidersLocked(app); 8161 if (providers != null) { 8162 for (int i=providers.size()-1; i>=0; i--) { 8163 ProviderInfo pi = (ProviderInfo)providers.get(i); 8164 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8165 Slog.w(TAG, "Not installing system proc provider " + pi.name 8166 + ": not system .apk"); 8167 providers.remove(i); 8168 } 8169 } 8170 } 8171 } 8172 if (providers != null) { 8173 mSystemThread.installSystemProviders(providers); 8174 } 8175 } 8176 8177 // ========================================================= 8178 // GLOBAL MANAGEMENT 8179 // ========================================================= 8180 8181 final ProcessRecord newProcessRecordLocked(IApplicationThread thread, 8182 ApplicationInfo info, String customProcess) { 8183 String proc = customProcess != null ? customProcess : info.processName; 8184 BatteryStatsImpl.Uid.Proc ps = null; 8185 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8186 synchronized (stats) { 8187 ps = stats.getProcessStatsLocked(info.uid, proc); 8188 } 8189 return new ProcessRecord(ps, thread, info, proc); 8190 } 8191 8192 final ProcessRecord addAppLocked(ApplicationInfo info) { 8193 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid); 8194 8195 if (app == null) { 8196 app = newProcessRecordLocked(null, info, null); 8197 mProcessNames.put(info.processName, info.uid, app); 8198 updateLruProcessLocked(app, true, true); 8199 } 8200 8201 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8202 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8203 app.persistent = true; 8204 app.maxAdj = CORE_SERVER_ADJ; 8205 } 8206 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8207 mPersistentStartingProcesses.add(app); 8208 startProcessLocked(app, "added application", app.processName); 8209 } 8210 8211 return app; 8212 } 8213 8214 public void unhandledBack() { 8215 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8216 "unhandledBack()"); 8217 8218 synchronized(this) { 8219 int count = mHistory.size(); 8220 if (DEBUG_SWITCH) Slog.d( 8221 TAG, "Performing unhandledBack(): stack size = " + count); 8222 if (count > 1) { 8223 final long origId = Binder.clearCallingIdentity(); 8224 finishActivityLocked((HistoryRecord)mHistory.get(count-1), 8225 count-1, Activity.RESULT_CANCELED, null, "unhandled-back"); 8226 Binder.restoreCallingIdentity(origId); 8227 } 8228 } 8229 } 8230 8231 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8232 String name = uri.getAuthority(); 8233 ContentProviderHolder cph = getContentProviderExternal(name); 8234 ParcelFileDescriptor pfd = null; 8235 if (cph != null) { 8236 // We record the binder invoker's uid in thread-local storage before 8237 // going to the content provider to open the file. Later, in the code 8238 // that handles all permissions checks, we look for this uid and use 8239 // that rather than the Activity Manager's own uid. The effect is that 8240 // we do the check against the caller's permissions even though it looks 8241 // to the content provider like the Activity Manager itself is making 8242 // the request. 8243 sCallerIdentity.set(new Identity( 8244 Binder.getCallingPid(), Binder.getCallingUid())); 8245 try { 8246 pfd = cph.provider.openFile(uri, "r"); 8247 } catch (FileNotFoundException e) { 8248 // do nothing; pfd will be returned null 8249 } finally { 8250 // Ensure that whatever happens, we clean up the identity state 8251 sCallerIdentity.remove(); 8252 } 8253 8254 // We've got the fd now, so we're done with the provider. 8255 removeContentProviderExternal(name); 8256 } else { 8257 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8258 } 8259 return pfd; 8260 } 8261 8262 public void goingToSleep() { 8263 synchronized(this) { 8264 mSleeping = true; 8265 mWindowManager.setEventDispatching(false); 8266 8267 if (mResumedActivity != null) { 8268 pauseIfSleepingLocked(); 8269 } else { 8270 Slog.w(TAG, "goingToSleep with no resumed activity!"); 8271 } 8272 } 8273 } 8274 8275 public boolean shutdown(int timeout) { 8276 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8277 != PackageManager.PERMISSION_GRANTED) { 8278 throw new SecurityException("Requires permission " 8279 + android.Manifest.permission.SHUTDOWN); 8280 } 8281 8282 boolean timedout = false; 8283 8284 synchronized(this) { 8285 mShuttingDown = true; 8286 mWindowManager.setEventDispatching(false); 8287 8288 if (mResumedActivity != null) { 8289 pauseIfSleepingLocked(); 8290 final long endTime = System.currentTimeMillis() + timeout; 8291 while (mResumedActivity != null || mPausingActivity != null) { 8292 long delay = endTime - System.currentTimeMillis(); 8293 if (delay <= 0) { 8294 Slog.w(TAG, "Activity manager shutdown timed out"); 8295 timedout = true; 8296 break; 8297 } 8298 try { 8299 this.wait(); 8300 } catch (InterruptedException e) { 8301 } 8302 } 8303 } 8304 } 8305 8306 mUsageStatsService.shutdown(); 8307 mBatteryStatsService.shutdown(); 8308 8309 return timedout; 8310 } 8311 8312 void pauseIfSleepingLocked() { 8313 if (mSleeping || mShuttingDown) { 8314 if (!mGoingToSleep.isHeld()) { 8315 mGoingToSleep.acquire(); 8316 if (mLaunchingActivity.isHeld()) { 8317 mLaunchingActivity.release(); 8318 mHandler.removeMessages(LAUNCH_TIMEOUT_MSG); 8319 } 8320 } 8321 8322 // If we are not currently pausing an activity, get the current 8323 // one to pause. If we are pausing one, we will just let that stuff 8324 // run and release the wake lock when all done. 8325 if (mPausingActivity == null) { 8326 if (DEBUG_PAUSE) Slog.v(TAG, "Sleep needs to pause..."); 8327 if (DEBUG_USER_LEAVING) Slog.v(TAG, "Sleep => pause with userLeaving=false"); 8328 startPausingLocked(false, true); 8329 } 8330 } 8331 } 8332 8333 public void wakingUp() { 8334 synchronized(this) { 8335 if (mGoingToSleep.isHeld()) { 8336 mGoingToSleep.release(); 8337 } 8338 mWindowManager.setEventDispatching(true); 8339 mSleeping = false; 8340 resumeTopActivityLocked(null); 8341 } 8342 } 8343 8344 public void stopAppSwitches() { 8345 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8346 != PackageManager.PERMISSION_GRANTED) { 8347 throw new SecurityException("Requires permission " 8348 + android.Manifest.permission.STOP_APP_SWITCHES); 8349 } 8350 8351 synchronized(this) { 8352 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8353 + APP_SWITCH_DELAY_TIME; 8354 mDidAppSwitch = false; 8355 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8356 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8357 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8358 } 8359 } 8360 8361 public void resumeAppSwitches() { 8362 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8363 != PackageManager.PERMISSION_GRANTED) { 8364 throw new SecurityException("Requires permission " 8365 + android.Manifest.permission.STOP_APP_SWITCHES); 8366 } 8367 8368 synchronized(this) { 8369 // Note that we don't execute any pending app switches... we will 8370 // let those wait until either the timeout, or the next start 8371 // activity request. 8372 mAppSwitchesAllowedTime = 0; 8373 } 8374 } 8375 8376 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8377 String name) { 8378 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8379 return true; 8380 } 8381 8382 final int perm = checkComponentPermission( 8383 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8384 callingUid, -1); 8385 if (perm == PackageManager.PERMISSION_GRANTED) { 8386 return true; 8387 } 8388 8389 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8390 return false; 8391 } 8392 8393 public void setDebugApp(String packageName, boolean waitForDebugger, 8394 boolean persistent) { 8395 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8396 "setDebugApp()"); 8397 8398 // Note that this is not really thread safe if there are multiple 8399 // callers into it at the same time, but that's not a situation we 8400 // care about. 8401 if (persistent) { 8402 final ContentResolver resolver = mContext.getContentResolver(); 8403 Settings.System.putString( 8404 resolver, Settings.System.DEBUG_APP, 8405 packageName); 8406 Settings.System.putInt( 8407 resolver, Settings.System.WAIT_FOR_DEBUGGER, 8408 waitForDebugger ? 1 : 0); 8409 } 8410 8411 synchronized (this) { 8412 if (!persistent) { 8413 mOrigDebugApp = mDebugApp; 8414 mOrigWaitForDebugger = mWaitForDebugger; 8415 } 8416 mDebugApp = packageName; 8417 mWaitForDebugger = waitForDebugger; 8418 mDebugTransient = !persistent; 8419 if (packageName != null) { 8420 final long origId = Binder.clearCallingIdentity(); 8421 forceStopPackageLocked(packageName, -1, false, false, true); 8422 Binder.restoreCallingIdentity(origId); 8423 } 8424 } 8425 } 8426 8427 public void setAlwaysFinish(boolean enabled) { 8428 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8429 "setAlwaysFinish()"); 8430 8431 Settings.System.putInt( 8432 mContext.getContentResolver(), 8433 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8434 8435 synchronized (this) { 8436 mAlwaysFinishActivities = enabled; 8437 } 8438 } 8439 8440 public void setActivityController(IActivityController controller) { 8441 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8442 "setActivityController()"); 8443 synchronized (this) { 8444 mController = controller; 8445 } 8446 } 8447 8448 public boolean isUserAMonkey() { 8449 // For now the fact that there is a controller implies 8450 // we have a monkey. 8451 synchronized (this) { 8452 return mController != null; 8453 } 8454 } 8455 8456 public void registerActivityWatcher(IActivityWatcher watcher) { 8457 synchronized (this) { 8458 mWatchers.register(watcher); 8459 } 8460 } 8461 8462 public void unregisterActivityWatcher(IActivityWatcher watcher) { 8463 synchronized (this) { 8464 mWatchers.unregister(watcher); 8465 } 8466 } 8467 8468 public final void enterSafeMode() { 8469 synchronized(this) { 8470 // It only makes sense to do this before the system is ready 8471 // and started launching other packages. 8472 if (!mSystemReady) { 8473 try { 8474 ActivityThread.getPackageManager().enterSafeMode(); 8475 } catch (RemoteException e) { 8476 } 8477 8478 View v = LayoutInflater.from(mContext).inflate( 8479 com.android.internal.R.layout.safe_mode, null); 8480 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8481 lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; 8482 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8483 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8484 lp.gravity = Gravity.BOTTOM | Gravity.LEFT; 8485 lp.format = v.getBackground().getOpacity(); 8486 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8487 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8488 ((WindowManager)mContext.getSystemService( 8489 Context.WINDOW_SERVICE)).addView(v, lp); 8490 } 8491 } 8492 } 8493 8494 public void noteWakeupAlarm(IIntentSender sender) { 8495 if (!(sender instanceof PendingIntentRecord)) { 8496 return; 8497 } 8498 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8499 synchronized (stats) { 8500 if (mBatteryStatsService.isOnBattery()) { 8501 mBatteryStatsService.enforceCallingPermission(); 8502 PendingIntentRecord rec = (PendingIntentRecord)sender; 8503 int MY_UID = Binder.getCallingUid(); 8504 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8505 BatteryStatsImpl.Uid.Pkg pkg = 8506 stats.getPackageStatsLocked(uid, rec.key.packageName); 8507 pkg.incWakeupsLocked(); 8508 } 8509 } 8510 } 8511 8512 public boolean killPids(int[] pids, String pReason) { 8513 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8514 throw new SecurityException("killPids only available to the system"); 8515 } 8516 String reason = (pReason == null) ? "Unknown" : pReason; 8517 // XXX Note: don't acquire main activity lock here, because the window 8518 // manager calls in with its locks held. 8519 8520 boolean killed = false; 8521 synchronized (mPidsSelfLocked) { 8522 int[] types = new int[pids.length]; 8523 int worstType = 0; 8524 for (int i=0; i<pids.length; i++) { 8525 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8526 if (proc != null) { 8527 int type = proc.setAdj; 8528 types[i] = type; 8529 if (type > worstType) { 8530 worstType = type; 8531 } 8532 } 8533 } 8534 8535 // If the worse oom_adj is somewhere in the hidden proc LRU range, 8536 // then constrain it so we will kill all hidden procs. 8537 if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) { 8538 worstType = HIDDEN_APP_MIN_ADJ; 8539 } 8540 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8541 for (int i=0; i<pids.length; i++) { 8542 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8543 if (proc == null) { 8544 continue; 8545 } 8546 int adj = proc.setAdj; 8547 if (adj >= worstType && !proc.killedBackground) { 8548 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); 8549 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid, 8550 proc.processName, adj, reason); 8551 killed = true; 8552 proc.killedBackground = true; 8553 Process.killProcessQuiet(pids[i]); 8554 } 8555 } 8556 } 8557 return killed; 8558 } 8559 8560 public void reportPss(IApplicationThread caller, int pss) { 8561 Watchdog.PssRequestor req; 8562 String name; 8563 ProcessRecord callerApp; 8564 synchronized (this) { 8565 if (caller == null) { 8566 return; 8567 } 8568 callerApp = getRecordForAppLocked(caller); 8569 if (callerApp == null) { 8570 return; 8571 } 8572 callerApp.lastPss = pss; 8573 req = callerApp; 8574 name = callerApp.processName; 8575 } 8576 Watchdog.getInstance().reportPss(req, name, pss); 8577 if (!callerApp.persistent) { 8578 removeRequestedPss(callerApp); 8579 } 8580 } 8581 8582 public void requestPss(Runnable completeCallback) { 8583 ArrayList<ProcessRecord> procs; 8584 synchronized (this) { 8585 mRequestPssCallback = completeCallback; 8586 mRequestPssList.clear(); 8587 for (int i=mLruProcesses.size()-1; i>=0; i--) { 8588 ProcessRecord proc = mLruProcesses.get(i); 8589 if (!proc.persistent) { 8590 mRequestPssList.add(proc); 8591 } 8592 } 8593 procs = new ArrayList<ProcessRecord>(mRequestPssList); 8594 } 8595 8596 int oldPri = Process.getThreadPriority(Process.myTid()); 8597 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 8598 for (int i=procs.size()-1; i>=0; i--) { 8599 ProcessRecord proc = procs.get(i); 8600 proc.lastPss = 0; 8601 proc.requestPss(); 8602 } 8603 Process.setThreadPriority(oldPri); 8604 } 8605 8606 void removeRequestedPss(ProcessRecord proc) { 8607 Runnable callback = null; 8608 synchronized (this) { 8609 if (mRequestPssList.remove(proc)) { 8610 if (mRequestPssList.size() == 0) { 8611 callback = mRequestPssCallback; 8612 mRequestPssCallback = null; 8613 } 8614 } 8615 } 8616 8617 if (callback != null) { 8618 callback.run(); 8619 } 8620 } 8621 8622 public void collectPss(Watchdog.PssStats stats) { 8623 stats.mEmptyPss = 0; 8624 stats.mEmptyCount = 0; 8625 stats.mBackgroundPss = 0; 8626 stats.mBackgroundCount = 0; 8627 stats.mServicePss = 0; 8628 stats.mServiceCount = 0; 8629 stats.mVisiblePss = 0; 8630 stats.mVisibleCount = 0; 8631 stats.mForegroundPss = 0; 8632 stats.mForegroundCount = 0; 8633 stats.mNoPssCount = 0; 8634 synchronized (this) { 8635 int i; 8636 int NPD = mProcDeaths.length < stats.mProcDeaths.length 8637 ? mProcDeaths.length : stats.mProcDeaths.length; 8638 int aggr = 0; 8639 for (i=0; i<NPD; i++) { 8640 aggr += mProcDeaths[i]; 8641 stats.mProcDeaths[i] = aggr; 8642 } 8643 while (i<stats.mProcDeaths.length) { 8644 stats.mProcDeaths[i] = 0; 8645 i++; 8646 } 8647 8648 for (i=mLruProcesses.size()-1; i>=0; i--) { 8649 ProcessRecord proc = mLruProcesses.get(i); 8650 if (proc.persistent) { 8651 continue; 8652 } 8653 //Slog.i(TAG, "Proc " + proc + ": pss=" + proc.lastPss); 8654 if (proc.lastPss == 0) { 8655 stats.mNoPssCount++; 8656 continue; 8657 } 8658 if (proc.setAdj >= HIDDEN_APP_MIN_ADJ) { 8659 if (proc.empty) { 8660 stats.mEmptyPss += proc.lastPss; 8661 stats.mEmptyCount++; 8662 } else { 8663 stats.mBackgroundPss += proc.lastPss; 8664 stats.mBackgroundCount++; 8665 } 8666 } else if (proc.setAdj >= VISIBLE_APP_ADJ) { 8667 stats.mVisiblePss += proc.lastPss; 8668 stats.mVisibleCount++; 8669 } else { 8670 stats.mForegroundPss += proc.lastPss; 8671 stats.mForegroundCount++; 8672 } 8673 } 8674 } 8675 } 8676 8677 public final void startRunning(String pkg, String cls, String action, 8678 String data) { 8679 synchronized(this) { 8680 if (mStartRunning) { 8681 return; 8682 } 8683 mStartRunning = true; 8684 mTopComponent = pkg != null && cls != null 8685 ? new ComponentName(pkg, cls) : null; 8686 mTopAction = action != null ? action : Intent.ACTION_MAIN; 8687 mTopData = data; 8688 if (!mSystemReady) { 8689 return; 8690 } 8691 } 8692 8693 systemReady(null); 8694 } 8695 8696 private void retrieveSettings() { 8697 final ContentResolver resolver = mContext.getContentResolver(); 8698 String debugApp = Settings.System.getString( 8699 resolver, Settings.System.DEBUG_APP); 8700 boolean waitForDebugger = Settings.System.getInt( 8701 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 8702 boolean alwaysFinishActivities = Settings.System.getInt( 8703 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 8704 8705 Configuration configuration = new Configuration(); 8706 Settings.System.getConfiguration(resolver, configuration); 8707 8708 synchronized (this) { 8709 mDebugApp = mOrigDebugApp = debugApp; 8710 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 8711 mAlwaysFinishActivities = alwaysFinishActivities; 8712 // This happens before any activities are started, so we can 8713 // change mConfiguration in-place. 8714 mConfiguration.updateFrom(configuration); 8715 mConfigurationSeq = mConfiguration.seq = 1; 8716 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 8717 } 8718 } 8719 8720 public boolean testIsSystemReady() { 8721 // no need to synchronize(this) just to read & return the value 8722 return mSystemReady; 8723 } 8724 8725 public void systemReady(final Runnable goingCallback) { 8726 // In the simulator, startRunning will never have been called, which 8727 // normally sets a few crucial variables. Do it here instead. 8728 if (!Process.supportsProcesses()) { 8729 mStartRunning = true; 8730 mTopAction = Intent.ACTION_MAIN; 8731 } 8732 8733 synchronized(this) { 8734 if (mSystemReady) { 8735 if (goingCallback != null) goingCallback.run(); 8736 return; 8737 } 8738 8739 // Check to see if there are any update receivers to run. 8740 if (!mDidUpdate) { 8741 if (mWaitingUpdate) { 8742 return; 8743 } 8744 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 8745 List<ResolveInfo> ris = null; 8746 try { 8747 ris = ActivityThread.getPackageManager().queryIntentReceivers( 8748 intent, null, 0); 8749 } catch (RemoteException e) { 8750 } 8751 if (ris != null) { 8752 for (int i=ris.size()-1; i>=0; i--) { 8753 if ((ris.get(i).activityInfo.applicationInfo.flags 8754 &ApplicationInfo.FLAG_SYSTEM) == 0) { 8755 ris.remove(i); 8756 } 8757 } 8758 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 8759 for (int i=0; i<ris.size(); i++) { 8760 ActivityInfo ai = ris.get(i).activityInfo; 8761 intent.setComponent(new ComponentName(ai.packageName, ai.name)); 8762 IIntentReceiver finisher = null; 8763 if (i == ris.size()-1) { 8764 finisher = new IIntentReceiver.Stub() { 8765 public void performReceive(Intent intent, int resultCode, 8766 String data, Bundle extras, boolean ordered, 8767 boolean sticky) 8768 throws RemoteException { 8769 synchronized (ActivityManagerService.this) { 8770 mDidUpdate = true; 8771 } 8772 systemReady(goingCallback); 8773 } 8774 }; 8775 } 8776 Slog.i(TAG, "Sending system update to: " + intent.getComponent()); 8777 broadcastIntentLocked(null, null, intent, null, finisher, 8778 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID); 8779 if (finisher != null) { 8780 mWaitingUpdate = true; 8781 } 8782 } 8783 } 8784 if (mWaitingUpdate) { 8785 return; 8786 } 8787 mDidUpdate = true; 8788 } 8789 8790 mSystemReady = true; 8791 if (!mStartRunning) { 8792 return; 8793 } 8794 } 8795 8796 ArrayList<ProcessRecord> procsToKill = null; 8797 synchronized(mPidsSelfLocked) { 8798 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 8799 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 8800 if (!isAllowedWhileBooting(proc.info)){ 8801 if (procsToKill == null) { 8802 procsToKill = new ArrayList<ProcessRecord>(); 8803 } 8804 procsToKill.add(proc); 8805 } 8806 } 8807 } 8808 8809 if (procsToKill != null) { 8810 synchronized(this) { 8811 for (int i=procsToKill.size()-1; i>=0; i--) { 8812 ProcessRecord proc = procsToKill.get(i); 8813 Slog.i(TAG, "Removing system update proc: " + proc); 8814 removeProcessLocked(proc, true); 8815 } 8816 } 8817 } 8818 8819 Slog.i(TAG, "System now ready"); 8820 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 8821 SystemClock.uptimeMillis()); 8822 8823 synchronized(this) { 8824 // Make sure we have no pre-ready processes sitting around. 8825 8826 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { 8827 ResolveInfo ri = mContext.getPackageManager() 8828 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 8829 STOCK_PM_FLAGS); 8830 CharSequence errorMsg = null; 8831 if (ri != null) { 8832 ActivityInfo ai = ri.activityInfo; 8833 ApplicationInfo app = ai.applicationInfo; 8834 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 8835 mTopAction = Intent.ACTION_FACTORY_TEST; 8836 mTopData = null; 8837 mTopComponent = new ComponentName(app.packageName, 8838 ai.name); 8839 } else { 8840 errorMsg = mContext.getResources().getText( 8841 com.android.internal.R.string.factorytest_not_system); 8842 } 8843 } else { 8844 errorMsg = mContext.getResources().getText( 8845 com.android.internal.R.string.factorytest_no_action); 8846 } 8847 if (errorMsg != null) { 8848 mTopAction = null; 8849 mTopData = null; 8850 mTopComponent = null; 8851 Message msg = Message.obtain(); 8852 msg.what = SHOW_FACTORY_ERROR_MSG; 8853 msg.getData().putCharSequence("msg", errorMsg); 8854 mHandler.sendMessage(msg); 8855 } 8856 } 8857 } 8858 8859 retrieveSettings(); 8860 8861 if (goingCallback != null) goingCallback.run(); 8862 8863 synchronized (this) { 8864 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { 8865 try { 8866 List apps = ActivityThread.getPackageManager(). 8867 getPersistentApplications(STOCK_PM_FLAGS); 8868 if (apps != null) { 8869 int N = apps.size(); 8870 int i; 8871 for (i=0; i<N; i++) { 8872 ApplicationInfo info 8873 = (ApplicationInfo)apps.get(i); 8874 if (info != null && 8875 !info.packageName.equals("android")) { 8876 addAppLocked(info); 8877 } 8878 } 8879 } 8880 } catch (RemoteException ex) { 8881 // pm is in same process, this will never happen. 8882 } 8883 } 8884 8885 // Start up initial activity. 8886 mBooting = true; 8887 8888 try { 8889 if (ActivityThread.getPackageManager().hasSystemUidErrors()) { 8890 Message msg = Message.obtain(); 8891 msg.what = SHOW_UID_ERROR_MSG; 8892 mHandler.sendMessage(msg); 8893 } 8894 } catch (RemoteException e) { 8895 } 8896 8897 resumeTopActivityLocked(null); 8898 } 8899 } 8900 8901 private boolean makeAppCrashingLocked(ProcessRecord app, 8902 String shortMsg, String longMsg, String stackTrace) { 8903 app.crashing = true; 8904 app.crashingReport = generateProcessError(app, 8905 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 8906 startAppProblemLocked(app); 8907 app.stopFreezingAllLocked(); 8908 return handleAppCrashLocked(app); 8909 } 8910 8911 private void makeAppNotRespondingLocked(ProcessRecord app, 8912 String activity, String shortMsg, String longMsg) { 8913 app.notResponding = true; 8914 app.notRespondingReport = generateProcessError(app, 8915 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 8916 activity, shortMsg, longMsg, null); 8917 startAppProblemLocked(app); 8918 app.stopFreezingAllLocked(); 8919 } 8920 8921 /** 8922 * Generate a process error record, suitable for attachment to a ProcessRecord. 8923 * 8924 * @param app The ProcessRecord in which the error occurred. 8925 * @param condition Crashing, Application Not Responding, etc. Values are defined in 8926 * ActivityManager.AppErrorStateInfo 8927 * @param activity The activity associated with the crash, if known. 8928 * @param shortMsg Short message describing the crash. 8929 * @param longMsg Long message describing the crash. 8930 * @param stackTrace Full crash stack trace, may be null. 8931 * 8932 * @return Returns a fully-formed AppErrorStateInfo record. 8933 */ 8934 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 8935 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 8936 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 8937 8938 report.condition = condition; 8939 report.processName = app.processName; 8940 report.pid = app.pid; 8941 report.uid = app.info.uid; 8942 report.tag = activity; 8943 report.shortMsg = shortMsg; 8944 report.longMsg = longMsg; 8945 report.stackTrace = stackTrace; 8946 8947 return report; 8948 } 8949 8950 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 8951 synchronized (this) { 8952 app.crashing = false; 8953 app.crashingReport = null; 8954 app.notResponding = false; 8955 app.notRespondingReport = null; 8956 if (app.anrDialog == fromDialog) { 8957 app.anrDialog = null; 8958 } 8959 if (app.waitDialog == fromDialog) { 8960 app.waitDialog = null; 8961 } 8962 if (app.pid > 0 && app.pid != MY_PID) { 8963 handleAppCrashLocked(app); 8964 Slog.i(ActivityManagerService.TAG, "Killing " 8965 + app.processName + " (pid=" + app.pid + "): user's request"); 8966 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid, 8967 app.processName, app.setAdj, "user's request after error"); 8968 Process.killProcess(app.pid); 8969 } 8970 } 8971 } 8972 8973 private boolean handleAppCrashLocked(ProcessRecord app) { 8974 long now = SystemClock.uptimeMillis(); 8975 8976 Long crashTime = mProcessCrashTimes.get(app.info.processName, 8977 app.info.uid); 8978 if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) { 8979 // This process loses! 8980 Slog.w(TAG, "Process " + app.info.processName 8981 + " has crashed too many times: killing!"); 8982 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 8983 app.info.processName, app.info.uid); 8984 killServicesLocked(app, false); 8985 for (int i=mHistory.size()-1; i>=0; i--) { 8986 HistoryRecord r = (HistoryRecord)mHistory.get(i); 8987 if (r.app == app) { 8988 Slog.w(TAG, " Force finishing activity " 8989 + r.intent.getComponent().flattenToShortString()); 8990 finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed"); 8991 } 8992 } 8993 if (!app.persistent) { 8994 // We don't want to start this process again until the user 8995 // explicitly does so... but for persistent process, we really 8996 // need to keep it running. If a persistent process is actually 8997 // repeatedly crashing, then badness for everyone. 8998 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid, 8999 app.info.processName); 9000 mBadProcesses.put(app.info.processName, app.info.uid, now); 9001 app.bad = true; 9002 mProcessCrashTimes.remove(app.info.processName, app.info.uid); 9003 app.removed = true; 9004 removeProcessLocked(app, false); 9005 return false; 9006 } 9007 } else { 9008 HistoryRecord r = topRunningActivityLocked(null); 9009 if (r.app == app) { 9010 // If the top running activity is from this crashing 9011 // process, then terminate it to avoid getting in a loop. 9012 Slog.w(TAG, " Force finishing activity " 9013 + r.intent.getComponent().flattenToShortString()); 9014 int index = indexOfTokenLocked(r); 9015 finishActivityLocked(r, index, 9016 Activity.RESULT_CANCELED, null, "crashed"); 9017 // Also terminate an activities below it that aren't yet 9018 // stopped, to avoid a situation where one will get 9019 // re-start our crashing activity once it gets resumed again. 9020 index--; 9021 if (index >= 0) { 9022 r = (HistoryRecord)mHistory.get(index); 9023 if (r.state == ActivityState.RESUMED 9024 || r.state == ActivityState.PAUSING 9025 || r.state == ActivityState.PAUSED) { 9026 if (!r.isHomeActivity) { 9027 Slog.w(TAG, " Force finishing activity " 9028 + r.intent.getComponent().flattenToShortString()); 9029 finishActivityLocked(r, index, 9030 Activity.RESULT_CANCELED, null, "crashed"); 9031 } 9032 } 9033 } 9034 } 9035 } 9036 9037 // Bump up the crash count of any services currently running in the proc. 9038 if (app.services.size() != 0) { 9039 // Any services running in the application need to be placed 9040 // back in the pending list. 9041 Iterator it = app.services.iterator(); 9042 while (it.hasNext()) { 9043 ServiceRecord sr = (ServiceRecord)it.next(); 9044 sr.crashCount++; 9045 } 9046 } 9047 9048 mProcessCrashTimes.put(app.info.processName, app.info.uid, now); 9049 return true; 9050 } 9051 9052 void startAppProblemLocked(ProcessRecord app) { 9053 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9054 mContext, app.info.packageName, app.info.flags); 9055 skipCurrentReceiverLocked(app); 9056 } 9057 9058 void skipCurrentReceiverLocked(ProcessRecord app) { 9059 boolean reschedule = false; 9060 BroadcastRecord r = app.curReceiver; 9061 if (r != null) { 9062 // The current broadcast is waiting for this app's receiver 9063 // to be finished. Looks like that's not going to happen, so 9064 // let the broadcast continue. 9065 logBroadcastReceiverDiscard(r); 9066 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 9067 r.resultExtras, r.resultAbort, true); 9068 reschedule = true; 9069 } 9070 r = mPendingBroadcast; 9071 if (r != null && r.curApp == app) { 9072 if (DEBUG_BROADCAST) Slog.v(TAG, 9073 "skip & discard pending app " + r); 9074 logBroadcastReceiverDiscard(r); 9075 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 9076 r.resultExtras, r.resultAbort, true); 9077 reschedule = true; 9078 } 9079 if (reschedule) { 9080 scheduleBroadcastsLocked(); 9081 } 9082 } 9083 9084 /** 9085 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9086 * The application process will exit immediately after this call returns. 9087 * @param app object of the crashing app, null for the system server 9088 * @param crashInfo describing the exception 9089 */ 9090 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9091 ProcessRecord r = findAppProcess(app); 9092 9093 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9094 app == null ? "system" : (r == null ? "unknown" : r.processName), 9095 r == null ? -1 : r.info.flags, 9096 crashInfo.exceptionClassName, 9097 crashInfo.exceptionMessage, 9098 crashInfo.throwFileName, 9099 crashInfo.throwLineNumber); 9100 9101 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo); 9102 9103 crashApplication(r, crashInfo); 9104 } 9105 9106 /** 9107 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9108 * @param app object of the crashing app, null for the system server 9109 * @param tag reported by the caller 9110 * @param crashInfo describing the context of the error 9111 * @return true if the process should exit immediately (WTF is fatal) 9112 */ 9113 public boolean handleApplicationWtf(IBinder app, String tag, 9114 ApplicationErrorReport.CrashInfo crashInfo) { 9115 ProcessRecord r = findAppProcess(app); 9116 9117 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(), 9118 app == null ? "system" : (r == null ? "unknown" : r.processName), 9119 r == null ? -1 : r.info.flags, 9120 tag, crashInfo.exceptionMessage); 9121 9122 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo); 9123 9124 if (Settings.Secure.getInt(mContext.getContentResolver(), 9125 Settings.Secure.WTF_IS_FATAL, 0) != 0) { 9126 crashApplication(r, crashInfo); 9127 return true; 9128 } else { 9129 return false; 9130 } 9131 } 9132 9133 /** 9134 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9135 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9136 */ 9137 private ProcessRecord findAppProcess(IBinder app) { 9138 if (app == null) { 9139 return null; 9140 } 9141 9142 synchronized (this) { 9143 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) { 9144 final int NA = apps.size(); 9145 for (int ia=0; ia<NA; ia++) { 9146 ProcessRecord p = apps.valueAt(ia); 9147 if (p.thread != null && p.thread.asBinder() == app) { 9148 return p; 9149 } 9150 } 9151 } 9152 9153 Slog.w(TAG, "Can't find mystery application: " + app); 9154 return null; 9155 } 9156 } 9157 9158 /** 9159 * Write a description of an error (crash, WTF, ANR) to the drop box. 9160 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 9161 * @param process which caused the error, null means the system server 9162 * @param activity which triggered the error, null if unknown 9163 * @param parent activity related to the error, null if unknown 9164 * @param subject line related to the error, null if absent 9165 * @param report in long form describing the error, null if absent 9166 * @param logFile to include in the report, null if none 9167 * @param crashInfo giving an application stack trace, null if absent 9168 */ 9169 public void addErrorToDropBox(String eventType, 9170 ProcessRecord process, HistoryRecord activity, HistoryRecord parent, String subject, 9171 final String report, final File logFile, 9172 final ApplicationErrorReport.CrashInfo crashInfo) { 9173 // NOTE -- this must never acquire the ActivityManagerService lock, 9174 // otherwise the watchdog may be prevented from resetting the system. 9175 9176 String prefix; 9177 if (process == null || process.pid == MY_PID) { 9178 prefix = "system_server_"; 9179 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 9180 prefix = "system_app_"; 9181 } else { 9182 prefix = "data_app_"; 9183 } 9184 9185 final String dropboxTag = prefix + eventType; 9186 final DropBoxManager dbox = (DropBoxManager) 9187 mContext.getSystemService(Context.DROPBOX_SERVICE); 9188 9189 // Exit early if the dropbox isn't configured to accept this report type. 9190 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9191 9192 final StringBuilder sb = new StringBuilder(1024); 9193 if (process == null || process.pid == MY_PID) { 9194 sb.append("Process: system_server\n"); 9195 } else { 9196 sb.append("Process: ").append(process.processName).append("\n"); 9197 } 9198 if (process != null) { 9199 int flags = process.info.flags; 9200 IPackageManager pm = ActivityThread.getPackageManager(); 9201 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 9202 for (String pkg : process.pkgList) { 9203 sb.append("Package: ").append(pkg); 9204 try { 9205 PackageInfo pi = pm.getPackageInfo(pkg, 0); 9206 if (pi != null) { 9207 sb.append(" v").append(pi.versionCode); 9208 if (pi.versionName != null) { 9209 sb.append(" (").append(pi.versionName).append(")"); 9210 } 9211 } 9212 } catch (RemoteException e) { 9213 Slog.e(TAG, "Error getting package info: " + pkg, e); 9214 } 9215 sb.append("\n"); 9216 } 9217 } 9218 if (activity != null) { 9219 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 9220 } 9221 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 9222 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 9223 } 9224 if (parent != null && parent != activity) { 9225 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 9226 } 9227 if (subject != null) { 9228 sb.append("Subject: ").append(subject).append("\n"); 9229 } 9230 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9231 sb.append("\n"); 9232 9233 // Do the rest in a worker thread to avoid blocking the caller on I/O 9234 // (After this point, we shouldn't access AMS internal data structures.) 9235 Thread worker = new Thread("Error dump: " + dropboxTag) { 9236 @Override 9237 public void run() { 9238 if (report != null) { 9239 sb.append(report); 9240 } 9241 if (logFile != null) { 9242 try { 9243 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]")); 9244 } catch (IOException e) { 9245 Slog.e(TAG, "Error reading " + logFile, e); 9246 } 9247 } 9248 if (crashInfo != null && crashInfo.stackTrace != null) { 9249 sb.append(crashInfo.stackTrace); 9250 } 9251 9252 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag; 9253 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0); 9254 if (lines > 0) { 9255 sb.append("\n"); 9256 9257 // Merge several logcat streams, and take the last N lines 9258 InputStreamReader input = null; 9259 try { 9260 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 9261 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 9262 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 9263 9264 try { logcat.getOutputStream().close(); } catch (IOException e) {} 9265 try { logcat.getErrorStream().close(); } catch (IOException e) {} 9266 input = new InputStreamReader(logcat.getInputStream()); 9267 9268 int num; 9269 char[] buf = new char[8192]; 9270 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 9271 } catch (IOException e) { 9272 Slog.e(TAG, "Error running logcat", e); 9273 } finally { 9274 if (input != null) try { input.close(); } catch (IOException e) {} 9275 } 9276 } 9277 9278 dbox.addText(dropboxTag, sb.toString()); 9279 } 9280 }; 9281 9282 if (process == null || process.pid == MY_PID) { 9283 worker.run(); // We may be about to die -- need to run this synchronously 9284 } else { 9285 worker.start(); 9286 } 9287 } 9288 9289 /** 9290 * Bring up the "unexpected error" dialog box for a crashing app. 9291 * Deal with edge cases (intercepts from instrumented applications, 9292 * ActivityController, error intent receivers, that sort of thing). 9293 * @param r the application crashing 9294 * @param crashInfo describing the failure 9295 */ 9296 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 9297 long timeMillis = System.currentTimeMillis(); 9298 String shortMsg = crashInfo.exceptionClassName; 9299 String longMsg = crashInfo.exceptionMessage; 9300 String stackTrace = crashInfo.stackTrace; 9301 if (shortMsg != null && longMsg != null) { 9302 longMsg = shortMsg + ": " + longMsg; 9303 } else if (shortMsg != null) { 9304 longMsg = shortMsg; 9305 } 9306 9307 AppErrorResult result = new AppErrorResult(); 9308 synchronized (this) { 9309 if (mController != null) { 9310 try { 9311 String name = r != null ? r.processName : null; 9312 int pid = r != null ? r.pid : Binder.getCallingPid(); 9313 if (!mController.appCrashed(name, pid, 9314 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 9315 Slog.w(TAG, "Force-killing crashed app " + name 9316 + " at watcher's request"); 9317 Process.killProcess(pid); 9318 return; 9319 } 9320 } catch (RemoteException e) { 9321 mController = null; 9322 } 9323 } 9324 9325 final long origId = Binder.clearCallingIdentity(); 9326 9327 // If this process is running instrumentation, finish it. 9328 if (r != null && r.instrumentationClass != null) { 9329 Slog.w(TAG, "Error in app " + r.processName 9330 + " running instrumentation " + r.instrumentationClass + ":"); 9331 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 9332 if (longMsg != null) Slog.w(TAG, " " + longMsg); 9333 Bundle info = new Bundle(); 9334 info.putString("shortMsg", shortMsg); 9335 info.putString("longMsg", longMsg); 9336 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 9337 Binder.restoreCallingIdentity(origId); 9338 return; 9339 } 9340 9341 // If we can't identify the process or it's already exceeded its crash quota, 9342 // quit right away without showing a crash dialog. 9343 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 9344 Binder.restoreCallingIdentity(origId); 9345 return; 9346 } 9347 9348 Message msg = Message.obtain(); 9349 msg.what = SHOW_ERROR_MSG; 9350 HashMap data = new HashMap(); 9351 data.put("result", result); 9352 data.put("app", r); 9353 msg.obj = data; 9354 mHandler.sendMessage(msg); 9355 9356 Binder.restoreCallingIdentity(origId); 9357 } 9358 9359 int res = result.get(); 9360 9361 Intent appErrorIntent = null; 9362 synchronized (this) { 9363 if (r != null) { 9364 mProcessCrashTimes.put(r.info.processName, r.info.uid, 9365 SystemClock.uptimeMillis()); 9366 } 9367 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 9368 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 9369 } 9370 } 9371 9372 if (appErrorIntent != null) { 9373 try { 9374 mContext.startActivity(appErrorIntent); 9375 } catch (ActivityNotFoundException e) { 9376 Slog.w(TAG, "bug report receiver dissappeared", e); 9377 } 9378 } 9379 } 9380 9381 Intent createAppErrorIntentLocked(ProcessRecord r, 9382 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 9383 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 9384 if (report == null) { 9385 return null; 9386 } 9387 Intent result = new Intent(Intent.ACTION_APP_ERROR); 9388 result.setComponent(r.errorReportReceiver); 9389 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 9390 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 9391 return result; 9392 } 9393 9394 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 9395 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 9396 if (r.errorReportReceiver == null) { 9397 return null; 9398 } 9399 9400 if (!r.crashing && !r.notResponding) { 9401 return null; 9402 } 9403 9404 ApplicationErrorReport report = new ApplicationErrorReport(); 9405 report.packageName = r.info.packageName; 9406 report.installerPackageName = r.errorReportReceiver.getPackageName(); 9407 report.processName = r.processName; 9408 report.time = timeMillis; 9409 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 9410 9411 if (r.crashing) { 9412 report.type = ApplicationErrorReport.TYPE_CRASH; 9413 report.crashInfo = crashInfo; 9414 } else if (r.notResponding) { 9415 report.type = ApplicationErrorReport.TYPE_ANR; 9416 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 9417 9418 report.anrInfo.activity = r.notRespondingReport.tag; 9419 report.anrInfo.cause = r.notRespondingReport.shortMsg; 9420 report.anrInfo.info = r.notRespondingReport.longMsg; 9421 } 9422 9423 return report; 9424 } 9425 9426 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 9427 // assume our apps are happy - lazy create the list 9428 List<ActivityManager.ProcessErrorStateInfo> errList = null; 9429 9430 synchronized (this) { 9431 9432 // iterate across all processes 9433 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9434 ProcessRecord app = mLruProcesses.get(i); 9435 if ((app.thread != null) && (app.crashing || app.notResponding)) { 9436 // This one's in trouble, so we'll generate a report for it 9437 // crashes are higher priority (in case there's a crash *and* an anr) 9438 ActivityManager.ProcessErrorStateInfo report = null; 9439 if (app.crashing) { 9440 report = app.crashingReport; 9441 } else if (app.notResponding) { 9442 report = app.notRespondingReport; 9443 } 9444 9445 if (report != null) { 9446 if (errList == null) { 9447 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 9448 } 9449 errList.add(report); 9450 } else { 9451 Slog.w(TAG, "Missing app error report, app = " + app.processName + 9452 " crashing = " + app.crashing + 9453 " notResponding = " + app.notResponding); 9454 } 9455 } 9456 } 9457 } 9458 9459 return errList; 9460 } 9461 9462 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 9463 // Lazy instantiation of list 9464 List<ActivityManager.RunningAppProcessInfo> runList = null; 9465 synchronized (this) { 9466 // Iterate across all processes 9467 for (int i=mLruProcesses.size()-1; i>=0; i--) { 9468 ProcessRecord app = mLruProcesses.get(i); 9469 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 9470 // Generate process state info for running application 9471 ActivityManager.RunningAppProcessInfo currApp = 9472 new ActivityManager.RunningAppProcessInfo(app.processName, 9473 app.pid, app.getPackageList()); 9474 currApp.uid = app.info.uid; 9475 int adj = app.curAdj; 9476 if (adj >= EMPTY_APP_ADJ) { 9477 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY; 9478 } else if (adj >= HIDDEN_APP_MIN_ADJ) { 9479 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 9480 currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1; 9481 } else if (adj >= HOME_APP_ADJ) { 9482 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 9483 currApp.lru = 0; 9484 } else if (adj >= SECONDARY_SERVER_ADJ) { 9485 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 9486 } else if (adj >= VISIBLE_APP_ADJ) { 9487 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 9488 } else { 9489 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 9490 } 9491 currApp.importanceReasonCode = app.adjTypeCode; 9492 if (app.adjSource instanceof ProcessRecord) { 9493 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 9494 } else if (app.adjSource instanceof HistoryRecord) { 9495 HistoryRecord r = (HistoryRecord)app.adjSource; 9496 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 9497 } 9498 if (app.adjTarget instanceof ComponentName) { 9499 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 9500 } 9501 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 9502 // + " lru=" + currApp.lru); 9503 if (runList == null) { 9504 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 9505 } 9506 runList.add(currApp); 9507 } 9508 } 9509 } 9510 return runList; 9511 } 9512 9513 public List<ApplicationInfo> getRunningExternalApplications() { 9514 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 9515 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 9516 if (runningApps != null && runningApps.size() > 0) { 9517 Set<String> extList = new HashSet<String>(); 9518 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 9519 if (app.pkgList != null) { 9520 for (String pkg : app.pkgList) { 9521 extList.add(pkg); 9522 } 9523 } 9524 } 9525 IPackageManager pm = ActivityThread.getPackageManager(); 9526 for (String pkg : extList) { 9527 try { 9528 ApplicationInfo info = pm.getApplicationInfo(pkg, 0); 9529 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 9530 retList.add(info); 9531 } 9532 } catch (RemoteException e) { 9533 } 9534 } 9535 } 9536 return retList; 9537 } 9538 9539 @Override 9540 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 9541 if (checkCallingPermission(android.Manifest.permission.DUMP) 9542 != PackageManager.PERMISSION_GRANTED) { 9543 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 9544 + Binder.getCallingPid() 9545 + ", uid=" + Binder.getCallingUid() 9546 + " without permission " 9547 + android.Manifest.permission.DUMP); 9548 return; 9549 } 9550 9551 boolean dumpAll = false; 9552 9553 int opti = 0; 9554 while (opti < args.length) { 9555 String opt = args[opti]; 9556 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 9557 break; 9558 } 9559 opti++; 9560 if ("-a".equals(opt)) { 9561 dumpAll = true; 9562 } else if ("-h".equals(opt)) { 9563 pw.println("Activity manager dump options:"); 9564 pw.println(" [-a] [-h] [cmd] ..."); 9565 pw.println(" cmd may be one of:"); 9566 pw.println(" activities: activity stack state"); 9567 pw.println(" broadcasts: broadcast state"); 9568 pw.println(" intents: pending intent state"); 9569 pw.println(" processes: process state"); 9570 pw.println(" providers: content provider state"); 9571 pw.println(" services: service state"); 9572 pw.println(" service [name]: service client-side state"); 9573 return; 9574 } else { 9575 pw.println("Unknown argument: " + opt + "; use -h for help"); 9576 } 9577 } 9578 9579 // Is the caller requesting to dump a particular piece of data? 9580 if (opti < args.length) { 9581 String cmd = args[opti]; 9582 opti++; 9583 if ("activities".equals(cmd) || "a".equals(cmd)) { 9584 synchronized (this) { 9585 dumpActivitiesLocked(fd, pw, args, opti, true, true); 9586 } 9587 return; 9588 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 9589 synchronized (this) { 9590 dumpBroadcastsLocked(fd, pw, args, opti, true); 9591 } 9592 return; 9593 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 9594 synchronized (this) { 9595 dumpPendingIntentsLocked(fd, pw, args, opti, true); 9596 } 9597 return; 9598 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 9599 synchronized (this) { 9600 dumpProcessesLocked(fd, pw, args, opti, true); 9601 } 9602 return; 9603 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 9604 synchronized (this) { 9605 dumpProvidersLocked(fd, pw, args, opti, true); 9606 } 9607 return; 9608 } else if ("service".equals(cmd)) { 9609 dumpService(fd, pw, args, opti, true); 9610 return; 9611 } else if ("services".equals(cmd) || "s".equals(cmd)) { 9612 synchronized (this) { 9613 dumpServicesLocked(fd, pw, args, opti, true); 9614 } 9615 return; 9616 } 9617 } 9618 9619 // No piece of data specified, dump everything. 9620 synchronized (this) { 9621 boolean needSep; 9622 if (dumpAll) { 9623 pw.println("Providers in Current Activity Manager State:"); 9624 } 9625 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll); 9626 if (needSep) { 9627 pw.println(" "); 9628 } 9629 if (dumpAll) { 9630 pw.println("-------------------------------------------------------------------------------"); 9631 pw.println("Broadcasts in Current Activity Manager State:"); 9632 } 9633 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll); 9634 if (needSep) { 9635 pw.println(" "); 9636 } 9637 if (dumpAll) { 9638 pw.println("-------------------------------------------------------------------------------"); 9639 pw.println("Services in Current Activity Manager State:"); 9640 } 9641 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll); 9642 if (needSep) { 9643 pw.println(" "); 9644 } 9645 if (dumpAll) { 9646 pw.println("-------------------------------------------------------------------------------"); 9647 pw.println("PendingIntents in Current Activity Manager State:"); 9648 } 9649 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll); 9650 if (needSep) { 9651 pw.println(" "); 9652 } 9653 if (dumpAll) { 9654 pw.println("-------------------------------------------------------------------------------"); 9655 pw.println("Activities in Current Activity Manager State:"); 9656 } 9657 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, !dumpAll); 9658 if (needSep) { 9659 pw.println(" "); 9660 } 9661 if (dumpAll) { 9662 pw.println("-------------------------------------------------------------------------------"); 9663 pw.println("Processes in Current Activity Manager State:"); 9664 } 9665 dumpProcessesLocked(fd, pw, args, opti, dumpAll); 9666 } 9667 } 9668 9669 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9670 int opti, boolean dumpAll, boolean needHeader) { 9671 if (needHeader) { 9672 pw.println(" Activity stack:"); 9673 } 9674 dumpHistoryList(pw, mHistory, " ", "Hist", true); 9675 pw.println(" "); 9676 pw.println(" Running activities (most recent first):"); 9677 dumpHistoryList(pw, mLRUActivities, " ", "Run", false); 9678 if (mWaitingVisibleActivities.size() > 0) { 9679 pw.println(" "); 9680 pw.println(" Activities waiting for another to become visible:"); 9681 dumpHistoryList(pw, mWaitingVisibleActivities, " ", "Wait", false); 9682 } 9683 if (mStoppingActivities.size() > 0) { 9684 pw.println(" "); 9685 pw.println(" Activities waiting to stop:"); 9686 dumpHistoryList(pw, mStoppingActivities, " ", "Stop", false); 9687 } 9688 if (mFinishingActivities.size() > 0) { 9689 pw.println(" "); 9690 pw.println(" Activities waiting to finish:"); 9691 dumpHistoryList(pw, mFinishingActivities, " ", "Fin", false); 9692 } 9693 9694 pw.println(" "); 9695 pw.println(" mPausingActivity: " + mPausingActivity); 9696 pw.println(" mResumedActivity: " + mResumedActivity); 9697 pw.println(" mFocusedActivity: " + mFocusedActivity); 9698 pw.println(" mLastPausedActivity: " + mLastPausedActivity); 9699 9700 if (dumpAll && mRecentTasks.size() > 0) { 9701 pw.println(" "); 9702 pw.println("Recent tasks in Current Activity Manager State:"); 9703 9704 final int N = mRecentTasks.size(); 9705 for (int i=0; i<N; i++) { 9706 TaskRecord tr = mRecentTasks.get(i); 9707 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 9708 pw.println(tr); 9709 mRecentTasks.get(i).dump(pw, " "); 9710 } 9711 } 9712 9713 pw.println(" "); 9714 pw.println(" mCurTask: " + mCurTask); 9715 9716 return true; 9717 } 9718 9719 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9720 int opti, boolean dumpAll) { 9721 boolean needSep = false; 9722 int numPers = 0; 9723 9724 if (dumpAll) { 9725 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) { 9726 final int NA = procs.size(); 9727 for (int ia=0; ia<NA; ia++) { 9728 if (!needSep) { 9729 pw.println(" All known processes:"); 9730 needSep = true; 9731 } 9732 ProcessRecord r = procs.valueAt(ia); 9733 pw.print(r.persistent ? " *PERS*" : " *APP*"); 9734 pw.print(" UID "); pw.print(procs.keyAt(ia)); 9735 pw.print(" "); pw.println(r); 9736 r.dump(pw, " "); 9737 if (r.persistent) { 9738 numPers++; 9739 } 9740 } 9741 } 9742 } 9743 9744 if (mLruProcesses.size() > 0) { 9745 if (needSep) pw.println(" "); 9746 needSep = true; 9747 pw.println(" Running processes (most recent first):"); 9748 dumpProcessList(pw, this, mLruProcesses, " ", 9749 "App ", "PERS", true); 9750 needSep = true; 9751 } 9752 9753 synchronized (mPidsSelfLocked) { 9754 if (mPidsSelfLocked.size() > 0) { 9755 if (needSep) pw.println(" "); 9756 needSep = true; 9757 pw.println(" PID mappings:"); 9758 for (int i=0; i<mPidsSelfLocked.size(); i++) { 9759 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 9760 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 9761 } 9762 } 9763 } 9764 9765 if (mForegroundProcesses.size() > 0) { 9766 if (needSep) pw.println(" "); 9767 needSep = true; 9768 pw.println(" Foreground Processes:"); 9769 for (int i=0; i<mForegroundProcesses.size(); i++) { 9770 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 9771 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 9772 } 9773 } 9774 9775 if (mPersistentStartingProcesses.size() > 0) { 9776 if (needSep) pw.println(" "); 9777 needSep = true; 9778 pw.println(" Persisent processes that are starting:"); 9779 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 9780 "Starting Norm", "Restarting PERS", false); 9781 } 9782 9783 if (mStartingProcesses.size() > 0) { 9784 if (needSep) pw.println(" "); 9785 needSep = true; 9786 pw.println(" Processes that are starting:"); 9787 dumpProcessList(pw, this, mStartingProcesses, " ", 9788 "Starting Norm", "Starting PERS", false); 9789 } 9790 9791 if (mRemovedProcesses.size() > 0) { 9792 if (needSep) pw.println(" "); 9793 needSep = true; 9794 pw.println(" Processes that are being removed:"); 9795 dumpProcessList(pw, this, mRemovedProcesses, " ", 9796 "Removed Norm", "Removed PERS", false); 9797 } 9798 9799 if (mProcessesOnHold.size() > 0) { 9800 if (needSep) pw.println(" "); 9801 needSep = true; 9802 pw.println(" Processes that are on old until the system is ready:"); 9803 dumpProcessList(pw, this, mProcessesOnHold, " ", 9804 "OnHold Norm", "OnHold PERS", false); 9805 } 9806 9807 if (mProcessesToGc.size() > 0) { 9808 if (needSep) pw.println(" "); 9809 needSep = true; 9810 pw.println(" Processes that are waiting to GC:"); 9811 long now = SystemClock.uptimeMillis(); 9812 for (int i=0; i<mProcessesToGc.size(); i++) { 9813 ProcessRecord proc = mProcessesToGc.get(i); 9814 pw.print(" Process "); pw.println(proc); 9815 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 9816 pw.print(", last gced="); 9817 pw.print(now-proc.lastRequestedGc); 9818 pw.print(" ms ago, last lowMem="); 9819 pw.print(now-proc.lastLowMemory); 9820 pw.println(" ms ago"); 9821 9822 } 9823 } 9824 9825 if (mProcessCrashTimes.getMap().size() > 0) { 9826 if (needSep) pw.println(" "); 9827 needSep = true; 9828 pw.println(" Time since processes crashed:"); 9829 long now = SystemClock.uptimeMillis(); 9830 for (Map.Entry<String, SparseArray<Long>> procs 9831 : mProcessCrashTimes.getMap().entrySet()) { 9832 SparseArray<Long> uids = procs.getValue(); 9833 final int N = uids.size(); 9834 for (int i=0; i<N; i++) { 9835 pw.print(" Process "); pw.print(procs.getKey()); 9836 pw.print(" uid "); pw.print(uids.keyAt(i)); 9837 pw.print(": last crashed "); 9838 pw.print((now-uids.valueAt(i))); 9839 pw.println(" ms ago"); 9840 } 9841 } 9842 } 9843 9844 if (mBadProcesses.getMap().size() > 0) { 9845 if (needSep) pw.println(" "); 9846 needSep = true; 9847 pw.println(" Bad processes:"); 9848 for (Map.Entry<String, SparseArray<Long>> procs 9849 : mBadProcesses.getMap().entrySet()) { 9850 SparseArray<Long> uids = procs.getValue(); 9851 final int N = uids.size(); 9852 for (int i=0; i<N; i++) { 9853 pw.print(" Bad process "); pw.print(procs.getKey()); 9854 pw.print(" uid "); pw.print(uids.keyAt(i)); 9855 pw.print(": crashed at time "); 9856 pw.println(uids.valueAt(i)); 9857 } 9858 } 9859 } 9860 9861 pw.println(" "); 9862 pw.println(" mHomeProcess: " + mHomeProcess); 9863 pw.println(" mConfiguration: " + mConfiguration); 9864 pw.println(" mConfigWillChange: " + mConfigWillChange); 9865 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown); 9866 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 9867 || mOrigWaitForDebugger) { 9868 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 9869 + " mDebugTransient=" + mDebugTransient 9870 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 9871 } 9872 if (mAlwaysFinishActivities || mController != null) { 9873 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 9874 + " mController=" + mController); 9875 } 9876 if (dumpAll) { 9877 pw.println(" Total persistent processes: " + numPers); 9878 pw.println(" mStartRunning=" + mStartRunning 9879 + " mSystemReady=" + mSystemReady 9880 + " mBooting=" + mBooting 9881 + " mBooted=" + mBooted 9882 + " mFactoryTest=" + mFactoryTest); 9883 pw.println(" mGoingToSleep=" + mGoingToSleep); 9884 pw.println(" mLaunchingActivity=" + mLaunchingActivity); 9885 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 9886 } 9887 9888 return true; 9889 } 9890 9891 /** 9892 * There are three ways to call this: 9893 * - no service specified: dump all the services 9894 * - a flattened component name that matched an existing service was specified as the 9895 * first arg: dump that one service 9896 * - the first arg isn't the flattened component name of an existing service: 9897 * dump all services whose component contains the first arg as a substring 9898 */ 9899 protected void dumpService(FileDescriptor fd, PrintWriter pw, String[] args, 9900 int opti, boolean dumpAll) { 9901 String[] newArgs; 9902 String componentNameString; 9903 ServiceRecord r; 9904 if (opti >= args.length) { 9905 componentNameString = null; 9906 newArgs = EMPTY_STRING_ARRAY; 9907 r = null; 9908 } else { 9909 componentNameString = args[opti]; 9910 opti++; 9911 ComponentName componentName = ComponentName.unflattenFromString(componentNameString); 9912 r = componentName != null ? mServices.get(componentName) : null; 9913 newArgs = new String[args.length - opti]; 9914 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 9915 } 9916 9917 if (r != null) { 9918 dumpService(fd, pw, r, newArgs); 9919 } else { 9920 for (ServiceRecord r1 : mServices.values()) { 9921 if (componentNameString == null 9922 || r1.name.flattenToString().contains(componentNameString)) { 9923 dumpService(fd, pw, r1, newArgs); 9924 } 9925 } 9926 } 9927 } 9928 9929 /** 9930 * Invokes IApplicationThread.dumpService() on the thread of the specified service if 9931 * there is a thread associated with the service. 9932 */ 9933 private void dumpService(FileDescriptor fd, PrintWriter pw, ServiceRecord r, String[] args) { 9934 pw.println(" Service " + r.name.flattenToString()); 9935 if (r.app != null && r.app.thread != null) { 9936 try { 9937 // flush anything that is already in the PrintWriter since the thread is going 9938 // to write to the file descriptor directly 9939 pw.flush(); 9940 r.app.thread.dumpService(fd, r, args); 9941 pw.print("\n"); 9942 } catch (RemoteException e) { 9943 pw.println("got a RemoteException while dumping the service"); 9944 } 9945 } 9946 } 9947 9948 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 9949 int opti, boolean dumpAll) { 9950 boolean needSep = false; 9951 9952 if (dumpAll) { 9953 if (mRegisteredReceivers.size() > 0) { 9954 pw.println(" "); 9955 pw.println(" Registered Receivers:"); 9956 Iterator it = mRegisteredReceivers.values().iterator(); 9957 while (it.hasNext()) { 9958 ReceiverList r = (ReceiverList)it.next(); 9959 pw.print(" * "); pw.println(r); 9960 r.dump(pw, " "); 9961 } 9962 } 9963 9964 pw.println(" "); 9965 pw.println("Receiver Resolver Table:"); 9966 mReceiverResolver.dump(pw, null, " ", null); 9967 needSep = true; 9968 } 9969 9970 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0 9971 || mPendingBroadcast != null) { 9972 if (mParallelBroadcasts.size() > 0) { 9973 pw.println(" "); 9974 pw.println(" Active broadcasts:"); 9975 } 9976 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) { 9977 pw.println(" Broadcast #" + i + ":"); 9978 mParallelBroadcasts.get(i).dump(pw, " "); 9979 } 9980 if (mOrderedBroadcasts.size() > 0) { 9981 pw.println(" "); 9982 pw.println(" Active ordered broadcasts:"); 9983 } 9984 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) { 9985 pw.println(" Serialized Broadcast #" + i + ":"); 9986 mOrderedBroadcasts.get(i).dump(pw, " "); 9987 } 9988 pw.println(" "); 9989 pw.println(" Pending broadcast:"); 9990 if (mPendingBroadcast != null) { 9991 mPendingBroadcast.dump(pw, " "); 9992 } else { 9993 pw.println(" (null)"); 9994 } 9995 needSep = true; 9996 } 9997 9998 if (dumpAll) { 9999 pw.println(" "); 10000 pw.println(" Historical broadcasts:"); 10001 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) { 10002 BroadcastRecord r = mBroadcastHistory[i]; 10003 if (r == null) { 10004 break; 10005 } 10006 pw.println(" Historical Broadcast #" + i + ":"); 10007 r.dump(pw, " "); 10008 } 10009 needSep = true; 10010 } 10011 10012 if (mStickyBroadcasts != null) { 10013 pw.println(" "); 10014 pw.println(" Sticky broadcasts:"); 10015 StringBuilder sb = new StringBuilder(128); 10016 for (Map.Entry<String, ArrayList<Intent>> ent 10017 : mStickyBroadcasts.entrySet()) { 10018 pw.print(" * Sticky action "); pw.print(ent.getKey()); 10019 pw.println(":"); 10020 ArrayList<Intent> intents = ent.getValue(); 10021 final int N = intents.size(); 10022 for (int i=0; i<N; i++) { 10023 sb.setLength(0); 10024 sb.append(" Intent: "); 10025 intents.get(i).toShortString(sb, true, false); 10026 pw.println(sb.toString()); 10027 Bundle bundle = intents.get(i).getExtras(); 10028 if (bundle != null) { 10029 pw.print(" "); 10030 pw.println(bundle.toString()); 10031 } 10032 } 10033 } 10034 needSep = true; 10035 } 10036 10037 if (dumpAll) { 10038 pw.println(" "); 10039 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled); 10040 pw.println(" mHandler:"); 10041 mHandler.dump(new PrintWriterPrinter(pw), " "); 10042 needSep = true; 10043 } 10044 10045 return needSep; 10046 } 10047 10048 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10049 int opti, boolean dumpAll) { 10050 boolean needSep = false; 10051 10052 if (dumpAll) { 10053 if (mServices.size() > 0) { 10054 pw.println(" Active services:"); 10055 Iterator<ServiceRecord> it = mServices.values().iterator(); 10056 while (it.hasNext()) { 10057 ServiceRecord r = it.next(); 10058 pw.print(" * "); pw.println(r); 10059 r.dump(pw, " "); 10060 } 10061 needSep = true; 10062 } 10063 } 10064 10065 if (mPendingServices.size() > 0) { 10066 if (needSep) pw.println(" "); 10067 pw.println(" Pending services:"); 10068 for (int i=0; i<mPendingServices.size(); i++) { 10069 ServiceRecord r = mPendingServices.get(i); 10070 pw.print(" * Pending "); pw.println(r); 10071 r.dump(pw, " "); 10072 } 10073 needSep = true; 10074 } 10075 10076 if (mRestartingServices.size() > 0) { 10077 if (needSep) pw.println(" "); 10078 pw.println(" Restarting services:"); 10079 for (int i=0; i<mRestartingServices.size(); i++) { 10080 ServiceRecord r = mRestartingServices.get(i); 10081 pw.print(" * Restarting "); pw.println(r); 10082 r.dump(pw, " "); 10083 } 10084 needSep = true; 10085 } 10086 10087 if (mStoppingServices.size() > 0) { 10088 if (needSep) pw.println(" "); 10089 pw.println(" Stopping services:"); 10090 for (int i=0; i<mStoppingServices.size(); i++) { 10091 ServiceRecord r = mStoppingServices.get(i); 10092 pw.print(" * Stopping "); pw.println(r); 10093 r.dump(pw, " "); 10094 } 10095 needSep = true; 10096 } 10097 10098 if (dumpAll) { 10099 if (mServiceConnections.size() > 0) { 10100 if (needSep) pw.println(" "); 10101 pw.println(" Connection bindings to services:"); 10102 Iterator<ConnectionRecord> it 10103 = mServiceConnections.values().iterator(); 10104 while (it.hasNext()) { 10105 ConnectionRecord r = it.next(); 10106 pw.print(" * "); pw.println(r); 10107 r.dump(pw, " "); 10108 } 10109 needSep = true; 10110 } 10111 } 10112 10113 return needSep; 10114 } 10115 10116 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10117 int opti, boolean dumpAll) { 10118 boolean needSep = false; 10119 10120 if (dumpAll) { 10121 if (mProvidersByClass.size() > 0) { 10122 if (needSep) pw.println(" "); 10123 pw.println(" Published content providers (by class):"); 10124 Iterator it = mProvidersByClass.entrySet().iterator(); 10125 while (it.hasNext()) { 10126 Map.Entry e = (Map.Entry)it.next(); 10127 ContentProviderRecord r = (ContentProviderRecord)e.getValue(); 10128 pw.print(" * "); pw.println(r); 10129 r.dump(pw, " "); 10130 } 10131 needSep = true; 10132 } 10133 10134 if (mProvidersByName.size() > 0) { 10135 pw.println(" "); 10136 pw.println(" Authority to provider mappings:"); 10137 Iterator it = mProvidersByName.entrySet().iterator(); 10138 while (it.hasNext()) { 10139 Map.Entry e = (Map.Entry)it.next(); 10140 ContentProviderRecord r = (ContentProviderRecord)e.getValue(); 10141 pw.print(" "); pw.print(e.getKey()); pw.print(": "); 10142 pw.println(r); 10143 } 10144 needSep = true; 10145 } 10146 } 10147 10148 if (mLaunchingProviders.size() > 0) { 10149 if (needSep) pw.println(" "); 10150 pw.println(" Launching content providers:"); 10151 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 10152 pw.print(" Launching #"); pw.print(i); pw.print(": "); 10153 pw.println(mLaunchingProviders.get(i)); 10154 } 10155 needSep = true; 10156 } 10157 10158 if (mGrantedUriPermissions.size() > 0) { 10159 pw.println(); 10160 pw.println("Granted Uri Permissions:"); 10161 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 10162 int uid = mGrantedUriPermissions.keyAt(i); 10163 HashMap<Uri, UriPermission> perms 10164 = mGrantedUriPermissions.valueAt(i); 10165 pw.print(" * UID "); pw.print(uid); 10166 pw.println(" holds:"); 10167 for (UriPermission perm : perms.values()) { 10168 pw.print(" "); pw.println(perm); 10169 perm.dump(pw, " "); 10170 } 10171 } 10172 needSep = true; 10173 } 10174 10175 return needSep; 10176 } 10177 10178 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10179 int opti, boolean dumpAll) { 10180 boolean needSep = false; 10181 10182 if (dumpAll) { 10183 if (this.mIntentSenderRecords.size() > 0) { 10184 Iterator<WeakReference<PendingIntentRecord>> it 10185 = mIntentSenderRecords.values().iterator(); 10186 while (it.hasNext()) { 10187 WeakReference<PendingIntentRecord> ref = it.next(); 10188 PendingIntentRecord rec = ref != null ? ref.get(): null; 10189 needSep = true; 10190 if (rec != null) { 10191 pw.print(" * "); pw.println(rec); 10192 rec.dump(pw, " "); 10193 } else { 10194 pw.print(" * "); pw.print(ref); 10195 } 10196 } 10197 } 10198 } 10199 10200 return needSep; 10201 } 10202 10203 private static final void dumpHistoryList(PrintWriter pw, List list, 10204 String prefix, String label, boolean complete) { 10205 TaskRecord lastTask = null; 10206 for (int i=list.size()-1; i>=0; i--) { 10207 HistoryRecord r = (HistoryRecord)list.get(i); 10208 final boolean full = complete || !r.inHistory; 10209 if (lastTask != r.task) { 10210 lastTask = r.task; 10211 pw.print(prefix); 10212 pw.print(full ? "* " : " "); 10213 pw.println(lastTask); 10214 if (full) { 10215 lastTask.dump(pw, prefix + " "); 10216 } 10217 } 10218 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label); 10219 pw.print(" #"); pw.print(i); pw.print(": "); 10220 pw.println(r); 10221 if (full) { 10222 r.dump(pw, prefix + " "); 10223 } 10224 } 10225 } 10226 10227 private static String buildOomTag(String prefix, String space, int val, int base) { 10228 if (val == base) { 10229 if (space == null) return prefix; 10230 return prefix + " "; 10231 } 10232 return prefix + "+" + Integer.toString(val-base); 10233 } 10234 10235 private static final int dumpProcessList(PrintWriter pw, 10236 ActivityManagerService service, List list, 10237 String prefix, String normalLabel, String persistentLabel, 10238 boolean inclOomAdj) { 10239 int numPers = 0; 10240 for (int i=list.size()-1; i>=0; i--) { 10241 ProcessRecord r = (ProcessRecord)list.get(i); 10242 if (false) { 10243 pw.println(prefix + (r.persistent ? persistentLabel : normalLabel) 10244 + " #" + i + ":"); 10245 r.dump(pw, prefix + " "); 10246 } else if (inclOomAdj) { 10247 String oomAdj; 10248 if (r.setAdj >= EMPTY_APP_ADJ) { 10249 oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ); 10250 } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) { 10251 oomAdj = buildOomTag("bak", " ", r.setAdj, HIDDEN_APP_MIN_ADJ); 10252 } else if (r.setAdj >= HOME_APP_ADJ) { 10253 oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ); 10254 } else if (r.setAdj >= SECONDARY_SERVER_ADJ) { 10255 oomAdj = buildOomTag("svc", " ", r.setAdj, SECONDARY_SERVER_ADJ); 10256 } else if (r.setAdj >= BACKUP_APP_ADJ) { 10257 oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ); 10258 } else if (r.setAdj >= VISIBLE_APP_ADJ) { 10259 oomAdj = buildOomTag("vis ", null, r.setAdj, VISIBLE_APP_ADJ); 10260 } else if (r.setAdj >= FOREGROUND_APP_ADJ) { 10261 oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ); 10262 } else if (r.setAdj >= CORE_SERVER_ADJ) { 10263 oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ); 10264 } else if (r.setAdj >= SYSTEM_ADJ) { 10265 oomAdj = buildOomTag("sys ", null, r.setAdj, SYSTEM_ADJ); 10266 } else { 10267 oomAdj = Integer.toString(r.setAdj); 10268 } 10269 String schedGroup; 10270 switch (r.setSchedGroup) { 10271 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 10272 schedGroup = "B"; 10273 break; 10274 case Process.THREAD_GROUP_DEFAULT: 10275 schedGroup = "F"; 10276 break; 10277 default: 10278 schedGroup = Integer.toString(r.setSchedGroup); 10279 break; 10280 } 10281 pw.println(String.format("%s%s #%2d: adj=%s/%s %s (%s)", 10282 prefix, (r.persistent ? persistentLabel : normalLabel), 10283 i, oomAdj, schedGroup, r.toShortString(), r.adjType)); 10284 if (r.adjSource != null || r.adjTarget != null) { 10285 pw.println(prefix + " " + r.adjTarget 10286 + "<=" + r.adjSource); 10287 } 10288 } else { 10289 pw.println(String.format("%s%s #%2d: %s", 10290 prefix, (r.persistent ? persistentLabel : normalLabel), 10291 i, r.toString())); 10292 } 10293 if (r.persistent) { 10294 numPers++; 10295 } 10296 } 10297 return numPers; 10298 } 10299 10300 static final void dumpApplicationMemoryUsage(FileDescriptor fd, 10301 PrintWriter pw, List list, String prefix, String[] args) { 10302 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 10303 long uptime = SystemClock.uptimeMillis(); 10304 long realtime = SystemClock.elapsedRealtime(); 10305 10306 if (isCheckinRequest) { 10307 // short checkin version 10308 pw.println(uptime + "," + realtime); 10309 pw.flush(); 10310 } else { 10311 pw.println("Applications Memory Usage (kB):"); 10312 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 10313 } 10314 for (int i = list.size() - 1 ; i >= 0 ; i--) { 10315 ProcessRecord r = (ProcessRecord)list.get(i); 10316 if (r.thread != null) { 10317 if (!isCheckinRequest) { 10318 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); 10319 pw.flush(); 10320 } 10321 try { 10322 r.thread.asBinder().dump(fd, args); 10323 } catch (RemoteException e) { 10324 if (!isCheckinRequest) { 10325 pw.println("Got RemoteException!"); 10326 pw.flush(); 10327 } 10328 } 10329 } 10330 } 10331 } 10332 10333 /** 10334 * Searches array of arguments for the specified string 10335 * @param args array of argument strings 10336 * @param value value to search for 10337 * @return true if the value is contained in the array 10338 */ 10339 private static boolean scanArgs(String[] args, String value) { 10340 if (args != null) { 10341 for (String arg : args) { 10342 if (value.equals(arg)) { 10343 return true; 10344 } 10345 } 10346 } 10347 return false; 10348 } 10349 10350 private final int indexOfTokenLocked(IBinder token) { 10351 int count = mHistory.size(); 10352 10353 // convert the token to an entry in the history. 10354 int index = -1; 10355 for (int i=count-1; i>=0; i--) { 10356 Object o = mHistory.get(i); 10357 if (o == token) { 10358 index = i; 10359 break; 10360 } 10361 } 10362 10363 return index; 10364 } 10365 10366 private final void killServicesLocked(ProcessRecord app, 10367 boolean allowRestart) { 10368 // Report disconnected services. 10369 if (false) { 10370 // XXX we are letting the client link to the service for 10371 // death notifications. 10372 if (app.services.size() > 0) { 10373 Iterator it = app.services.iterator(); 10374 while (it.hasNext()) { 10375 ServiceRecord r = (ServiceRecord)it.next(); 10376 if (r.connections.size() > 0) { 10377 Iterator<ConnectionRecord> jt 10378 = r.connections.values().iterator(); 10379 while (jt.hasNext()) { 10380 ConnectionRecord c = jt.next(); 10381 if (c.binding.client != app) { 10382 try { 10383 //c.conn.connected(r.className, null); 10384 } catch (Exception e) { 10385 // todo: this should be asynchronous! 10386 Slog.w(TAG, "Exception thrown disconnected servce " 10387 + r.shortName 10388 + " from app " + app.processName, e); 10389 } 10390 } 10391 } 10392 } 10393 } 10394 } 10395 } 10396 10397 // Clean up any connections this application has to other services. 10398 if (app.connections.size() > 0) { 10399 Iterator<ConnectionRecord> it = app.connections.iterator(); 10400 while (it.hasNext()) { 10401 ConnectionRecord r = it.next(); 10402 removeConnectionLocked(r, app, null); 10403 } 10404 } 10405 app.connections.clear(); 10406 10407 if (app.services.size() != 0) { 10408 // Any services running in the application need to be placed 10409 // back in the pending list. 10410 Iterator it = app.services.iterator(); 10411 while (it.hasNext()) { 10412 ServiceRecord sr = (ServiceRecord)it.next(); 10413 synchronized (sr.stats.getBatteryStats()) { 10414 sr.stats.stopLaunchedLocked(); 10415 } 10416 sr.app = null; 10417 sr.executeNesting = 0; 10418 mStoppingServices.remove(sr); 10419 10420 boolean hasClients = sr.bindings.size() > 0; 10421 if (hasClients) { 10422 Iterator<IntentBindRecord> bindings 10423 = sr.bindings.values().iterator(); 10424 while (bindings.hasNext()) { 10425 IntentBindRecord b = bindings.next(); 10426 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b 10427 + ": shouldUnbind=" + b.hasBound); 10428 b.binder = null; 10429 b.requested = b.received = b.hasBound = false; 10430 } 10431 } 10432 10433 if (sr.crashCount >= 2) { 10434 Slog.w(TAG, "Service crashed " + sr.crashCount 10435 + " times, stopping: " + sr); 10436 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH, 10437 sr.crashCount, sr.shortName, app.pid); 10438 bringDownServiceLocked(sr, true); 10439 } else if (!allowRestart) { 10440 bringDownServiceLocked(sr, true); 10441 } else { 10442 boolean canceled = scheduleServiceRestartLocked(sr, true); 10443 10444 // Should the service remain running? Note that in the 10445 // extreme case of so many attempts to deliver a command 10446 // that it failed, that we also will stop it here. 10447 if (sr.startRequested && (sr.stopIfKilled || canceled)) { 10448 if (sr.pendingStarts.size() == 0) { 10449 sr.startRequested = false; 10450 if (!hasClients) { 10451 // Whoops, no reason to restart! 10452 bringDownServiceLocked(sr, true); 10453 } 10454 } 10455 } 10456 } 10457 } 10458 10459 if (!allowRestart) { 10460 app.services.clear(); 10461 } 10462 } 10463 10464 // Make sure we have no more records on the stopping list. 10465 int i = mStoppingServices.size(); 10466 while (i > 0) { 10467 i--; 10468 ServiceRecord sr = mStoppingServices.get(i); 10469 if (sr.app == app) { 10470 mStoppingServices.remove(i); 10471 } 10472 } 10473 10474 app.executingServices.clear(); 10475 } 10476 10477 private final void removeDyingProviderLocked(ProcessRecord proc, 10478 ContentProviderRecord cpr) { 10479 synchronized (cpr) { 10480 cpr.launchingApp = null; 10481 cpr.notifyAll(); 10482 } 10483 10484 mProvidersByClass.remove(cpr.info.name); 10485 String names[] = cpr.info.authority.split(";"); 10486 for (int j = 0; j < names.length; j++) { 10487 mProvidersByName.remove(names[j]); 10488 } 10489 10490 Iterator<ProcessRecord> cit = cpr.clients.iterator(); 10491 while (cit.hasNext()) { 10492 ProcessRecord capp = cit.next(); 10493 if (!capp.persistent && capp.thread != null 10494 && capp.pid != 0 10495 && capp.pid != MY_PID) { 10496 Slog.i(TAG, "Kill " + capp.processName 10497 + " (pid " + capp.pid + "): provider " + cpr.info.name 10498 + " in dying process " + proc.processName); 10499 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid, 10500 capp.processName, capp.setAdj, "dying provider " + proc.processName); 10501 Process.killProcess(capp.pid); 10502 } 10503 } 10504 10505 mLaunchingProviders.remove(cpr); 10506 } 10507 10508 /** 10509 * Main code for cleaning up a process when it has gone away. This is 10510 * called both as a result of the process dying, or directly when stopping 10511 * a process when running in single process mode. 10512 */ 10513 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 10514 boolean restarting, int index) { 10515 if (index >= 0) { 10516 mLruProcesses.remove(index); 10517 } 10518 10519 mProcessesToGc.remove(app); 10520 10521 // Dismiss any open dialogs. 10522 if (app.crashDialog != null) { 10523 app.crashDialog.dismiss(); 10524 app.crashDialog = null; 10525 } 10526 if (app.anrDialog != null) { 10527 app.anrDialog.dismiss(); 10528 app.anrDialog = null; 10529 } 10530 if (app.waitDialog != null) { 10531 app.waitDialog.dismiss(); 10532 app.waitDialog = null; 10533 } 10534 10535 app.crashing = false; 10536 app.notResponding = false; 10537 10538 app.resetPackageList(); 10539 app.thread = null; 10540 app.forcingToForeground = null; 10541 app.foregroundServices = false; 10542 10543 killServicesLocked(app, true); 10544 10545 boolean restart = false; 10546 10547 int NL = mLaunchingProviders.size(); 10548 10549 // Remove published content providers. 10550 if (!app.pubProviders.isEmpty()) { 10551 Iterator it = app.pubProviders.values().iterator(); 10552 while (it.hasNext()) { 10553 ContentProviderRecord cpr = (ContentProviderRecord)it.next(); 10554 cpr.provider = null; 10555 cpr.app = null; 10556 10557 // See if someone is waiting for this provider... in which 10558 // case we don't remove it, but just let it restart. 10559 int i = 0; 10560 if (!app.bad) { 10561 for (; i<NL; i++) { 10562 if (mLaunchingProviders.get(i) == cpr) { 10563 restart = true; 10564 break; 10565 } 10566 } 10567 } else { 10568 i = NL; 10569 } 10570 10571 if (i >= NL) { 10572 removeDyingProviderLocked(app, cpr); 10573 NL = mLaunchingProviders.size(); 10574 } 10575 } 10576 app.pubProviders.clear(); 10577 } 10578 10579 // Take care of any launching providers waiting for this process. 10580 if (checkAppInLaunchingProvidersLocked(app, false)) { 10581 restart = true; 10582 } 10583 10584 // Unregister from connected content providers. 10585 if (!app.conProviders.isEmpty()) { 10586 Iterator it = app.conProviders.keySet().iterator(); 10587 while (it.hasNext()) { 10588 ContentProviderRecord cpr = (ContentProviderRecord)it.next(); 10589 cpr.clients.remove(app); 10590 } 10591 app.conProviders.clear(); 10592 } 10593 10594 // At this point there may be remaining entries in mLaunchingProviders 10595 // where we were the only one waiting, so they are no longer of use. 10596 // Look for these and clean up if found. 10597 // XXX Commented out for now. Trying to figure out a way to reproduce 10598 // the actual situation to identify what is actually going on. 10599 if (false) { 10600 for (int i=0; i<NL; i++) { 10601 ContentProviderRecord cpr = (ContentProviderRecord) 10602 mLaunchingProviders.get(i); 10603 if (cpr.clients.size() <= 0 && cpr.externals <= 0) { 10604 synchronized (cpr) { 10605 cpr.launchingApp = null; 10606 cpr.notifyAll(); 10607 } 10608 } 10609 } 10610 } 10611 10612 skipCurrentReceiverLocked(app); 10613 10614 // Unregister any receivers. 10615 if (app.receivers.size() > 0) { 10616 Iterator<ReceiverList> it = app.receivers.iterator(); 10617 while (it.hasNext()) { 10618 removeReceiverLocked(it.next()); 10619 } 10620 app.receivers.clear(); 10621 } 10622 10623 // If the app is undergoing backup, tell the backup manager about it 10624 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 10625 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup"); 10626 try { 10627 IBackupManager bm = IBackupManager.Stub.asInterface( 10628 ServiceManager.getService(Context.BACKUP_SERVICE)); 10629 bm.agentDisconnected(app.info.packageName); 10630 } catch (RemoteException e) { 10631 // can't happen; backup manager is local 10632 } 10633 } 10634 10635 // If the caller is restarting this app, then leave it in its 10636 // current lists and let the caller take care of it. 10637 if (restarting) { 10638 return; 10639 } 10640 10641 if (!app.persistent) { 10642 if (DEBUG_PROCESSES) Slog.v(TAG, 10643 "Removing non-persistent process during cleanup: " + app); 10644 mProcessNames.remove(app.processName, app.info.uid); 10645 } else if (!app.removed) { 10646 // This app is persistent, so we need to keep its record around. 10647 // If it is not already on the pending app list, add it there 10648 // and start a new process for it. 10649 app.thread = null; 10650 app.forcingToForeground = null; 10651 app.foregroundServices = false; 10652 if (mPersistentStartingProcesses.indexOf(app) < 0) { 10653 mPersistentStartingProcesses.add(app); 10654 restart = true; 10655 } 10656 } 10657 mProcessesOnHold.remove(app); 10658 10659 if (app == mHomeProcess) { 10660 mHomeProcess = null; 10661 } 10662 10663 if (restart) { 10664 // We have components that still need to be running in the 10665 // process, so re-launch it. 10666 mProcessNames.put(app.processName, app.info.uid, app); 10667 startProcessLocked(app, "restart", app.processName); 10668 } else if (app.pid > 0 && app.pid != MY_PID) { 10669 // Goodbye! 10670 synchronized (mPidsSelfLocked) { 10671 mPidsSelfLocked.remove(app.pid); 10672 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 10673 } 10674 app.setPid(0); 10675 } 10676 } 10677 10678 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 10679 // Look through the content providers we are waiting to have launched, 10680 // and if any run in this process then either schedule a restart of 10681 // the process or kill the client waiting for it if this process has 10682 // gone bad. 10683 int NL = mLaunchingProviders.size(); 10684 boolean restart = false; 10685 for (int i=0; i<NL; i++) { 10686 ContentProviderRecord cpr = (ContentProviderRecord) 10687 mLaunchingProviders.get(i); 10688 if (cpr.launchingApp == app) { 10689 if (!alwaysBad && !app.bad) { 10690 restart = true; 10691 } else { 10692 removeDyingProviderLocked(app, cpr); 10693 NL = mLaunchingProviders.size(); 10694 } 10695 } 10696 } 10697 return restart; 10698 } 10699 10700 // ========================================================= 10701 // SERVICES 10702 // ========================================================= 10703 10704 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) { 10705 ActivityManager.RunningServiceInfo info = 10706 new ActivityManager.RunningServiceInfo(); 10707 info.service = r.name; 10708 if (r.app != null) { 10709 info.pid = r.app.pid; 10710 } 10711 info.uid = r.appInfo.uid; 10712 info.process = r.processName; 10713 info.foreground = r.isForeground; 10714 info.activeSince = r.createTime; 10715 info.started = r.startRequested; 10716 info.clientCount = r.connections.size(); 10717 info.crashCount = r.crashCount; 10718 info.lastActivityTime = r.lastActivity; 10719 if (r.isForeground) { 10720 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND; 10721 } 10722 if (r.startRequested) { 10723 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED; 10724 } 10725 if (r.app != null && r.app.pid == MY_PID) { 10726 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS; 10727 } 10728 if (r.app != null && r.app.persistent) { 10729 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS; 10730 } 10731 for (ConnectionRecord conn : r.connections.values()) { 10732 if (conn.clientLabel != 0) { 10733 info.clientPackage = conn.binding.client.info.packageName; 10734 info.clientLabel = conn.clientLabel; 10735 break; 10736 } 10737 } 10738 return info; 10739 } 10740 10741 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 10742 int flags) { 10743 synchronized (this) { 10744 ArrayList<ActivityManager.RunningServiceInfo> res 10745 = new ArrayList<ActivityManager.RunningServiceInfo>(); 10746 10747 if (mServices.size() > 0) { 10748 Iterator<ServiceRecord> it = mServices.values().iterator(); 10749 while (it.hasNext() && res.size() < maxNum) { 10750 res.add(makeRunningServiceInfoLocked(it.next())); 10751 } 10752 } 10753 10754 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) { 10755 ServiceRecord r = mRestartingServices.get(i); 10756 ActivityManager.RunningServiceInfo info = 10757 makeRunningServiceInfoLocked(r); 10758 info.restarting = r.nextRestartTime; 10759 res.add(info); 10760 } 10761 10762 return res; 10763 } 10764 } 10765 10766 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 10767 synchronized (this) { 10768 ServiceRecord r = mServices.get(name); 10769 if (r != null) { 10770 for (ConnectionRecord conn : r.connections.values()) { 10771 if (conn.clientIntent != null) { 10772 return conn.clientIntent; 10773 } 10774 } 10775 } 10776 } 10777 return null; 10778 } 10779 10780 private final ServiceRecord findServiceLocked(ComponentName name, 10781 IBinder token) { 10782 ServiceRecord r = mServices.get(name); 10783 return r == token ? r : null; 10784 } 10785 10786 private final class ServiceLookupResult { 10787 final ServiceRecord record; 10788 final String permission; 10789 10790 ServiceLookupResult(ServiceRecord _record, String _permission) { 10791 record = _record; 10792 permission = _permission; 10793 } 10794 }; 10795 10796 private ServiceLookupResult findServiceLocked(Intent service, 10797 String resolvedType) { 10798 ServiceRecord r = null; 10799 if (service.getComponent() != null) { 10800 r = mServices.get(service.getComponent()); 10801 } 10802 if (r == null) { 10803 Intent.FilterComparison filter = new Intent.FilterComparison(service); 10804 r = mServicesByIntent.get(filter); 10805 } 10806 10807 if (r == null) { 10808 try { 10809 ResolveInfo rInfo = 10810 ActivityThread.getPackageManager().resolveService( 10811 service, resolvedType, 0); 10812 ServiceInfo sInfo = 10813 rInfo != null ? rInfo.serviceInfo : null; 10814 if (sInfo == null) { 10815 return null; 10816 } 10817 10818 ComponentName name = new ComponentName( 10819 sInfo.applicationInfo.packageName, sInfo.name); 10820 r = mServices.get(name); 10821 } catch (RemoteException ex) { 10822 // pm is in same process, this will never happen. 10823 } 10824 } 10825 if (r != null) { 10826 int callingPid = Binder.getCallingPid(); 10827 int callingUid = Binder.getCallingUid(); 10828 if (checkComponentPermission(r.permission, 10829 callingPid, callingUid, r.exported ? -1 : r.appInfo.uid) 10830 != PackageManager.PERMISSION_GRANTED) { 10831 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 10832 + " from pid=" + callingPid 10833 + ", uid=" + callingUid 10834 + " requires " + r.permission); 10835 return new ServiceLookupResult(null, r.permission); 10836 } 10837 return new ServiceLookupResult(r, null); 10838 } 10839 return null; 10840 } 10841 10842 private class ServiceRestarter implements Runnable { 10843 private ServiceRecord mService; 10844 10845 void setService(ServiceRecord service) { 10846 mService = service; 10847 } 10848 10849 public void run() { 10850 synchronized(ActivityManagerService.this) { 10851 performServiceRestartLocked(mService); 10852 } 10853 } 10854 } 10855 10856 private ServiceLookupResult retrieveServiceLocked(Intent service, 10857 String resolvedType, int callingPid, int callingUid) { 10858 ServiceRecord r = null; 10859 if (service.getComponent() != null) { 10860 r = mServices.get(service.getComponent()); 10861 } 10862 Intent.FilterComparison filter = new Intent.FilterComparison(service); 10863 r = mServicesByIntent.get(filter); 10864 if (r == null) { 10865 try { 10866 ResolveInfo rInfo = 10867 ActivityThread.getPackageManager().resolveService( 10868 service, resolvedType, STOCK_PM_FLAGS); 10869 ServiceInfo sInfo = 10870 rInfo != null ? rInfo.serviceInfo : null; 10871 if (sInfo == null) { 10872 Slog.w(TAG, "Unable to start service " + service + 10873 ": not found"); 10874 return null; 10875 } 10876 10877 ComponentName name = new ComponentName( 10878 sInfo.applicationInfo.packageName, sInfo.name); 10879 r = mServices.get(name); 10880 if (r == null) { 10881 filter = new Intent.FilterComparison(service.cloneFilter()); 10882 ServiceRestarter res = new ServiceRestarter(); 10883 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 10884 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10885 synchronized (stats) { 10886 ss = stats.getServiceStatsLocked( 10887 sInfo.applicationInfo.uid, sInfo.packageName, 10888 sInfo.name); 10889 } 10890 r = new ServiceRecord(this, ss, name, filter, sInfo, res); 10891 res.setService(r); 10892 mServices.put(name, r); 10893 mServicesByIntent.put(filter, r); 10894 10895 // Make sure this component isn't in the pending list. 10896 int N = mPendingServices.size(); 10897 for (int i=0; i<N; i++) { 10898 ServiceRecord pr = mPendingServices.get(i); 10899 if (pr.name.equals(name)) { 10900 mPendingServices.remove(i); 10901 i--; 10902 N--; 10903 } 10904 } 10905 } 10906 } catch (RemoteException ex) { 10907 // pm is in same process, this will never happen. 10908 } 10909 } 10910 if (r != null) { 10911 if (checkComponentPermission(r.permission, 10912 callingPid, callingUid, r.exported ? -1 : r.appInfo.uid) 10913 != PackageManager.PERMISSION_GRANTED) { 10914 Slog.w(TAG, "Permission Denial: Accessing service " + r.name 10915 + " from pid=" + Binder.getCallingPid() 10916 + ", uid=" + Binder.getCallingUid() 10917 + " requires " + r.permission); 10918 return new ServiceLookupResult(null, r.permission); 10919 } 10920 return new ServiceLookupResult(r, null); 10921 } 10922 return null; 10923 } 10924 10925 private final void bumpServiceExecutingLocked(ServiceRecord r) { 10926 long now = SystemClock.uptimeMillis(); 10927 if (r.executeNesting == 0 && r.app != null) { 10928 if (r.app.executingServices.size() == 0) { 10929 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 10930 msg.obj = r.app; 10931 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT); 10932 } 10933 r.app.executingServices.add(r); 10934 } 10935 r.executeNesting++; 10936 r.executingStart = now; 10937 } 10938 10939 private final void sendServiceArgsLocked(ServiceRecord r, 10940 boolean oomAdjusted) { 10941 final int N = r.pendingStarts.size(); 10942 if (N == 0) { 10943 return; 10944 } 10945 10946 int i = 0; 10947 while (i < N) { 10948 try { 10949 ServiceRecord.StartItem si = r.pendingStarts.get(i); 10950 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to service: " 10951 + r.name + " " + r.intent + " args=" + si.intent); 10952 if (si.intent == null && N > 1) { 10953 // If somehow we got a dummy start at the front, then 10954 // just drop it here. 10955 i++; 10956 continue; 10957 } 10958 bumpServiceExecutingLocked(r); 10959 if (!oomAdjusted) { 10960 oomAdjusted = true; 10961 updateOomAdjLocked(r.app); 10962 } 10963 int flags = 0; 10964 if (si.deliveryCount > 0) { 10965 flags |= Service.START_FLAG_RETRY; 10966 } 10967 if (si.doneExecutingCount > 0) { 10968 flags |= Service.START_FLAG_REDELIVERY; 10969 } 10970 r.app.thread.scheduleServiceArgs(r, si.id, flags, si.intent); 10971 si.deliveredTime = SystemClock.uptimeMillis(); 10972 r.deliveredStarts.add(si); 10973 si.deliveryCount++; 10974 i++; 10975 } catch (RemoteException e) { 10976 // Remote process gone... we'll let the normal cleanup take 10977 // care of this. 10978 break; 10979 } catch (Exception e) { 10980 Slog.w(TAG, "Unexpected exception", e); 10981 break; 10982 } 10983 } 10984 if (i == N) { 10985 r.pendingStarts.clear(); 10986 } else { 10987 while (i > 0) { 10988 i--; 10989 r.pendingStarts.remove(i); 10990 } 10991 } 10992 } 10993 10994 private final boolean requestServiceBindingLocked(ServiceRecord r, 10995 IntentBindRecord i, boolean rebind) { 10996 if (r.app == null || r.app.thread == null) { 10997 // If service is not currently running, can't yet bind. 10998 return false; 10999 } 11000 if ((!i.requested || rebind) && i.apps.size() > 0) { 11001 try { 11002 bumpServiceExecutingLocked(r); 11003 if (DEBUG_SERVICE) Slog.v(TAG, "Connecting binding " + i 11004 + ": shouldUnbind=" + i.hasBound); 11005 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind); 11006 if (!rebind) { 11007 i.requested = true; 11008 } 11009 i.hasBound = true; 11010 i.doRebind = false; 11011 } catch (RemoteException e) { 11012 return false; 11013 } 11014 } 11015 return true; 11016 } 11017 11018 private final void requestServiceBindingsLocked(ServiceRecord r) { 11019 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator(); 11020 while (bindings.hasNext()) { 11021 IntentBindRecord i = bindings.next(); 11022 if (!requestServiceBindingLocked(r, i, false)) { 11023 break; 11024 } 11025 } 11026 } 11027 11028 private final void realStartServiceLocked(ServiceRecord r, 11029 ProcessRecord app) throws RemoteException { 11030 if (app.thread == null) { 11031 throw new RemoteException(); 11032 } 11033 11034 r.app = app; 11035 r.restartTime = r.lastActivity = SystemClock.uptimeMillis(); 11036 11037 app.services.add(r); 11038 bumpServiceExecutingLocked(r); 11039 updateLruProcessLocked(app, true, true); 11040 11041 boolean created = false; 11042 try { 11043 if (DEBUG_SERVICE) Slog.v(TAG, "Scheduling start service: " 11044 + r.name + " " + r.intent); 11045 mStringBuilder.setLength(0); 11046 r.intent.getIntent().toShortString(mStringBuilder, false, true); 11047 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE, 11048 System.identityHashCode(r), r.shortName, 11049 mStringBuilder.toString(), r.app.pid); 11050 synchronized (r.stats.getBatteryStats()) { 11051 r.stats.startLaunchedLocked(); 11052 } 11053 ensurePackageDexOpt(r.serviceInfo.packageName); 11054 app.thread.scheduleCreateService(r, r.serviceInfo); 11055 r.postNotification(); 11056 created = true; 11057 } finally { 11058 if (!created) { 11059 app.services.remove(r); 11060 scheduleServiceRestartLocked(r, false); 11061 } 11062 } 11063 11064 requestServiceBindingsLocked(r); 11065 11066 // If the service is in the started state, and there are no 11067 // pending arguments, then fake up one so its onStartCommand() will 11068 // be called. 11069 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) { 11070 r.lastStartId++; 11071 if (r.lastStartId < 1) { 11072 r.lastStartId = 1; 11073 } 11074 r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, null)); 11075 } 11076 11077 sendServiceArgsLocked(r, true); 11078 } 11079 11080 private final boolean scheduleServiceRestartLocked(ServiceRecord r, 11081 boolean allowCancel) { 11082 boolean canceled = false; 11083 11084 final long now = SystemClock.uptimeMillis(); 11085 long minDuration = SERVICE_RESTART_DURATION; 11086 long resetTime = SERVICE_RESET_RUN_DURATION; 11087 11088 // Any delivered but not yet finished starts should be put back 11089 // on the pending list. 11090 final int N = r.deliveredStarts.size(); 11091 if (N > 0) { 11092 for (int i=N-1; i>=0; i--) { 11093 ServiceRecord.StartItem si = r.deliveredStarts.get(i); 11094 if (si.intent == null) { 11095 // We'll generate this again if needed. 11096 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT 11097 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) { 11098 r.pendingStarts.add(0, si); 11099 long dur = SystemClock.uptimeMillis() - si.deliveredTime; 11100 dur *= 2; 11101 if (minDuration < dur) minDuration = dur; 11102 if (resetTime < dur) resetTime = dur; 11103 } else { 11104 Slog.w(TAG, "Canceling start item " + si.intent + " in service " 11105 + r.name); 11106 canceled = true; 11107 } 11108 } 11109 r.deliveredStarts.clear(); 11110 } 11111 11112 r.totalRestartCount++; 11113 if (r.restartDelay == 0) { 11114 r.restartCount++; 11115 r.restartDelay = minDuration; 11116 } else { 11117 // If it has been a "reasonably long time" since the service 11118 // was started, then reset our restart duration back to 11119 // the beginning, so we don't infinitely increase the duration 11120 // on a service that just occasionally gets killed (which is 11121 // a normal case, due to process being killed to reclaim memory). 11122 if (now > (r.restartTime+resetTime)) { 11123 r.restartCount = 1; 11124 r.restartDelay = minDuration; 11125 } else { 11126 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR; 11127 if (r.restartDelay < minDuration) { 11128 r.restartDelay = minDuration; 11129 } 11130 } 11131 } 11132 11133 r.nextRestartTime = now + r.restartDelay; 11134 11135 // Make sure that we don't end up restarting a bunch of services 11136 // all at the same time. 11137 boolean repeat; 11138 do { 11139 repeat = false; 11140 for (int i=mRestartingServices.size()-1; i>=0; i--) { 11141 ServiceRecord r2 = mRestartingServices.get(i); 11142 if (r2 != r && r.nextRestartTime 11143 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN) 11144 && r.nextRestartTime 11145 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) { 11146 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN; 11147 r.restartDelay = r.nextRestartTime - now; 11148 repeat = true; 11149 break; 11150 } 11151 } 11152 } while (repeat); 11153 11154 if (!mRestartingServices.contains(r)) { 11155 mRestartingServices.add(r); 11156 } 11157 11158 r.cancelNotification(); 11159 11160 mHandler.removeCallbacks(r.restarter); 11161 mHandler.postAtTime(r.restarter, r.nextRestartTime); 11162 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay; 11163 Slog.w(TAG, "Scheduling restart of crashed service " 11164 + r.shortName + " in " + r.restartDelay + "ms"); 11165 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART, 11166 r.shortName, r.restartDelay); 11167 11168 return canceled; 11169 } 11170 11171 final void performServiceRestartLocked(ServiceRecord r) { 11172 if (!mRestartingServices.contains(r)) { 11173 return; 11174 } 11175 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true); 11176 } 11177 11178 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) { 11179 if (r.restartDelay == 0) { 11180 return false; 11181 } 11182 r.resetRestartCounter(); 11183 mRestartingServices.remove(r); 11184 mHandler.removeCallbacks(r.restarter); 11185 return true; 11186 } 11187 11188 private final boolean bringUpServiceLocked(ServiceRecord r, 11189 int intentFlags, boolean whileRestarting) { 11190 //Slog.i(TAG, "Bring up service:"); 11191 //r.dump(" "); 11192 11193 if (r.app != null && r.app.thread != null) { 11194 sendServiceArgsLocked(r, false); 11195 return true; 11196 } 11197 11198 if (!whileRestarting && r.restartDelay > 0) { 11199 // If waiting for a restart, then do nothing. 11200 return true; 11201 } 11202 11203 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up service " + r.name 11204 + " " + r.intent); 11205 11206 // We are now bringing the service up, so no longer in the 11207 // restarting state. 11208 mRestartingServices.remove(r); 11209 11210 final String appName = r.processName; 11211 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid); 11212 if (app != null && app.thread != null) { 11213 try { 11214 realStartServiceLocked(r, app); 11215 return true; 11216 } catch (RemoteException e) { 11217 Slog.w(TAG, "Exception when starting service " + r.shortName, e); 11218 } 11219 11220 // If a dead object exception was thrown -- fall through to 11221 // restart the application. 11222 } 11223 11224 // Not running -- get it started, and enqueue this service record 11225 // to be executed when the app comes up. 11226 if (startProcessLocked(appName, r.appInfo, true, intentFlags, 11227 "service", r.name, false) == null) { 11228 Slog.w(TAG, "Unable to launch app " 11229 + r.appInfo.packageName + "/" 11230 + r.appInfo.uid + " for service " 11231 + r.intent.getIntent() + ": process is bad"); 11232 bringDownServiceLocked(r, true); 11233 return false; 11234 } 11235 11236 if (!mPendingServices.contains(r)) { 11237 mPendingServices.add(r); 11238 } 11239 11240 return true; 11241 } 11242 11243 private final void bringDownServiceLocked(ServiceRecord r, boolean force) { 11244 //Slog.i(TAG, "Bring down service:"); 11245 //r.dump(" "); 11246 11247 // Does it still need to run? 11248 if (!force && r.startRequested) { 11249 return; 11250 } 11251 if (r.connections.size() > 0) { 11252 if (!force) { 11253 // XXX should probably keep a count of the number of auto-create 11254 // connections directly in the service. 11255 Iterator<ConnectionRecord> it = r.connections.values().iterator(); 11256 while (it.hasNext()) { 11257 ConnectionRecord cr = it.next(); 11258 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) { 11259 return; 11260 } 11261 } 11262 } 11263 11264 // Report to all of the connections that the service is no longer 11265 // available. 11266 Iterator<ConnectionRecord> it = r.connections.values().iterator(); 11267 while (it.hasNext()) { 11268 ConnectionRecord c = it.next(); 11269 try { 11270 // todo: shouldn't be a synchronous call! 11271 c.conn.connected(r.name, null); 11272 } catch (Exception e) { 11273 Slog.w(TAG, "Failure disconnecting service " + r.name + 11274 " to connection " + c.conn.asBinder() + 11275 " (in " + c.binding.client.processName + ")", e); 11276 } 11277 } 11278 } 11279 11280 // Tell the service that it has been unbound. 11281 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) { 11282 Iterator<IntentBindRecord> it = r.bindings.values().iterator(); 11283 while (it.hasNext()) { 11284 IntentBindRecord ibr = it.next(); 11285 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr 11286 + ": hasBound=" + ibr.hasBound); 11287 if (r.app != null && r.app.thread != null && ibr.hasBound) { 11288 try { 11289 bumpServiceExecutingLocked(r); 11290 updateOomAdjLocked(r.app); 11291 ibr.hasBound = false; 11292 r.app.thread.scheduleUnbindService(r, 11293 ibr.intent.getIntent()); 11294 } catch (Exception e) { 11295 Slog.w(TAG, "Exception when unbinding service " 11296 + r.shortName, e); 11297 serviceDoneExecutingLocked(r, true); 11298 } 11299 } 11300 } 11301 } 11302 11303 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down service " + r.name 11304 + " " + r.intent); 11305 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE, 11306 System.identityHashCode(r), r.shortName, 11307 (r.app != null) ? r.app.pid : -1); 11308 11309 mServices.remove(r.name); 11310 mServicesByIntent.remove(r.intent); 11311 if (localLOGV) Slog.v(TAG, "BRING DOWN SERVICE: " + r.shortName); 11312 r.totalRestartCount = 0; 11313 unscheduleServiceRestartLocked(r); 11314 11315 // Also make sure it is not on the pending list. 11316 int N = mPendingServices.size(); 11317 for (int i=0; i<N; i++) { 11318 if (mPendingServices.get(i) == r) { 11319 mPendingServices.remove(i); 11320 if (DEBUG_SERVICE) Slog.v( 11321 TAG, "Removed pending service: " + r.shortName); 11322 i--; 11323 N--; 11324 } 11325 } 11326 11327 r.cancelNotification(); 11328 r.isForeground = false; 11329 r.foregroundId = 0; 11330 r.foregroundNoti = null; 11331 11332 // Clear start entries. 11333 r.deliveredStarts.clear(); 11334 r.pendingStarts.clear(); 11335 11336 if (r.app != null) { 11337 synchronized (r.stats.getBatteryStats()) { 11338 r.stats.stopLaunchedLocked(); 11339 } 11340 r.app.services.remove(r); 11341 if (r.app.thread != null) { 11342 try { 11343 if (DEBUG_SERVICE) Slog.v(TAG, 11344 "Stopping service: " + r.shortName); 11345 bumpServiceExecutingLocked(r); 11346 mStoppingServices.add(r); 11347 updateOomAdjLocked(r.app); 11348 r.app.thread.scheduleStopService(r); 11349 } catch (Exception e) { 11350 Slog.w(TAG, "Exception when stopping service " 11351 + r.shortName, e); 11352 serviceDoneExecutingLocked(r, true); 11353 } 11354 updateServiceForegroundLocked(r.app, false); 11355 } else { 11356 if (DEBUG_SERVICE) Slog.v( 11357 TAG, "Removed service that has no process: " + r.shortName); 11358 } 11359 } else { 11360 if (DEBUG_SERVICE) Slog.v( 11361 TAG, "Removed service that is not running: " + r.shortName); 11362 } 11363 } 11364 11365 ComponentName startServiceLocked(IApplicationThread caller, 11366 Intent service, String resolvedType, 11367 int callingPid, int callingUid) { 11368 synchronized(this) { 11369 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service 11370 + " type=" + resolvedType + " args=" + service.getExtras()); 11371 11372 if (caller != null) { 11373 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11374 if (callerApp == null) { 11375 throw new SecurityException( 11376 "Unable to find app for caller " + caller 11377 + " (pid=" + Binder.getCallingPid() 11378 + ") when starting service " + service); 11379 } 11380 } 11381 11382 ServiceLookupResult res = 11383 retrieveServiceLocked(service, resolvedType, 11384 callingPid, callingUid); 11385 if (res == null) { 11386 return null; 11387 } 11388 if (res.record == null) { 11389 return new ComponentName("!", res.permission != null 11390 ? res.permission : "private to package"); 11391 } 11392 ServiceRecord r = res.record; 11393 if (unscheduleServiceRestartLocked(r)) { 11394 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " 11395 + r.shortName); 11396 } 11397 r.startRequested = true; 11398 r.callStart = false; 11399 r.lastStartId++; 11400 if (r.lastStartId < 1) { 11401 r.lastStartId = 1; 11402 } 11403 r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, service)); 11404 r.lastActivity = SystemClock.uptimeMillis(); 11405 synchronized (r.stats.getBatteryStats()) { 11406 r.stats.startRunningLocked(); 11407 } 11408 if (!bringUpServiceLocked(r, service.getFlags(), false)) { 11409 return new ComponentName("!", "Service process is bad"); 11410 } 11411 return r.name; 11412 } 11413 } 11414 11415 public ComponentName startService(IApplicationThread caller, Intent service, 11416 String resolvedType) { 11417 // Refuse possible leaked file descriptors 11418 if (service != null && service.hasFileDescriptors() == true) { 11419 throw new IllegalArgumentException("File descriptors passed in Intent"); 11420 } 11421 11422 synchronized(this) { 11423 final int callingPid = Binder.getCallingPid(); 11424 final int callingUid = Binder.getCallingUid(); 11425 final long origId = Binder.clearCallingIdentity(); 11426 ComponentName res = startServiceLocked(caller, service, 11427 resolvedType, callingPid, callingUid); 11428 Binder.restoreCallingIdentity(origId); 11429 return res; 11430 } 11431 } 11432 11433 ComponentName startServiceInPackage(int uid, 11434 Intent service, String resolvedType) { 11435 synchronized(this) { 11436 final long origId = Binder.clearCallingIdentity(); 11437 ComponentName res = startServiceLocked(null, service, 11438 resolvedType, -1, uid); 11439 Binder.restoreCallingIdentity(origId); 11440 return res; 11441 } 11442 } 11443 11444 public int stopService(IApplicationThread caller, Intent service, 11445 String resolvedType) { 11446 // Refuse possible leaked file descriptors 11447 if (service != null && service.hasFileDescriptors() == true) { 11448 throw new IllegalArgumentException("File descriptors passed in Intent"); 11449 } 11450 11451 synchronized(this) { 11452 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service 11453 + " type=" + resolvedType); 11454 11455 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11456 if (caller != null && callerApp == null) { 11457 throw new SecurityException( 11458 "Unable to find app for caller " + caller 11459 + " (pid=" + Binder.getCallingPid() 11460 + ") when stopping service " + service); 11461 } 11462 11463 // If this service is active, make sure it is stopped. 11464 ServiceLookupResult r = findServiceLocked(service, resolvedType); 11465 if (r != null) { 11466 if (r.record != null) { 11467 synchronized (r.record.stats.getBatteryStats()) { 11468 r.record.stats.stopRunningLocked(); 11469 } 11470 r.record.startRequested = false; 11471 r.record.callStart = false; 11472 final long origId = Binder.clearCallingIdentity(); 11473 bringDownServiceLocked(r.record, false); 11474 Binder.restoreCallingIdentity(origId); 11475 return 1; 11476 } 11477 return -1; 11478 } 11479 } 11480 11481 return 0; 11482 } 11483 11484 public IBinder peekService(Intent service, String resolvedType) { 11485 // Refuse possible leaked file descriptors 11486 if (service != null && service.hasFileDescriptors() == true) { 11487 throw new IllegalArgumentException("File descriptors passed in Intent"); 11488 } 11489 11490 IBinder ret = null; 11491 11492 synchronized(this) { 11493 ServiceLookupResult r = findServiceLocked(service, resolvedType); 11494 11495 if (r != null) { 11496 // r.record is null if findServiceLocked() failed the caller permission check 11497 if (r.record == null) { 11498 throw new SecurityException( 11499 "Permission Denial: Accessing service " + r.record.name 11500 + " from pid=" + Binder.getCallingPid() 11501 + ", uid=" + Binder.getCallingUid() 11502 + " requires " + r.permission); 11503 } 11504 IntentBindRecord ib = r.record.bindings.get(r.record.intent); 11505 if (ib != null) { 11506 ret = ib.binder; 11507 } 11508 } 11509 } 11510 11511 return ret; 11512 } 11513 11514 public boolean stopServiceToken(ComponentName className, IBinder token, 11515 int startId) { 11516 synchronized(this) { 11517 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className 11518 + " " + token + " startId=" + startId); 11519 ServiceRecord r = findServiceLocked(className, token); 11520 if (r != null) { 11521 if (startId >= 0) { 11522 // Asked to only stop if done with all work. Note that 11523 // to avoid leaks, we will take this as dropping all 11524 // start items up to and including this one. 11525 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 11526 if (si != null) { 11527 while (r.deliveredStarts.size() > 0) { 11528 if (r.deliveredStarts.remove(0) == si) { 11529 break; 11530 } 11531 } 11532 } 11533 11534 if (r.lastStartId != startId) { 11535 return false; 11536 } 11537 11538 if (r.deliveredStarts.size() > 0) { 11539 Slog.w(TAG, "stopServiceToken startId " + startId 11540 + " is last, but have " + r.deliveredStarts.size() 11541 + " remaining args"); 11542 } 11543 } 11544 11545 synchronized (r.stats.getBatteryStats()) { 11546 r.stats.stopRunningLocked(); 11547 r.startRequested = false; 11548 r.callStart = false; 11549 } 11550 final long origId = Binder.clearCallingIdentity(); 11551 bringDownServiceLocked(r, false); 11552 Binder.restoreCallingIdentity(origId); 11553 return true; 11554 } 11555 } 11556 return false; 11557 } 11558 11559 public void setServiceForeground(ComponentName className, IBinder token, 11560 int id, Notification notification, boolean removeNotification) { 11561 final long origId = Binder.clearCallingIdentity(); 11562 try { 11563 synchronized(this) { 11564 ServiceRecord r = findServiceLocked(className, token); 11565 if (r != null) { 11566 if (id != 0) { 11567 if (notification == null) { 11568 throw new IllegalArgumentException("null notification"); 11569 } 11570 if (r.foregroundId != id) { 11571 r.cancelNotification(); 11572 r.foregroundId = id; 11573 } 11574 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE; 11575 r.foregroundNoti = notification; 11576 r.isForeground = true; 11577 r.postNotification(); 11578 if (r.app != null) { 11579 updateServiceForegroundLocked(r.app, true); 11580 } 11581 } else { 11582 if (r.isForeground) { 11583 r.isForeground = false; 11584 if (r.app != null) { 11585 updateLruProcessLocked(r.app, false, true); 11586 updateServiceForegroundLocked(r.app, true); 11587 } 11588 } 11589 if (removeNotification) { 11590 r.cancelNotification(); 11591 r.foregroundId = 0; 11592 r.foregroundNoti = null; 11593 } 11594 } 11595 } 11596 } 11597 } finally { 11598 Binder.restoreCallingIdentity(origId); 11599 } 11600 } 11601 11602 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) { 11603 boolean anyForeground = false; 11604 for (ServiceRecord sr : (HashSet<ServiceRecord>)proc.services) { 11605 if (sr.isForeground) { 11606 anyForeground = true; 11607 break; 11608 } 11609 } 11610 if (anyForeground != proc.foregroundServices) { 11611 proc.foregroundServices = anyForeground; 11612 if (oomAdj) { 11613 updateOomAdjLocked(); 11614 } 11615 } 11616 } 11617 11618 public int bindService(IApplicationThread caller, IBinder token, 11619 Intent service, String resolvedType, 11620 IServiceConnection connection, int flags) { 11621 // Refuse possible leaked file descriptors 11622 if (service != null && service.hasFileDescriptors() == true) { 11623 throw new IllegalArgumentException("File descriptors passed in Intent"); 11624 } 11625 11626 synchronized(this) { 11627 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service 11628 + " type=" + resolvedType + " conn=" + connection.asBinder() 11629 + " flags=0x" + Integer.toHexString(flags)); 11630 final ProcessRecord callerApp = getRecordForAppLocked(caller); 11631 if (callerApp == null) { 11632 throw new SecurityException( 11633 "Unable to find app for caller " + caller 11634 + " (pid=" + Binder.getCallingPid() 11635 + ") when binding service " + service); 11636 } 11637 11638 HistoryRecord activity = null; 11639 if (token != null) { 11640 int aindex = indexOfTokenLocked(token); 11641 if (aindex < 0) { 11642 Slog.w(TAG, "Binding with unknown activity: " + token); 11643 return 0; 11644 } 11645 activity = (HistoryRecord)mHistory.get(aindex); 11646 } 11647 11648 int clientLabel = 0; 11649 PendingIntent clientIntent = null; 11650 11651 if (callerApp.info.uid == Process.SYSTEM_UID) { 11652 // Hacky kind of thing -- allow system stuff to tell us 11653 // what they are, so we can report this elsewhere for 11654 // others to know why certain services are running. 11655 try { 11656 clientIntent = (PendingIntent)service.getParcelableExtra( 11657 Intent.EXTRA_CLIENT_INTENT); 11658 } catch (RuntimeException e) { 11659 } 11660 if (clientIntent != null) { 11661 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0); 11662 if (clientLabel != 0) { 11663 // There are no useful extras in the intent, trash them. 11664 // System code calling with this stuff just needs to know 11665 // this will happen. 11666 service = service.cloneFilter(); 11667 } 11668 } 11669 } 11670 11671 ServiceLookupResult res = 11672 retrieveServiceLocked(service, resolvedType, 11673 Binder.getCallingPid(), Binder.getCallingUid()); 11674 if (res == null) { 11675 return 0; 11676 } 11677 if (res.record == null) { 11678 return -1; 11679 } 11680 ServiceRecord s = res.record; 11681 11682 final long origId = Binder.clearCallingIdentity(); 11683 11684 if (unscheduleServiceRestartLocked(s)) { 11685 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: " 11686 + s.shortName); 11687 } 11688 11689 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp); 11690 ConnectionRecord c = new ConnectionRecord(b, activity, 11691 connection, flags, clientLabel, clientIntent); 11692 11693 IBinder binder = connection.asBinder(); 11694 s.connections.put(binder, c); 11695 b.connections.add(c); 11696 if (activity != null) { 11697 if (activity.connections == null) { 11698 activity.connections = new HashSet<ConnectionRecord>(); 11699 } 11700 activity.connections.add(c); 11701 } 11702 b.client.connections.add(c); 11703 mServiceConnections.put(binder, c); 11704 11705 if ((flags&Context.BIND_AUTO_CREATE) != 0) { 11706 s.lastActivity = SystemClock.uptimeMillis(); 11707 if (!bringUpServiceLocked(s, service.getFlags(), false)) { 11708 return 0; 11709 } 11710 } 11711 11712 if (s.app != null) { 11713 // This could have made the service more important. 11714 updateOomAdjLocked(s.app); 11715 } 11716 11717 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b 11718 + ": received=" + b.intent.received 11719 + " apps=" + b.intent.apps.size() 11720 + " doRebind=" + b.intent.doRebind); 11721 11722 if (s.app != null && b.intent.received) { 11723 // Service is already running, so we can immediately 11724 // publish the connection. 11725 try { 11726 c.conn.connected(s.name, b.intent.binder); 11727 } catch (Exception e) { 11728 Slog.w(TAG, "Failure sending service " + s.shortName 11729 + " to connection " + c.conn.asBinder() 11730 + " (in " + c.binding.client.processName + ")", e); 11731 } 11732 11733 // If this is the first app connected back to this binding, 11734 // and the service had previously asked to be told when 11735 // rebound, then do so. 11736 if (b.intent.apps.size() == 1 && b.intent.doRebind) { 11737 requestServiceBindingLocked(s, b.intent, true); 11738 } 11739 } else if (!b.intent.requested) { 11740 requestServiceBindingLocked(s, b.intent, false); 11741 } 11742 11743 Binder.restoreCallingIdentity(origId); 11744 } 11745 11746 return 1; 11747 } 11748 11749 private void removeConnectionLocked( 11750 ConnectionRecord c, ProcessRecord skipApp, HistoryRecord skipAct) { 11751 IBinder binder = c.conn.asBinder(); 11752 AppBindRecord b = c.binding; 11753 ServiceRecord s = b.service; 11754 s.connections.remove(binder); 11755 b.connections.remove(c); 11756 if (c.activity != null && c.activity != skipAct) { 11757 if (c.activity.connections != null) { 11758 c.activity.connections.remove(c); 11759 } 11760 } 11761 if (b.client != skipApp) { 11762 b.client.connections.remove(c); 11763 } 11764 mServiceConnections.remove(binder); 11765 11766 if (b.connections.size() == 0) { 11767 b.intent.apps.remove(b.client); 11768 } 11769 11770 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent 11771 + ": shouldUnbind=" + b.intent.hasBound); 11772 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0 11773 && b.intent.hasBound) { 11774 try { 11775 bumpServiceExecutingLocked(s); 11776 updateOomAdjLocked(s.app); 11777 b.intent.hasBound = false; 11778 // Assume the client doesn't want to know about a rebind; 11779 // we will deal with that later if it asks for one. 11780 b.intent.doRebind = false; 11781 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent()); 11782 } catch (Exception e) { 11783 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e); 11784 serviceDoneExecutingLocked(s, true); 11785 } 11786 } 11787 11788 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) { 11789 bringDownServiceLocked(s, false); 11790 } 11791 } 11792 11793 public boolean unbindService(IServiceConnection connection) { 11794 synchronized (this) { 11795 IBinder binder = connection.asBinder(); 11796 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder); 11797 ConnectionRecord r = mServiceConnections.get(binder); 11798 if (r == null) { 11799 Slog.w(TAG, "Unbind failed: could not find connection for " 11800 + connection.asBinder()); 11801 return false; 11802 } 11803 11804 final long origId = Binder.clearCallingIdentity(); 11805 11806 removeConnectionLocked(r, null, null); 11807 11808 if (r.binding.service.app != null) { 11809 // This could have made the service less important. 11810 updateOomAdjLocked(r.binding.service.app); 11811 } 11812 11813 Binder.restoreCallingIdentity(origId); 11814 } 11815 11816 return true; 11817 } 11818 11819 public void publishService(IBinder token, Intent intent, IBinder service) { 11820 // Refuse possible leaked file descriptors 11821 if (intent != null && intent.hasFileDescriptors() == true) { 11822 throw new IllegalArgumentException("File descriptors passed in Intent"); 11823 } 11824 11825 synchronized(this) { 11826 if (!(token instanceof ServiceRecord)) { 11827 throw new IllegalArgumentException("Invalid service token"); 11828 } 11829 ServiceRecord r = (ServiceRecord)token; 11830 11831 final long origId = Binder.clearCallingIdentity(); 11832 11833 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING SERVICE " + r.name 11834 + " " + intent + ": " + service); 11835 if (r != null) { 11836 Intent.FilterComparison filter 11837 = new Intent.FilterComparison(intent); 11838 IntentBindRecord b = r.bindings.get(filter); 11839 if (b != null && !b.received) { 11840 b.binder = service; 11841 b.requested = true; 11842 b.received = true; 11843 if (r.connections.size() > 0) { 11844 Iterator<ConnectionRecord> it 11845 = r.connections.values().iterator(); 11846 while (it.hasNext()) { 11847 ConnectionRecord c = it.next(); 11848 if (!filter.equals(c.binding.intent.intent)) { 11849 if (DEBUG_SERVICE) Slog.v( 11850 TAG, "Not publishing to: " + c); 11851 if (DEBUG_SERVICE) Slog.v( 11852 TAG, "Bound intent: " + c.binding.intent.intent); 11853 if (DEBUG_SERVICE) Slog.v( 11854 TAG, "Published intent: " + intent); 11855 continue; 11856 } 11857 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c); 11858 try { 11859 c.conn.connected(r.name, service); 11860 } catch (Exception e) { 11861 Slog.w(TAG, "Failure sending service " + r.name + 11862 " to connection " + c.conn.asBinder() + 11863 " (in " + c.binding.client.processName + ")", e); 11864 } 11865 } 11866 } 11867 } 11868 11869 serviceDoneExecutingLocked(r, mStoppingServices.contains(r)); 11870 11871 Binder.restoreCallingIdentity(origId); 11872 } 11873 } 11874 } 11875 11876 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 11877 // Refuse possible leaked file descriptors 11878 if (intent != null && intent.hasFileDescriptors() == true) { 11879 throw new IllegalArgumentException("File descriptors passed in Intent"); 11880 } 11881 11882 synchronized(this) { 11883 if (!(token instanceof ServiceRecord)) { 11884 throw new IllegalArgumentException("Invalid service token"); 11885 } 11886 ServiceRecord r = (ServiceRecord)token; 11887 11888 final long origId = Binder.clearCallingIdentity(); 11889 11890 if (r != null) { 11891 Intent.FilterComparison filter 11892 = new Intent.FilterComparison(intent); 11893 IntentBindRecord b = r.bindings.get(filter); 11894 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r 11895 + " at " + b + ": apps=" 11896 + (b != null ? b.apps.size() : 0)); 11897 if (b != null) { 11898 if (b.apps.size() > 0) { 11899 // Applications have already bound since the last 11900 // unbind, so just rebind right here. 11901 requestServiceBindingLocked(r, b, true); 11902 } else { 11903 // Note to tell the service the next time there is 11904 // a new client. 11905 b.doRebind = true; 11906 } 11907 } 11908 11909 serviceDoneExecutingLocked(r, mStoppingServices.contains(r)); 11910 11911 Binder.restoreCallingIdentity(origId); 11912 } 11913 } 11914 } 11915 11916 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 11917 synchronized(this) { 11918 if (!(token instanceof ServiceRecord)) { 11919 throw new IllegalArgumentException("Invalid service token"); 11920 } 11921 ServiceRecord r = (ServiceRecord)token; 11922 boolean inStopping = mStoppingServices.contains(token); 11923 if (r != null) { 11924 if (DEBUG_SERVICE) Slog.v(TAG, "DONE EXECUTING SERVICE " + r.name 11925 + ": nesting=" + r.executeNesting 11926 + ", inStopping=" + inStopping); 11927 if (r != token) { 11928 Slog.w(TAG, "Done executing service " + r.name 11929 + " with incorrect token: given " + token 11930 + ", expected " + r); 11931 return; 11932 } 11933 11934 if (type == 1) { 11935 // This is a call from a service start... take care of 11936 // book-keeping. 11937 r.callStart = true; 11938 switch (res) { 11939 case Service.START_STICKY_COMPATIBILITY: 11940 case Service.START_STICKY: { 11941 // We are done with the associated start arguments. 11942 r.findDeliveredStart(startId, true); 11943 // Don't stop if killed. 11944 r.stopIfKilled = false; 11945 break; 11946 } 11947 case Service.START_NOT_STICKY: { 11948 // We are done with the associated start arguments. 11949 r.findDeliveredStart(startId, true); 11950 if (r.lastStartId == startId) { 11951 // There is no more work, and this service 11952 // doesn't want to hang around if killed. 11953 r.stopIfKilled = true; 11954 } 11955 break; 11956 } 11957 case Service.START_REDELIVER_INTENT: { 11958 // We'll keep this item until they explicitly 11959 // call stop for it, but keep track of the fact 11960 // that it was delivered. 11961 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); 11962 if (si != null) { 11963 si.deliveryCount = 0; 11964 si.doneExecutingCount++; 11965 // Don't stop if killed. 11966 r.stopIfKilled = true; 11967 } 11968 break; 11969 } 11970 default: 11971 throw new IllegalArgumentException( 11972 "Unknown service start result: " + res); 11973 } 11974 if (res == Service.START_STICKY_COMPATIBILITY) { 11975 r.callStart = false; 11976 } 11977 } 11978 11979 final long origId = Binder.clearCallingIdentity(); 11980 serviceDoneExecutingLocked(r, inStopping); 11981 Binder.restoreCallingIdentity(origId); 11982 } else { 11983 Slog.w(TAG, "Done executing unknown service " + r.name 11984 + " with token " + token); 11985 } 11986 } 11987 } 11988 11989 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) { 11990 r.executeNesting--; 11991 if (r.executeNesting <= 0 && r.app != null) { 11992 r.app.executingServices.remove(r); 11993 if (r.app.executingServices.size() == 0) { 11994 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app); 11995 } 11996 if (inStopping) { 11997 mStoppingServices.remove(r); 11998 } 11999 updateOomAdjLocked(r.app); 12000 } 12001 } 12002 12003 void serviceTimeout(ProcessRecord proc) { 12004 String anrMessage = null; 12005 12006 synchronized(this) { 12007 if (proc.executingServices.size() == 0 || proc.thread == null) { 12008 return; 12009 } 12010 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT; 12011 Iterator<ServiceRecord> it = proc.executingServices.iterator(); 12012 ServiceRecord timeout = null; 12013 long nextTime = 0; 12014 while (it.hasNext()) { 12015 ServiceRecord sr = it.next(); 12016 if (sr.executingStart < maxTime) { 12017 timeout = sr; 12018 break; 12019 } 12020 if (sr.executingStart > nextTime) { 12021 nextTime = sr.executingStart; 12022 } 12023 } 12024 if (timeout != null && mLruProcesses.contains(proc)) { 12025 Slog.w(TAG, "Timeout executing service: " + timeout); 12026 anrMessage = "Executing service " + timeout.shortName; 12027 } else { 12028 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 12029 msg.obj = proc; 12030 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT); 12031 } 12032 } 12033 12034 if (anrMessage != null) { 12035 appNotResponding(proc, null, null, anrMessage); 12036 } 12037 } 12038 12039 // ========================================================= 12040 // BACKUP AND RESTORE 12041 // ========================================================= 12042 12043 // Cause the target app to be launched if necessary and its backup agent 12044 // instantiated. The backup agent will invoke backupAgentCreated() on the 12045 // activity manager to announce its creation. 12046 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12047 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode); 12048 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent"); 12049 12050 synchronized(this) { 12051 // !!! TODO: currently no check here that we're already bound 12052 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12053 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12054 synchronized (stats) { 12055 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12056 } 12057 12058 BackupRecord r = new BackupRecord(ss, app, backupMode); 12059 ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName); 12060 // startProcessLocked() returns existing proc's record if it's already running 12061 ProcessRecord proc = startProcessLocked(app.processName, app, 12062 false, 0, "backup", hostingName, false); 12063 if (proc == null) { 12064 Slog.e(TAG, "Unable to start backup agent process " + r); 12065 return false; 12066 } 12067 12068 r.app = proc; 12069 mBackupTarget = r; 12070 mBackupAppName = app.packageName; 12071 12072 // Try not to kill the process during backup 12073 updateOomAdjLocked(proc); 12074 12075 // If the process is already attached, schedule the creation of the backup agent now. 12076 // If it is not yet live, this will be done when it attaches to the framework. 12077 if (proc.thread != null) { 12078 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12079 try { 12080 proc.thread.scheduleCreateBackupAgent(app, backupMode); 12081 } catch (RemoteException e) { 12082 // Will time out on the backup manager side 12083 } 12084 } else { 12085 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 12086 } 12087 // Invariants: at this point, the target app process exists and the application 12088 // is either already running or in the process of coming up. mBackupTarget and 12089 // mBackupAppName describe the app, so that when it binds back to the AM we 12090 // know that it's scheduled for a backup-agent operation. 12091 } 12092 12093 return true; 12094 } 12095 12096 // A backup agent has just come up 12097 public void backupAgentCreated(String agentPackageName, IBinder agent) { 12098 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 12099 + " = " + agent); 12100 12101 synchronized(this) { 12102 if (!agentPackageName.equals(mBackupAppName)) { 12103 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 12104 return; 12105 } 12106 12107 long oldIdent = Binder.clearCallingIdentity(); 12108 try { 12109 IBackupManager bm = IBackupManager.Stub.asInterface( 12110 ServiceManager.getService(Context.BACKUP_SERVICE)); 12111 bm.agentConnected(agentPackageName, agent); 12112 } catch (RemoteException e) { 12113 // can't happen; the backup manager service is local 12114 } catch (Exception e) { 12115 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 12116 e.printStackTrace(); 12117 } finally { 12118 Binder.restoreCallingIdentity(oldIdent); 12119 } 12120 } 12121 } 12122 12123 // done with this agent 12124 public void unbindBackupAgent(ApplicationInfo appInfo) { 12125 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 12126 if (appInfo == null) { 12127 Slog.w(TAG, "unbind backup agent for null app"); 12128 return; 12129 } 12130 12131 synchronized(this) { 12132 if (mBackupAppName == null) { 12133 Slog.w(TAG, "Unbinding backup agent with no active backup"); 12134 return; 12135 } 12136 12137 if (!mBackupAppName.equals(appInfo.packageName)) { 12138 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 12139 return; 12140 } 12141 12142 ProcessRecord proc = mBackupTarget.app; 12143 mBackupTarget = null; 12144 mBackupAppName = null; 12145 12146 // Not backing this app up any more; reset its OOM adjustment 12147 updateOomAdjLocked(proc); 12148 12149 // If the app crashed during backup, 'thread' will be null here 12150 if (proc.thread != null) { 12151 try { 12152 proc.thread.scheduleDestroyBackupAgent(appInfo); 12153 } catch (Exception e) { 12154 Slog.e(TAG, "Exception when unbinding backup agent:"); 12155 e.printStackTrace(); 12156 } 12157 } 12158 } 12159 } 12160 // ========================================================= 12161 // BROADCASTS 12162 // ========================================================= 12163 12164 private final List getStickiesLocked(String action, IntentFilter filter, 12165 List cur) { 12166 final ContentResolver resolver = mContext.getContentResolver(); 12167 final ArrayList<Intent> list = mStickyBroadcasts.get(action); 12168 if (list == null) { 12169 return cur; 12170 } 12171 int N = list.size(); 12172 for (int i=0; i<N; i++) { 12173 Intent intent = list.get(i); 12174 if (filter.match(resolver, intent, true, TAG) >= 0) { 12175 if (cur == null) { 12176 cur = new ArrayList<Intent>(); 12177 } 12178 cur.add(intent); 12179 } 12180 } 12181 return cur; 12182 } 12183 12184 private final void scheduleBroadcastsLocked() { 12185 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current=" 12186 + mBroadcastsScheduled); 12187 12188 if (mBroadcastsScheduled) { 12189 return; 12190 } 12191 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG); 12192 mBroadcastsScheduled = true; 12193 } 12194 12195 public Intent registerReceiver(IApplicationThread caller, 12196 IIntentReceiver receiver, IntentFilter filter, String permission) { 12197 synchronized(this) { 12198 ProcessRecord callerApp = null; 12199 if (caller != null) { 12200 callerApp = getRecordForAppLocked(caller); 12201 if (callerApp == null) { 12202 throw new SecurityException( 12203 "Unable to find app for caller " + caller 12204 + " (pid=" + Binder.getCallingPid() 12205 + ") when registering receiver " + receiver); 12206 } 12207 } 12208 12209 List allSticky = null; 12210 12211 // Look for any matching sticky broadcasts... 12212 Iterator actions = filter.actionsIterator(); 12213 if (actions != null) { 12214 while (actions.hasNext()) { 12215 String action = (String)actions.next(); 12216 allSticky = getStickiesLocked(action, filter, allSticky); 12217 } 12218 } else { 12219 allSticky = getStickiesLocked(null, filter, allSticky); 12220 } 12221 12222 // The first sticky in the list is returned directly back to 12223 // the client. 12224 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 12225 12226 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 12227 + ": " + sticky); 12228 12229 if (receiver == null) { 12230 return sticky; 12231 } 12232 12233 ReceiverList rl 12234 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 12235 if (rl == null) { 12236 rl = new ReceiverList(this, callerApp, 12237 Binder.getCallingPid(), 12238 Binder.getCallingUid(), receiver); 12239 if (rl.app != null) { 12240 rl.app.receivers.add(rl); 12241 } else { 12242 try { 12243 receiver.asBinder().linkToDeath(rl, 0); 12244 } catch (RemoteException e) { 12245 return sticky; 12246 } 12247 rl.linkedToDeath = true; 12248 } 12249 mRegisteredReceivers.put(receiver.asBinder(), rl); 12250 } 12251 BroadcastFilter bf = new BroadcastFilter(filter, rl, permission); 12252 rl.add(bf); 12253 if (!bf.debugCheck()) { 12254 Slog.w(TAG, "==> For Dynamic broadast"); 12255 } 12256 mReceiverResolver.addFilter(bf); 12257 12258 // Enqueue broadcasts for all existing stickies that match 12259 // this filter. 12260 if (allSticky != null) { 12261 ArrayList receivers = new ArrayList(); 12262 receivers.add(bf); 12263 12264 int N = allSticky.size(); 12265 for (int i=0; i<N; i++) { 12266 Intent intent = (Intent)allSticky.get(i); 12267 BroadcastRecord r = new BroadcastRecord(intent, null, 12268 null, -1, -1, null, receivers, null, 0, null, null, 12269 false, true, true); 12270 if (mParallelBroadcasts.size() == 0) { 12271 scheduleBroadcastsLocked(); 12272 } 12273 mParallelBroadcasts.add(r); 12274 } 12275 } 12276 12277 return sticky; 12278 } 12279 } 12280 12281 public void unregisterReceiver(IIntentReceiver receiver) { 12282 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 12283 12284 boolean doNext = false; 12285 12286 synchronized(this) { 12287 ReceiverList rl 12288 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 12289 if (rl != null) { 12290 if (rl.curBroadcast != null) { 12291 BroadcastRecord r = rl.curBroadcast; 12292 doNext = finishReceiverLocked( 12293 receiver.asBinder(), r.resultCode, r.resultData, 12294 r.resultExtras, r.resultAbort, true); 12295 } 12296 12297 if (rl.app != null) { 12298 rl.app.receivers.remove(rl); 12299 } 12300 removeReceiverLocked(rl); 12301 if (rl.linkedToDeath) { 12302 rl.linkedToDeath = false; 12303 rl.receiver.asBinder().unlinkToDeath(rl, 0); 12304 } 12305 } 12306 } 12307 12308 if (!doNext) { 12309 return; 12310 } 12311 12312 final long origId = Binder.clearCallingIdentity(); 12313 processNextBroadcast(false); 12314 trimApplications(); 12315 Binder.restoreCallingIdentity(origId); 12316 } 12317 12318 void removeReceiverLocked(ReceiverList rl) { 12319 mRegisteredReceivers.remove(rl.receiver.asBinder()); 12320 int N = rl.size(); 12321 for (int i=0; i<N; i++) { 12322 mReceiverResolver.removeFilter(rl.get(i)); 12323 } 12324 } 12325 12326 private final void sendPackageBroadcastLocked(int cmd, String[] packages) { 12327 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 12328 ProcessRecord r = mLruProcesses.get(i); 12329 if (r.thread != null) { 12330 try { 12331 r.thread.dispatchPackageBroadcast(cmd, packages); 12332 } catch (RemoteException ex) { 12333 } 12334 } 12335 } 12336 } 12337 12338 private final int broadcastIntentLocked(ProcessRecord callerApp, 12339 String callerPackage, Intent intent, String resolvedType, 12340 IIntentReceiver resultTo, int resultCode, String resultData, 12341 Bundle map, String requiredPermission, 12342 boolean ordered, boolean sticky, int callingPid, int callingUid) { 12343 intent = new Intent(intent); 12344 12345 if (DEBUG_BROADCAST_LIGHT) Slog.v( 12346 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 12347 + " ordered=" + ordered); 12348 if ((resultTo != null) && !ordered) { 12349 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 12350 } 12351 12352 // Handle special intents: if this broadcast is from the package 12353 // manager about a package being removed, we need to remove all of 12354 // its activities from the history stack. 12355 final boolean uidRemoved = intent.ACTION_UID_REMOVED.equals( 12356 intent.getAction()); 12357 if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 12358 || intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 12359 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 12360 || uidRemoved) { 12361 if (checkComponentPermission( 12362 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 12363 callingPid, callingUid, -1) 12364 == PackageManager.PERMISSION_GRANTED) { 12365 if (uidRemoved) { 12366 final Bundle intentExtras = intent.getExtras(); 12367 final int uid = intentExtras != null 12368 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 12369 if (uid >= 0) { 12370 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 12371 synchronized (bs) { 12372 bs.removeUidStatsLocked(uid); 12373 } 12374 } 12375 } else { 12376 // If resources are unvailble just force stop all 12377 // those packages and flush the attribute cache as well. 12378 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 12379 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 12380 if (list != null && (list.length > 0)) { 12381 for (String pkg : list) { 12382 forceStopPackageLocked(pkg, -1, false, true, true); 12383 } 12384 sendPackageBroadcastLocked( 12385 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list); 12386 } 12387 } else { 12388 Uri data = intent.getData(); 12389 String ssp; 12390 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 12391 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 12392 forceStopPackageLocked(ssp, 12393 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true); 12394 } 12395 if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { 12396 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 12397 new String[] {ssp}); 12398 } 12399 } 12400 } 12401 } 12402 } else { 12403 String msg = "Permission Denial: " + intent.getAction() 12404 + " broadcast from " + callerPackage + " (pid=" + callingPid 12405 + ", uid=" + callingUid + ")" 12406 + " requires " 12407 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 12408 Slog.w(TAG, msg); 12409 throw new SecurityException(msg); 12410 } 12411 } 12412 12413 /* 12414 * If this is the time zone changed action, queue up a message that will reset the timezone 12415 * of all currently running processes. This message will get queued up before the broadcast 12416 * happens. 12417 */ 12418 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 12419 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 12420 } 12421 12422 /* 12423 * Prevent non-system code (defined here to be non-persistent 12424 * processes) from sending protected broadcasts. 12425 */ 12426 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID 12427 || callingUid == Process.SHELL_UID || callingUid == 0) { 12428 // Always okay. 12429 } else if (callerApp == null || !callerApp.persistent) { 12430 try { 12431 if (ActivityThread.getPackageManager().isProtectedBroadcast( 12432 intent.getAction())) { 12433 String msg = "Permission Denial: not allowed to send broadcast " 12434 + intent.getAction() + " from pid=" 12435 + callingPid + ", uid=" + callingUid; 12436 Slog.w(TAG, msg); 12437 throw new SecurityException(msg); 12438 } 12439 } catch (RemoteException e) { 12440 Slog.w(TAG, "Remote exception", e); 12441 return BROADCAST_SUCCESS; 12442 } 12443 } 12444 12445 // Add to the sticky list if requested. 12446 if (sticky) { 12447 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 12448 callingPid, callingUid) 12449 != PackageManager.PERMISSION_GRANTED) { 12450 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 12451 + callingPid + ", uid=" + callingUid 12452 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 12453 Slog.w(TAG, msg); 12454 throw new SecurityException(msg); 12455 } 12456 if (requiredPermission != null) { 12457 Slog.w(TAG, "Can't broadcast sticky intent " + intent 12458 + " and enforce permission " + requiredPermission); 12459 return BROADCAST_STICKY_CANT_HAVE_PERMISSION; 12460 } 12461 if (intent.getComponent() != null) { 12462 throw new SecurityException( 12463 "Sticky broadcasts can't target a specific component"); 12464 } 12465 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 12466 if (list == null) { 12467 list = new ArrayList<Intent>(); 12468 mStickyBroadcasts.put(intent.getAction(), list); 12469 } 12470 int N = list.size(); 12471 int i; 12472 for (i=0; i<N; i++) { 12473 if (intent.filterEquals(list.get(i))) { 12474 // This sticky already exists, replace it. 12475 list.set(i, new Intent(intent)); 12476 break; 12477 } 12478 } 12479 if (i >= N) { 12480 list.add(new Intent(intent)); 12481 } 12482 } 12483 12484 // Figure out who all will receive this broadcast. 12485 List receivers = null; 12486 List<BroadcastFilter> registeredReceivers = null; 12487 try { 12488 if (intent.getComponent() != null) { 12489 // Broadcast is going to one specific receiver class... 12490 ActivityInfo ai = ActivityThread.getPackageManager(). 12491 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS); 12492 if (ai != null) { 12493 receivers = new ArrayList(); 12494 ResolveInfo ri = new ResolveInfo(); 12495 ri.activityInfo = ai; 12496 receivers.add(ri); 12497 } 12498 } else { 12499 // Need to resolve the intent to interested receivers... 12500 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 12501 == 0) { 12502 receivers = 12503 ActivityThread.getPackageManager().queryIntentReceivers( 12504 intent, resolvedType, STOCK_PM_FLAGS); 12505 } 12506 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false); 12507 } 12508 } catch (RemoteException ex) { 12509 // pm is in same process, this will never happen. 12510 } 12511 12512 final boolean replacePending = 12513 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 12514 12515 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 12516 + " replacePending=" + replacePending); 12517 12518 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 12519 if (!ordered && NR > 0) { 12520 // If we are not serializing this broadcast, then send the 12521 // registered receivers separately so they don't wait for the 12522 // components to be launched. 12523 BroadcastRecord r = new BroadcastRecord(intent, callerApp, 12524 callerPackage, callingPid, callingUid, requiredPermission, 12525 registeredReceivers, resultTo, resultCode, resultData, map, 12526 ordered, sticky, false); 12527 if (DEBUG_BROADCAST) Slog.v( 12528 TAG, "Enqueueing parallel broadcast " + r 12529 + ": prev had " + mParallelBroadcasts.size()); 12530 boolean replaced = false; 12531 if (replacePending) { 12532 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) { 12533 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) { 12534 if (DEBUG_BROADCAST) Slog.v(TAG, 12535 "***** DROPPING PARALLEL: " + intent); 12536 mParallelBroadcasts.set(i, r); 12537 replaced = true; 12538 break; 12539 } 12540 } 12541 } 12542 if (!replaced) { 12543 mParallelBroadcasts.add(r); 12544 scheduleBroadcastsLocked(); 12545 } 12546 registeredReceivers = null; 12547 NR = 0; 12548 } 12549 12550 // Merge into one list. 12551 int ir = 0; 12552 if (receivers != null) { 12553 // A special case for PACKAGE_ADDED: do not allow the package 12554 // being added to see this broadcast. This prevents them from 12555 // using this as a back door to get run as soon as they are 12556 // installed. Maybe in the future we want to have a special install 12557 // broadcast or such for apps, but we'd like to deliberately make 12558 // this decision. 12559 String skipPackages[] = null; 12560 if (intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 12561 || intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 12562 || intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 12563 Uri data = intent.getData(); 12564 if (data != null) { 12565 String pkgName = data.getSchemeSpecificPart(); 12566 if (pkgName != null) { 12567 skipPackages = new String[] { pkgName }; 12568 } 12569 } 12570 } else if (intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 12571 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 12572 } 12573 if (skipPackages != null && (skipPackages.length > 0)) { 12574 for (String skipPackage : skipPackages) { 12575 if (skipPackage != null) { 12576 int NT = receivers.size(); 12577 for (int it=0; it<NT; it++) { 12578 ResolveInfo curt = (ResolveInfo)receivers.get(it); 12579 if (curt.activityInfo.packageName.equals(skipPackage)) { 12580 receivers.remove(it); 12581 it--; 12582 NT--; 12583 } 12584 } 12585 } 12586 } 12587 } 12588 12589 int NT = receivers != null ? receivers.size() : 0; 12590 int it = 0; 12591 ResolveInfo curt = null; 12592 BroadcastFilter curr = null; 12593 while (it < NT && ir < NR) { 12594 if (curt == null) { 12595 curt = (ResolveInfo)receivers.get(it); 12596 } 12597 if (curr == null) { 12598 curr = registeredReceivers.get(ir); 12599 } 12600 if (curr.getPriority() >= curt.priority) { 12601 // Insert this broadcast record into the final list. 12602 receivers.add(it, curr); 12603 ir++; 12604 curr = null; 12605 it++; 12606 NT++; 12607 } else { 12608 // Skip to the next ResolveInfo in the final list. 12609 it++; 12610 curt = null; 12611 } 12612 } 12613 } 12614 while (ir < NR) { 12615 if (receivers == null) { 12616 receivers = new ArrayList(); 12617 } 12618 receivers.add(registeredReceivers.get(ir)); 12619 ir++; 12620 } 12621 12622 if ((receivers != null && receivers.size() > 0) 12623 || resultTo != null) { 12624 BroadcastRecord r = new BroadcastRecord(intent, callerApp, 12625 callerPackage, callingPid, callingUid, requiredPermission, 12626 receivers, resultTo, resultCode, resultData, map, ordered, 12627 sticky, false); 12628 if (DEBUG_BROADCAST) Slog.v( 12629 TAG, "Enqueueing ordered broadcast " + r 12630 + ": prev had " + mOrderedBroadcasts.size()); 12631 if (DEBUG_BROADCAST) { 12632 int seq = r.intent.getIntExtra("seq", -1); 12633 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 12634 } 12635 boolean replaced = false; 12636 if (replacePending) { 12637 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) { 12638 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) { 12639 if (DEBUG_BROADCAST) Slog.v(TAG, 12640 "***** DROPPING ORDERED: " + intent); 12641 mOrderedBroadcasts.set(i, r); 12642 replaced = true; 12643 break; 12644 } 12645 } 12646 } 12647 if (!replaced) { 12648 mOrderedBroadcasts.add(r); 12649 scheduleBroadcastsLocked(); 12650 } 12651 } 12652 12653 return BROADCAST_SUCCESS; 12654 } 12655 12656 public final int broadcastIntent(IApplicationThread caller, 12657 Intent intent, String resolvedType, IIntentReceiver resultTo, 12658 int resultCode, String resultData, Bundle map, 12659 String requiredPermission, boolean serialized, boolean sticky) { 12660 // Refuse possible leaked file descriptors 12661 if (intent != null && intent.hasFileDescriptors() == true) { 12662 throw new IllegalArgumentException("File descriptors passed in Intent"); 12663 } 12664 12665 synchronized(this) { 12666 int flags = intent.getFlags(); 12667 12668 if (!mSystemReady) { 12669 // if the caller really truly claims to know what they're doing, go 12670 // ahead and allow the broadcast without launching any receivers 12671 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 12672 intent = new Intent(intent); 12673 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 12674 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0){ 12675 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 12676 + " before boot completion"); 12677 throw new IllegalStateException("Cannot broadcast before boot completed"); 12678 } 12679 } 12680 12681 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 12682 throw new IllegalArgumentException( 12683 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 12684 } 12685 12686 final ProcessRecord callerApp = getRecordForAppLocked(caller); 12687 final int callingPid = Binder.getCallingPid(); 12688 final int callingUid = Binder.getCallingUid(); 12689 final long origId = Binder.clearCallingIdentity(); 12690 int res = broadcastIntentLocked(callerApp, 12691 callerApp != null ? callerApp.info.packageName : null, 12692 intent, resolvedType, resultTo, 12693 resultCode, resultData, map, requiredPermission, serialized, 12694 sticky, callingPid, callingUid); 12695 Binder.restoreCallingIdentity(origId); 12696 return res; 12697 } 12698 } 12699 12700 int broadcastIntentInPackage(String packageName, int uid, 12701 Intent intent, String resolvedType, IIntentReceiver resultTo, 12702 int resultCode, String resultData, Bundle map, 12703 String requiredPermission, boolean serialized, boolean sticky) { 12704 synchronized(this) { 12705 final long origId = Binder.clearCallingIdentity(); 12706 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 12707 resultTo, resultCode, resultData, map, requiredPermission, 12708 serialized, sticky, -1, uid); 12709 Binder.restoreCallingIdentity(origId); 12710 return res; 12711 } 12712 } 12713 12714 public final void unbroadcastIntent(IApplicationThread caller, 12715 Intent intent) { 12716 // Refuse possible leaked file descriptors 12717 if (intent != null && intent.hasFileDescriptors() == true) { 12718 throw new IllegalArgumentException("File descriptors passed in Intent"); 12719 } 12720 12721 synchronized(this) { 12722 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 12723 != PackageManager.PERMISSION_GRANTED) { 12724 String msg = "Permission Denial: unbroadcastIntent() from pid=" 12725 + Binder.getCallingPid() 12726 + ", uid=" + Binder.getCallingUid() 12727 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 12728 Slog.w(TAG, msg); 12729 throw new SecurityException(msg); 12730 } 12731 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction()); 12732 if (list != null) { 12733 int N = list.size(); 12734 int i; 12735 for (i=0; i<N; i++) { 12736 if (intent.filterEquals(list.get(i))) { 12737 list.remove(i); 12738 break; 12739 } 12740 } 12741 } 12742 } 12743 } 12744 12745 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 12746 String resultData, Bundle resultExtras, boolean resultAbort, 12747 boolean explicit) { 12748 if (mOrderedBroadcasts.size() == 0) { 12749 if (explicit) { 12750 Slog.w(TAG, "finishReceiver called but no pending broadcasts"); 12751 } 12752 return false; 12753 } 12754 BroadcastRecord r = mOrderedBroadcasts.get(0); 12755 if (r.receiver == null) { 12756 if (explicit) { 12757 Slog.w(TAG, "finishReceiver called but none active"); 12758 } 12759 return false; 12760 } 12761 if (r.receiver != receiver) { 12762 Slog.w(TAG, "finishReceiver called but active receiver is different"); 12763 return false; 12764 } 12765 int state = r.state; 12766 r.state = r.IDLE; 12767 if (state == r.IDLE) { 12768 if (explicit) { 12769 Slog.w(TAG, "finishReceiver called but state is IDLE"); 12770 } 12771 } 12772 r.receiver = null; 12773 r.intent.setComponent(null); 12774 if (r.curApp != null) { 12775 r.curApp.curReceiver = null; 12776 } 12777 if (r.curFilter != null) { 12778 r.curFilter.receiverList.curBroadcast = null; 12779 } 12780 r.curFilter = null; 12781 r.curApp = null; 12782 r.curComponent = null; 12783 r.curReceiver = null; 12784 mPendingBroadcast = null; 12785 12786 r.resultCode = resultCode; 12787 r.resultData = resultData; 12788 r.resultExtras = resultExtras; 12789 r.resultAbort = resultAbort; 12790 12791 // We will process the next receiver right now if this is finishing 12792 // an app receiver (which is always asynchronous) or after we have 12793 // come back from calling a receiver. 12794 return state == BroadcastRecord.APP_RECEIVE 12795 || state == BroadcastRecord.CALL_DONE_RECEIVE; 12796 } 12797 12798 public void finishReceiver(IBinder who, int resultCode, String resultData, 12799 Bundle resultExtras, boolean resultAbort) { 12800 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 12801 12802 // Refuse possible leaked file descriptors 12803 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 12804 throw new IllegalArgumentException("File descriptors passed in Bundle"); 12805 } 12806 12807 boolean doNext; 12808 12809 final long origId = Binder.clearCallingIdentity(); 12810 12811 synchronized(this) { 12812 doNext = finishReceiverLocked( 12813 who, resultCode, resultData, resultExtras, resultAbort, true); 12814 } 12815 12816 if (doNext) { 12817 processNextBroadcast(false); 12818 } 12819 trimApplications(); 12820 12821 Binder.restoreCallingIdentity(origId); 12822 } 12823 12824 private final void logBroadcastReceiverDiscard(BroadcastRecord r) { 12825 if (r.nextReceiver > 0) { 12826 Object curReceiver = r.receivers.get(r.nextReceiver-1); 12827 if (curReceiver instanceof BroadcastFilter) { 12828 BroadcastFilter bf = (BroadcastFilter) curReceiver; 12829 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER, 12830 System.identityHashCode(r), 12831 r.intent.getAction(), 12832 r.nextReceiver - 1, 12833 System.identityHashCode(bf)); 12834 } else { 12835 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP, 12836 System.identityHashCode(r), 12837 r.intent.getAction(), 12838 r.nextReceiver - 1, 12839 ((ResolveInfo)curReceiver).toString()); 12840 } 12841 } else { 12842 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: " 12843 + r); 12844 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP, 12845 System.identityHashCode(r), 12846 r.intent.getAction(), 12847 r.nextReceiver, 12848 "NONE"); 12849 } 12850 } 12851 12852 private final void broadcastTimeout() { 12853 ProcessRecord app = null; 12854 String anrMessage = null; 12855 12856 synchronized (this) { 12857 if (mOrderedBroadcasts.size() == 0) { 12858 return; 12859 } 12860 long now = SystemClock.uptimeMillis(); 12861 BroadcastRecord r = mOrderedBroadcasts.get(0); 12862 if ((r.receiverTime+BROADCAST_TIMEOUT) > now) { 12863 if (DEBUG_BROADCAST) Slog.v(TAG, 12864 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for " 12865 + (r.receiverTime + BROADCAST_TIMEOUT)); 12866 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG); 12867 mHandler.sendMessageAtTime(msg, r.receiverTime+BROADCAST_TIMEOUT); 12868 return; 12869 } 12870 12871 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver); 12872 r.receiverTime = now; 12873 r.anrCount++; 12874 12875 // Current receiver has passed its expiration date. 12876 if (r.nextReceiver <= 0) { 12877 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0"); 12878 return; 12879 } 12880 12881 Object curReceiver = r.receivers.get(r.nextReceiver-1); 12882 Slog.w(TAG, "Receiver during timeout: " + curReceiver); 12883 logBroadcastReceiverDiscard(r); 12884 if (curReceiver instanceof BroadcastFilter) { 12885 BroadcastFilter bf = (BroadcastFilter)curReceiver; 12886 if (bf.receiverList.pid != 0 12887 && bf.receiverList.pid != MY_PID) { 12888 synchronized (this.mPidsSelfLocked) { 12889 app = this.mPidsSelfLocked.get( 12890 bf.receiverList.pid); 12891 } 12892 } 12893 } else { 12894 app = r.curApp; 12895 } 12896 12897 if (app != null) { 12898 anrMessage = "Broadcast of " + r.intent.toString(); 12899 } 12900 12901 if (mPendingBroadcast == r) { 12902 mPendingBroadcast = null; 12903 } 12904 12905 // Move on to the next receiver. 12906 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 12907 r.resultExtras, r.resultAbort, true); 12908 scheduleBroadcastsLocked(); 12909 } 12910 12911 if (anrMessage != null) { 12912 appNotResponding(app, null, null, anrMessage); 12913 } 12914 } 12915 12916 private final void processCurBroadcastLocked(BroadcastRecord r, 12917 ProcessRecord app) throws RemoteException { 12918 if (app.thread == null) { 12919 throw new RemoteException(); 12920 } 12921 r.receiver = app.thread.asBinder(); 12922 r.curApp = app; 12923 app.curReceiver = r; 12924 updateLruProcessLocked(app, true, true); 12925 12926 // Tell the application to launch this receiver. 12927 r.intent.setComponent(r.curComponent); 12928 12929 boolean started = false; 12930 try { 12931 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, 12932 "Delivering to component " + r.curComponent 12933 + ": " + r); 12934 ensurePackageDexOpt(r.intent.getComponent().getPackageName()); 12935 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver, 12936 r.resultCode, r.resultData, r.resultExtras, r.ordered); 12937 started = true; 12938 } finally { 12939 if (!started) { 12940 r.receiver = null; 12941 r.curApp = null; 12942 app.curReceiver = null; 12943 } 12944 } 12945 12946 } 12947 12948 static void performReceive(ProcessRecord app, IIntentReceiver receiver, 12949 Intent intent, int resultCode, String data, Bundle extras, 12950 boolean ordered, boolean sticky) throws RemoteException { 12951 if (app != null && app.thread != null) { 12952 // If we have an app thread, do the call through that so it is 12953 // correctly ordered with other one-way calls. 12954 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode, 12955 data, extras, ordered, sticky); 12956 } else { 12957 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky); 12958 } 12959 } 12960 12961 private final void deliverToRegisteredReceiver(BroadcastRecord r, 12962 BroadcastFilter filter, boolean ordered) { 12963 boolean skip = false; 12964 if (filter.requiredPermission != null) { 12965 int perm = checkComponentPermission(filter.requiredPermission, 12966 r.callingPid, r.callingUid, -1); 12967 if (perm != PackageManager.PERMISSION_GRANTED) { 12968 Slog.w(TAG, "Permission Denial: broadcasting " 12969 + r.intent.toString() 12970 + " from " + r.callerPackage + " (pid=" 12971 + r.callingPid + ", uid=" + r.callingUid + ")" 12972 + " requires " + filter.requiredPermission 12973 + " due to registered receiver " + filter); 12974 skip = true; 12975 } 12976 } 12977 if (r.requiredPermission != null) { 12978 int perm = checkComponentPermission(r.requiredPermission, 12979 filter.receiverList.pid, filter.receiverList.uid, -1); 12980 if (perm != PackageManager.PERMISSION_GRANTED) { 12981 Slog.w(TAG, "Permission Denial: receiving " 12982 + r.intent.toString() 12983 + " to " + filter.receiverList.app 12984 + " (pid=" + filter.receiverList.pid 12985 + ", uid=" + filter.receiverList.uid + ")" 12986 + " requires " + r.requiredPermission 12987 + " due to sender " + r.callerPackage 12988 + " (uid " + r.callingUid + ")"); 12989 skip = true; 12990 } 12991 } 12992 12993 if (!skip) { 12994 // If this is not being sent as an ordered broadcast, then we 12995 // don't want to touch the fields that keep track of the current 12996 // state of ordered broadcasts. 12997 if (ordered) { 12998 r.receiver = filter.receiverList.receiver.asBinder(); 12999 r.curFilter = filter; 13000 filter.receiverList.curBroadcast = r; 13001 r.state = BroadcastRecord.CALL_IN_RECEIVE; 13002 if (filter.receiverList.app != null) { 13003 // Bump hosting application to no longer be in background 13004 // scheduling class. Note that we can't do that if there 13005 // isn't an app... but we can only be in that case for 13006 // things that directly call the IActivityManager API, which 13007 // are already core system stuff so don't matter for this. 13008 r.curApp = filter.receiverList.app; 13009 filter.receiverList.app.curReceiver = r; 13010 updateOomAdjLocked(); 13011 } 13012 } 13013 try { 13014 if (DEBUG_BROADCAST_LIGHT) { 13015 int seq = r.intent.getIntExtra("seq", -1); 13016 Slog.i(TAG, "Delivering to " + filter 13017 + " (seq=" + seq + "): " + r); 13018 } 13019 performReceive(filter.receiverList.app, filter.receiverList.receiver, 13020 new Intent(r.intent), r.resultCode, 13021 r.resultData, r.resultExtras, r.ordered, r.initialSticky); 13022 if (ordered) { 13023 r.state = BroadcastRecord.CALL_DONE_RECEIVE; 13024 } 13025 } catch (RemoteException e) { 13026 Slog.w(TAG, "Failure sending broadcast " + r.intent, e); 13027 if (ordered) { 13028 r.receiver = null; 13029 r.curFilter = null; 13030 filter.receiverList.curBroadcast = null; 13031 if (filter.receiverList.app != null) { 13032 filter.receiverList.app.curReceiver = null; 13033 } 13034 } 13035 } 13036 } 13037 } 13038 13039 private final void addBroadcastToHistoryLocked(BroadcastRecord r) { 13040 if (r.callingUid < 0) { 13041 // This was from a registerReceiver() call; ignore it. 13042 return; 13043 } 13044 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1, 13045 MAX_BROADCAST_HISTORY-1); 13046 r.finishTime = SystemClock.uptimeMillis(); 13047 mBroadcastHistory[0] = r; 13048 } 13049 13050 private final void processNextBroadcast(boolean fromMsg) { 13051 synchronized(this) { 13052 BroadcastRecord r; 13053 13054 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: " 13055 + mParallelBroadcasts.size() + " broadcasts, " 13056 + mOrderedBroadcasts.size() + " ordered broadcasts"); 13057 13058 updateCpuStats(); 13059 13060 if (fromMsg) { 13061 mBroadcastsScheduled = false; 13062 } 13063 13064 // First, deliver any non-serialized broadcasts right away. 13065 while (mParallelBroadcasts.size() > 0) { 13066 r = mParallelBroadcasts.remove(0); 13067 r.dispatchTime = SystemClock.uptimeMillis(); 13068 final int N = r.receivers.size(); 13069 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast " 13070 + r); 13071 for (int i=0; i<N; i++) { 13072 Object target = r.receivers.get(i); 13073 if (DEBUG_BROADCAST) Slog.v(TAG, 13074 "Delivering non-ordered to registered " 13075 + target + ": " + r); 13076 deliverToRegisteredReceiver(r, (BroadcastFilter)target, false); 13077 } 13078 addBroadcastToHistoryLocked(r); 13079 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast " 13080 + r); 13081 } 13082 13083 // Now take care of the next serialized one... 13084 13085 // If we are waiting for a process to come up to handle the next 13086 // broadcast, then do nothing at this point. Just in case, we 13087 // check that the process we're waiting for still exists. 13088 if (mPendingBroadcast != null) { 13089 if (DEBUG_BROADCAST_LIGHT) { 13090 Slog.v(TAG, "processNextBroadcast: waiting for " 13091 + mPendingBroadcast.curApp); 13092 } 13093 13094 boolean isDead; 13095 synchronized (mPidsSelfLocked) { 13096 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null); 13097 } 13098 if (!isDead) { 13099 // It's still alive, so keep waiting 13100 return; 13101 } else { 13102 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp 13103 + " died before responding to broadcast"); 13104 mPendingBroadcast = null; 13105 } 13106 } 13107 13108 boolean looped = false; 13109 13110 do { 13111 if (mOrderedBroadcasts.size() == 0) { 13112 // No more broadcasts pending, so all done! 13113 scheduleAppGcsLocked(); 13114 if (looped) { 13115 // If we had finished the last ordered broadcast, then 13116 // make sure all processes have correct oom and sched 13117 // adjustments. 13118 updateOomAdjLocked(); 13119 } 13120 return; 13121 } 13122 r = mOrderedBroadcasts.get(0); 13123 boolean forceReceive = false; 13124 13125 // Ensure that even if something goes awry with the timeout 13126 // detection, we catch "hung" broadcasts here, discard them, 13127 // and continue to make progress. 13128 // 13129 // This is only done if the system is ready so that PRE_BOOT_COMPLETED 13130 // receivers don't get executed with with timeouts. They're intended for 13131 // one time heavy lifting after system upgrades and can take 13132 // significant amounts of time. 13133 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0; 13134 if (mSystemReady && r.dispatchTime > 0) { 13135 long now = SystemClock.uptimeMillis(); 13136 if ((numReceivers > 0) && 13137 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) { 13138 Slog.w(TAG, "Hung broadcast discarded after timeout failure:" 13139 + " now=" + now 13140 + " dispatchTime=" + r.dispatchTime 13141 + " startTime=" + r.receiverTime 13142 + " intent=" + r.intent 13143 + " numReceivers=" + numReceivers 13144 + " nextReceiver=" + r.nextReceiver 13145 + " state=" + r.state); 13146 broadcastTimeout(); // forcibly finish this broadcast 13147 forceReceive = true; 13148 r.state = BroadcastRecord.IDLE; 13149 } 13150 } 13151 13152 if (r.state != BroadcastRecord.IDLE) { 13153 if (DEBUG_BROADCAST) Slog.d(TAG, 13154 "processNextBroadcast() called when not idle (state=" 13155 + r.state + ")"); 13156 return; 13157 } 13158 13159 if (r.receivers == null || r.nextReceiver >= numReceivers 13160 || r.resultAbort || forceReceive) { 13161 // No more receivers for this broadcast! Send the final 13162 // result if requested... 13163 if (r.resultTo != null) { 13164 try { 13165 if (DEBUG_BROADCAST) { 13166 int seq = r.intent.getIntExtra("seq", -1); 13167 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction() 13168 + " seq=" + seq + " app=" + r.callerApp); 13169 } 13170 performReceive(r.callerApp, r.resultTo, 13171 new Intent(r.intent), r.resultCode, 13172 r.resultData, r.resultExtras, false, false); 13173 } catch (RemoteException e) { 13174 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e); 13175 } 13176 } 13177 13178 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG"); 13179 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG); 13180 13181 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast " 13182 + r); 13183 13184 // ... and on to the next... 13185 addBroadcastToHistoryLocked(r); 13186 mOrderedBroadcasts.remove(0); 13187 r = null; 13188 looped = true; 13189 continue; 13190 } 13191 } while (r == null); 13192 13193 // Get the next receiver... 13194 int recIdx = r.nextReceiver++; 13195 13196 // Keep track of when this receiver started, and make sure there 13197 // is a timeout message pending to kill it if need be. 13198 r.receiverTime = SystemClock.uptimeMillis(); 13199 if (recIdx == 0) { 13200 r.dispatchTime = r.receiverTime; 13201 13202 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast " 13203 + r); 13204 if (DEBUG_BROADCAST) Slog.v(TAG, 13205 "Submitting BROADCAST_TIMEOUT_MSG for " 13206 + (r.receiverTime + BROADCAST_TIMEOUT)); 13207 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG); 13208 mHandler.sendMessageAtTime(msg, r.receiverTime+BROADCAST_TIMEOUT); 13209 } 13210 13211 Object nextReceiver = r.receivers.get(recIdx); 13212 if (nextReceiver instanceof BroadcastFilter) { 13213 // Simple case: this is a registered receiver who gets 13214 // a direct call. 13215 BroadcastFilter filter = (BroadcastFilter)nextReceiver; 13216 if (DEBUG_BROADCAST) Slog.v(TAG, 13217 "Delivering ordered to registered " 13218 + filter + ": " + r); 13219 deliverToRegisteredReceiver(r, filter, r.ordered); 13220 if (r.receiver == null || !r.ordered) { 13221 // The receiver has already finished, so schedule to 13222 // process the next one. 13223 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered=" 13224 + r.ordered + " receiver=" + r.receiver); 13225 r.state = BroadcastRecord.IDLE; 13226 scheduleBroadcastsLocked(); 13227 } 13228 return; 13229 } 13230 13231 // Hard case: need to instantiate the receiver, possibly 13232 // starting its application process to host it. 13233 13234 ResolveInfo info = 13235 (ResolveInfo)nextReceiver; 13236 13237 boolean skip = false; 13238 int perm = checkComponentPermission(info.activityInfo.permission, 13239 r.callingPid, r.callingUid, 13240 info.activityInfo.exported 13241 ? -1 : info.activityInfo.applicationInfo.uid); 13242 if (perm != PackageManager.PERMISSION_GRANTED) { 13243 Slog.w(TAG, "Permission Denial: broadcasting " 13244 + r.intent.toString() 13245 + " from " + r.callerPackage + " (pid=" + r.callingPid 13246 + ", uid=" + r.callingUid + ")" 13247 + " requires " + info.activityInfo.permission 13248 + " due to receiver " + info.activityInfo.packageName 13249 + "/" + info.activityInfo.name); 13250 skip = true; 13251 } 13252 if (r.callingUid != Process.SYSTEM_UID && 13253 r.requiredPermission != null) { 13254 try { 13255 perm = ActivityThread.getPackageManager(). 13256 checkPermission(r.requiredPermission, 13257 info.activityInfo.applicationInfo.packageName); 13258 } catch (RemoteException e) { 13259 perm = PackageManager.PERMISSION_DENIED; 13260 } 13261 if (perm != PackageManager.PERMISSION_GRANTED) { 13262 Slog.w(TAG, "Permission Denial: receiving " 13263 + r.intent + " to " 13264 + info.activityInfo.applicationInfo.packageName 13265 + " requires " + r.requiredPermission 13266 + " due to sender " + r.callerPackage 13267 + " (uid " + r.callingUid + ")"); 13268 skip = true; 13269 } 13270 } 13271 if (r.curApp != null && r.curApp.crashing) { 13272 // If the target process is crashing, just skip it. 13273 skip = true; 13274 } 13275 13276 if (skip) { 13277 r.receiver = null; 13278 r.curFilter = null; 13279 r.state = BroadcastRecord.IDLE; 13280 scheduleBroadcastsLocked(); 13281 return; 13282 } 13283 13284 r.state = BroadcastRecord.APP_RECEIVE; 13285 String targetProcess = info.activityInfo.processName; 13286 r.curComponent = new ComponentName( 13287 info.activityInfo.applicationInfo.packageName, 13288 info.activityInfo.name); 13289 r.curReceiver = info.activityInfo; 13290 13291 // Is this receiver's application already running? 13292 ProcessRecord app = getProcessRecordLocked(targetProcess, 13293 info.activityInfo.applicationInfo.uid); 13294 if (app != null && app.thread != null) { 13295 try { 13296 processCurBroadcastLocked(r, app); 13297 return; 13298 } catch (RemoteException e) { 13299 Slog.w(TAG, "Exception when sending broadcast to " 13300 + r.curComponent, e); 13301 } 13302 13303 // If a dead object exception was thrown -- fall through to 13304 // restart the application. 13305 } 13306 13307 // Not running -- get it started, to be executed when the app comes up. 13308 if ((r.curApp=startProcessLocked(targetProcess, 13309 info.activityInfo.applicationInfo, true, 13310 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND, 13311 "broadcast", r.curComponent, 13312 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0)) 13313 == null) { 13314 // Ah, this recipient is unavailable. Finish it if necessary, 13315 // and mark the broadcast record as ready for the next. 13316 Slog.w(TAG, "Unable to launch app " 13317 + info.activityInfo.applicationInfo.packageName + "/" 13318 + info.activityInfo.applicationInfo.uid + " for broadcast " 13319 + r.intent + ": process is bad"); 13320 logBroadcastReceiverDiscard(r); 13321 finishReceiverLocked(r.receiver, r.resultCode, r.resultData, 13322 r.resultExtras, r.resultAbort, true); 13323 scheduleBroadcastsLocked(); 13324 r.state = BroadcastRecord.IDLE; 13325 return; 13326 } 13327 13328 mPendingBroadcast = r; 13329 } 13330 } 13331 13332 // ========================================================= 13333 // INSTRUMENTATION 13334 // ========================================================= 13335 13336 public boolean startInstrumentation(ComponentName className, 13337 String profileFile, int flags, Bundle arguments, 13338 IInstrumentationWatcher watcher) { 13339 // Refuse possible leaked file descriptors 13340 if (arguments != null && arguments.hasFileDescriptors()) { 13341 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13342 } 13343 13344 synchronized(this) { 13345 InstrumentationInfo ii = null; 13346 ApplicationInfo ai = null; 13347 try { 13348 ii = mContext.getPackageManager().getInstrumentationInfo( 13349 className, STOCK_PM_FLAGS); 13350 ai = mContext.getPackageManager().getApplicationInfo( 13351 ii.targetPackage, STOCK_PM_FLAGS); 13352 } catch (PackageManager.NameNotFoundException e) { 13353 } 13354 if (ii == null) { 13355 reportStartInstrumentationFailure(watcher, className, 13356 "Unable to find instrumentation info for: " + className); 13357 return false; 13358 } 13359 if (ai == null) { 13360 reportStartInstrumentationFailure(watcher, className, 13361 "Unable to find instrumentation target package: " + ii.targetPackage); 13362 return false; 13363 } 13364 13365 int match = mContext.getPackageManager().checkSignatures( 13366 ii.targetPackage, ii.packageName); 13367 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 13368 String msg = "Permission Denial: starting instrumentation " 13369 + className + " from pid=" 13370 + Binder.getCallingPid() 13371 + ", uid=" + Binder.getCallingPid() 13372 + " not allowed because package " + ii.packageName 13373 + " does not have a signature matching the target " 13374 + ii.targetPackage; 13375 reportStartInstrumentationFailure(watcher, className, msg); 13376 throw new SecurityException(msg); 13377 } 13378 13379 final long origId = Binder.clearCallingIdentity(); 13380 forceStopPackageLocked(ii.targetPackage, -1, true, false, true); 13381 ProcessRecord app = addAppLocked(ai); 13382 app.instrumentationClass = className; 13383 app.instrumentationInfo = ai; 13384 app.instrumentationProfileFile = profileFile; 13385 app.instrumentationArguments = arguments; 13386 app.instrumentationWatcher = watcher; 13387 app.instrumentationResultClass = className; 13388 Binder.restoreCallingIdentity(origId); 13389 } 13390 13391 return true; 13392 } 13393 13394 /** 13395 * Report errors that occur while attempting to start Instrumentation. Always writes the 13396 * error to the logs, but if somebody is watching, send the report there too. This enables 13397 * the "am" command to report errors with more information. 13398 * 13399 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 13400 * @param cn The component name of the instrumentation. 13401 * @param report The error report. 13402 */ 13403 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 13404 ComponentName cn, String report) { 13405 Slog.w(TAG, report); 13406 try { 13407 if (watcher != null) { 13408 Bundle results = new Bundle(); 13409 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 13410 results.putString("Error", report); 13411 watcher.instrumentationStatus(cn, -1, results); 13412 } 13413 } catch (RemoteException e) { 13414 Slog.w(TAG, e); 13415 } 13416 } 13417 13418 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 13419 if (app.instrumentationWatcher != null) { 13420 try { 13421 // NOTE: IInstrumentationWatcher *must* be oneway here 13422 app.instrumentationWatcher.instrumentationFinished( 13423 app.instrumentationClass, 13424 resultCode, 13425 results); 13426 } catch (RemoteException e) { 13427 } 13428 } 13429 app.instrumentationWatcher = null; 13430 app.instrumentationClass = null; 13431 app.instrumentationInfo = null; 13432 app.instrumentationProfileFile = null; 13433 app.instrumentationArguments = null; 13434 13435 forceStopPackageLocked(app.processName, -1, false, false, true); 13436 } 13437 13438 public void finishInstrumentation(IApplicationThread target, 13439 int resultCode, Bundle results) { 13440 // Refuse possible leaked file descriptors 13441 if (results != null && results.hasFileDescriptors()) { 13442 throw new IllegalArgumentException("File descriptors passed in Intent"); 13443 } 13444 13445 synchronized(this) { 13446 ProcessRecord app = getRecordForAppLocked(target); 13447 if (app == null) { 13448 Slog.w(TAG, "finishInstrumentation: no app for " + target); 13449 return; 13450 } 13451 final long origId = Binder.clearCallingIdentity(); 13452 finishInstrumentationLocked(app, resultCode, results); 13453 Binder.restoreCallingIdentity(origId); 13454 } 13455 } 13456 13457 // ========================================================= 13458 // CONFIGURATION 13459 // ========================================================= 13460 13461 public ConfigurationInfo getDeviceConfigurationInfo() { 13462 ConfigurationInfo config = new ConfigurationInfo(); 13463 synchronized (this) { 13464 config.reqTouchScreen = mConfiguration.touchscreen; 13465 config.reqKeyboardType = mConfiguration.keyboard; 13466 config.reqNavigation = mConfiguration.navigation; 13467 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 13468 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 13469 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 13470 } 13471 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 13472 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 13473 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 13474 } 13475 config.reqGlEsVersion = GL_ES_VERSION; 13476 } 13477 return config; 13478 } 13479 13480 public Configuration getConfiguration() { 13481 Configuration ci; 13482 synchronized(this) { 13483 ci = new Configuration(mConfiguration); 13484 } 13485 return ci; 13486 } 13487 13488 public void updateConfiguration(Configuration values) { 13489 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 13490 "updateConfiguration()"); 13491 13492 synchronized(this) { 13493 if (values == null && mWindowManager != null) { 13494 // sentinel: fetch the current configuration from the window manager 13495 values = mWindowManager.computeNewConfiguration(); 13496 } 13497 13498 final long origId = Binder.clearCallingIdentity(); 13499 updateConfigurationLocked(values, null); 13500 Binder.restoreCallingIdentity(origId); 13501 } 13502 } 13503 13504 /** 13505 * Do either or both things: (1) change the current configuration, and (2) 13506 * make sure the given activity is running with the (now) current 13507 * configuration. Returns true if the activity has been left running, or 13508 * false if <var>starting</var> is being destroyed to match the new 13509 * configuration. 13510 */ 13511 public boolean updateConfigurationLocked(Configuration values, 13512 HistoryRecord starting) { 13513 int changes = 0; 13514 13515 boolean kept = true; 13516 13517 if (values != null) { 13518 Configuration newConfig = new Configuration(mConfiguration); 13519 changes = newConfig.updateFrom(values); 13520 if (changes != 0) { 13521 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13522 Slog.i(TAG, "Updating configuration to: " + values); 13523 } 13524 13525 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 13526 13527 if (values.locale != null) { 13528 saveLocaleLocked(values.locale, 13529 !values.locale.equals(mConfiguration.locale), 13530 values.userSetLocale); 13531 } 13532 13533 mConfigurationSeq++; 13534 if (mConfigurationSeq <= 0) { 13535 mConfigurationSeq = 1; 13536 } 13537 newConfig.seq = mConfigurationSeq; 13538 mConfiguration = newConfig; 13539 Slog.i(TAG, "Config changed: " + newConfig); 13540 13541 AttributeCache ac = AttributeCache.instance(); 13542 if (ac != null) { 13543 ac.updateConfiguration(mConfiguration); 13544 } 13545 13546 if (Settings.System.hasInterestingConfigurationChanges(changes)) { 13547 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 13548 msg.obj = new Configuration(mConfiguration); 13549 mHandler.sendMessage(msg); 13550 } 13551 13552 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13553 ProcessRecord app = mLruProcesses.get(i); 13554 try { 13555 if (app.thread != null) { 13556 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 13557 + app.processName + " new config " + mConfiguration); 13558 app.thread.scheduleConfigurationChanged(mConfiguration); 13559 } 13560 } catch (Exception e) { 13561 } 13562 } 13563 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 13564 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 13565 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 13566 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 13567 null, false, false, MY_PID, Process.SYSTEM_UID); 13568 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 13569 broadcastIntentLocked(null, null, 13570 new Intent(Intent.ACTION_LOCALE_CHANGED), 13571 null, null, 0, null, null, 13572 null, false, false, MY_PID, Process.SYSTEM_UID); 13573 } 13574 } 13575 } 13576 13577 if (changes != 0 && starting == null) { 13578 // If the configuration changed, and the caller is not already 13579 // in the process of starting an activity, then find the top 13580 // activity to check if its configuration needs to change. 13581 starting = topRunningActivityLocked(null); 13582 } 13583 13584 if (starting != null) { 13585 kept = ensureActivityConfigurationLocked(starting, changes); 13586 if (kept) { 13587 // If this didn't result in the starting activity being 13588 // destroyed, then we need to make sure at this point that all 13589 // other activities are made visible. 13590 if (DEBUG_SWITCH) Slog.i(TAG, "Config didn't destroy " + starting 13591 + ", ensuring others are correct."); 13592 ensureActivitiesVisibleLocked(starting, changes); 13593 } 13594 } 13595 13596 if (values != null && mWindowManager != null) { 13597 mWindowManager.setNewConfiguration(mConfiguration); 13598 } 13599 13600 return kept; 13601 } 13602 13603 private final boolean relaunchActivityLocked(HistoryRecord r, 13604 int changes, boolean andResume) { 13605 List<ResultInfo> results = null; 13606 List<Intent> newIntents = null; 13607 if (andResume) { 13608 results = r.results; 13609 newIntents = r.newIntents; 13610 } 13611 if (DEBUG_SWITCH) Slog.v(TAG, "Relaunching: " + r 13612 + " with results=" + results + " newIntents=" + newIntents 13613 + " andResume=" + andResume); 13614 EventLog.writeEvent(andResume ? EventLogTags.AM_RELAUNCH_RESUME_ACTIVITY 13615 : EventLogTags.AM_RELAUNCH_ACTIVITY, System.identityHashCode(r), 13616 r.task.taskId, r.shortComponentName); 13617 13618 r.startFreezingScreenLocked(r.app, 0); 13619 13620 try { 13621 if (DEBUG_SWITCH) Slog.i(TAG, "Switch is restarting resumed " + r); 13622 r.app.thread.scheduleRelaunchActivity(r, results, newIntents, 13623 changes, !andResume, mConfiguration); 13624 // Note: don't need to call pauseIfSleepingLocked() here, because 13625 // the caller will only pass in 'andResume' if this activity is 13626 // currently resumed, which implies we aren't sleeping. 13627 } catch (RemoteException e) { 13628 return false; 13629 } 13630 13631 if (andResume) { 13632 r.results = null; 13633 r.newIntents = null; 13634 reportResumedActivityLocked(r); 13635 } 13636 13637 return true; 13638 } 13639 13640 /** 13641 * Make sure the given activity matches the current configuration. Returns 13642 * false if the activity had to be destroyed. Returns true if the 13643 * configuration is the same, or the activity will remain running as-is 13644 * for whatever reason. Ensures the HistoryRecord is updated with the 13645 * correct configuration and all other bookkeeping is handled. 13646 */ 13647 private final boolean ensureActivityConfigurationLocked(HistoryRecord r, 13648 int globalChanges) { 13649 if (mConfigWillChange) { 13650 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG, 13651 "Skipping config check (will change): " + r); 13652 return true; 13653 } 13654 13655 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG, 13656 "Ensuring correct configuration: " + r); 13657 13658 // Short circuit: if the two configurations are the exact same 13659 // object (the common case), then there is nothing to do. 13660 Configuration newConfig = mConfiguration; 13661 if (r.configuration == newConfig) { 13662 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG, 13663 "Configuration unchanged in " + r); 13664 return true; 13665 } 13666 13667 // We don't worry about activities that are finishing. 13668 if (r.finishing) { 13669 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG, 13670 "Configuration doesn't matter in finishing " + r); 13671 r.stopFreezingScreenLocked(false); 13672 return true; 13673 } 13674 13675 // Okay we now are going to make this activity have the new config. 13676 // But then we need to figure out how it needs to deal with that. 13677 Configuration oldConfig = r.configuration; 13678 r.configuration = newConfig; 13679 13680 // If the activity isn't currently running, just leave the new 13681 // configuration and it will pick that up next time it starts. 13682 if (r.app == null || r.app.thread == null) { 13683 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG, 13684 "Configuration doesn't matter not running " + r); 13685 r.stopFreezingScreenLocked(false); 13686 return true; 13687 } 13688 13689 // If the activity isn't persistent, there is a chance we will 13690 // need to restart it. 13691 if (!r.persistent) { 13692 13693 // Figure out what has changed between the two configurations. 13694 int changes = oldConfig.diff(newConfig); 13695 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 13696 Slog.v(TAG, "Checking to restart " + r.info.name + ": changed=0x" 13697 + Integer.toHexString(changes) + ", handles=0x" 13698 + Integer.toHexString(r.info.configChanges) 13699 + ", newConfig=" + newConfig); 13700 } 13701 if ((changes&(~r.info.configChanges)) != 0) { 13702 // Aha, the activity isn't handling the change, so DIE DIE DIE. 13703 r.configChangeFlags |= changes; 13704 r.startFreezingScreenLocked(r.app, globalChanges); 13705 if (r.app == null || r.app.thread == null) { 13706 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG, 13707 "Switch is destroying non-running " + r); 13708 destroyActivityLocked(r, true); 13709 } else if (r.state == ActivityState.PAUSING) { 13710 // A little annoying: we are waiting for this activity to 13711 // finish pausing. Let's not do anything now, but just 13712 // flag that it needs to be restarted when done pausing. 13713 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG, 13714 "Switch is skipping already pausing " + r); 13715 r.configDestroy = true; 13716 return true; 13717 } else if (r.state == ActivityState.RESUMED) { 13718 // Try to optimize this case: the configuration is changing 13719 // and we need to restart the top, resumed activity. 13720 // Instead of doing the normal handshaking, just say 13721 // "restart!". 13722 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG, 13723 "Switch is restarting resumed " + r); 13724 relaunchActivityLocked(r, r.configChangeFlags, true); 13725 r.configChangeFlags = 0; 13726 } else { 13727 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG, 13728 "Switch is restarting non-resumed " + r); 13729 relaunchActivityLocked(r, r.configChangeFlags, false); 13730 r.configChangeFlags = 0; 13731 } 13732 13733 // All done... tell the caller we weren't able to keep this 13734 // activity around. 13735 return false; 13736 } 13737 } 13738 13739 // Default case: the activity can handle this new configuration, so 13740 // hand it over. Note that we don't need to give it the new 13741 // configuration, since we always send configuration changes to all 13742 // process when they happen so it can just use whatever configuration 13743 // it last got. 13744 if (r.app != null && r.app.thread != null) { 13745 try { 13746 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending new config to " + r); 13747 r.app.thread.scheduleActivityConfigurationChanged(r); 13748 } catch (RemoteException e) { 13749 // If process died, whatever. 13750 } 13751 } 13752 r.stopFreezingScreenLocked(false); 13753 13754 return true; 13755 } 13756 13757 /** 13758 * Save the locale. You must be inside a synchronized (this) block. 13759 */ 13760 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 13761 if(isDiff) { 13762 SystemProperties.set("user.language", l.getLanguage()); 13763 SystemProperties.set("user.region", l.getCountry()); 13764 } 13765 13766 if(isPersist) { 13767 SystemProperties.set("persist.sys.language", l.getLanguage()); 13768 SystemProperties.set("persist.sys.country", l.getCountry()); 13769 SystemProperties.set("persist.sys.localevar", l.getVariant()); 13770 } 13771 } 13772 13773 // ========================================================= 13774 // LIFETIME MANAGEMENT 13775 // ========================================================= 13776 13777 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, 13778 ProcessRecord TOP_APP, boolean recursed) { 13779 if (mAdjSeq == app.adjSeq) { 13780 // This adjustment has already been computed. If we are calling 13781 // from the top, we may have already computed our adjustment with 13782 // an earlier hidden adjustment that isn't really for us... if 13783 // so, use the new hidden adjustment. 13784 if (!recursed && app.hidden) { 13785 app.curAdj = hiddenAdj; 13786 } 13787 return app.curAdj; 13788 } 13789 13790 if (app.thread == null) { 13791 app.adjSeq = mAdjSeq; 13792 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13793 return (app.curAdj=EMPTY_APP_ADJ); 13794 } 13795 13796 if (app.maxAdj <= FOREGROUND_APP_ADJ) { 13797 // The max adjustment doesn't allow this app to be anything 13798 // below foreground, so it is not worth doing work for it. 13799 app.adjType = "fixed"; 13800 app.adjSeq = mAdjSeq; 13801 app.curRawAdj = app.maxAdj; 13802 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 13803 return (app.curAdj=app.maxAdj); 13804 } 13805 13806 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 13807 app.adjSource = null; 13808 app.adjTarget = null; 13809 app.empty = false; 13810 app.hidden = false; 13811 13812 // Determine the importance of the process, starting with most 13813 // important to least, and assign an appropriate OOM adjustment. 13814 int adj; 13815 int schedGroup; 13816 int N; 13817 if (app == TOP_APP) { 13818 // The last app on the list is the foreground app. 13819 adj = FOREGROUND_APP_ADJ; 13820 schedGroup = Process.THREAD_GROUP_DEFAULT; 13821 app.adjType = "top-activity"; 13822 } else if (app.instrumentationClass != null) { 13823 // Don't want to kill running instrumentation. 13824 adj = FOREGROUND_APP_ADJ; 13825 schedGroup = Process.THREAD_GROUP_DEFAULT; 13826 app.adjType = "instrumentation"; 13827 } else if (app.persistentActivities > 0) { 13828 // Special persistent activities... shouldn't be used these days. 13829 adj = FOREGROUND_APP_ADJ; 13830 schedGroup = Process.THREAD_GROUP_DEFAULT; 13831 app.adjType = "persistent"; 13832 } else if (app.curReceiver != null || 13833 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) { 13834 // An app that is currently receiving a broadcast also 13835 // counts as being in the foreground. 13836 adj = FOREGROUND_APP_ADJ; 13837 schedGroup = Process.THREAD_GROUP_DEFAULT; 13838 app.adjType = "broadcast"; 13839 } else if (app.executingServices.size() > 0) { 13840 // An app that is currently executing a service callback also 13841 // counts as being in the foreground. 13842 adj = FOREGROUND_APP_ADJ; 13843 schedGroup = Process.THREAD_GROUP_DEFAULT; 13844 app.adjType = "exec-service"; 13845 } else if (app.foregroundServices) { 13846 // The user is aware of this app, so make it visible. 13847 adj = VISIBLE_APP_ADJ; 13848 schedGroup = Process.THREAD_GROUP_DEFAULT; 13849 app.adjType = "foreground-service"; 13850 } else if (app.forcingToForeground != null) { 13851 // The user is aware of this app, so make it visible. 13852 adj = VISIBLE_APP_ADJ; 13853 schedGroup = Process.THREAD_GROUP_DEFAULT; 13854 app.adjType = "force-foreground"; 13855 app.adjSource = app.forcingToForeground; 13856 } else if (app == mHomeProcess) { 13857 // This process is hosting what we currently consider to be the 13858 // home app, so we don't want to let it go into the background. 13859 adj = HOME_APP_ADJ; 13860 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13861 app.adjType = "home"; 13862 } else if ((N=app.activities.size()) != 0) { 13863 // This app is in the background with paused activities. 13864 app.hidden = true; 13865 adj = hiddenAdj; 13866 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13867 app.adjType = "bg-activities"; 13868 N = app.activities.size(); 13869 for (int j=0; j<N; j++) { 13870 if (((HistoryRecord)app.activities.get(j)).visible) { 13871 // This app has a visible activity! 13872 app.hidden = false; 13873 adj = VISIBLE_APP_ADJ; 13874 schedGroup = Process.THREAD_GROUP_DEFAULT; 13875 app.adjType = "visible"; 13876 break; 13877 } 13878 } 13879 } else { 13880 // A very not-needed process. If this is lower in the lru list, 13881 // we will push it in to the empty bucket. 13882 app.hidden = true; 13883 app.empty = true; 13884 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 13885 adj = hiddenAdj; 13886 app.adjType = "bg-empty"; 13887 } 13888 13889 //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj); 13890 13891 // By default, we use the computed adjustment. It may be changed if 13892 // there are applications dependent on our services or providers, but 13893 // this gives us a baseline and makes sure we don't get into an 13894 // infinite recursion. 13895 app.adjSeq = mAdjSeq; 13896 app.curRawAdj = adj; 13897 13898 if (mBackupTarget != null && app == mBackupTarget.app) { 13899 // If possible we want to avoid killing apps while they're being backed up 13900 if (adj > BACKUP_APP_ADJ) { 13901 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 13902 adj = BACKUP_APP_ADJ; 13903 app.adjType = "backup"; 13904 app.hidden = false; 13905 } 13906 } 13907 13908 if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ 13909 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13910 final long now = SystemClock.uptimeMillis(); 13911 // This process is more important if the top activity is 13912 // bound to the service. 13913 Iterator jt = app.services.iterator(); 13914 while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) { 13915 ServiceRecord s = (ServiceRecord)jt.next(); 13916 if (s.startRequested) { 13917 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) { 13918 // This service has seen some activity within 13919 // recent memory, so we will keep its process ahead 13920 // of the background processes. 13921 if (adj > SECONDARY_SERVER_ADJ) { 13922 adj = SECONDARY_SERVER_ADJ; 13923 app.adjType = "started-services"; 13924 app.hidden = false; 13925 } 13926 } 13927 // If we have let the service slide into the background 13928 // state, still have some text describing what it is doing 13929 // even though the service no longer has an impact. 13930 if (adj > SECONDARY_SERVER_ADJ) { 13931 app.adjType = "started-bg-services"; 13932 } 13933 } 13934 if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ 13935 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 13936 Iterator<ConnectionRecord> kt 13937 = s.connections.values().iterator(); 13938 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) { 13939 // XXX should compute this based on the max of 13940 // all connected clients. 13941 ConnectionRecord cr = kt.next(); 13942 if (cr.binding.client == app) { 13943 // Binding to ourself is not interesting. 13944 continue; 13945 } 13946 if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) { 13947 ProcessRecord client = cr.binding.client; 13948 int myHiddenAdj = hiddenAdj; 13949 if (myHiddenAdj > client.hiddenAdj) { 13950 if (client.hiddenAdj > VISIBLE_APP_ADJ) { 13951 myHiddenAdj = client.hiddenAdj; 13952 } else { 13953 myHiddenAdj = VISIBLE_APP_ADJ; 13954 } 13955 } 13956 int clientAdj = computeOomAdjLocked( 13957 client, myHiddenAdj, TOP_APP, true); 13958 if (adj > clientAdj) { 13959 adj = clientAdj > VISIBLE_APP_ADJ 13960 ? clientAdj : VISIBLE_APP_ADJ; 13961 if (!client.hidden) { 13962 app.hidden = false; 13963 } 13964 app.adjType = "service"; 13965 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13966 .REASON_SERVICE_IN_USE; 13967 app.adjSource = cr.binding.client; 13968 app.adjTarget = s.serviceInfo.name; 13969 } 13970 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 13971 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 13972 schedGroup = Process.THREAD_GROUP_DEFAULT; 13973 } 13974 } 13975 } 13976 HistoryRecord a = cr.activity; 13977 //if (a != null) { 13978 // Slog.i(TAG, "Connection to " + a ": state=" + a.state); 13979 //} 13980 if (a != null && adj > FOREGROUND_APP_ADJ && 13981 (a.state == ActivityState.RESUMED 13982 || a.state == ActivityState.PAUSING)) { 13983 adj = FOREGROUND_APP_ADJ; 13984 schedGroup = Process.THREAD_GROUP_DEFAULT; 13985 app.hidden = false; 13986 app.adjType = "service"; 13987 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 13988 .REASON_SERVICE_IN_USE; 13989 app.adjSource = a; 13990 app.adjTarget = s.serviceInfo.name; 13991 } 13992 } 13993 } 13994 } 13995 13996 // Finally, f this process has active services running in it, we 13997 // would like to avoid killing it unless it would prevent the current 13998 // application from running. By default we put the process in 13999 // with the rest of the background processes; as we scan through 14000 // its services we may bump it up from there. 14001 if (adj > hiddenAdj) { 14002 adj = hiddenAdj; 14003 app.hidden = false; 14004 app.adjType = "bg-services"; 14005 } 14006 } 14007 14008 if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ 14009 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 14010 Iterator jt = app.pubProviders.values().iterator(); 14011 while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ 14012 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) { 14013 ContentProviderRecord cpr = (ContentProviderRecord)jt.next(); 14014 if (cpr.clients.size() != 0) { 14015 Iterator<ProcessRecord> kt = cpr.clients.iterator(); 14016 while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) { 14017 ProcessRecord client = kt.next(); 14018 if (client == app) { 14019 // Being our own client is not interesting. 14020 continue; 14021 } 14022 int myHiddenAdj = hiddenAdj; 14023 if (myHiddenAdj > client.hiddenAdj) { 14024 if (client.hiddenAdj > FOREGROUND_APP_ADJ) { 14025 myHiddenAdj = client.hiddenAdj; 14026 } else { 14027 myHiddenAdj = FOREGROUND_APP_ADJ; 14028 } 14029 } 14030 int clientAdj = computeOomAdjLocked( 14031 client, myHiddenAdj, TOP_APP, true); 14032 if (adj > clientAdj) { 14033 adj = clientAdj > FOREGROUND_APP_ADJ 14034 ? clientAdj : FOREGROUND_APP_ADJ; 14035 if (!client.hidden) { 14036 app.hidden = false; 14037 } 14038 app.adjType = "provider"; 14039 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14040 .REASON_PROVIDER_IN_USE; 14041 app.adjSource = client; 14042 app.adjTarget = cpr.info.name; 14043 } 14044 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14045 schedGroup = Process.THREAD_GROUP_DEFAULT; 14046 } 14047 } 14048 } 14049 // If the provider has external (non-framework) process 14050 // dependencies, ensure that its adjustment is at least 14051 // FOREGROUND_APP_ADJ. 14052 if (cpr.externals != 0) { 14053 if (adj > FOREGROUND_APP_ADJ) { 14054 adj = FOREGROUND_APP_ADJ; 14055 schedGroup = Process.THREAD_GROUP_DEFAULT; 14056 app.hidden = false; 14057 app.adjType = "provider"; 14058 app.adjTarget = cpr.info.name; 14059 } 14060 } 14061 } 14062 } 14063 14064 app.curRawAdj = adj; 14065 14066 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 14067 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 14068 if (adj > app.maxAdj) { 14069 adj = app.maxAdj;