ActivityManagerService.java revision fae2aabc30b0c3143fe3096140f8f4a9b00d87a7
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.ApplicationThreadNative; 37import android.app.IActivityContainer; 38import android.app.IActivityContainerCallback; 39import android.app.IAppTask; 40import android.app.ProfilerInfo; 41import android.app.admin.DevicePolicyManager; 42import android.app.usage.UsageEvents; 43import android.app.usage.UsageStatsManagerInternal; 44import android.appwidget.AppWidgetManager; 45import android.content.res.Resources; 46import android.graphics.Bitmap; 47import android.graphics.Point; 48import android.graphics.Rect; 49import android.os.BatteryStats; 50import android.os.PersistableBundle; 51import android.service.voice.IVoiceInteractionSession; 52import android.util.ArrayMap; 53import android.util.ArraySet; 54import android.util.SparseIntArray; 55 56import com.android.internal.R; 57import com.android.internal.annotations.GuardedBy; 58import com.android.internal.app.IAppOpsService; 59import com.android.internal.app.IVoiceInteractor; 60import com.android.internal.app.ProcessMap; 61import com.android.internal.app.ProcessStats; 62import com.android.internal.content.PackageMonitor; 63import com.android.internal.os.BackgroundThread; 64import com.android.internal.os.BatteryStatsImpl; 65import com.android.internal.os.ProcessCpuTracker; 66import com.android.internal.os.TransferPipe; 67import com.android.internal.os.Zygote; 68import com.android.internal.util.FastPrintWriter; 69import com.android.internal.util.FastXmlSerializer; 70import com.android.internal.util.MemInfoReader; 71import com.android.internal.util.Preconditions; 72import com.android.server.AppOpsService; 73import com.android.server.AttributeCache; 74import com.android.server.IntentResolver; 75import com.android.server.LocalServices; 76import com.android.server.ServiceThread; 77import com.android.server.SystemService; 78import com.android.server.SystemServiceManager; 79import com.android.server.Watchdog; 80import com.android.server.am.ActivityStack.ActivityState; 81import com.android.server.firewall.IntentFirewall; 82import com.android.server.pm.UserManagerService; 83import com.android.server.wm.AppTransition; 84import com.android.server.wm.WindowManagerService; 85import com.google.android.collect.Lists; 86import com.google.android.collect.Maps; 87 88import libcore.io.IoUtils; 89 90import org.xmlpull.v1.XmlPullParser; 91import org.xmlpull.v1.XmlPullParserException; 92import org.xmlpull.v1.XmlSerializer; 93 94import android.app.Activity; 95import android.app.ActivityManager; 96import android.app.ActivityManager.RunningTaskInfo; 97import android.app.ActivityManager.StackInfo; 98import android.app.ActivityManagerInternal; 99import android.app.ActivityManagerNative; 100import android.app.ActivityOptions; 101import android.app.ActivityThread; 102import android.app.AlertDialog; 103import android.app.AppGlobals; 104import android.app.ApplicationErrorReport; 105import android.app.Dialog; 106import android.app.IActivityController; 107import android.app.IApplicationThread; 108import android.app.IInstrumentationWatcher; 109import android.app.INotificationManager; 110import android.app.IProcessObserver; 111import android.app.IServiceConnection; 112import android.app.IStopUserCallback; 113import android.app.IUiAutomationConnection; 114import android.app.IUserSwitchObserver; 115import android.app.Instrumentation; 116import android.app.Notification; 117import android.app.NotificationManager; 118import android.app.PendingIntent; 119import android.app.backup.IBackupManager; 120import android.content.ActivityNotFoundException; 121import android.content.BroadcastReceiver; 122import android.content.ClipData; 123import android.content.ComponentCallbacks2; 124import android.content.ComponentName; 125import android.content.ContentProvider; 126import android.content.ContentResolver; 127import android.content.Context; 128import android.content.DialogInterface; 129import android.content.IContentProvider; 130import android.content.IIntentReceiver; 131import android.content.IIntentSender; 132import android.content.Intent; 133import android.content.IntentFilter; 134import android.content.IntentSender; 135import android.content.pm.ActivityInfo; 136import android.content.pm.ApplicationInfo; 137import android.content.pm.ConfigurationInfo; 138import android.content.pm.IPackageDataObserver; 139import android.content.pm.IPackageManager; 140import android.content.pm.InstrumentationInfo; 141import android.content.pm.PackageInfo; 142import android.content.pm.PackageManager; 143import android.content.pm.ParceledListSlice; 144import android.content.pm.UserInfo; 145import android.content.pm.PackageManager.NameNotFoundException; 146import android.content.pm.PathPermission; 147import android.content.pm.ProviderInfo; 148import android.content.pm.ResolveInfo; 149import android.content.pm.ServiceInfo; 150import android.content.res.CompatibilityInfo; 151import android.content.res.Configuration; 152import android.net.Proxy; 153import android.net.ProxyInfo; 154import android.net.Uri; 155import android.os.Binder; 156import android.os.Build; 157import android.os.Bundle; 158import android.os.Debug; 159import android.os.DropBoxManager; 160import android.os.Environment; 161import android.os.FactoryTest; 162import android.os.FileObserver; 163import android.os.FileUtils; 164import android.os.Handler; 165import android.os.IBinder; 166import android.os.IPermissionController; 167import android.os.IRemoteCallback; 168import android.os.IUserManager; 169import android.os.Looper; 170import android.os.Message; 171import android.os.Parcel; 172import android.os.ParcelFileDescriptor; 173import android.os.Process; 174import android.os.RemoteCallbackList; 175import android.os.RemoteException; 176import android.os.SELinux; 177import android.os.ServiceManager; 178import android.os.StrictMode; 179import android.os.SystemClock; 180import android.os.SystemProperties; 181import android.os.UpdateLock; 182import android.os.UserHandle; 183import android.os.UserManager; 184import android.provider.Settings; 185import android.text.format.DateUtils; 186import android.text.format.Time; 187import android.util.AtomicFile; 188import android.util.EventLog; 189import android.util.Log; 190import android.util.Pair; 191import android.util.PrintWriterPrinter; 192import android.util.Slog; 193import android.util.SparseArray; 194import android.util.TimeUtils; 195import android.util.Xml; 196import android.view.Gravity; 197import android.view.LayoutInflater; 198import android.view.View; 199import android.view.WindowManager; 200import dalvik.system.VMRuntime; 201 202import java.io.BufferedInputStream; 203import java.io.BufferedOutputStream; 204import java.io.DataInputStream; 205import java.io.DataOutputStream; 206import java.io.File; 207import java.io.FileDescriptor; 208import java.io.FileInputStream; 209import java.io.FileNotFoundException; 210import java.io.FileOutputStream; 211import java.io.IOException; 212import java.io.InputStreamReader; 213import java.io.PrintWriter; 214import java.io.StringWriter; 215import java.lang.ref.WeakReference; 216import java.util.ArrayList; 217import java.util.Arrays; 218import java.util.Collections; 219import java.util.Comparator; 220import java.util.HashMap; 221import java.util.HashSet; 222import java.util.Iterator; 223import java.util.List; 224import java.util.Locale; 225import java.util.Map; 226import java.util.Set; 227import java.util.concurrent.atomic.AtomicBoolean; 228import java.util.concurrent.atomic.AtomicLong; 229 230public final class ActivityManagerService extends ActivityManagerNative 231 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 232 233 private static final String USER_DATA_DIR = "/data/user/"; 234 // File that stores last updated system version and called preboot receivers 235 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 236 237 static final String TAG = "ActivityManager"; 238 static final String TAG_MU = "ActivityManagerServiceMU"; 239 static final boolean DEBUG = false; 240 static final boolean localLOGV = DEBUG; 241 static final boolean DEBUG_BACKUP = localLOGV || false; 242 static final boolean DEBUG_BROADCAST = localLOGV || false; 243 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 244 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 245 static final boolean DEBUG_CLEANUP = localLOGV || false; 246 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 247 static final boolean DEBUG_FOCUS = false; 248 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 249 static final boolean DEBUG_MU = localLOGV || false; 250 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 251 static final boolean DEBUG_LRU = localLOGV || false; 252 static final boolean DEBUG_PAUSE = localLOGV || false; 253 static final boolean DEBUG_POWER = localLOGV || false; 254 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 255 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 256 static final boolean DEBUG_PROCESSES = localLOGV || false; 257 static final boolean DEBUG_PROVIDER = localLOGV || false; 258 static final boolean DEBUG_RESULTS = localLOGV || false; 259 static final boolean DEBUG_SERVICE = localLOGV || false; 260 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 261 static final boolean DEBUG_STACK = localLOGV || false; 262 static final boolean DEBUG_SWITCH = localLOGV || false; 263 static final boolean DEBUG_TASKS = localLOGV || false; 264 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 265 static final boolean DEBUG_TRANSITION = localLOGV || false; 266 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 267 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 268 static final boolean DEBUG_VISBILITY = localLOGV || false; 269 static final boolean DEBUG_PSS = localLOGV || false; 270 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 271 static final boolean DEBUG_RECENTS = localLOGV || false; 272 static final boolean VALIDATE_TOKENS = false; 273 static final boolean SHOW_ACTIVITY_START_TIME = true; 274 275 // Control over CPU and battery monitoring. 276 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 277 static final boolean MONITOR_CPU_USAGE = true; 278 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 279 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 280 static final boolean MONITOR_THREAD_CPU_USAGE = false; 281 282 // The flags that are set for all calls we make to the package manager. 283 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 284 285 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 286 287 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 288 289 // Maximum number recent bitmaps to keep in memory. 290 static final int MAX_RECENT_BITMAPS = 5; 291 292 // Amount of time after a call to stopAppSwitches() during which we will 293 // prevent further untrusted switches from happening. 294 static final long APP_SWITCH_DELAY_TIME = 5*1000; 295 296 // How long we wait for a launched process to attach to the activity manager 297 // before we decide it's never going to come up for real. 298 static final int PROC_START_TIMEOUT = 10*1000; 299 300 // How long we wait for a launched process to attach to the activity manager 301 // before we decide it's never going to come up for real, when the process was 302 // started with a wrapper for instrumentation (such as Valgrind) because it 303 // could take much longer than usual. 304 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 305 306 // How long to wait after going idle before forcing apps to GC. 307 static final int GC_TIMEOUT = 5*1000; 308 309 // The minimum amount of time between successive GC requests for a process. 310 static final int GC_MIN_INTERVAL = 60*1000; 311 312 // The minimum amount of time between successive PSS requests for a process. 313 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 314 315 // The minimum amount of time between successive PSS requests for a process 316 // when the request is due to the memory state being lowered. 317 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 318 319 // The rate at which we check for apps using excessive power -- 15 mins. 320 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 321 322 // The minimum sample duration we will allow before deciding we have 323 // enough data on wake locks to start killing things. 324 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 325 326 // The minimum sample duration we will allow before deciding we have 327 // enough data on CPU usage to start killing things. 328 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 329 330 // How long we allow a receiver to run before giving up on it. 331 static final int BROADCAST_FG_TIMEOUT = 10*1000; 332 static final int BROADCAST_BG_TIMEOUT = 60*1000; 333 334 // How long we wait until we timeout on key dispatching. 335 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 336 337 // How long we wait until we timeout on key dispatching during instrumentation. 338 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 339 340 // Amount of time we wait for observers to handle a user switch before 341 // giving up on them and unfreezing the screen. 342 static final int USER_SWITCH_TIMEOUT = 2*1000; 343 344 // Maximum number of users we allow to be running at a time. 345 static final int MAX_RUNNING_USERS = 3; 346 347 // How long to wait in getAssistContextExtras for the activity and foreground services 348 // to respond with the result. 349 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 350 351 // Maximum number of persisted Uri grants a package is allowed 352 static final int MAX_PERSISTED_URI_GRANTS = 128; 353 354 static final int MY_PID = Process.myPid(); 355 356 static final String[] EMPTY_STRING_ARRAY = new String[0]; 357 358 // How many bytes to write into the dropbox log before truncating 359 static final int DROPBOX_MAX_SIZE = 256 * 1024; 360 361 // Access modes for handleIncomingUser. 362 static final int ALLOW_NON_FULL = 0; 363 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 364 static final int ALLOW_FULL_ONLY = 2; 365 366 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 367 368 /** All system services */ 369 SystemServiceManager mSystemServiceManager; 370 371 /** Run all ActivityStacks through this */ 372 ActivityStackSupervisor mStackSupervisor; 373 374 public IntentFirewall mIntentFirewall; 375 376 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 377 // default actuion automatically. Important for devices without direct input 378 // devices. 379 private boolean mShowDialogs = true; 380 381 BroadcastQueue mFgBroadcastQueue; 382 BroadcastQueue mBgBroadcastQueue; 383 // Convenient for easy iteration over the queues. Foreground is first 384 // so that dispatch of foreground broadcasts gets precedence. 385 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 386 387 BroadcastQueue broadcastQueueForIntent(Intent intent) { 388 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 389 if (DEBUG_BACKGROUND_BROADCAST) { 390 Slog.i(TAG, "Broadcast intent " + intent + " on " 391 + (isFg ? "foreground" : "background") 392 + " queue"); 393 } 394 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 395 } 396 397 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 398 for (BroadcastQueue queue : mBroadcastQueues) { 399 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 400 if (r != null) { 401 return r; 402 } 403 } 404 return null; 405 } 406 407 /** 408 * Activity we have told the window manager to have key focus. 409 */ 410 ActivityRecord mFocusedActivity = null; 411 412 /** 413 * List of intents that were used to start the most recent tasks. 414 */ 415 ArrayList<TaskRecord> mRecentTasks; 416 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 417 418 /** 419 * For addAppTask: cached of the last activity component that was added. 420 */ 421 ComponentName mLastAddedTaskComponent; 422 423 /** 424 * For addAppTask: cached of the last activity uid that was added. 425 */ 426 int mLastAddedTaskUid; 427 428 /** 429 * For addAppTask: cached of the last ActivityInfo that was added. 430 */ 431 ActivityInfo mLastAddedTaskActivity; 432 433 public class PendingAssistExtras extends Binder implements Runnable { 434 public final ActivityRecord activity; 435 public boolean haveResult = false; 436 public Bundle result = null; 437 public PendingAssistExtras(ActivityRecord _activity) { 438 activity = _activity; 439 } 440 @Override 441 public void run() { 442 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 443 synchronized (this) { 444 haveResult = true; 445 notifyAll(); 446 } 447 } 448 } 449 450 final ArrayList<PendingAssistExtras> mPendingAssistExtras 451 = new ArrayList<PendingAssistExtras>(); 452 453 /** 454 * Process management. 455 */ 456 final ProcessList mProcessList = new ProcessList(); 457 458 /** 459 * All of the applications we currently have running organized by name. 460 * The keys are strings of the application package name (as 461 * returned by the package manager), and the keys are ApplicationRecord 462 * objects. 463 */ 464 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 465 466 /** 467 * Tracking long-term execution of processes to look for abuse and other 468 * bad app behavior. 469 */ 470 final ProcessStatsService mProcessStats; 471 472 /** 473 * The currently running isolated processes. 474 */ 475 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 476 477 /** 478 * Counter for assigning isolated process uids, to avoid frequently reusing the 479 * same ones. 480 */ 481 int mNextIsolatedProcessUid = 0; 482 483 /** 484 * The currently running heavy-weight process, if any. 485 */ 486 ProcessRecord mHeavyWeightProcess = null; 487 488 /** 489 * The last time that various processes have crashed. 490 */ 491 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 492 493 /** 494 * Information about a process that is currently marked as bad. 495 */ 496 static final class BadProcessInfo { 497 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 498 this.time = time; 499 this.shortMsg = shortMsg; 500 this.longMsg = longMsg; 501 this.stack = stack; 502 } 503 504 final long time; 505 final String shortMsg; 506 final String longMsg; 507 final String stack; 508 } 509 510 /** 511 * Set of applications that we consider to be bad, and will reject 512 * incoming broadcasts from (which the user has no control over). 513 * Processes are added to this set when they have crashed twice within 514 * a minimum amount of time; they are removed from it when they are 515 * later restarted (hopefully due to some user action). The value is the 516 * time it was added to the list. 517 */ 518 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 519 520 /** 521 * All of the processes we currently have running organized by pid. 522 * The keys are the pid running the application. 523 * 524 * <p>NOTE: This object is protected by its own lock, NOT the global 525 * activity manager lock! 526 */ 527 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 528 529 /** 530 * All of the processes that have been forced to be foreground. The key 531 * is the pid of the caller who requested it (we hold a death 532 * link on it). 533 */ 534 abstract class ForegroundToken implements IBinder.DeathRecipient { 535 int pid; 536 IBinder token; 537 } 538 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 539 540 /** 541 * List of records for processes that someone had tried to start before the 542 * system was ready. We don't start them at that point, but ensure they 543 * are started by the time booting is complete. 544 */ 545 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 546 547 /** 548 * List of persistent applications that are in the process 549 * of being started. 550 */ 551 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 552 553 /** 554 * Processes that are being forcibly torn down. 555 */ 556 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 557 558 /** 559 * List of running applications, sorted by recent usage. 560 * The first entry in the list is the least recently used. 561 */ 562 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 563 564 /** 565 * Where in mLruProcesses that the processes hosting activities start. 566 */ 567 int mLruProcessActivityStart = 0; 568 569 /** 570 * Where in mLruProcesses that the processes hosting services start. 571 * This is after (lower index) than mLruProcessesActivityStart. 572 */ 573 int mLruProcessServiceStart = 0; 574 575 /** 576 * List of processes that should gc as soon as things are idle. 577 */ 578 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 579 580 /** 581 * Processes we want to collect PSS data from. 582 */ 583 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 584 585 /** 586 * Last time we requested PSS data of all processes. 587 */ 588 long mLastFullPssTime = SystemClock.uptimeMillis(); 589 590 /** 591 * If set, the next time we collect PSS data we should do a full collection 592 * with data from native processes and the kernel. 593 */ 594 boolean mFullPssPending = false; 595 596 /** 597 * This is the process holding what we currently consider to be 598 * the "home" activity. 599 */ 600 ProcessRecord mHomeProcess; 601 602 /** 603 * This is the process holding the activity the user last visited that 604 * is in a different process from the one they are currently in. 605 */ 606 ProcessRecord mPreviousProcess; 607 608 /** 609 * The time at which the previous process was last visible. 610 */ 611 long mPreviousProcessVisibleTime; 612 613 /** 614 * Which uses have been started, so are allowed to run code. 615 */ 616 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 617 618 /** 619 * LRU list of history of current users. Most recently current is at the end. 620 */ 621 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 622 623 /** 624 * Constant array of the users that are currently started. 625 */ 626 int[] mStartedUserArray = new int[] { 0 }; 627 628 /** 629 * Registered observers of the user switching mechanics. 630 */ 631 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 632 = new RemoteCallbackList<IUserSwitchObserver>(); 633 634 /** 635 * Currently active user switch. 636 */ 637 Object mCurUserSwitchCallback; 638 639 /** 640 * Packages that the user has asked to have run in screen size 641 * compatibility mode instead of filling the screen. 642 */ 643 final CompatModePackages mCompatModePackages; 644 645 /** 646 * Set of IntentSenderRecord objects that are currently active. 647 */ 648 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 649 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 650 651 /** 652 * Fingerprints (hashCode()) of stack traces that we've 653 * already logged DropBox entries for. Guarded by itself. If 654 * something (rogue user app) forces this over 655 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 656 */ 657 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 658 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 659 660 /** 661 * Strict Mode background batched logging state. 662 * 663 * The string buffer is guarded by itself, and its lock is also 664 * used to determine if another batched write is already 665 * in-flight. 666 */ 667 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 668 669 /** 670 * Keeps track of all IIntentReceivers that have been registered for 671 * broadcasts. Hash keys are the receiver IBinder, hash value is 672 * a ReceiverList. 673 */ 674 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 675 new HashMap<IBinder, ReceiverList>(); 676 677 /** 678 * Resolver for broadcast intents to registered receivers. 679 * Holds BroadcastFilter (subclass of IntentFilter). 680 */ 681 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 682 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 683 @Override 684 protected boolean allowFilterResult( 685 BroadcastFilter filter, List<BroadcastFilter> dest) { 686 IBinder target = filter.receiverList.receiver.asBinder(); 687 for (int i=dest.size()-1; i>=0; i--) { 688 if (dest.get(i).receiverList.receiver.asBinder() == target) { 689 return false; 690 } 691 } 692 return true; 693 } 694 695 @Override 696 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 697 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 698 || userId == filter.owningUserId) { 699 return super.newResult(filter, match, userId); 700 } 701 return null; 702 } 703 704 @Override 705 protected BroadcastFilter[] newArray(int size) { 706 return new BroadcastFilter[size]; 707 } 708 709 @Override 710 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 711 return packageName.equals(filter.packageName); 712 } 713 }; 714 715 /** 716 * State of all active sticky broadcasts per user. Keys are the action of the 717 * sticky Intent, values are an ArrayList of all broadcasted intents with 718 * that action (which should usually be one). The SparseArray is keyed 719 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 720 * for stickies that are sent to all users. 721 */ 722 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 723 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 724 725 final ActiveServices mServices; 726 727 /** 728 * Backup/restore process management 729 */ 730 String mBackupAppName = null; 731 BackupRecord mBackupTarget = null; 732 733 final ProviderMap mProviderMap; 734 735 /** 736 * List of content providers who have clients waiting for them. The 737 * application is currently being launched and the provider will be 738 * removed from this list once it is published. 739 */ 740 final ArrayList<ContentProviderRecord> mLaunchingProviders 741 = new ArrayList<ContentProviderRecord>(); 742 743 /** 744 * File storing persisted {@link #mGrantedUriPermissions}. 745 */ 746 private final AtomicFile mGrantFile; 747 748 /** XML constants used in {@link #mGrantFile} */ 749 private static final String TAG_URI_GRANTS = "uri-grants"; 750 private static final String TAG_URI_GRANT = "uri-grant"; 751 private static final String ATTR_USER_HANDLE = "userHandle"; 752 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 753 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 754 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 755 private static final String ATTR_TARGET_PKG = "targetPkg"; 756 private static final String ATTR_URI = "uri"; 757 private static final String ATTR_MODE_FLAGS = "modeFlags"; 758 private static final String ATTR_CREATED_TIME = "createdTime"; 759 private static final String ATTR_PREFIX = "prefix"; 760 761 /** 762 * Global set of specific {@link Uri} permissions that have been granted. 763 * This optimized lookup structure maps from {@link UriPermission#targetUid} 764 * to {@link UriPermission#uri} to {@link UriPermission}. 765 */ 766 @GuardedBy("this") 767 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 768 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 769 770 public static class GrantUri { 771 public final int sourceUserId; 772 public final Uri uri; 773 public boolean prefix; 774 775 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 776 this.sourceUserId = sourceUserId; 777 this.uri = uri; 778 this.prefix = prefix; 779 } 780 781 @Override 782 public int hashCode() { 783 return toString().hashCode(); 784 } 785 786 @Override 787 public boolean equals(Object o) { 788 if (o instanceof GrantUri) { 789 GrantUri other = (GrantUri) o; 790 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 791 && prefix == other.prefix; 792 } 793 return false; 794 } 795 796 @Override 797 public String toString() { 798 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 799 if (prefix) result += " [prefix]"; 800 return result; 801 } 802 803 public String toSafeString() { 804 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 805 if (prefix) result += " [prefix]"; 806 return result; 807 } 808 809 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 810 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 811 ContentProvider.getUriWithoutUserId(uri), false); 812 } 813 } 814 815 CoreSettingsObserver mCoreSettingsObserver; 816 817 /** 818 * Thread-local storage used to carry caller permissions over through 819 * indirect content-provider access. 820 */ 821 private class Identity { 822 public int pid; 823 public int uid; 824 825 Identity(int _pid, int _uid) { 826 pid = _pid; 827 uid = _uid; 828 } 829 } 830 831 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 832 833 /** 834 * All information we have collected about the runtime performance of 835 * any user id that can impact battery performance. 836 */ 837 final BatteryStatsService mBatteryStatsService; 838 839 /** 840 * Information about component usage 841 */ 842 UsageStatsManagerInternal mUsageStatsService; 843 844 /** 845 * Information about and control over application operations 846 */ 847 final AppOpsService mAppOpsService; 848 849 /** 850 * Save recent tasks information across reboots. 851 */ 852 final TaskPersister mTaskPersister; 853 854 /** 855 * Current configuration information. HistoryRecord objects are given 856 * a reference to this object to indicate which configuration they are 857 * currently running in, so this object must be kept immutable. 858 */ 859 Configuration mConfiguration = new Configuration(); 860 861 /** 862 * Current sequencing integer of the configuration, for skipping old 863 * configurations. 864 */ 865 int mConfigurationSeq = 0; 866 867 /** 868 * Hardware-reported OpenGLES version. 869 */ 870 final int GL_ES_VERSION; 871 872 /** 873 * List of initialization arguments to pass to all processes when binding applications to them. 874 * For example, references to the commonly used services. 875 */ 876 HashMap<String, IBinder> mAppBindArgs; 877 878 /** 879 * Temporary to avoid allocations. Protected by main lock. 880 */ 881 final StringBuilder mStringBuilder = new StringBuilder(256); 882 883 /** 884 * Used to control how we initialize the service. 885 */ 886 ComponentName mTopComponent; 887 String mTopAction = Intent.ACTION_MAIN; 888 String mTopData; 889 boolean mProcessesReady = false; 890 boolean mSystemReady = false; 891 boolean mBooting = false; 892 boolean mCallFinishBooting = false; 893 boolean mBootAnimationComplete = false; 894 boolean mWaitingUpdate = false; 895 boolean mDidUpdate = false; 896 boolean mOnBattery = false; 897 boolean mLaunchWarningShown = false; 898 899 Context mContext; 900 901 int mFactoryTest; 902 903 boolean mCheckedForSetup; 904 905 /** 906 * The time at which we will allow normal application switches again, 907 * after a call to {@link #stopAppSwitches()}. 908 */ 909 long mAppSwitchesAllowedTime; 910 911 /** 912 * This is set to true after the first switch after mAppSwitchesAllowedTime 913 * is set; any switches after that will clear the time. 914 */ 915 boolean mDidAppSwitch; 916 917 /** 918 * Last time (in realtime) at which we checked for power usage. 919 */ 920 long mLastPowerCheckRealtime; 921 922 /** 923 * Last time (in uptime) at which we checked for power usage. 924 */ 925 long mLastPowerCheckUptime; 926 927 /** 928 * Set while we are wanting to sleep, to prevent any 929 * activities from being started/resumed. 930 */ 931 private boolean mSleeping = false; 932 933 /** 934 * Set while we are running a voice interaction. This overrides 935 * sleeping while it is active. 936 */ 937 private boolean mRunningVoice = false; 938 939 /** 940 * State of external calls telling us if the device is asleep. 941 */ 942 private boolean mWentToSleep = false; 943 944 /** 945 * State of external call telling us if the lock screen is shown. 946 */ 947 private boolean mLockScreenShown = false; 948 949 /** 950 * Set if we are shutting down the system, similar to sleeping. 951 */ 952 boolean mShuttingDown = false; 953 954 /** 955 * Current sequence id for oom_adj computation traversal. 956 */ 957 int mAdjSeq = 0; 958 959 /** 960 * Current sequence id for process LRU updating. 961 */ 962 int mLruSeq = 0; 963 964 /** 965 * Keep track of the non-cached/empty process we last found, to help 966 * determine how to distribute cached/empty processes next time. 967 */ 968 int mNumNonCachedProcs = 0; 969 970 /** 971 * Keep track of the number of cached hidden procs, to balance oom adj 972 * distribution between those and empty procs. 973 */ 974 int mNumCachedHiddenProcs = 0; 975 976 /** 977 * Keep track of the number of service processes we last found, to 978 * determine on the next iteration which should be B services. 979 */ 980 int mNumServiceProcs = 0; 981 int mNewNumAServiceProcs = 0; 982 int mNewNumServiceProcs = 0; 983 984 /** 985 * Allow the current computed overall memory level of the system to go down? 986 * This is set to false when we are killing processes for reasons other than 987 * memory management, so that the now smaller process list will not be taken as 988 * an indication that memory is tighter. 989 */ 990 boolean mAllowLowerMemLevel = false; 991 992 /** 993 * The last computed memory level, for holding when we are in a state that 994 * processes are going away for other reasons. 995 */ 996 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 997 998 /** 999 * The last total number of process we have, to determine if changes actually look 1000 * like a shrinking number of process due to lower RAM. 1001 */ 1002 int mLastNumProcesses; 1003 1004 /** 1005 * The uptime of the last time we performed idle maintenance. 1006 */ 1007 long mLastIdleTime = SystemClock.uptimeMillis(); 1008 1009 /** 1010 * Total time spent with RAM that has been added in the past since the last idle time. 1011 */ 1012 long mLowRamTimeSinceLastIdle = 0; 1013 1014 /** 1015 * If RAM is currently low, when that horrible situation started. 1016 */ 1017 long mLowRamStartTime = 0; 1018 1019 /** 1020 * For reporting to battery stats the current top application. 1021 */ 1022 private String mCurResumedPackage = null; 1023 private int mCurResumedUid = -1; 1024 1025 /** 1026 * For reporting to battery stats the apps currently running foreground 1027 * service. The ProcessMap is package/uid tuples; each of these contain 1028 * an array of the currently foreground processes. 1029 */ 1030 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1031 = new ProcessMap<ArrayList<ProcessRecord>>(); 1032 1033 /** 1034 * This is set if we had to do a delayed dexopt of an app before launching 1035 * it, to increase the ANR timeouts in that case. 1036 */ 1037 boolean mDidDexOpt; 1038 1039 /** 1040 * Set if the systemServer made a call to enterSafeMode. 1041 */ 1042 boolean mSafeMode; 1043 1044 String mDebugApp = null; 1045 boolean mWaitForDebugger = false; 1046 boolean mDebugTransient = false; 1047 String mOrigDebugApp = null; 1048 boolean mOrigWaitForDebugger = false; 1049 boolean mAlwaysFinishActivities = false; 1050 IActivityController mController = null; 1051 String mProfileApp = null; 1052 ProcessRecord mProfileProc = null; 1053 String mProfileFile; 1054 ParcelFileDescriptor mProfileFd; 1055 int mSamplingInterval = 0; 1056 boolean mAutoStopProfiler = false; 1057 int mProfileType = 0; 1058 String mOpenGlTraceApp = null; 1059 1060 static class ProcessChangeItem { 1061 static final int CHANGE_ACTIVITIES = 1<<0; 1062 static final int CHANGE_PROCESS_STATE = 1<<1; 1063 int changes; 1064 int uid; 1065 int pid; 1066 int processState; 1067 boolean foregroundActivities; 1068 } 1069 1070 final RemoteCallbackList<IProcessObserver> mProcessObservers 1071 = new RemoteCallbackList<IProcessObserver>(); 1072 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1073 1074 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1075 = new ArrayList<ProcessChangeItem>(); 1076 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1077 = new ArrayList<ProcessChangeItem>(); 1078 1079 /** 1080 * Runtime CPU use collection thread. This object's lock is used to 1081 * perform synchronization with the thread (notifying it to run). 1082 */ 1083 final Thread mProcessCpuThread; 1084 1085 /** 1086 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1087 * Must acquire this object's lock when accessing it. 1088 * NOTE: this lock will be held while doing long operations (trawling 1089 * through all processes in /proc), so it should never be acquired by 1090 * any critical paths such as when holding the main activity manager lock. 1091 */ 1092 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1093 MONITOR_THREAD_CPU_USAGE); 1094 final AtomicLong mLastCpuTime = new AtomicLong(0); 1095 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1096 1097 long mLastWriteTime = 0; 1098 1099 /** 1100 * Used to retain an update lock when the foreground activity is in 1101 * immersive mode. 1102 */ 1103 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1104 1105 /** 1106 * Set to true after the system has finished booting. 1107 */ 1108 boolean mBooted = false; 1109 1110 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1111 int mProcessLimitOverride = -1; 1112 1113 WindowManagerService mWindowManager; 1114 1115 final ActivityThread mSystemThread; 1116 1117 // Holds the current foreground user's id 1118 int mCurrentUserId = 0; 1119 // Holds the target user's id during a user switch 1120 int mTargetUserId = UserHandle.USER_NULL; 1121 // If there are multiple profiles for the current user, their ids are here 1122 // Currently only the primary user can have managed profiles 1123 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1124 1125 /** 1126 * Mapping from each known user ID to the profile group ID it is associated with. 1127 */ 1128 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1129 1130 private UserManagerService mUserManager; 1131 1132 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1133 final ProcessRecord mApp; 1134 final int mPid; 1135 final IApplicationThread mAppThread; 1136 1137 AppDeathRecipient(ProcessRecord app, int pid, 1138 IApplicationThread thread) { 1139 if (localLOGV) Slog.v( 1140 TAG, "New death recipient " + this 1141 + " for thread " + thread.asBinder()); 1142 mApp = app; 1143 mPid = pid; 1144 mAppThread = thread; 1145 } 1146 1147 @Override 1148 public void binderDied() { 1149 if (localLOGV) Slog.v( 1150 TAG, "Death received in " + this 1151 + " for thread " + mAppThread.asBinder()); 1152 synchronized(ActivityManagerService.this) { 1153 appDiedLocked(mApp, mPid, mAppThread); 1154 } 1155 } 1156 } 1157 1158 static final int SHOW_ERROR_MSG = 1; 1159 static final int SHOW_NOT_RESPONDING_MSG = 2; 1160 static final int SHOW_FACTORY_ERROR_MSG = 3; 1161 static final int UPDATE_CONFIGURATION_MSG = 4; 1162 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1163 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1164 static final int SERVICE_TIMEOUT_MSG = 12; 1165 static final int UPDATE_TIME_ZONE = 13; 1166 static final int SHOW_UID_ERROR_MSG = 14; 1167 static final int IM_FEELING_LUCKY_MSG = 15; 1168 static final int PROC_START_TIMEOUT_MSG = 20; 1169 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1170 static final int KILL_APPLICATION_MSG = 22; 1171 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1172 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1173 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1174 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1175 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1176 static final int CLEAR_DNS_CACHE_MSG = 28; 1177 static final int UPDATE_HTTP_PROXY_MSG = 29; 1178 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1179 static final int DISPATCH_PROCESSES_CHANGED = 31; 1180 static final int DISPATCH_PROCESS_DIED = 32; 1181 static final int REPORT_MEM_USAGE_MSG = 33; 1182 static final int REPORT_USER_SWITCH_MSG = 34; 1183 static final int CONTINUE_USER_SWITCH_MSG = 35; 1184 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1185 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1186 static final int PERSIST_URI_GRANTS_MSG = 38; 1187 static final int REQUEST_ALL_PSS_MSG = 39; 1188 static final int START_PROFILES_MSG = 40; 1189 static final int UPDATE_TIME = 41; 1190 static final int SYSTEM_USER_START_MSG = 42; 1191 static final int SYSTEM_USER_CURRENT_MSG = 43; 1192 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1193 static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45; 1194 static final int START_USER_SWITCH_MSG = 46; 1195 1196 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1197 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1198 static final int FIRST_COMPAT_MODE_MSG = 300; 1199 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1200 1201 AlertDialog mUidAlert; 1202 CompatModeDialog mCompatModeDialog; 1203 long mLastMemUsageReportTime = 0; 1204 1205 private LockToAppRequestDialog mLockToAppRequest; 1206 1207 /** 1208 * Flag whether the current user is a "monkey", i.e. whether 1209 * the UI is driven by a UI automation tool. 1210 */ 1211 private boolean mUserIsMonkey; 1212 1213 /** Flag whether the device has a Recents UI */ 1214 boolean mHasRecents; 1215 1216 /** The dimensions of the thumbnails in the Recents UI. */ 1217 int mThumbnailWidth; 1218 int mThumbnailHeight; 1219 1220 final ServiceThread mHandlerThread; 1221 final MainHandler mHandler; 1222 1223 final class MainHandler extends Handler { 1224 public MainHandler(Looper looper) { 1225 super(looper, null, true); 1226 } 1227 1228 @Override 1229 public void handleMessage(Message msg) { 1230 switch (msg.what) { 1231 case SHOW_ERROR_MSG: { 1232 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1233 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1234 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1235 synchronized (ActivityManagerService.this) { 1236 ProcessRecord proc = (ProcessRecord)data.get("app"); 1237 AppErrorResult res = (AppErrorResult) data.get("result"); 1238 if (proc != null && proc.crashDialog != null) { 1239 Slog.e(TAG, "App already has crash dialog: " + proc); 1240 if (res != null) { 1241 res.set(0); 1242 } 1243 return; 1244 } 1245 boolean isBackground = (UserHandle.getAppId(proc.uid) 1246 >= Process.FIRST_APPLICATION_UID 1247 && proc.pid != MY_PID); 1248 for (int userId : mCurrentProfileIds) { 1249 isBackground &= (proc.userId != userId); 1250 } 1251 if (isBackground && !showBackground) { 1252 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1253 if (res != null) { 1254 res.set(0); 1255 } 1256 return; 1257 } 1258 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1259 Dialog d = new AppErrorDialog(mContext, 1260 ActivityManagerService.this, res, proc); 1261 d.show(); 1262 proc.crashDialog = d; 1263 } else { 1264 // The device is asleep, so just pretend that the user 1265 // saw a crash dialog and hit "force quit". 1266 if (res != null) { 1267 res.set(0); 1268 } 1269 } 1270 } 1271 1272 ensureBootCompleted(); 1273 } break; 1274 case SHOW_NOT_RESPONDING_MSG: { 1275 synchronized (ActivityManagerService.this) { 1276 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1277 ProcessRecord proc = (ProcessRecord)data.get("app"); 1278 if (proc != null && proc.anrDialog != null) { 1279 Slog.e(TAG, "App already has anr dialog: " + proc); 1280 return; 1281 } 1282 1283 Intent intent = new Intent("android.intent.action.ANR"); 1284 if (!mProcessesReady) { 1285 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1286 | Intent.FLAG_RECEIVER_FOREGROUND); 1287 } 1288 broadcastIntentLocked(null, null, intent, 1289 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1290 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1291 1292 if (mShowDialogs) { 1293 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1294 mContext, proc, (ActivityRecord)data.get("activity"), 1295 msg.arg1 != 0); 1296 d.show(); 1297 proc.anrDialog = d; 1298 } else { 1299 // Just kill the app if there is no dialog to be shown. 1300 killAppAtUsersRequest(proc, null); 1301 } 1302 } 1303 1304 ensureBootCompleted(); 1305 } break; 1306 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1307 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1308 synchronized (ActivityManagerService.this) { 1309 ProcessRecord proc = (ProcessRecord) data.get("app"); 1310 if (proc == null) { 1311 Slog.e(TAG, "App not found when showing strict mode dialog."); 1312 break; 1313 } 1314 if (proc.crashDialog != null) { 1315 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1316 return; 1317 } 1318 AppErrorResult res = (AppErrorResult) data.get("result"); 1319 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1320 Dialog d = new StrictModeViolationDialog(mContext, 1321 ActivityManagerService.this, res, proc); 1322 d.show(); 1323 proc.crashDialog = d; 1324 } else { 1325 // The device is asleep, so just pretend that the user 1326 // saw a crash dialog and hit "force quit". 1327 res.set(0); 1328 } 1329 } 1330 ensureBootCompleted(); 1331 } break; 1332 case SHOW_FACTORY_ERROR_MSG: { 1333 Dialog d = new FactoryErrorDialog( 1334 mContext, msg.getData().getCharSequence("msg")); 1335 d.show(); 1336 ensureBootCompleted(); 1337 } break; 1338 case UPDATE_CONFIGURATION_MSG: { 1339 final ContentResolver resolver = mContext.getContentResolver(); 1340 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1341 } break; 1342 case GC_BACKGROUND_PROCESSES_MSG: { 1343 synchronized (ActivityManagerService.this) { 1344 performAppGcsIfAppropriateLocked(); 1345 } 1346 } break; 1347 case WAIT_FOR_DEBUGGER_MSG: { 1348 synchronized (ActivityManagerService.this) { 1349 ProcessRecord app = (ProcessRecord)msg.obj; 1350 if (msg.arg1 != 0) { 1351 if (!app.waitedForDebugger) { 1352 Dialog d = new AppWaitingForDebuggerDialog( 1353 ActivityManagerService.this, 1354 mContext, app); 1355 app.waitDialog = d; 1356 app.waitedForDebugger = true; 1357 d.show(); 1358 } 1359 } else { 1360 if (app.waitDialog != null) { 1361 app.waitDialog.dismiss(); 1362 app.waitDialog = null; 1363 } 1364 } 1365 } 1366 } break; 1367 case SERVICE_TIMEOUT_MSG: { 1368 if (mDidDexOpt) { 1369 mDidDexOpt = false; 1370 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1371 nmsg.obj = msg.obj; 1372 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1373 return; 1374 } 1375 mServices.serviceTimeout((ProcessRecord)msg.obj); 1376 } break; 1377 case UPDATE_TIME_ZONE: { 1378 synchronized (ActivityManagerService.this) { 1379 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1380 ProcessRecord r = mLruProcesses.get(i); 1381 if (r.thread != null) { 1382 try { 1383 r.thread.updateTimeZone(); 1384 } catch (RemoteException ex) { 1385 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1386 } 1387 } 1388 } 1389 } 1390 } break; 1391 case CLEAR_DNS_CACHE_MSG: { 1392 synchronized (ActivityManagerService.this) { 1393 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1394 ProcessRecord r = mLruProcesses.get(i); 1395 if (r.thread != null) { 1396 try { 1397 r.thread.clearDnsCache(); 1398 } catch (RemoteException ex) { 1399 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1400 } 1401 } 1402 } 1403 } 1404 } break; 1405 case UPDATE_HTTP_PROXY_MSG: { 1406 ProxyInfo proxy = (ProxyInfo)msg.obj; 1407 String host = ""; 1408 String port = ""; 1409 String exclList = ""; 1410 Uri pacFileUrl = Uri.EMPTY; 1411 if (proxy != null) { 1412 host = proxy.getHost(); 1413 port = Integer.toString(proxy.getPort()); 1414 exclList = proxy.getExclusionListAsString(); 1415 pacFileUrl = proxy.getPacFileUrl(); 1416 } 1417 synchronized (ActivityManagerService.this) { 1418 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1419 ProcessRecord r = mLruProcesses.get(i); 1420 if (r.thread != null) { 1421 try { 1422 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1423 } catch (RemoteException ex) { 1424 Slog.w(TAG, "Failed to update http proxy for: " + 1425 r.info.processName); 1426 } 1427 } 1428 } 1429 } 1430 } break; 1431 case SHOW_UID_ERROR_MSG: { 1432 String title = "System UIDs Inconsistent"; 1433 String text = "UIDs on the system are inconsistent, you need to wipe your" 1434 + " data partition or your device will be unstable."; 1435 Log.e(TAG, title + ": " + text); 1436 if (mShowDialogs) { 1437 // XXX This is a temporary dialog, no need to localize. 1438 AlertDialog d = new BaseErrorDialog(mContext); 1439 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1440 d.setCancelable(false); 1441 d.setTitle(title); 1442 d.setMessage(text); 1443 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1444 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1445 mUidAlert = d; 1446 d.show(); 1447 } 1448 } break; 1449 case IM_FEELING_LUCKY_MSG: { 1450 if (mUidAlert != null) { 1451 mUidAlert.dismiss(); 1452 mUidAlert = null; 1453 } 1454 } break; 1455 case PROC_START_TIMEOUT_MSG: { 1456 if (mDidDexOpt) { 1457 mDidDexOpt = false; 1458 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1459 nmsg.obj = msg.obj; 1460 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1461 return; 1462 } 1463 ProcessRecord app = (ProcessRecord)msg.obj; 1464 synchronized (ActivityManagerService.this) { 1465 processStartTimedOutLocked(app); 1466 } 1467 } break; 1468 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1469 synchronized (ActivityManagerService.this) { 1470 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1471 } 1472 } break; 1473 case KILL_APPLICATION_MSG: { 1474 synchronized (ActivityManagerService.this) { 1475 int appid = msg.arg1; 1476 boolean restart = (msg.arg2 == 1); 1477 Bundle bundle = (Bundle)msg.obj; 1478 String pkg = bundle.getString("pkg"); 1479 String reason = bundle.getString("reason"); 1480 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1481 false, UserHandle.USER_ALL, reason); 1482 } 1483 } break; 1484 case FINALIZE_PENDING_INTENT_MSG: { 1485 ((PendingIntentRecord)msg.obj).completeFinalize(); 1486 } break; 1487 case POST_HEAVY_NOTIFICATION_MSG: { 1488 INotificationManager inm = NotificationManager.getService(); 1489 if (inm == null) { 1490 return; 1491 } 1492 1493 ActivityRecord root = (ActivityRecord)msg.obj; 1494 ProcessRecord process = root.app; 1495 if (process == null) { 1496 return; 1497 } 1498 1499 try { 1500 Context context = mContext.createPackageContext(process.info.packageName, 0); 1501 String text = mContext.getString(R.string.heavy_weight_notification, 1502 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1503 Notification notification = new Notification(); 1504 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1505 notification.when = 0; 1506 notification.flags = Notification.FLAG_ONGOING_EVENT; 1507 notification.tickerText = text; 1508 notification.defaults = 0; // please be quiet 1509 notification.sound = null; 1510 notification.vibrate = null; 1511 notification.color = mContext.getResources().getColor( 1512 com.android.internal.R.color.system_notification_accent_color); 1513 notification.setLatestEventInfo(context, text, 1514 mContext.getText(R.string.heavy_weight_notification_detail), 1515 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1516 PendingIntent.FLAG_CANCEL_CURRENT, null, 1517 new UserHandle(root.userId))); 1518 1519 try { 1520 int[] outId = new int[1]; 1521 inm.enqueueNotificationWithTag("android", "android", null, 1522 R.string.heavy_weight_notification, 1523 notification, outId, root.userId); 1524 } catch (RuntimeException e) { 1525 Slog.w(ActivityManagerService.TAG, 1526 "Error showing notification for heavy-weight app", e); 1527 } catch (RemoteException e) { 1528 } 1529 } catch (NameNotFoundException e) { 1530 Slog.w(TAG, "Unable to create context for heavy notification", e); 1531 } 1532 } break; 1533 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1534 INotificationManager inm = NotificationManager.getService(); 1535 if (inm == null) { 1536 return; 1537 } 1538 try { 1539 inm.cancelNotificationWithTag("android", null, 1540 R.string.heavy_weight_notification, msg.arg1); 1541 } catch (RuntimeException e) { 1542 Slog.w(ActivityManagerService.TAG, 1543 "Error canceling notification for service", e); 1544 } catch (RemoteException e) { 1545 } 1546 } break; 1547 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1548 synchronized (ActivityManagerService.this) { 1549 checkExcessivePowerUsageLocked(true); 1550 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1551 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1552 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1553 } 1554 } break; 1555 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1556 synchronized (ActivityManagerService.this) { 1557 ActivityRecord ar = (ActivityRecord)msg.obj; 1558 if (mCompatModeDialog != null) { 1559 if (mCompatModeDialog.mAppInfo.packageName.equals( 1560 ar.info.applicationInfo.packageName)) { 1561 return; 1562 } 1563 mCompatModeDialog.dismiss(); 1564 mCompatModeDialog = null; 1565 } 1566 if (ar != null && false) { 1567 if (mCompatModePackages.getPackageAskCompatModeLocked( 1568 ar.packageName)) { 1569 int mode = mCompatModePackages.computeCompatModeLocked( 1570 ar.info.applicationInfo); 1571 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1572 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1573 mCompatModeDialog = new CompatModeDialog( 1574 ActivityManagerService.this, mContext, 1575 ar.info.applicationInfo); 1576 mCompatModeDialog.show(); 1577 } 1578 } 1579 } 1580 } 1581 break; 1582 } 1583 case DISPATCH_PROCESSES_CHANGED: { 1584 dispatchProcessesChanged(); 1585 break; 1586 } 1587 case DISPATCH_PROCESS_DIED: { 1588 final int pid = msg.arg1; 1589 final int uid = msg.arg2; 1590 dispatchProcessDied(pid, uid); 1591 break; 1592 } 1593 case REPORT_MEM_USAGE_MSG: { 1594 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1595 Thread thread = new Thread() { 1596 @Override public void run() { 1597 final SparseArray<ProcessMemInfo> infoMap 1598 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1599 for (int i=0, N=memInfos.size(); i<N; i++) { 1600 ProcessMemInfo mi = memInfos.get(i); 1601 infoMap.put(mi.pid, mi); 1602 } 1603 updateCpuStatsNow(); 1604 synchronized (mProcessCpuTracker) { 1605 final int N = mProcessCpuTracker.countStats(); 1606 for (int i=0; i<N; i++) { 1607 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1608 if (st.vsize > 0) { 1609 long pss = Debug.getPss(st.pid, null); 1610 if (pss > 0) { 1611 if (infoMap.indexOfKey(st.pid) < 0) { 1612 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1613 ProcessList.NATIVE_ADJ, -1, "native", null); 1614 mi.pss = pss; 1615 memInfos.add(mi); 1616 } 1617 } 1618 } 1619 } 1620 } 1621 1622 long totalPss = 0; 1623 for (int i=0, N=memInfos.size(); i<N; i++) { 1624 ProcessMemInfo mi = memInfos.get(i); 1625 if (mi.pss == 0) { 1626 mi.pss = Debug.getPss(mi.pid, null); 1627 } 1628 totalPss += mi.pss; 1629 } 1630 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1631 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1632 if (lhs.oomAdj != rhs.oomAdj) { 1633 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1634 } 1635 if (lhs.pss != rhs.pss) { 1636 return lhs.pss < rhs.pss ? 1 : -1; 1637 } 1638 return 0; 1639 } 1640 }); 1641 1642 StringBuilder tag = new StringBuilder(128); 1643 StringBuilder stack = new StringBuilder(128); 1644 tag.append("Low on memory -- "); 1645 appendMemBucket(tag, totalPss, "total", false); 1646 appendMemBucket(stack, totalPss, "total", true); 1647 1648 StringBuilder logBuilder = new StringBuilder(1024); 1649 logBuilder.append("Low on memory:\n"); 1650 1651 boolean firstLine = true; 1652 int lastOomAdj = Integer.MIN_VALUE; 1653 for (int i=0, N=memInfos.size(); i<N; i++) { 1654 ProcessMemInfo mi = memInfos.get(i); 1655 1656 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1657 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1658 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1659 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1660 if (lastOomAdj != mi.oomAdj) { 1661 lastOomAdj = mi.oomAdj; 1662 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1663 tag.append(" / "); 1664 } 1665 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1666 if (firstLine) { 1667 stack.append(":"); 1668 firstLine = false; 1669 } 1670 stack.append("\n\t at "); 1671 } else { 1672 stack.append("$"); 1673 } 1674 } else { 1675 tag.append(" "); 1676 stack.append("$"); 1677 } 1678 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1679 appendMemBucket(tag, mi.pss, mi.name, false); 1680 } 1681 appendMemBucket(stack, mi.pss, mi.name, true); 1682 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1683 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1684 stack.append("("); 1685 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1686 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1687 stack.append(DUMP_MEM_OOM_LABEL[k]); 1688 stack.append(":"); 1689 stack.append(DUMP_MEM_OOM_ADJ[k]); 1690 } 1691 } 1692 stack.append(")"); 1693 } 1694 } 1695 1696 logBuilder.append(" "); 1697 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1698 logBuilder.append(' '); 1699 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1700 logBuilder.append(' '); 1701 ProcessList.appendRamKb(logBuilder, mi.pss); 1702 logBuilder.append(" kB: "); 1703 logBuilder.append(mi.name); 1704 logBuilder.append(" ("); 1705 logBuilder.append(mi.pid); 1706 logBuilder.append(") "); 1707 logBuilder.append(mi.adjType); 1708 logBuilder.append('\n'); 1709 if (mi.adjReason != null) { 1710 logBuilder.append(" "); 1711 logBuilder.append(mi.adjReason); 1712 logBuilder.append('\n'); 1713 } 1714 } 1715 1716 logBuilder.append(" "); 1717 ProcessList.appendRamKb(logBuilder, totalPss); 1718 logBuilder.append(" kB: TOTAL\n"); 1719 1720 long[] infos = new long[Debug.MEMINFO_COUNT]; 1721 Debug.getMemInfo(infos); 1722 logBuilder.append(" MemInfo: "); 1723 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1724 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1725 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1726 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1727 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1728 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1729 logBuilder.append(" ZRAM: "); 1730 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1731 logBuilder.append(" kB RAM, "); 1732 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1733 logBuilder.append(" kB swap total, "); 1734 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1735 logBuilder.append(" kB swap free\n"); 1736 } 1737 Slog.i(TAG, logBuilder.toString()); 1738 1739 StringBuilder dropBuilder = new StringBuilder(1024); 1740 /* 1741 StringWriter oomSw = new StringWriter(); 1742 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1743 StringWriter catSw = new StringWriter(); 1744 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1745 String[] emptyArgs = new String[] { }; 1746 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1747 oomPw.flush(); 1748 String oomString = oomSw.toString(); 1749 */ 1750 dropBuilder.append(stack); 1751 dropBuilder.append('\n'); 1752 dropBuilder.append('\n'); 1753 dropBuilder.append(logBuilder); 1754 dropBuilder.append('\n'); 1755 /* 1756 dropBuilder.append(oomString); 1757 dropBuilder.append('\n'); 1758 */ 1759 StringWriter catSw = new StringWriter(); 1760 synchronized (ActivityManagerService.this) { 1761 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1762 String[] emptyArgs = new String[] { }; 1763 catPw.println(); 1764 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1765 catPw.println(); 1766 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1767 false, false, null); 1768 catPw.println(); 1769 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1770 catPw.flush(); 1771 } 1772 dropBuilder.append(catSw.toString()); 1773 addErrorToDropBox("lowmem", null, "system_server", null, 1774 null, tag.toString(), dropBuilder.toString(), null, null); 1775 //Slog.i(TAG, "Sent to dropbox:"); 1776 //Slog.i(TAG, dropBuilder.toString()); 1777 synchronized (ActivityManagerService.this) { 1778 long now = SystemClock.uptimeMillis(); 1779 if (mLastMemUsageReportTime < now) { 1780 mLastMemUsageReportTime = now; 1781 } 1782 } 1783 } 1784 }; 1785 thread.start(); 1786 break; 1787 } 1788 case START_USER_SWITCH_MSG: { 1789 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1790 break; 1791 } 1792 case REPORT_USER_SWITCH_MSG: { 1793 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1794 break; 1795 } 1796 case CONTINUE_USER_SWITCH_MSG: { 1797 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1798 break; 1799 } 1800 case USER_SWITCH_TIMEOUT_MSG: { 1801 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1802 break; 1803 } 1804 case IMMERSIVE_MODE_LOCK_MSG: { 1805 final boolean nextState = (msg.arg1 != 0); 1806 if (mUpdateLock.isHeld() != nextState) { 1807 if (DEBUG_IMMERSIVE) { 1808 final ActivityRecord r = (ActivityRecord) msg.obj; 1809 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1810 } 1811 if (nextState) { 1812 mUpdateLock.acquire(); 1813 } else { 1814 mUpdateLock.release(); 1815 } 1816 } 1817 break; 1818 } 1819 case PERSIST_URI_GRANTS_MSG: { 1820 writeGrantedUriPermissions(); 1821 break; 1822 } 1823 case REQUEST_ALL_PSS_MSG: { 1824 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1825 break; 1826 } 1827 case START_PROFILES_MSG: { 1828 synchronized (ActivityManagerService.this) { 1829 startProfilesLocked(); 1830 } 1831 break; 1832 } 1833 case UPDATE_TIME: { 1834 synchronized (ActivityManagerService.this) { 1835 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1836 ProcessRecord r = mLruProcesses.get(i); 1837 if (r.thread != null) { 1838 try { 1839 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1840 } catch (RemoteException ex) { 1841 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1842 } 1843 } 1844 } 1845 } 1846 break; 1847 } 1848 case SYSTEM_USER_START_MSG: { 1849 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1850 Integer.toString(msg.arg1), msg.arg1); 1851 mSystemServiceManager.startUser(msg.arg1); 1852 break; 1853 } 1854 case SYSTEM_USER_CURRENT_MSG: { 1855 mBatteryStatsService.noteEvent( 1856 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1857 Integer.toString(msg.arg2), msg.arg2); 1858 mBatteryStatsService.noteEvent( 1859 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1860 Integer.toString(msg.arg1), msg.arg1); 1861 mSystemServiceManager.switchUser(msg.arg1); 1862 mLockToAppRequest.clearPrompt(); 1863 break; 1864 } 1865 case ENTER_ANIMATION_COMPLETE_MSG: { 1866 synchronized (ActivityManagerService.this) { 1867 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1868 if (r != null && r.app != null && r.app.thread != null) { 1869 try { 1870 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1871 } catch (RemoteException e) { 1872 } 1873 } 1874 } 1875 break; 1876 } 1877 case ENABLE_SCREEN_AFTER_BOOT_MSG: { 1878 enableScreenAfterBoot(); 1879 break; 1880 } 1881 } 1882 } 1883 }; 1884 1885 static final int COLLECT_PSS_BG_MSG = 1; 1886 1887 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1888 @Override 1889 public void handleMessage(Message msg) { 1890 switch (msg.what) { 1891 case COLLECT_PSS_BG_MSG: { 1892 long start = SystemClock.uptimeMillis(); 1893 MemInfoReader memInfo = null; 1894 synchronized (ActivityManagerService.this) { 1895 if (mFullPssPending) { 1896 mFullPssPending = false; 1897 memInfo = new MemInfoReader(); 1898 } 1899 } 1900 if (memInfo != null) { 1901 updateCpuStatsNow(); 1902 long nativeTotalPss = 0; 1903 synchronized (mProcessCpuTracker) { 1904 final int N = mProcessCpuTracker.countStats(); 1905 for (int j=0; j<N; j++) { 1906 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1907 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1908 // This is definitely an application process; skip it. 1909 continue; 1910 } 1911 synchronized (mPidsSelfLocked) { 1912 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1913 // This is one of our own processes; skip it. 1914 continue; 1915 } 1916 } 1917 nativeTotalPss += Debug.getPss(st.pid, null); 1918 } 1919 } 1920 memInfo.readMemInfo(); 1921 synchronized (ActivityManagerService.this) { 1922 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1923 + (SystemClock.uptimeMillis()-start) + "ms"); 1924 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1925 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1926 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1927 +memInfo.getSlabSizeKb(), 1928 nativeTotalPss); 1929 } 1930 } 1931 1932 int i=0, num=0; 1933 long[] tmp = new long[1]; 1934 do { 1935 ProcessRecord proc; 1936 int procState; 1937 int pid; 1938 synchronized (ActivityManagerService.this) { 1939 if (i >= mPendingPssProcesses.size()) { 1940 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1941 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1942 mPendingPssProcesses.clear(); 1943 return; 1944 } 1945 proc = mPendingPssProcesses.get(i); 1946 procState = proc.pssProcState; 1947 if (proc.thread != null && procState == proc.setProcState) { 1948 pid = proc.pid; 1949 } else { 1950 proc = null; 1951 pid = 0; 1952 } 1953 i++; 1954 } 1955 if (proc != null) { 1956 long pss = Debug.getPss(pid, tmp); 1957 synchronized (ActivityManagerService.this) { 1958 if (proc.thread != null && proc.setProcState == procState 1959 && proc.pid == pid) { 1960 num++; 1961 proc.lastPssTime = SystemClock.uptimeMillis(); 1962 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1963 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1964 + ": " + pss + " lastPss=" + proc.lastPss 1965 + " state=" + ProcessList.makeProcStateString(procState)); 1966 if (proc.initialIdlePss == 0) { 1967 proc.initialIdlePss = pss; 1968 } 1969 proc.lastPss = pss; 1970 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1971 proc.lastCachedPss = pss; 1972 } 1973 } 1974 } 1975 } 1976 } while (true); 1977 } 1978 } 1979 } 1980 }; 1981 1982 /** 1983 * Monitor for package changes and update our internal state. 1984 */ 1985 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1986 @Override 1987 public void onPackageRemoved(String packageName, int uid) { 1988 // Remove all tasks with activities in the specified package from the list of recent tasks 1989 final int eventUserId = getChangingUserId(); 1990 synchronized (ActivityManagerService.this) { 1991 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1992 TaskRecord tr = mRecentTasks.get(i); 1993 if (tr.userId != eventUserId) continue; 1994 1995 ComponentName cn = tr.intent.getComponent(); 1996 if (cn != null && cn.getPackageName().equals(packageName)) { 1997 // If the package name matches, remove the task and kill the process 1998 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1999 } 2000 } 2001 } 2002 } 2003 2004 @Override 2005 public boolean onPackageChanged(String packageName, int uid, String[] components) { 2006 onPackageModified(packageName); 2007 return true; 2008 } 2009 2010 @Override 2011 public void onPackageModified(String packageName) { 2012 final int eventUserId = getChangingUserId(); 2013 final PackageManager pm = mContext.getPackageManager(); 2014 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 2015 new ArrayList<Pair<Intent, Integer>>(); 2016 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 2017 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2018 // Copy the list of recent tasks so that we don't hold onto the lock on 2019 // ActivityManagerService for long periods while checking if components exist. 2020 synchronized (ActivityManagerService.this) { 2021 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2022 TaskRecord tr = mRecentTasks.get(i); 2023 if (tr.userId != eventUserId) continue; 2024 2025 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2026 } 2027 } 2028 // Check the recent tasks and filter out all tasks with components that no longer exist. 2029 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2030 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2031 ComponentName cn = p.first.getComponent(); 2032 if (cn != null && cn.getPackageName().equals(packageName)) { 2033 if (componentsKnownToExist.contains(cn)) { 2034 // If we know that the component still exists in the package, then skip 2035 continue; 2036 } 2037 try { 2038 ActivityInfo info = pm.getActivityInfo(cn, eventUserId); 2039 if (info != null && info.isEnabled()) { 2040 componentsKnownToExist.add(cn); 2041 } else { 2042 tasksToRemove.add(p.second); 2043 } 2044 } catch (Exception e) {} 2045 } 2046 } 2047 // Prune all the tasks with removed components from the list of recent tasks 2048 synchronized (ActivityManagerService.this) { 2049 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2050 // Remove the task but don't kill the process (since other components in that 2051 // package may still be running and in the background) 2052 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2053 } 2054 } 2055 } 2056 2057 @Override 2058 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2059 // Force stop the specified packages 2060 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 2061 if (packages != null) { 2062 for (String pkg : packages) { 2063 synchronized (ActivityManagerService.this) { 2064 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 2065 userId, "finished booting")) { 2066 return true; 2067 } 2068 } 2069 } 2070 } 2071 return false; 2072 } 2073 }; 2074 2075 public void setSystemProcess() { 2076 try { 2077 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2078 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2079 ServiceManager.addService("meminfo", new MemBinder(this)); 2080 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2081 ServiceManager.addService("dbinfo", new DbBinder(this)); 2082 if (MONITOR_CPU_USAGE) { 2083 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2084 } 2085 ServiceManager.addService("permission", new PermissionController(this)); 2086 2087 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2088 "android", STOCK_PM_FLAGS); 2089 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2090 2091 synchronized (this) { 2092 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2093 app.persistent = true; 2094 app.pid = MY_PID; 2095 app.maxAdj = ProcessList.SYSTEM_ADJ; 2096 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2097 mProcessNames.put(app.processName, app.uid, app); 2098 synchronized (mPidsSelfLocked) { 2099 mPidsSelfLocked.put(app.pid, app); 2100 } 2101 updateLruProcessLocked(app, false, null); 2102 updateOomAdjLocked(); 2103 } 2104 } catch (PackageManager.NameNotFoundException e) { 2105 throw new RuntimeException( 2106 "Unable to find android system package", e); 2107 } 2108 } 2109 2110 public void setWindowManager(WindowManagerService wm) { 2111 mWindowManager = wm; 2112 mStackSupervisor.setWindowManager(wm); 2113 } 2114 2115 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2116 mUsageStatsService = usageStatsManager; 2117 } 2118 2119 public void startObservingNativeCrashes() { 2120 final NativeCrashListener ncl = new NativeCrashListener(this); 2121 ncl.start(); 2122 } 2123 2124 public IAppOpsService getAppOpsService() { 2125 return mAppOpsService; 2126 } 2127 2128 static class MemBinder extends Binder { 2129 ActivityManagerService mActivityManagerService; 2130 MemBinder(ActivityManagerService activityManagerService) { 2131 mActivityManagerService = activityManagerService; 2132 } 2133 2134 @Override 2135 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2136 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2137 != PackageManager.PERMISSION_GRANTED) { 2138 pw.println("Permission Denial: can't dump meminfo from from pid=" 2139 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2140 + " without permission " + android.Manifest.permission.DUMP); 2141 return; 2142 } 2143 2144 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2145 } 2146 } 2147 2148 static class GraphicsBinder extends Binder { 2149 ActivityManagerService mActivityManagerService; 2150 GraphicsBinder(ActivityManagerService activityManagerService) { 2151 mActivityManagerService = activityManagerService; 2152 } 2153 2154 @Override 2155 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2156 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2157 != PackageManager.PERMISSION_GRANTED) { 2158 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2159 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2160 + " without permission " + android.Manifest.permission.DUMP); 2161 return; 2162 } 2163 2164 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2165 } 2166 } 2167 2168 static class DbBinder extends Binder { 2169 ActivityManagerService mActivityManagerService; 2170 DbBinder(ActivityManagerService activityManagerService) { 2171 mActivityManagerService = activityManagerService; 2172 } 2173 2174 @Override 2175 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2176 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2177 != PackageManager.PERMISSION_GRANTED) { 2178 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2179 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2180 + " without permission " + android.Manifest.permission.DUMP); 2181 return; 2182 } 2183 2184 mActivityManagerService.dumpDbInfo(fd, pw, args); 2185 } 2186 } 2187 2188 static class CpuBinder extends Binder { 2189 ActivityManagerService mActivityManagerService; 2190 CpuBinder(ActivityManagerService activityManagerService) { 2191 mActivityManagerService = activityManagerService; 2192 } 2193 2194 @Override 2195 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2196 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2197 != PackageManager.PERMISSION_GRANTED) { 2198 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2199 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2200 + " without permission " + android.Manifest.permission.DUMP); 2201 return; 2202 } 2203 2204 synchronized (mActivityManagerService.mProcessCpuTracker) { 2205 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2206 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2207 SystemClock.uptimeMillis())); 2208 } 2209 } 2210 } 2211 2212 public static final class Lifecycle extends SystemService { 2213 private final ActivityManagerService mService; 2214 2215 public Lifecycle(Context context) { 2216 super(context); 2217 mService = new ActivityManagerService(context); 2218 } 2219 2220 @Override 2221 public void onStart() { 2222 mService.start(); 2223 } 2224 2225 public ActivityManagerService getService() { 2226 return mService; 2227 } 2228 } 2229 2230 // Note: This method is invoked on the main thread but may need to attach various 2231 // handlers to other threads. So take care to be explicit about the looper. 2232 public ActivityManagerService(Context systemContext) { 2233 mContext = systemContext; 2234 mFactoryTest = FactoryTest.getMode(); 2235 mSystemThread = ActivityThread.currentActivityThread(); 2236 2237 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2238 2239 mHandlerThread = new ServiceThread(TAG, 2240 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2241 mHandlerThread.start(); 2242 mHandler = new MainHandler(mHandlerThread.getLooper()); 2243 2244 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2245 "foreground", BROADCAST_FG_TIMEOUT, false); 2246 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2247 "background", BROADCAST_BG_TIMEOUT, true); 2248 mBroadcastQueues[0] = mFgBroadcastQueue; 2249 mBroadcastQueues[1] = mBgBroadcastQueue; 2250 2251 mServices = new ActiveServices(this); 2252 mProviderMap = new ProviderMap(this); 2253 2254 // TODO: Move creation of battery stats service outside of activity manager service. 2255 File dataDir = Environment.getDataDirectory(); 2256 File systemDir = new File(dataDir, "system"); 2257 systemDir.mkdirs(); 2258 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2259 mBatteryStatsService.getActiveStatistics().readLocked(); 2260 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2261 mOnBattery = DEBUG_POWER ? true 2262 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2263 mBatteryStatsService.getActiveStatistics().setCallback(this); 2264 2265 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2266 2267 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2268 2269 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2270 2271 // User 0 is the first and only user that runs at boot. 2272 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2273 mUserLru.add(Integer.valueOf(0)); 2274 updateStartedUserArrayLocked(); 2275 2276 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2277 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2278 2279 mConfiguration.setToDefaults(); 2280 mConfiguration.setLocale(Locale.getDefault()); 2281 2282 mConfigurationSeq = mConfiguration.seq = 1; 2283 mProcessCpuTracker.init(); 2284 2285 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2286 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2287 mStackSupervisor = new ActivityStackSupervisor(this); 2288 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2289 2290 mProcessCpuThread = new Thread("CpuTracker") { 2291 @Override 2292 public void run() { 2293 while (true) { 2294 try { 2295 try { 2296 synchronized(this) { 2297 final long now = SystemClock.uptimeMillis(); 2298 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2299 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2300 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2301 // + ", write delay=" + nextWriteDelay); 2302 if (nextWriteDelay < nextCpuDelay) { 2303 nextCpuDelay = nextWriteDelay; 2304 } 2305 if (nextCpuDelay > 0) { 2306 mProcessCpuMutexFree.set(true); 2307 this.wait(nextCpuDelay); 2308 } 2309 } 2310 } catch (InterruptedException e) { 2311 } 2312 updateCpuStatsNow(); 2313 } catch (Exception e) { 2314 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2315 } 2316 } 2317 } 2318 }; 2319 2320 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2321 2322 Watchdog.getInstance().addMonitor(this); 2323 Watchdog.getInstance().addThread(mHandler); 2324 } 2325 2326 public void setSystemServiceManager(SystemServiceManager mgr) { 2327 mSystemServiceManager = mgr; 2328 } 2329 2330 private void start() { 2331 Process.removeAllProcessGroups(); 2332 mProcessCpuThread.start(); 2333 2334 mBatteryStatsService.publish(mContext); 2335 mAppOpsService.publish(mContext); 2336 Slog.d("AppOps", "AppOpsService published"); 2337 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2338 } 2339 2340 public void initPowerManagement() { 2341 mStackSupervisor.initPowerManagement(); 2342 mBatteryStatsService.initPowerManagement(); 2343 } 2344 2345 @Override 2346 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2347 throws RemoteException { 2348 if (code == SYSPROPS_TRANSACTION) { 2349 // We need to tell all apps about the system property change. 2350 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2351 synchronized(this) { 2352 final int NP = mProcessNames.getMap().size(); 2353 for (int ip=0; ip<NP; ip++) { 2354 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2355 final int NA = apps.size(); 2356 for (int ia=0; ia<NA; ia++) { 2357 ProcessRecord app = apps.valueAt(ia); 2358 if (app.thread != null) { 2359 procs.add(app.thread.asBinder()); 2360 } 2361 } 2362 } 2363 } 2364 2365 int N = procs.size(); 2366 for (int i=0; i<N; i++) { 2367 Parcel data2 = Parcel.obtain(); 2368 try { 2369 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2370 } catch (RemoteException e) { 2371 } 2372 data2.recycle(); 2373 } 2374 } 2375 try { 2376 return super.onTransact(code, data, reply, flags); 2377 } catch (RuntimeException e) { 2378 // The activity manager only throws security exceptions, so let's 2379 // log all others. 2380 if (!(e instanceof SecurityException)) { 2381 Slog.wtf(TAG, "Activity Manager Crash", e); 2382 } 2383 throw e; 2384 } 2385 } 2386 2387 void updateCpuStats() { 2388 final long now = SystemClock.uptimeMillis(); 2389 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2390 return; 2391 } 2392 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2393 synchronized (mProcessCpuThread) { 2394 mProcessCpuThread.notify(); 2395 } 2396 } 2397 } 2398 2399 void updateCpuStatsNow() { 2400 synchronized (mProcessCpuTracker) { 2401 mProcessCpuMutexFree.set(false); 2402 final long now = SystemClock.uptimeMillis(); 2403 boolean haveNewCpuStats = false; 2404 2405 if (MONITOR_CPU_USAGE && 2406 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2407 mLastCpuTime.set(now); 2408 haveNewCpuStats = true; 2409 mProcessCpuTracker.update(); 2410 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2411 //Slog.i(TAG, "Total CPU usage: " 2412 // + mProcessCpu.getTotalCpuPercent() + "%"); 2413 2414 // Slog the cpu usage if the property is set. 2415 if ("true".equals(SystemProperties.get("events.cpu"))) { 2416 int user = mProcessCpuTracker.getLastUserTime(); 2417 int system = mProcessCpuTracker.getLastSystemTime(); 2418 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2419 int irq = mProcessCpuTracker.getLastIrqTime(); 2420 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2421 int idle = mProcessCpuTracker.getLastIdleTime(); 2422 2423 int total = user + system + iowait + irq + softIrq + idle; 2424 if (total == 0) total = 1; 2425 2426 EventLog.writeEvent(EventLogTags.CPU, 2427 ((user+system+iowait+irq+softIrq) * 100) / total, 2428 (user * 100) / total, 2429 (system * 100) / total, 2430 (iowait * 100) / total, 2431 (irq * 100) / total, 2432 (softIrq * 100) / total); 2433 } 2434 } 2435 2436 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2437 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2438 synchronized(bstats) { 2439 synchronized(mPidsSelfLocked) { 2440 if (haveNewCpuStats) { 2441 if (mOnBattery) { 2442 int perc = bstats.startAddingCpuLocked(); 2443 int totalUTime = 0; 2444 int totalSTime = 0; 2445 final int N = mProcessCpuTracker.countStats(); 2446 for (int i=0; i<N; i++) { 2447 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2448 if (!st.working) { 2449 continue; 2450 } 2451 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2452 int otherUTime = (st.rel_utime*perc)/100; 2453 int otherSTime = (st.rel_stime*perc)/100; 2454 totalUTime += otherUTime; 2455 totalSTime += otherSTime; 2456 if (pr != null) { 2457 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2458 if (ps == null || !ps.isActive()) { 2459 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2460 pr.info.uid, pr.processName); 2461 } 2462 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2463 st.rel_stime-otherSTime); 2464 ps.addSpeedStepTimes(cpuSpeedTimes); 2465 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2466 } else { 2467 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2468 if (ps == null || !ps.isActive()) { 2469 st.batteryStats = ps = bstats.getProcessStatsLocked( 2470 bstats.mapUid(st.uid), st.name); 2471 } 2472 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2473 st.rel_stime-otherSTime); 2474 ps.addSpeedStepTimes(cpuSpeedTimes); 2475 } 2476 } 2477 bstats.finishAddingCpuLocked(perc, totalUTime, 2478 totalSTime, cpuSpeedTimes); 2479 } 2480 } 2481 } 2482 2483 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2484 mLastWriteTime = now; 2485 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2486 } 2487 } 2488 } 2489 } 2490 2491 @Override 2492 public void batteryNeedsCpuUpdate() { 2493 updateCpuStatsNow(); 2494 } 2495 2496 @Override 2497 public void batteryPowerChanged(boolean onBattery) { 2498 // When plugging in, update the CPU stats first before changing 2499 // the plug state. 2500 updateCpuStatsNow(); 2501 synchronized (this) { 2502 synchronized(mPidsSelfLocked) { 2503 mOnBattery = DEBUG_POWER ? true : onBattery; 2504 } 2505 } 2506 } 2507 2508 /** 2509 * Initialize the application bind args. These are passed to each 2510 * process when the bindApplication() IPC is sent to the process. They're 2511 * lazily setup to make sure the services are running when they're asked for. 2512 */ 2513 private HashMap<String, IBinder> getCommonServicesLocked() { 2514 if (mAppBindArgs == null) { 2515 mAppBindArgs = new HashMap<String, IBinder>(); 2516 2517 // Setup the application init args 2518 mAppBindArgs.put("package", ServiceManager.getService("package")); 2519 mAppBindArgs.put("window", ServiceManager.getService("window")); 2520 mAppBindArgs.put(Context.ALARM_SERVICE, 2521 ServiceManager.getService(Context.ALARM_SERVICE)); 2522 } 2523 return mAppBindArgs; 2524 } 2525 2526 final void setFocusedActivityLocked(ActivityRecord r) { 2527 if (mFocusedActivity != r) { 2528 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2529 mFocusedActivity = r; 2530 if (r.task != null && r.task.voiceInteractor != null) { 2531 startRunningVoiceLocked(); 2532 } else { 2533 finishRunningVoiceLocked(); 2534 } 2535 mStackSupervisor.setFocusedStack(r); 2536 if (r != null) { 2537 mWindowManager.setFocusedApp(r.appToken, true); 2538 } 2539 applyUpdateLockStateLocked(r); 2540 } 2541 } 2542 2543 final void clearFocusedActivity(ActivityRecord r) { 2544 if (mFocusedActivity == r) { 2545 mFocusedActivity = null; 2546 } 2547 } 2548 2549 @Override 2550 public void setFocusedStack(int stackId) { 2551 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2552 synchronized (ActivityManagerService.this) { 2553 ActivityStack stack = mStackSupervisor.getStack(stackId); 2554 if (stack != null) { 2555 ActivityRecord r = stack.topRunningActivityLocked(null); 2556 if (r != null) { 2557 setFocusedActivityLocked(r); 2558 } 2559 } 2560 } 2561 } 2562 2563 @Override 2564 public void notifyActivityDrawn(IBinder token) { 2565 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2566 synchronized (this) { 2567 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2568 if (r != null) { 2569 r.task.stack.notifyActivityDrawnLocked(r); 2570 } 2571 } 2572 } 2573 2574 final void applyUpdateLockStateLocked(ActivityRecord r) { 2575 // Modifications to the UpdateLock state are done on our handler, outside 2576 // the activity manager's locks. The new state is determined based on the 2577 // state *now* of the relevant activity record. The object is passed to 2578 // the handler solely for logging detail, not to be consulted/modified. 2579 final boolean nextState = r != null && r.immersive; 2580 mHandler.sendMessage( 2581 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2582 } 2583 2584 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2585 Message msg = Message.obtain(); 2586 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2587 msg.obj = r.task.askedCompatMode ? null : r; 2588 mHandler.sendMessage(msg); 2589 } 2590 2591 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2592 String what, Object obj, ProcessRecord srcApp) { 2593 app.lastActivityTime = now; 2594 2595 if (app.activities.size() > 0) { 2596 // Don't want to touch dependent processes that are hosting activities. 2597 return index; 2598 } 2599 2600 int lrui = mLruProcesses.lastIndexOf(app); 2601 if (lrui < 0) { 2602 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2603 + what + " " + obj + " from " + srcApp); 2604 return index; 2605 } 2606 2607 if (lrui >= index) { 2608 // Don't want to cause this to move dependent processes *back* in the 2609 // list as if they were less frequently used. 2610 return index; 2611 } 2612 2613 if (lrui >= mLruProcessActivityStart) { 2614 // Don't want to touch dependent processes that are hosting activities. 2615 return index; 2616 } 2617 2618 mLruProcesses.remove(lrui); 2619 if (index > 0) { 2620 index--; 2621 } 2622 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2623 + " in LRU list: " + app); 2624 mLruProcesses.add(index, app); 2625 return index; 2626 } 2627 2628 final void removeLruProcessLocked(ProcessRecord app) { 2629 int lrui = mLruProcesses.lastIndexOf(app); 2630 if (lrui >= 0) { 2631 if (!app.killed) { 2632 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2633 Process.killProcessQuiet(app.pid); 2634 Process.killProcessGroup(app.info.uid, app.pid); 2635 } 2636 if (lrui <= mLruProcessActivityStart) { 2637 mLruProcessActivityStart--; 2638 } 2639 if (lrui <= mLruProcessServiceStart) { 2640 mLruProcessServiceStart--; 2641 } 2642 mLruProcesses.remove(lrui); 2643 } 2644 } 2645 2646 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2647 ProcessRecord client) { 2648 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2649 || app.treatLikeActivity; 2650 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2651 if (!activityChange && hasActivity) { 2652 // The process has activities, so we are only allowing activity-based adjustments 2653 // to move it. It should be kept in the front of the list with other 2654 // processes that have activities, and we don't want those to change their 2655 // order except due to activity operations. 2656 return; 2657 } 2658 2659 mLruSeq++; 2660 final long now = SystemClock.uptimeMillis(); 2661 app.lastActivityTime = now; 2662 2663 // First a quick reject: if the app is already at the position we will 2664 // put it, then there is nothing to do. 2665 if (hasActivity) { 2666 final int N = mLruProcesses.size(); 2667 if (N > 0 && mLruProcesses.get(N-1) == app) { 2668 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2669 return; 2670 } 2671 } else { 2672 if (mLruProcessServiceStart > 0 2673 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2674 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2675 return; 2676 } 2677 } 2678 2679 int lrui = mLruProcesses.lastIndexOf(app); 2680 2681 if (app.persistent && lrui >= 0) { 2682 // We don't care about the position of persistent processes, as long as 2683 // they are in the list. 2684 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2685 return; 2686 } 2687 2688 /* In progress: compute new position first, so we can avoid doing work 2689 if the process is not actually going to move. Not yet working. 2690 int addIndex; 2691 int nextIndex; 2692 boolean inActivity = false, inService = false; 2693 if (hasActivity) { 2694 // Process has activities, put it at the very tipsy-top. 2695 addIndex = mLruProcesses.size(); 2696 nextIndex = mLruProcessServiceStart; 2697 inActivity = true; 2698 } else if (hasService) { 2699 // Process has services, put it at the top of the service list. 2700 addIndex = mLruProcessActivityStart; 2701 nextIndex = mLruProcessServiceStart; 2702 inActivity = true; 2703 inService = true; 2704 } else { 2705 // Process not otherwise of interest, it goes to the top of the non-service area. 2706 addIndex = mLruProcessServiceStart; 2707 if (client != null) { 2708 int clientIndex = mLruProcesses.lastIndexOf(client); 2709 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2710 + app); 2711 if (clientIndex >= 0 && addIndex > clientIndex) { 2712 addIndex = clientIndex; 2713 } 2714 } 2715 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2716 } 2717 2718 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2719 + mLruProcessActivityStart + "): " + app); 2720 */ 2721 2722 if (lrui >= 0) { 2723 if (lrui < mLruProcessActivityStart) { 2724 mLruProcessActivityStart--; 2725 } 2726 if (lrui < mLruProcessServiceStart) { 2727 mLruProcessServiceStart--; 2728 } 2729 /* 2730 if (addIndex > lrui) { 2731 addIndex--; 2732 } 2733 if (nextIndex > lrui) { 2734 nextIndex--; 2735 } 2736 */ 2737 mLruProcesses.remove(lrui); 2738 } 2739 2740 /* 2741 mLruProcesses.add(addIndex, app); 2742 if (inActivity) { 2743 mLruProcessActivityStart++; 2744 } 2745 if (inService) { 2746 mLruProcessActivityStart++; 2747 } 2748 */ 2749 2750 int nextIndex; 2751 if (hasActivity) { 2752 final int N = mLruProcesses.size(); 2753 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2754 // Process doesn't have activities, but has clients with 2755 // activities... move it up, but one below the top (the top 2756 // should always have a real activity). 2757 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2758 mLruProcesses.add(N-1, app); 2759 // To keep it from spamming the LRU list (by making a bunch of clients), 2760 // we will push down any other entries owned by the app. 2761 final int uid = app.info.uid; 2762 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2763 ProcessRecord subProc = mLruProcesses.get(i); 2764 if (subProc.info.uid == uid) { 2765 // We want to push this one down the list. If the process after 2766 // it is for the same uid, however, don't do so, because we don't 2767 // want them internally to be re-ordered. 2768 if (mLruProcesses.get(i-1).info.uid != uid) { 2769 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2770 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2771 ProcessRecord tmp = mLruProcesses.get(i); 2772 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2773 mLruProcesses.set(i-1, tmp); 2774 i--; 2775 } 2776 } else { 2777 // A gap, we can stop here. 2778 break; 2779 } 2780 } 2781 } else { 2782 // Process has activities, put it at the very tipsy-top. 2783 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2784 mLruProcesses.add(app); 2785 } 2786 nextIndex = mLruProcessServiceStart; 2787 } else if (hasService) { 2788 // Process has services, put it at the top of the service list. 2789 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2790 mLruProcesses.add(mLruProcessActivityStart, app); 2791 nextIndex = mLruProcessServiceStart; 2792 mLruProcessActivityStart++; 2793 } else { 2794 // Process not otherwise of interest, it goes to the top of the non-service area. 2795 int index = mLruProcessServiceStart; 2796 if (client != null) { 2797 // If there is a client, don't allow the process to be moved up higher 2798 // in the list than that client. 2799 int clientIndex = mLruProcesses.lastIndexOf(client); 2800 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2801 + " when updating " + app); 2802 if (clientIndex <= lrui) { 2803 // Don't allow the client index restriction to push it down farther in the 2804 // list than it already is. 2805 clientIndex = lrui; 2806 } 2807 if (clientIndex >= 0 && index > clientIndex) { 2808 index = clientIndex; 2809 } 2810 } 2811 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2812 mLruProcesses.add(index, app); 2813 nextIndex = index-1; 2814 mLruProcessActivityStart++; 2815 mLruProcessServiceStart++; 2816 } 2817 2818 // If the app is currently using a content provider or service, 2819 // bump those processes as well. 2820 for (int j=app.connections.size()-1; j>=0; j--) { 2821 ConnectionRecord cr = app.connections.valueAt(j); 2822 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2823 && cr.binding.service.app != null 2824 && cr.binding.service.app.lruSeq != mLruSeq 2825 && !cr.binding.service.app.persistent) { 2826 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2827 "service connection", cr, app); 2828 } 2829 } 2830 for (int j=app.conProviders.size()-1; j>=0; j--) { 2831 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2832 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2833 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2834 "provider reference", cpr, app); 2835 } 2836 } 2837 } 2838 2839 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2840 if (uid == Process.SYSTEM_UID) { 2841 // The system gets to run in any process. If there are multiple 2842 // processes with the same uid, just pick the first (this 2843 // should never happen). 2844 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2845 if (procs == null) return null; 2846 final int N = procs.size(); 2847 for (int i = 0; i < N; i++) { 2848 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2849 } 2850 } 2851 ProcessRecord proc = mProcessNames.get(processName, uid); 2852 if (false && proc != null && !keepIfLarge 2853 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2854 && proc.lastCachedPss >= 4000) { 2855 // Turn this condition on to cause killing to happen regularly, for testing. 2856 if (proc.baseProcessTracker != null) { 2857 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2858 } 2859 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2860 } else if (proc != null && !keepIfLarge 2861 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2862 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2863 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2864 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2865 if (proc.baseProcessTracker != null) { 2866 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2867 } 2868 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2869 } 2870 } 2871 return proc; 2872 } 2873 2874 void ensurePackageDexOpt(String packageName) { 2875 IPackageManager pm = AppGlobals.getPackageManager(); 2876 try { 2877 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2878 mDidDexOpt = true; 2879 } 2880 } catch (RemoteException e) { 2881 } 2882 } 2883 2884 boolean isNextTransitionForward() { 2885 int transit = mWindowManager.getPendingAppTransition(); 2886 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2887 || transit == AppTransition.TRANSIT_TASK_OPEN 2888 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2889 } 2890 2891 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2892 String processName, String abiOverride, int uid, Runnable crashHandler) { 2893 synchronized(this) { 2894 ApplicationInfo info = new ApplicationInfo(); 2895 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2896 // For isolated processes, the former contains the parent's uid and the latter the 2897 // actual uid of the isolated process. 2898 // In the special case introduced by this method (which is, starting an isolated 2899 // process directly from the SystemServer without an actual parent app process) the 2900 // closest thing to a parent's uid is SYSTEM_UID. 2901 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2902 // the |isolated| logic in the ProcessRecord constructor. 2903 info.uid = Process.SYSTEM_UID; 2904 info.processName = processName; 2905 info.className = entryPoint; 2906 info.packageName = "android"; 2907 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2908 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2909 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2910 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2911 crashHandler); 2912 return proc != null ? proc.pid : 0; 2913 } 2914 } 2915 2916 final ProcessRecord startProcessLocked(String processName, 2917 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2918 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2919 boolean isolated, boolean keepIfLarge) { 2920 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2921 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2922 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2923 null /* crashHandler */); 2924 } 2925 2926 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2927 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2928 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2929 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2930 long startTime = SystemClock.elapsedRealtime(); 2931 ProcessRecord app; 2932 if (!isolated) { 2933 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2934 checkTime(startTime, "startProcess: after getProcessRecord"); 2935 } else { 2936 // If this is an isolated process, it can't re-use an existing process. 2937 app = null; 2938 } 2939 // We don't have to do anything more if: 2940 // (1) There is an existing application record; and 2941 // (2) The caller doesn't think it is dead, OR there is no thread 2942 // object attached to it so we know it couldn't have crashed; and 2943 // (3) There is a pid assigned to it, so it is either starting or 2944 // already running. 2945 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2946 + " app=" + app + " knownToBeDead=" + knownToBeDead 2947 + " thread=" + (app != null ? app.thread : null) 2948 + " pid=" + (app != null ? app.pid : -1)); 2949 if (app != null && app.pid > 0) { 2950 if (!knownToBeDead || app.thread == null) { 2951 // We already have the app running, or are waiting for it to 2952 // come up (we have a pid but not yet its thread), so keep it. 2953 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2954 // If this is a new package in the process, add the package to the list 2955 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2956 checkTime(startTime, "startProcess: done, added package to proc"); 2957 return app; 2958 } 2959 2960 // An application record is attached to a previous process, 2961 // clean it up now. 2962 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2963 checkTime(startTime, "startProcess: bad proc running, killing"); 2964 Process.killProcessGroup(app.info.uid, app.pid); 2965 handleAppDiedLocked(app, true, true); 2966 checkTime(startTime, "startProcess: done killing old proc"); 2967 } 2968 2969 String hostingNameStr = hostingName != null 2970 ? hostingName.flattenToShortString() : null; 2971 2972 if (!isolated) { 2973 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2974 // If we are in the background, then check to see if this process 2975 // is bad. If so, we will just silently fail. 2976 if (mBadProcesses.get(info.processName, info.uid) != null) { 2977 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2978 + "/" + info.processName); 2979 return null; 2980 } 2981 } else { 2982 // When the user is explicitly starting a process, then clear its 2983 // crash count so that we won't make it bad until they see at 2984 // least one crash dialog again, and make the process good again 2985 // if it had been bad. 2986 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2987 + "/" + info.processName); 2988 mProcessCrashTimes.remove(info.processName, info.uid); 2989 if (mBadProcesses.get(info.processName, info.uid) != null) { 2990 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2991 UserHandle.getUserId(info.uid), info.uid, 2992 info.processName); 2993 mBadProcesses.remove(info.processName, info.uid); 2994 if (app != null) { 2995 app.bad = false; 2996 } 2997 } 2998 } 2999 } 3000 3001 if (app == null) { 3002 checkTime(startTime, "startProcess: creating new process record"); 3003 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 3004 app.crashHandler = crashHandler; 3005 if (app == null) { 3006 Slog.w(TAG, "Failed making new process record for " 3007 + processName + "/" + info.uid + " isolated=" + isolated); 3008 return null; 3009 } 3010 mProcessNames.put(processName, app.uid, app); 3011 if (isolated) { 3012 mIsolatedProcesses.put(app.uid, app); 3013 } 3014 checkTime(startTime, "startProcess: done creating new process record"); 3015 } else { 3016 // If this is a new package in the process, add the package to the list 3017 app.addPackage(info.packageName, info.versionCode, mProcessStats); 3018 checkTime(startTime, "startProcess: added package to existing proc"); 3019 } 3020 3021 // If the system is not ready yet, then hold off on starting this 3022 // process until it is. 3023 if (!mProcessesReady 3024 && !isAllowedWhileBooting(info) 3025 && !allowWhileBooting) { 3026 if (!mProcessesOnHold.contains(app)) { 3027 mProcessesOnHold.add(app); 3028 } 3029 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 3030 checkTime(startTime, "startProcess: returning with proc on hold"); 3031 return app; 3032 } 3033 3034 checkTime(startTime, "startProcess: stepping in to startProcess"); 3035 startProcessLocked( 3036 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3037 checkTime(startTime, "startProcess: done starting proc!"); 3038 return (app.pid != 0) ? app : null; 3039 } 3040 3041 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3042 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3043 } 3044 3045 private final void startProcessLocked(ProcessRecord app, 3046 String hostingType, String hostingNameStr) { 3047 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3048 null /* entryPoint */, null /* entryPointArgs */); 3049 } 3050 3051 private final void startProcessLocked(ProcessRecord app, String hostingType, 3052 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3053 long startTime = SystemClock.elapsedRealtime(); 3054 if (app.pid > 0 && app.pid != MY_PID) { 3055 checkTime(startTime, "startProcess: removing from pids map"); 3056 synchronized (mPidsSelfLocked) { 3057 mPidsSelfLocked.remove(app.pid); 3058 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3059 } 3060 checkTime(startTime, "startProcess: done removing from pids map"); 3061 app.setPid(0); 3062 } 3063 3064 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3065 "startProcessLocked removing on hold: " + app); 3066 mProcessesOnHold.remove(app); 3067 3068 checkTime(startTime, "startProcess: starting to update cpu stats"); 3069 updateCpuStats(); 3070 checkTime(startTime, "startProcess: done updating cpu stats"); 3071 3072 try { 3073 int uid = app.uid; 3074 3075 int[] gids = null; 3076 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3077 if (!app.isolated) { 3078 int[] permGids = null; 3079 try { 3080 checkTime(startTime, "startProcess: getting gids from package manager"); 3081 final PackageManager pm = mContext.getPackageManager(); 3082 permGids = pm.getPackageGids(app.info.packageName); 3083 3084 if (Environment.isExternalStorageEmulated()) { 3085 checkTime(startTime, "startProcess: checking external storage perm"); 3086 if (pm.checkPermission( 3087 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3088 app.info.packageName) == PERMISSION_GRANTED) { 3089 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3090 } else { 3091 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3092 } 3093 } 3094 } catch (PackageManager.NameNotFoundException e) { 3095 Slog.w(TAG, "Unable to retrieve gids", e); 3096 } 3097 3098 /* 3099 * Add shared application and profile GIDs so applications can share some 3100 * resources like shared libraries and access user-wide resources 3101 */ 3102 if (permGids == null) { 3103 gids = new int[2]; 3104 } else { 3105 gids = new int[permGids.length + 2]; 3106 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3107 } 3108 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3109 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3110 } 3111 checkTime(startTime, "startProcess: building args"); 3112 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3113 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3114 && mTopComponent != null 3115 && app.processName.equals(mTopComponent.getPackageName())) { 3116 uid = 0; 3117 } 3118 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3119 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3120 uid = 0; 3121 } 3122 } 3123 int debugFlags = 0; 3124 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3125 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3126 // Also turn on CheckJNI for debuggable apps. It's quite 3127 // awkward to turn on otherwise. 3128 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3129 } 3130 // Run the app in safe mode if its manifest requests so or the 3131 // system is booted in safe mode. 3132 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3133 mSafeMode == true) { 3134 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3135 } 3136 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3137 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3138 } 3139 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3140 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3141 } 3142 if ("1".equals(SystemProperties.get("debug.assert"))) { 3143 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3144 } 3145 3146 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3147 if (requiredAbi == null) { 3148 requiredAbi = Build.SUPPORTED_ABIS[0]; 3149 } 3150 3151 String instructionSet = null; 3152 if (app.info.primaryCpuAbi != null) { 3153 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3154 } 3155 3156 // Start the process. It will either succeed and return a result containing 3157 // the PID of the new process, or else throw a RuntimeException. 3158 boolean isActivityProcess = (entryPoint == null); 3159 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3160 checkTime(startTime, "startProcess: asking zygote to start proc"); 3161 Process.ProcessStartResult startResult = Process.start(entryPoint, 3162 app.processName, uid, uid, gids, debugFlags, mountExternal, 3163 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3164 entryPointArgs); 3165 checkTime(startTime, "startProcess: returned from zygote!"); 3166 3167 if (app.isolated) { 3168 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3169 } 3170 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3171 checkTime(startTime, "startProcess: done updating battery stats"); 3172 3173 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3174 UserHandle.getUserId(uid), startResult.pid, uid, 3175 app.processName, hostingType, 3176 hostingNameStr != null ? hostingNameStr : ""); 3177 3178 if (app.persistent) { 3179 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3180 } 3181 3182 checkTime(startTime, "startProcess: building log message"); 3183 StringBuilder buf = mStringBuilder; 3184 buf.setLength(0); 3185 buf.append("Start proc "); 3186 buf.append(app.processName); 3187 if (!isActivityProcess) { 3188 buf.append(" ["); 3189 buf.append(entryPoint); 3190 buf.append("]"); 3191 } 3192 buf.append(" for "); 3193 buf.append(hostingType); 3194 if (hostingNameStr != null) { 3195 buf.append(" "); 3196 buf.append(hostingNameStr); 3197 } 3198 buf.append(": pid="); 3199 buf.append(startResult.pid); 3200 buf.append(" uid="); 3201 buf.append(uid); 3202 buf.append(" gids={"); 3203 if (gids != null) { 3204 for (int gi=0; gi<gids.length; gi++) { 3205 if (gi != 0) buf.append(", "); 3206 buf.append(gids[gi]); 3207 3208 } 3209 } 3210 buf.append("}"); 3211 if (requiredAbi != null) { 3212 buf.append(" abi="); 3213 buf.append(requiredAbi); 3214 } 3215 Slog.i(TAG, buf.toString()); 3216 app.setPid(startResult.pid); 3217 app.usingWrapper = startResult.usingWrapper; 3218 app.removed = false; 3219 app.killed = false; 3220 app.killedByAm = false; 3221 checkTime(startTime, "startProcess: starting to update pids map"); 3222 synchronized (mPidsSelfLocked) { 3223 this.mPidsSelfLocked.put(startResult.pid, app); 3224 if (isActivityProcess) { 3225 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3226 msg.obj = app; 3227 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3228 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3229 } 3230 } 3231 checkTime(startTime, "startProcess: done updating pids map"); 3232 } catch (RuntimeException e) { 3233 // XXX do better error recovery. 3234 app.setPid(0); 3235 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3236 if (app.isolated) { 3237 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3238 } 3239 Slog.e(TAG, "Failure starting process " + app.processName, e); 3240 } 3241 } 3242 3243 void updateUsageStats(ActivityRecord component, boolean resumed) { 3244 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3245 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3246 if (resumed) { 3247 if (mUsageStatsService != null) { 3248 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3249 UsageEvents.Event.MOVE_TO_FOREGROUND); 3250 } 3251 synchronized (stats) { 3252 stats.noteActivityResumedLocked(component.app.uid); 3253 } 3254 } else { 3255 if (mUsageStatsService != null) { 3256 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3257 UsageEvents.Event.MOVE_TO_BACKGROUND); 3258 } 3259 synchronized (stats) { 3260 stats.noteActivityPausedLocked(component.app.uid); 3261 } 3262 } 3263 } 3264 3265 Intent getHomeIntent() { 3266 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3267 intent.setComponent(mTopComponent); 3268 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3269 intent.addCategory(Intent.CATEGORY_HOME); 3270 } 3271 return intent; 3272 } 3273 3274 boolean startHomeActivityLocked(int userId) { 3275 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3276 && mTopAction == null) { 3277 // We are running in factory test mode, but unable to find 3278 // the factory test app, so just sit around displaying the 3279 // error message and don't try to start anything. 3280 return false; 3281 } 3282 Intent intent = getHomeIntent(); 3283 ActivityInfo aInfo = 3284 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3285 if (aInfo != null) { 3286 intent.setComponent(new ComponentName( 3287 aInfo.applicationInfo.packageName, aInfo.name)); 3288 // Don't do this if the home app is currently being 3289 // instrumented. 3290 aInfo = new ActivityInfo(aInfo); 3291 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3292 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3293 aInfo.applicationInfo.uid, true); 3294 if (app == null || app.instrumentationClass == null) { 3295 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3296 mStackSupervisor.startHomeActivity(intent, aInfo); 3297 } 3298 } 3299 3300 return true; 3301 } 3302 3303 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3304 ActivityInfo ai = null; 3305 ComponentName comp = intent.getComponent(); 3306 try { 3307 if (comp != null) { 3308 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3309 } else { 3310 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3311 intent, 3312 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3313 flags, userId); 3314 3315 if (info != null) { 3316 ai = info.activityInfo; 3317 } 3318 } 3319 } catch (RemoteException e) { 3320 // ignore 3321 } 3322 3323 return ai; 3324 } 3325 3326 /** 3327 * Starts the "new version setup screen" if appropriate. 3328 */ 3329 void startSetupActivityLocked() { 3330 // Only do this once per boot. 3331 if (mCheckedForSetup) { 3332 return; 3333 } 3334 3335 // We will show this screen if the current one is a different 3336 // version than the last one shown, and we are not running in 3337 // low-level factory test mode. 3338 final ContentResolver resolver = mContext.getContentResolver(); 3339 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3340 Settings.Global.getInt(resolver, 3341 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3342 mCheckedForSetup = true; 3343 3344 // See if we should be showing the platform update setup UI. 3345 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3346 List<ResolveInfo> ris = mContext.getPackageManager() 3347 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3348 3349 // We don't allow third party apps to replace this. 3350 ResolveInfo ri = null; 3351 for (int i=0; ris != null && i<ris.size(); i++) { 3352 if ((ris.get(i).activityInfo.applicationInfo.flags 3353 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3354 ri = ris.get(i); 3355 break; 3356 } 3357 } 3358 3359 if (ri != null) { 3360 String vers = ri.activityInfo.metaData != null 3361 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3362 : null; 3363 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3364 vers = ri.activityInfo.applicationInfo.metaData.getString( 3365 Intent.METADATA_SETUP_VERSION); 3366 } 3367 String lastVers = Settings.Secure.getString( 3368 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3369 if (vers != null && !vers.equals(lastVers)) { 3370 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3371 intent.setComponent(new ComponentName( 3372 ri.activityInfo.packageName, ri.activityInfo.name)); 3373 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3374 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3375 null); 3376 } 3377 } 3378 } 3379 } 3380 3381 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3382 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3383 } 3384 3385 void enforceNotIsolatedCaller(String caller) { 3386 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3387 throw new SecurityException("Isolated process not allowed to call " + caller); 3388 } 3389 } 3390 3391 void enforceShellRestriction(String restriction, int userHandle) { 3392 if (Binder.getCallingUid() == Process.SHELL_UID) { 3393 if (userHandle < 0 3394 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3395 throw new SecurityException("Shell does not have permission to access user " 3396 + userHandle); 3397 } 3398 } 3399 } 3400 3401 @Override 3402 public int getFrontActivityScreenCompatMode() { 3403 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3404 synchronized (this) { 3405 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3406 } 3407 } 3408 3409 @Override 3410 public void setFrontActivityScreenCompatMode(int mode) { 3411 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3412 "setFrontActivityScreenCompatMode"); 3413 synchronized (this) { 3414 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3415 } 3416 } 3417 3418 @Override 3419 public int getPackageScreenCompatMode(String packageName) { 3420 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3421 synchronized (this) { 3422 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3423 } 3424 } 3425 3426 @Override 3427 public void setPackageScreenCompatMode(String packageName, int mode) { 3428 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3429 "setPackageScreenCompatMode"); 3430 synchronized (this) { 3431 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3432 } 3433 } 3434 3435 @Override 3436 public boolean getPackageAskScreenCompat(String packageName) { 3437 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3438 synchronized (this) { 3439 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3440 } 3441 } 3442 3443 @Override 3444 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3445 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3446 "setPackageAskScreenCompat"); 3447 synchronized (this) { 3448 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3449 } 3450 } 3451 3452 private void dispatchProcessesChanged() { 3453 int N; 3454 synchronized (this) { 3455 N = mPendingProcessChanges.size(); 3456 if (mActiveProcessChanges.length < N) { 3457 mActiveProcessChanges = new ProcessChangeItem[N]; 3458 } 3459 mPendingProcessChanges.toArray(mActiveProcessChanges); 3460 mAvailProcessChanges.addAll(mPendingProcessChanges); 3461 mPendingProcessChanges.clear(); 3462 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3463 } 3464 3465 int i = mProcessObservers.beginBroadcast(); 3466 while (i > 0) { 3467 i--; 3468 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3469 if (observer != null) { 3470 try { 3471 for (int j=0; j<N; j++) { 3472 ProcessChangeItem item = mActiveProcessChanges[j]; 3473 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3474 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3475 + item.pid + " uid=" + item.uid + ": " 3476 + item.foregroundActivities); 3477 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3478 item.foregroundActivities); 3479 } 3480 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3481 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3482 + item.pid + " uid=" + item.uid + ": " + item.processState); 3483 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3484 } 3485 } 3486 } catch (RemoteException e) { 3487 } 3488 } 3489 } 3490 mProcessObservers.finishBroadcast(); 3491 } 3492 3493 private void dispatchProcessDied(int pid, int uid) { 3494 int i = mProcessObservers.beginBroadcast(); 3495 while (i > 0) { 3496 i--; 3497 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3498 if (observer != null) { 3499 try { 3500 observer.onProcessDied(pid, uid); 3501 } catch (RemoteException e) { 3502 } 3503 } 3504 } 3505 mProcessObservers.finishBroadcast(); 3506 } 3507 3508 @Override 3509 public final int startActivity(IApplicationThread caller, String callingPackage, 3510 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3511 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3512 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3513 resultWho, requestCode, startFlags, profilerInfo, options, 3514 UserHandle.getCallingUserId()); 3515 } 3516 3517 @Override 3518 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3519 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3520 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3521 enforceNotIsolatedCaller("startActivity"); 3522 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3523 false, ALLOW_FULL_ONLY, "startActivity", null); 3524 // TODO: Switch to user app stacks here. 3525 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3526 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3527 profilerInfo, null, null, options, userId, null, null); 3528 } 3529 3530 @Override 3531 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3532 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3533 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3534 3535 // This is very dangerous -- it allows you to perform a start activity (including 3536 // permission grants) as any app that may launch one of your own activities. So 3537 // we will only allow this to be done from activities that are part of the core framework, 3538 // and then only when they are running as the system. 3539 final ActivityRecord sourceRecord; 3540 final int targetUid; 3541 final String targetPackage; 3542 synchronized (this) { 3543 if (resultTo == null) { 3544 throw new SecurityException("Must be called from an activity"); 3545 } 3546 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3547 if (sourceRecord == null) { 3548 throw new SecurityException("Called with bad activity token: " + resultTo); 3549 } 3550 if (!sourceRecord.info.packageName.equals("android")) { 3551 throw new SecurityException( 3552 "Must be called from an activity that is declared in the android package"); 3553 } 3554 if (sourceRecord.app == null) { 3555 throw new SecurityException("Called without a process attached to activity"); 3556 } 3557 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3558 // This is still okay, as long as this activity is running under the 3559 // uid of the original calling activity. 3560 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3561 throw new SecurityException( 3562 "Calling activity in uid " + sourceRecord.app.uid 3563 + " must be system uid or original calling uid " 3564 + sourceRecord.launchedFromUid); 3565 } 3566 } 3567 targetUid = sourceRecord.launchedFromUid; 3568 targetPackage = sourceRecord.launchedFromPackage; 3569 } 3570 3571 // TODO: Switch to user app stacks here. 3572 try { 3573 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3574 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3575 null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null); 3576 return ret; 3577 } catch (SecurityException e) { 3578 // XXX need to figure out how to propagate to original app. 3579 // A SecurityException here is generally actually a fault of the original 3580 // calling activity (such as a fairly granting permissions), so propagate it 3581 // back to them. 3582 /* 3583 StringBuilder msg = new StringBuilder(); 3584 msg.append("While launching"); 3585 msg.append(intent.toString()); 3586 msg.append(": "); 3587 msg.append(e.getMessage()); 3588 */ 3589 throw e; 3590 } 3591 } 3592 3593 @Override 3594 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3595 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3596 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3597 enforceNotIsolatedCaller("startActivityAndWait"); 3598 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3599 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3600 WaitResult res = new WaitResult(); 3601 // TODO: Switch to user app stacks here. 3602 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3603 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3604 options, userId, null, null); 3605 return res; 3606 } 3607 3608 @Override 3609 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3610 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3611 int startFlags, Configuration config, Bundle options, int userId) { 3612 enforceNotIsolatedCaller("startActivityWithConfig"); 3613 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3614 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3615 // TODO: Switch to user app stacks here. 3616 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3617 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3618 null, null, config, options, userId, null, null); 3619 return ret; 3620 } 3621 3622 @Override 3623 public int startActivityIntentSender(IApplicationThread caller, 3624 IntentSender intent, Intent fillInIntent, String resolvedType, 3625 IBinder resultTo, String resultWho, int requestCode, 3626 int flagsMask, int flagsValues, Bundle options) { 3627 enforceNotIsolatedCaller("startActivityIntentSender"); 3628 // Refuse possible leaked file descriptors 3629 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3630 throw new IllegalArgumentException("File descriptors passed in Intent"); 3631 } 3632 3633 IIntentSender sender = intent.getTarget(); 3634 if (!(sender instanceof PendingIntentRecord)) { 3635 throw new IllegalArgumentException("Bad PendingIntent object"); 3636 } 3637 3638 PendingIntentRecord pir = (PendingIntentRecord)sender; 3639 3640 synchronized (this) { 3641 // If this is coming from the currently resumed activity, it is 3642 // effectively saying that app switches are allowed at this point. 3643 final ActivityStack stack = getFocusedStack(); 3644 if (stack.mResumedActivity != null && 3645 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3646 mAppSwitchesAllowedTime = 0; 3647 } 3648 } 3649 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3650 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3651 return ret; 3652 } 3653 3654 @Override 3655 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3656 Intent intent, String resolvedType, IVoiceInteractionSession session, 3657 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3658 Bundle options, int userId) { 3659 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3660 != PackageManager.PERMISSION_GRANTED) { 3661 String msg = "Permission Denial: startVoiceActivity() from pid=" 3662 + Binder.getCallingPid() 3663 + ", uid=" + Binder.getCallingUid() 3664 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3665 Slog.w(TAG, msg); 3666 throw new SecurityException(msg); 3667 } 3668 if (session == null || interactor == null) { 3669 throw new NullPointerException("null session or interactor"); 3670 } 3671 userId = handleIncomingUser(callingPid, callingUid, userId, 3672 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3673 // TODO: Switch to user app stacks here. 3674 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3675 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3676 null, options, userId, null, null); 3677 } 3678 3679 @Override 3680 public boolean startNextMatchingActivity(IBinder callingActivity, 3681 Intent intent, Bundle options) { 3682 // Refuse possible leaked file descriptors 3683 if (intent != null && intent.hasFileDescriptors() == true) { 3684 throw new IllegalArgumentException("File descriptors passed in Intent"); 3685 } 3686 3687 synchronized (this) { 3688 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3689 if (r == null) { 3690 ActivityOptions.abort(options); 3691 return false; 3692 } 3693 if (r.app == null || r.app.thread == null) { 3694 // The caller is not running... d'oh! 3695 ActivityOptions.abort(options); 3696 return false; 3697 } 3698 intent = new Intent(intent); 3699 // The caller is not allowed to change the data. 3700 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3701 // And we are resetting to find the next component... 3702 intent.setComponent(null); 3703 3704 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3705 3706 ActivityInfo aInfo = null; 3707 try { 3708 List<ResolveInfo> resolves = 3709 AppGlobals.getPackageManager().queryIntentActivities( 3710 intent, r.resolvedType, 3711 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3712 UserHandle.getCallingUserId()); 3713 3714 // Look for the original activity in the list... 3715 final int N = resolves != null ? resolves.size() : 0; 3716 for (int i=0; i<N; i++) { 3717 ResolveInfo rInfo = resolves.get(i); 3718 if (rInfo.activityInfo.packageName.equals(r.packageName) 3719 && rInfo.activityInfo.name.equals(r.info.name)) { 3720 // We found the current one... the next matching is 3721 // after it. 3722 i++; 3723 if (i<N) { 3724 aInfo = resolves.get(i).activityInfo; 3725 } 3726 if (debug) { 3727 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3728 + "/" + r.info.name); 3729 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3730 + "/" + aInfo.name); 3731 } 3732 break; 3733 } 3734 } 3735 } catch (RemoteException e) { 3736 } 3737 3738 if (aInfo == null) { 3739 // Nobody who is next! 3740 ActivityOptions.abort(options); 3741 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3742 return false; 3743 } 3744 3745 intent.setComponent(new ComponentName( 3746 aInfo.applicationInfo.packageName, aInfo.name)); 3747 intent.setFlags(intent.getFlags()&~( 3748 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3749 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3750 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3751 Intent.FLAG_ACTIVITY_NEW_TASK)); 3752 3753 // Okay now we need to start the new activity, replacing the 3754 // currently running activity. This is a little tricky because 3755 // we want to start the new one as if the current one is finished, 3756 // but not finish the current one first so that there is no flicker. 3757 // And thus... 3758 final boolean wasFinishing = r.finishing; 3759 r.finishing = true; 3760 3761 // Propagate reply information over to the new activity. 3762 final ActivityRecord resultTo = r.resultTo; 3763 final String resultWho = r.resultWho; 3764 final int requestCode = r.requestCode; 3765 r.resultTo = null; 3766 if (resultTo != null) { 3767 resultTo.removeResultsLocked(r, resultWho, requestCode); 3768 } 3769 3770 final long origId = Binder.clearCallingIdentity(); 3771 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3772 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3773 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3774 -1, r.launchedFromUid, 0, options, false, null, null, null); 3775 Binder.restoreCallingIdentity(origId); 3776 3777 r.finishing = wasFinishing; 3778 if (res != ActivityManager.START_SUCCESS) { 3779 return false; 3780 } 3781 return true; 3782 } 3783 } 3784 3785 @Override 3786 public final int startActivityFromRecents(int taskId, Bundle options) { 3787 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3788 String msg = "Permission Denial: startActivityFromRecents called without " + 3789 START_TASKS_FROM_RECENTS; 3790 Slog.w(TAG, msg); 3791 throw new SecurityException(msg); 3792 } 3793 return startActivityFromRecentsInner(taskId, options); 3794 } 3795 3796 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3797 final TaskRecord task; 3798 final int callingUid; 3799 final String callingPackage; 3800 final Intent intent; 3801 final int userId; 3802 synchronized (this) { 3803 task = recentTaskForIdLocked(taskId); 3804 if (task == null) { 3805 throw new IllegalArgumentException("Task " + taskId + " not found."); 3806 } 3807 callingUid = task.mCallingUid; 3808 callingPackage = task.mCallingPackage; 3809 intent = task.intent; 3810 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3811 userId = task.userId; 3812 } 3813 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3814 options, userId, null, task); 3815 } 3816 3817 final int startActivityInPackage(int uid, String callingPackage, 3818 Intent intent, String resolvedType, IBinder resultTo, 3819 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3820 IActivityContainer container, TaskRecord inTask) { 3821 3822 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3823 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3824 3825 // TODO: Switch to user app stacks here. 3826 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3827 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3828 null, null, null, options, userId, container, inTask); 3829 return ret; 3830 } 3831 3832 @Override 3833 public final int startActivities(IApplicationThread caller, String callingPackage, 3834 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3835 int userId) { 3836 enforceNotIsolatedCaller("startActivities"); 3837 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3838 false, ALLOW_FULL_ONLY, "startActivity", null); 3839 // TODO: Switch to user app stacks here. 3840 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3841 resolvedTypes, resultTo, options, userId); 3842 return ret; 3843 } 3844 3845 final int startActivitiesInPackage(int uid, String callingPackage, 3846 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3847 Bundle options, int userId) { 3848 3849 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3850 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3851 // TODO: Switch to user app stacks here. 3852 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3853 resultTo, options, userId); 3854 return ret; 3855 } 3856 3857 //explicitly remove thd old information in mRecentTasks when removing existing user. 3858 private void removeRecentTasksForUserLocked(int userId) { 3859 if(userId <= 0) { 3860 Slog.i(TAG, "Can't remove recent task on user " + userId); 3861 return; 3862 } 3863 3864 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3865 TaskRecord tr = mRecentTasks.get(i); 3866 if (tr.userId == userId) { 3867 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3868 + " when finishing user" + userId); 3869 mRecentTasks.remove(i); 3870 tr.removedFromRecents(mTaskPersister); 3871 } 3872 } 3873 3874 // Remove tasks from persistent storage. 3875 mTaskPersister.wakeup(null, true); 3876 } 3877 3878 // Sort by taskId 3879 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3880 @Override 3881 public int compare(TaskRecord lhs, TaskRecord rhs) { 3882 return rhs.taskId - lhs.taskId; 3883 } 3884 }; 3885 3886 // Extract the affiliates of the chain containing mRecentTasks[start]. 3887 private int processNextAffiliateChain(int start) { 3888 final TaskRecord startTask = mRecentTasks.get(start); 3889 final int affiliateId = startTask.mAffiliatedTaskId; 3890 3891 // Quick identification of isolated tasks. I.e. those not launched behind. 3892 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3893 startTask.mNextAffiliate == null) { 3894 // There is still a slim chance that there are other tasks that point to this task 3895 // and that the chain is so messed up that this task no longer points to them but 3896 // the gain of this optimization outweighs the risk. 3897 startTask.inRecents = true; 3898 return start + 1; 3899 } 3900 3901 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3902 mTmpRecents.clear(); 3903 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3904 final TaskRecord task = mRecentTasks.get(i); 3905 if (task.mAffiliatedTaskId == affiliateId) { 3906 mRecentTasks.remove(i); 3907 mTmpRecents.add(task); 3908 } 3909 } 3910 3911 // Sort them all by taskId. That is the order they were create in and that order will 3912 // always be correct. 3913 Collections.sort(mTmpRecents, mTaskRecordComparator); 3914 3915 // Go through and fix up the linked list. 3916 // The first one is the end of the chain and has no next. 3917 final TaskRecord first = mTmpRecents.get(0); 3918 first.inRecents = true; 3919 if (first.mNextAffiliate != null) { 3920 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3921 first.setNextAffiliate(null); 3922 mTaskPersister.wakeup(first, false); 3923 } 3924 // Everything in the middle is doubly linked from next to prev. 3925 final int tmpSize = mTmpRecents.size(); 3926 for (int i = 0; i < tmpSize - 1; ++i) { 3927 final TaskRecord next = mTmpRecents.get(i); 3928 final TaskRecord prev = mTmpRecents.get(i + 1); 3929 if (next.mPrevAffiliate != prev) { 3930 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3931 " setting prev=" + prev); 3932 next.setPrevAffiliate(prev); 3933 mTaskPersister.wakeup(next, false); 3934 } 3935 if (prev.mNextAffiliate != next) { 3936 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3937 " setting next=" + next); 3938 prev.setNextAffiliate(next); 3939 mTaskPersister.wakeup(prev, false); 3940 } 3941 prev.inRecents = true; 3942 } 3943 // The last one is the beginning of the list and has no prev. 3944 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3945 if (last.mPrevAffiliate != null) { 3946 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3947 last.setPrevAffiliate(null); 3948 mTaskPersister.wakeup(last, false); 3949 } 3950 3951 // Insert the group back into mRecentTasks at start. 3952 mRecentTasks.addAll(start, mTmpRecents); 3953 3954 // Let the caller know where we left off. 3955 return start + tmpSize; 3956 } 3957 3958 /** 3959 * Update the recent tasks lists: make sure tasks should still be here (their 3960 * applications / activities still exist), update their availability, fixup ordering 3961 * of affiliations. 3962 */ 3963 void cleanupRecentTasksLocked(int userId) { 3964 if (mRecentTasks == null) { 3965 // Happens when called from the packagemanager broadcast before boot. 3966 return; 3967 } 3968 3969 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3970 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3971 final IPackageManager pm = AppGlobals.getPackageManager(); 3972 final ActivityInfo dummyAct = new ActivityInfo(); 3973 final ApplicationInfo dummyApp = new ApplicationInfo(); 3974 3975 int N = mRecentTasks.size(); 3976 3977 int[] users = userId == UserHandle.USER_ALL 3978 ? getUsersLocked() : new int[] { userId }; 3979 for (int user : users) { 3980 for (int i = 0; i < N; i++) { 3981 TaskRecord task = mRecentTasks.get(i); 3982 if (task.userId != user) { 3983 // Only look at tasks for the user ID of interest. 3984 continue; 3985 } 3986 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3987 // This situation is broken, and we should just get rid of it now. 3988 mRecentTasks.remove(i); 3989 task.removedFromRecents(mTaskPersister); 3990 i--; 3991 N--; 3992 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3993 continue; 3994 } 3995 // Check whether this activity is currently available. 3996 if (task.realActivity != null) { 3997 ActivityInfo ai = availActCache.get(task.realActivity); 3998 if (ai == null) { 3999 try { 4000 ai = pm.getActivityInfo(task.realActivity, 4001 PackageManager.GET_UNINSTALLED_PACKAGES 4002 | PackageManager.GET_DISABLED_COMPONENTS, user); 4003 } catch (RemoteException e) { 4004 // Will never happen. 4005 continue; 4006 } 4007 if (ai == null) { 4008 ai = dummyAct; 4009 } 4010 availActCache.put(task.realActivity, ai); 4011 } 4012 if (ai == dummyAct) { 4013 // This could be either because the activity no longer exists, or the 4014 // app is temporarily gone. For the former we want to remove the recents 4015 // entry; for the latter we want to mark it as unavailable. 4016 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 4017 if (app == null) { 4018 try { 4019 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 4020 PackageManager.GET_UNINSTALLED_PACKAGES 4021 | PackageManager.GET_DISABLED_COMPONENTS, user); 4022 } catch (RemoteException e) { 4023 // Will never happen. 4024 continue; 4025 } 4026 if (app == null) { 4027 app = dummyApp; 4028 } 4029 availAppCache.put(task.realActivity.getPackageName(), app); 4030 } 4031 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4032 // Doesn't exist any more! Good-bye. 4033 mRecentTasks.remove(i); 4034 task.removedFromRecents(mTaskPersister); 4035 i--; 4036 N--; 4037 Slog.w(TAG, "Removing no longer valid recent: " + task); 4038 continue; 4039 } else { 4040 // Otherwise just not available for now. 4041 if (task.isAvailable) { 4042 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4043 + task); 4044 } 4045 task.isAvailable = false; 4046 } 4047 } else { 4048 if (!ai.enabled || !ai.applicationInfo.enabled 4049 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4050 if (task.isAvailable) { 4051 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4052 + task + " (enabled=" + ai.enabled + "/" 4053 + ai.applicationInfo.enabled + " flags=" 4054 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 4055 } 4056 task.isAvailable = false; 4057 } else { 4058 if (!task.isAvailable) { 4059 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 4060 + task); 4061 } 4062 task.isAvailable = true; 4063 } 4064 } 4065 } 4066 } 4067 } 4068 4069 // Verify the affiliate chain for each task. 4070 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 4071 } 4072 4073 mTmpRecents.clear(); 4074 // mRecentTasks is now in sorted, affiliated order. 4075 } 4076 4077 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 4078 int N = mRecentTasks.size(); 4079 TaskRecord top = task; 4080 int topIndex = taskIndex; 4081 while (top.mNextAffiliate != null && topIndex > 0) { 4082 top = top.mNextAffiliate; 4083 topIndex--; 4084 } 4085 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 4086 + topIndex + " from intial " + taskIndex); 4087 // Find the end of the chain, doing a sanity check along the way. 4088 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 4089 int endIndex = topIndex; 4090 TaskRecord prev = top; 4091 while (endIndex < N) { 4092 TaskRecord cur = mRecentTasks.get(endIndex); 4093 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 4094 + endIndex + " " + cur); 4095 if (cur == top) { 4096 // Verify start of the chain. 4097 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 4098 Slog.wtf(TAG, "Bad chain @" + endIndex 4099 + ": first task has next affiliate: " + prev); 4100 sane = false; 4101 break; 4102 } 4103 } else { 4104 // Verify middle of the chain's next points back to the one before. 4105 if (cur.mNextAffiliate != prev 4106 || cur.mNextAffiliateTaskId != prev.taskId) { 4107 Slog.wtf(TAG, "Bad chain @" + endIndex 4108 + ": middle task " + cur + " @" + endIndex 4109 + " has bad next affiliate " 4110 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4111 + ", expected " + prev); 4112 sane = false; 4113 break; 4114 } 4115 } 4116 if (cur.mPrevAffiliateTaskId == -1) { 4117 // Chain ends here. 4118 if (cur.mPrevAffiliate != null) { 4119 Slog.wtf(TAG, "Bad chain @" + endIndex 4120 + ": last task " + cur + " has previous affiliate " 4121 + cur.mPrevAffiliate); 4122 sane = false; 4123 } 4124 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4125 break; 4126 } else { 4127 // Verify middle of the chain's prev points to a valid item. 4128 if (cur.mPrevAffiliate == null) { 4129 Slog.wtf(TAG, "Bad chain @" + endIndex 4130 + ": task " + cur + " has previous affiliate " 4131 + cur.mPrevAffiliate + " but should be id " 4132 + cur.mPrevAffiliate); 4133 sane = false; 4134 break; 4135 } 4136 } 4137 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4138 Slog.wtf(TAG, "Bad chain @" + endIndex 4139 + ": task " + cur + " has affiliated id " 4140 + cur.mAffiliatedTaskId + " but should be " 4141 + task.mAffiliatedTaskId); 4142 sane = false; 4143 break; 4144 } 4145 prev = cur; 4146 endIndex++; 4147 if (endIndex >= N) { 4148 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4149 + ": last task " + prev); 4150 sane = false; 4151 break; 4152 } 4153 } 4154 if (sane) { 4155 if (endIndex < taskIndex) { 4156 Slog.wtf(TAG, "Bad chain @" + endIndex 4157 + ": did not extend to task " + task + " @" + taskIndex); 4158 sane = false; 4159 } 4160 } 4161 if (sane) { 4162 // All looks good, we can just move all of the affiliated tasks 4163 // to the top. 4164 for (int i=topIndex; i<=endIndex; i++) { 4165 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4166 + " from " + i + " to " + (i-topIndex)); 4167 TaskRecord cur = mRecentTasks.remove(i); 4168 mRecentTasks.add(i-topIndex, cur); 4169 } 4170 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4171 + " to " + endIndex); 4172 return true; 4173 } 4174 4175 // Whoops, couldn't do it. 4176 return false; 4177 } 4178 4179 final void addRecentTaskLocked(TaskRecord task) { 4180 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4181 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4182 4183 int N = mRecentTasks.size(); 4184 // Quick case: check if the top-most recent task is the same. 4185 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4186 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4187 return; 4188 } 4189 // Another quick case: check if this is part of a set of affiliated 4190 // tasks that are at the top. 4191 if (isAffiliated && N > 0 && task.inRecents 4192 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4193 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4194 + " at top when adding " + task); 4195 return; 4196 } 4197 // Another quick case: never add voice sessions. 4198 if (task.voiceSession != null) { 4199 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4200 return; 4201 } 4202 4203 boolean needAffiliationFix = false; 4204 4205 // Slightly less quick case: the task is already in recents, so all we need 4206 // to do is move it. 4207 if (task.inRecents) { 4208 int taskIndex = mRecentTasks.indexOf(task); 4209 if (taskIndex >= 0) { 4210 if (!isAffiliated) { 4211 // Simple case: this is not an affiliated task, so we just move it to the front. 4212 mRecentTasks.remove(taskIndex); 4213 mRecentTasks.add(0, task); 4214 notifyTaskPersisterLocked(task, false); 4215 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4216 + " from " + taskIndex); 4217 return; 4218 } else { 4219 // More complicated: need to keep all affiliated tasks together. 4220 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4221 // All went well. 4222 return; 4223 } 4224 4225 // Uh oh... something bad in the affiliation chain, try to rebuild 4226 // everything and then go through our general path of adding a new task. 4227 needAffiliationFix = true; 4228 } 4229 } else { 4230 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4231 needAffiliationFix = true; 4232 } 4233 } 4234 4235 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4236 trimRecentsForTask(task, true); 4237 4238 N = mRecentTasks.size(); 4239 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4240 final TaskRecord tr = mRecentTasks.remove(N - 1); 4241 tr.removedFromRecents(mTaskPersister); 4242 N--; 4243 } 4244 task.inRecents = true; 4245 if (!isAffiliated || needAffiliationFix) { 4246 // If this is a simple non-affiliated task, or we had some failure trying to 4247 // handle it as part of an affilated task, then just place it at the top. 4248 mRecentTasks.add(0, task); 4249 } else if (isAffiliated) { 4250 // If this is a new affiliated task, then move all of the affiliated tasks 4251 // to the front and insert this new one. 4252 TaskRecord other = task.mNextAffiliate; 4253 if (other == null) { 4254 other = task.mPrevAffiliate; 4255 } 4256 if (other != null) { 4257 int otherIndex = mRecentTasks.indexOf(other); 4258 if (otherIndex >= 0) { 4259 // Insert new task at appropriate location. 4260 int taskIndex; 4261 if (other == task.mNextAffiliate) { 4262 // We found the index of our next affiliation, which is who is 4263 // before us in the list, so add after that point. 4264 taskIndex = otherIndex+1; 4265 } else { 4266 // We found the index of our previous affiliation, which is who is 4267 // after us in the list, so add at their position. 4268 taskIndex = otherIndex; 4269 } 4270 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4271 + taskIndex + ": " + task); 4272 mRecentTasks.add(taskIndex, task); 4273 4274 // Now move everything to the front. 4275 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4276 // All went well. 4277 return; 4278 } 4279 4280 // Uh oh... something bad in the affiliation chain, try to rebuild 4281 // everything and then go through our general path of adding a new task. 4282 needAffiliationFix = true; 4283 } else { 4284 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4285 + other); 4286 needAffiliationFix = true; 4287 } 4288 } else { 4289 if (DEBUG_RECENTS) Slog.d(TAG, 4290 "addRecent: adding affiliated task without next/prev:" + task); 4291 needAffiliationFix = true; 4292 } 4293 } 4294 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4295 4296 if (needAffiliationFix) { 4297 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4298 cleanupRecentTasksLocked(task.userId); 4299 } 4300 } 4301 4302 /** 4303 * If needed, remove oldest existing entries in recents that are for the same kind 4304 * of task as the given one. 4305 */ 4306 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4307 int N = mRecentTasks.size(); 4308 final Intent intent = task.intent; 4309 final boolean document = intent != null && intent.isDocument(); 4310 4311 int maxRecents = task.maxRecents - 1; 4312 for (int i=0; i<N; i++) { 4313 final TaskRecord tr = mRecentTasks.get(i); 4314 if (task != tr) { 4315 if (task.userId != tr.userId) { 4316 continue; 4317 } 4318 if (i > MAX_RECENT_BITMAPS) { 4319 tr.freeLastThumbnail(); 4320 } 4321 final Intent trIntent = tr.intent; 4322 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4323 (intent == null || !intent.filterEquals(trIntent))) { 4324 continue; 4325 } 4326 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4327 if (document && trIsDocument) { 4328 // These are the same document activity (not necessarily the same doc). 4329 if (maxRecents > 0) { 4330 --maxRecents; 4331 continue; 4332 } 4333 // Hit the maximum number of documents for this task. Fall through 4334 // and remove this document from recents. 4335 } else if (document || trIsDocument) { 4336 // Only one of these is a document. Not the droid we're looking for. 4337 continue; 4338 } 4339 } 4340 4341 if (!doTrim) { 4342 // If the caller is not actually asking for a trim, just tell them we reached 4343 // a point where the trim would happen. 4344 return i; 4345 } 4346 4347 // Either task and tr are the same or, their affinities match or their intents match 4348 // and neither of them is a document, or they are documents using the same activity 4349 // and their maxRecents has been reached. 4350 tr.disposeThumbnail(); 4351 mRecentTasks.remove(i); 4352 if (task != tr) { 4353 tr.removedFromRecents(mTaskPersister); 4354 } 4355 i--; 4356 N--; 4357 if (task.intent == null) { 4358 // If the new recent task we are adding is not fully 4359 // specified, then replace it with the existing recent task. 4360 task = tr; 4361 } 4362 notifyTaskPersisterLocked(tr, false); 4363 } 4364 4365 return -1; 4366 } 4367 4368 @Override 4369 public void reportActivityFullyDrawn(IBinder token) { 4370 synchronized (this) { 4371 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4372 if (r == null) { 4373 return; 4374 } 4375 r.reportFullyDrawnLocked(); 4376 } 4377 } 4378 4379 @Override 4380 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4381 synchronized (this) { 4382 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4383 if (r == null) { 4384 return; 4385 } 4386 final long origId = Binder.clearCallingIdentity(); 4387 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4388 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4389 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4390 if (config != null) { 4391 r.frozenBeforeDestroy = true; 4392 if (!updateConfigurationLocked(config, r, false, false)) { 4393 mStackSupervisor.resumeTopActivitiesLocked(); 4394 } 4395 } 4396 Binder.restoreCallingIdentity(origId); 4397 } 4398 } 4399 4400 @Override 4401 public int getRequestedOrientation(IBinder token) { 4402 synchronized (this) { 4403 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4404 if (r == null) { 4405 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4406 } 4407 return mWindowManager.getAppOrientation(r.appToken); 4408 } 4409 } 4410 4411 /** 4412 * This is the internal entry point for handling Activity.finish(). 4413 * 4414 * @param token The Binder token referencing the Activity we want to finish. 4415 * @param resultCode Result code, if any, from this Activity. 4416 * @param resultData Result data (Intent), if any, from this Activity. 4417 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4418 * the root Activity in the task. 4419 * 4420 * @return Returns true if the activity successfully finished, or false if it is still running. 4421 */ 4422 @Override 4423 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4424 boolean finishTask) { 4425 // Refuse possible leaked file descriptors 4426 if (resultData != null && resultData.hasFileDescriptors() == true) { 4427 throw new IllegalArgumentException("File descriptors passed in Intent"); 4428 } 4429 4430 synchronized(this) { 4431 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4432 if (r == null) { 4433 return true; 4434 } 4435 // Keep track of the root activity of the task before we finish it 4436 TaskRecord tr = r.task; 4437 ActivityRecord rootR = tr.getRootActivity(); 4438 // Do not allow task to finish in Lock Task mode. 4439 if (tr == mStackSupervisor.mLockTaskModeTask) { 4440 if (rootR == r) { 4441 mStackSupervisor.showLockTaskToast(); 4442 return false; 4443 } 4444 } 4445 if (mController != null) { 4446 // Find the first activity that is not finishing. 4447 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4448 if (next != null) { 4449 // ask watcher if this is allowed 4450 boolean resumeOK = true; 4451 try { 4452 resumeOK = mController.activityResuming(next.packageName); 4453 } catch (RemoteException e) { 4454 mController = null; 4455 Watchdog.getInstance().setActivityController(null); 4456 } 4457 4458 if (!resumeOK) { 4459 return false; 4460 } 4461 } 4462 } 4463 final long origId = Binder.clearCallingIdentity(); 4464 try { 4465 boolean res; 4466 if (finishTask && r == rootR) { 4467 // If requested, remove the task that is associated to this activity only if it 4468 // was the root activity in the task. The result code and data is ignored because 4469 // we don't support returning them across task boundaries. 4470 res = removeTaskByIdLocked(tr.taskId, 0); 4471 } else { 4472 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4473 resultData, "app-request", true); 4474 } 4475 return res; 4476 } finally { 4477 Binder.restoreCallingIdentity(origId); 4478 } 4479 } 4480 } 4481 4482 @Override 4483 public final void finishHeavyWeightApp() { 4484 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4485 != PackageManager.PERMISSION_GRANTED) { 4486 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4487 + Binder.getCallingPid() 4488 + ", uid=" + Binder.getCallingUid() 4489 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4490 Slog.w(TAG, msg); 4491 throw new SecurityException(msg); 4492 } 4493 4494 synchronized(this) { 4495 if (mHeavyWeightProcess == null) { 4496 return; 4497 } 4498 4499 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4500 mHeavyWeightProcess.activities); 4501 for (int i=0; i<activities.size(); i++) { 4502 ActivityRecord r = activities.get(i); 4503 if (!r.finishing) { 4504 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4505 null, "finish-heavy", true); 4506 } 4507 } 4508 4509 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4510 mHeavyWeightProcess.userId, 0)); 4511 mHeavyWeightProcess = null; 4512 } 4513 } 4514 4515 @Override 4516 public void crashApplication(int uid, int initialPid, String packageName, 4517 String message) { 4518 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4519 != PackageManager.PERMISSION_GRANTED) { 4520 String msg = "Permission Denial: crashApplication() from pid=" 4521 + Binder.getCallingPid() 4522 + ", uid=" + Binder.getCallingUid() 4523 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4524 Slog.w(TAG, msg); 4525 throw new SecurityException(msg); 4526 } 4527 4528 synchronized(this) { 4529 ProcessRecord proc = null; 4530 4531 // Figure out which process to kill. We don't trust that initialPid 4532 // still has any relation to current pids, so must scan through the 4533 // list. 4534 synchronized (mPidsSelfLocked) { 4535 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4536 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4537 if (p.uid != uid) { 4538 continue; 4539 } 4540 if (p.pid == initialPid) { 4541 proc = p; 4542 break; 4543 } 4544 if (p.pkgList.containsKey(packageName)) { 4545 proc = p; 4546 } 4547 } 4548 } 4549 4550 if (proc == null) { 4551 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4552 + " initialPid=" + initialPid 4553 + " packageName=" + packageName); 4554 return; 4555 } 4556 4557 if (proc.thread != null) { 4558 if (proc.pid == Process.myPid()) { 4559 Log.w(TAG, "crashApplication: trying to crash self!"); 4560 return; 4561 } 4562 long ident = Binder.clearCallingIdentity(); 4563 try { 4564 proc.thread.scheduleCrash(message); 4565 } catch (RemoteException e) { 4566 } 4567 Binder.restoreCallingIdentity(ident); 4568 } 4569 } 4570 } 4571 4572 @Override 4573 public final void finishSubActivity(IBinder token, String resultWho, 4574 int requestCode) { 4575 synchronized(this) { 4576 final long origId = Binder.clearCallingIdentity(); 4577 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4578 if (r != null) { 4579 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4580 } 4581 Binder.restoreCallingIdentity(origId); 4582 } 4583 } 4584 4585 @Override 4586 public boolean finishActivityAffinity(IBinder token) { 4587 synchronized(this) { 4588 final long origId = Binder.clearCallingIdentity(); 4589 try { 4590 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4591 4592 ActivityRecord rootR = r.task.getRootActivity(); 4593 // Do not allow task to finish in Lock Task mode. 4594 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4595 if (rootR == r) { 4596 mStackSupervisor.showLockTaskToast(); 4597 return false; 4598 } 4599 } 4600 boolean res = false; 4601 if (r != null) { 4602 res = r.task.stack.finishActivityAffinityLocked(r); 4603 } 4604 return res; 4605 } finally { 4606 Binder.restoreCallingIdentity(origId); 4607 } 4608 } 4609 } 4610 4611 @Override 4612 public void finishVoiceTask(IVoiceInteractionSession session) { 4613 synchronized(this) { 4614 final long origId = Binder.clearCallingIdentity(); 4615 try { 4616 mStackSupervisor.finishVoiceTask(session); 4617 } finally { 4618 Binder.restoreCallingIdentity(origId); 4619 } 4620 } 4621 4622 } 4623 4624 @Override 4625 public boolean releaseActivityInstance(IBinder token) { 4626 synchronized(this) { 4627 final long origId = Binder.clearCallingIdentity(); 4628 try { 4629 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4630 if (r.task == null || r.task.stack == null) { 4631 return false; 4632 } 4633 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4634 } finally { 4635 Binder.restoreCallingIdentity(origId); 4636 } 4637 } 4638 } 4639 4640 @Override 4641 public void releaseSomeActivities(IApplicationThread appInt) { 4642 synchronized(this) { 4643 final long origId = Binder.clearCallingIdentity(); 4644 try { 4645 ProcessRecord app = getRecordForAppLocked(appInt); 4646 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4647 } finally { 4648 Binder.restoreCallingIdentity(origId); 4649 } 4650 } 4651 } 4652 4653 @Override 4654 public boolean willActivityBeVisible(IBinder token) { 4655 synchronized(this) { 4656 ActivityStack stack = ActivityRecord.getStackLocked(token); 4657 if (stack != null) { 4658 return stack.willActivityBeVisibleLocked(token); 4659 } 4660 return false; 4661 } 4662 } 4663 4664 @Override 4665 public void overridePendingTransition(IBinder token, String packageName, 4666 int enterAnim, int exitAnim) { 4667 synchronized(this) { 4668 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4669 if (self == null) { 4670 return; 4671 } 4672 4673 final long origId = Binder.clearCallingIdentity(); 4674 4675 if (self.state == ActivityState.RESUMED 4676 || self.state == ActivityState.PAUSING) { 4677 mWindowManager.overridePendingAppTransition(packageName, 4678 enterAnim, exitAnim, null); 4679 } 4680 4681 Binder.restoreCallingIdentity(origId); 4682 } 4683 } 4684 4685 /** 4686 * Main function for removing an existing process from the activity manager 4687 * as a result of that process going away. Clears out all connections 4688 * to the process. 4689 */ 4690 private final void handleAppDiedLocked(ProcessRecord app, 4691 boolean restarting, boolean allowRestart) { 4692 int pid = app.pid; 4693 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4694 if (!restarting) { 4695 removeLruProcessLocked(app); 4696 if (pid > 0) { 4697 ProcessList.remove(pid); 4698 } 4699 } 4700 4701 if (mProfileProc == app) { 4702 clearProfilerLocked(); 4703 } 4704 4705 // Remove this application's activities from active lists. 4706 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4707 4708 app.activities.clear(); 4709 4710 if (app.instrumentationClass != null) { 4711 Slog.w(TAG, "Crash of app " + app.processName 4712 + " running instrumentation " + app.instrumentationClass); 4713 Bundle info = new Bundle(); 4714 info.putString("shortMsg", "Process crashed."); 4715 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4716 } 4717 4718 if (!restarting) { 4719 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4720 // If there was nothing to resume, and we are not already 4721 // restarting this process, but there is a visible activity that 4722 // is hosted by the process... then make sure all visible 4723 // activities are running, taking care of restarting this 4724 // process. 4725 if (hasVisibleActivities) { 4726 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4727 } 4728 } 4729 } 4730 } 4731 4732 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4733 IBinder threadBinder = thread.asBinder(); 4734 // Find the application record. 4735 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4736 ProcessRecord rec = mLruProcesses.get(i); 4737 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4738 return i; 4739 } 4740 } 4741 return -1; 4742 } 4743 4744 final ProcessRecord getRecordForAppLocked( 4745 IApplicationThread thread) { 4746 if (thread == null) { 4747 return null; 4748 } 4749 4750 int appIndex = getLRURecordIndexForAppLocked(thread); 4751 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4752 } 4753 4754 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4755 // If there are no longer any background processes running, 4756 // and the app that died was not running instrumentation, 4757 // then tell everyone we are now low on memory. 4758 boolean haveBg = false; 4759 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4760 ProcessRecord rec = mLruProcesses.get(i); 4761 if (rec.thread != null 4762 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4763 haveBg = true; 4764 break; 4765 } 4766 } 4767 4768 if (!haveBg) { 4769 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4770 if (doReport) { 4771 long now = SystemClock.uptimeMillis(); 4772 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4773 doReport = false; 4774 } else { 4775 mLastMemUsageReportTime = now; 4776 } 4777 } 4778 final ArrayList<ProcessMemInfo> memInfos 4779 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4780 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4781 long now = SystemClock.uptimeMillis(); 4782 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4783 ProcessRecord rec = mLruProcesses.get(i); 4784 if (rec == dyingProc || rec.thread == null) { 4785 continue; 4786 } 4787 if (doReport) { 4788 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4789 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4790 } 4791 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4792 // The low memory report is overriding any current 4793 // state for a GC request. Make sure to do 4794 // heavy/important/visible/foreground processes first. 4795 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4796 rec.lastRequestedGc = 0; 4797 } else { 4798 rec.lastRequestedGc = rec.lastLowMemory; 4799 } 4800 rec.reportLowMemory = true; 4801 rec.lastLowMemory = now; 4802 mProcessesToGc.remove(rec); 4803 addProcessToGcListLocked(rec); 4804 } 4805 } 4806 if (doReport) { 4807 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4808 mHandler.sendMessage(msg); 4809 } 4810 scheduleAppGcsLocked(); 4811 } 4812 } 4813 4814 final void appDiedLocked(ProcessRecord app) { 4815 appDiedLocked(app, app.pid, app.thread); 4816 } 4817 4818 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4819 4820 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4821 synchronized (stats) { 4822 stats.noteProcessDiedLocked(app.info.uid, pid); 4823 } 4824 4825 Process.killProcessQuiet(pid); 4826 Process.killProcessGroup(app.info.uid, pid); 4827 app.killed = true; 4828 4829 // Clean up already done if the process has been re-started. 4830 if (app.pid == pid && app.thread != null && 4831 app.thread.asBinder() == thread.asBinder()) { 4832 boolean doLowMem = app.instrumentationClass == null; 4833 boolean doOomAdj = doLowMem; 4834 if (!app.killedByAm) { 4835 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4836 + ") has died."); 4837 mAllowLowerMemLevel = true; 4838 } else { 4839 // Note that we always want to do oom adj to update our state with the 4840 // new number of procs. 4841 mAllowLowerMemLevel = false; 4842 doLowMem = false; 4843 } 4844 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4845 if (DEBUG_CLEANUP) Slog.v( 4846 TAG, "Dying app: " + app + ", pid: " + pid 4847 + ", thread: " + thread.asBinder()); 4848 handleAppDiedLocked(app, false, true); 4849 4850 if (doOomAdj) { 4851 updateOomAdjLocked(); 4852 } 4853 if (doLowMem) { 4854 doLowMemReportIfNeededLocked(app); 4855 } 4856 } else if (app.pid != pid) { 4857 // A new process has already been started. 4858 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4859 + ") has died and restarted (pid " + app.pid + ")."); 4860 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4861 } else if (DEBUG_PROCESSES) { 4862 Slog.d(TAG, "Received spurious death notification for thread " 4863 + thread.asBinder()); 4864 } 4865 } 4866 4867 /** 4868 * If a stack trace dump file is configured, dump process stack traces. 4869 * @param clearTraces causes the dump file to be erased prior to the new 4870 * traces being written, if true; when false, the new traces will be 4871 * appended to any existing file content. 4872 * @param firstPids of dalvik VM processes to dump stack traces for first 4873 * @param lastPids of dalvik VM processes to dump stack traces for last 4874 * @param nativeProcs optional list of native process names to dump stack crawls 4875 * @return file containing stack traces, or null if no dump file is configured 4876 */ 4877 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4878 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4879 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4880 if (tracesPath == null || tracesPath.length() == 0) { 4881 return null; 4882 } 4883 4884 File tracesFile = new File(tracesPath); 4885 try { 4886 File tracesDir = tracesFile.getParentFile(); 4887 if (!tracesDir.exists()) { 4888 tracesDir.mkdirs(); 4889 if (!SELinux.restorecon(tracesDir)) { 4890 return null; 4891 } 4892 } 4893 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4894 4895 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4896 tracesFile.createNewFile(); 4897 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4898 } catch (IOException e) { 4899 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4900 return null; 4901 } 4902 4903 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4904 return tracesFile; 4905 } 4906 4907 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4908 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4909 // Use a FileObserver to detect when traces finish writing. 4910 // The order of traces is considered important to maintain for legibility. 4911 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4912 @Override 4913 public synchronized void onEvent(int event, String path) { notify(); } 4914 }; 4915 4916 try { 4917 observer.startWatching(); 4918 4919 // First collect all of the stacks of the most important pids. 4920 if (firstPids != null) { 4921 try { 4922 int num = firstPids.size(); 4923 for (int i = 0; i < num; i++) { 4924 synchronized (observer) { 4925 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4926 observer.wait(200); // Wait for write-close, give up after 200msec 4927 } 4928 } 4929 } catch (InterruptedException e) { 4930 Log.wtf(TAG, e); 4931 } 4932 } 4933 4934 // Next collect the stacks of the native pids 4935 if (nativeProcs != null) { 4936 int[] pids = Process.getPidsForCommands(nativeProcs); 4937 if (pids != null) { 4938 for (int pid : pids) { 4939 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4940 } 4941 } 4942 } 4943 4944 // Lastly, measure CPU usage. 4945 if (processCpuTracker != null) { 4946 processCpuTracker.init(); 4947 System.gc(); 4948 processCpuTracker.update(); 4949 try { 4950 synchronized (processCpuTracker) { 4951 processCpuTracker.wait(500); // measure over 1/2 second. 4952 } 4953 } catch (InterruptedException e) { 4954 } 4955 processCpuTracker.update(); 4956 4957 // We'll take the stack crawls of just the top apps using CPU. 4958 final int N = processCpuTracker.countWorkingStats(); 4959 int numProcs = 0; 4960 for (int i=0; i<N && numProcs<5; i++) { 4961 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4962 if (lastPids.indexOfKey(stats.pid) >= 0) { 4963 numProcs++; 4964 try { 4965 synchronized (observer) { 4966 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4967 observer.wait(200); // Wait for write-close, give up after 200msec 4968 } 4969 } catch (InterruptedException e) { 4970 Log.wtf(TAG, e); 4971 } 4972 4973 } 4974 } 4975 } 4976 } finally { 4977 observer.stopWatching(); 4978 } 4979 } 4980 4981 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4982 if (true || IS_USER_BUILD) { 4983 return; 4984 } 4985 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4986 if (tracesPath == null || tracesPath.length() == 0) { 4987 return; 4988 } 4989 4990 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4991 StrictMode.allowThreadDiskWrites(); 4992 try { 4993 final File tracesFile = new File(tracesPath); 4994 final File tracesDir = tracesFile.getParentFile(); 4995 final File tracesTmp = new File(tracesDir, "__tmp__"); 4996 try { 4997 if (!tracesDir.exists()) { 4998 tracesDir.mkdirs(); 4999 if (!SELinux.restorecon(tracesDir.getPath())) { 5000 return; 5001 } 5002 } 5003 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 5004 5005 if (tracesFile.exists()) { 5006 tracesTmp.delete(); 5007 tracesFile.renameTo(tracesTmp); 5008 } 5009 StringBuilder sb = new StringBuilder(); 5010 Time tobj = new Time(); 5011 tobj.set(System.currentTimeMillis()); 5012 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 5013 sb.append(": "); 5014 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 5015 sb.append(" since "); 5016 sb.append(msg); 5017 FileOutputStream fos = new FileOutputStream(tracesFile); 5018 fos.write(sb.toString().getBytes()); 5019 if (app == null) { 5020 fos.write("\n*** No application process!".getBytes()); 5021 } 5022 fos.close(); 5023 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 5024 } catch (IOException e) { 5025 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 5026 return; 5027 } 5028 5029 if (app != null) { 5030 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 5031 firstPids.add(app.pid); 5032 dumpStackTraces(tracesPath, firstPids, null, null, null); 5033 } 5034 5035 File lastTracesFile = null; 5036 File curTracesFile = null; 5037 for (int i=9; i>=0; i--) { 5038 String name = String.format(Locale.US, "slow%02d.txt", i); 5039 curTracesFile = new File(tracesDir, name); 5040 if (curTracesFile.exists()) { 5041 if (lastTracesFile != null) { 5042 curTracesFile.renameTo(lastTracesFile); 5043 } else { 5044 curTracesFile.delete(); 5045 } 5046 } 5047 lastTracesFile = curTracesFile; 5048 } 5049 tracesFile.renameTo(curTracesFile); 5050 if (tracesTmp.exists()) { 5051 tracesTmp.renameTo(tracesFile); 5052 } 5053 } finally { 5054 StrictMode.setThreadPolicy(oldPolicy); 5055 } 5056 } 5057 5058 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 5059 ActivityRecord parent, boolean aboveSystem, final String annotation) { 5060 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 5061 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 5062 5063 if (mController != null) { 5064 try { 5065 // 0 == continue, -1 = kill process immediately 5066 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 5067 if (res < 0 && app.pid != MY_PID) { 5068 app.kill("anr", true); 5069 } 5070 } catch (RemoteException e) { 5071 mController = null; 5072 Watchdog.getInstance().setActivityController(null); 5073 } 5074 } 5075 5076 long anrTime = SystemClock.uptimeMillis(); 5077 if (MONITOR_CPU_USAGE) { 5078 updateCpuStatsNow(); 5079 } 5080 5081 synchronized (this) { 5082 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 5083 if (mShuttingDown) { 5084 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 5085 return; 5086 } else if (app.notResponding) { 5087 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 5088 return; 5089 } else if (app.crashing) { 5090 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 5091 return; 5092 } 5093 5094 // In case we come through here for the same app before completing 5095 // this one, mark as anring now so we will bail out. 5096 app.notResponding = true; 5097 5098 // Log the ANR to the event log. 5099 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 5100 app.processName, app.info.flags, annotation); 5101 5102 // Dump thread traces as quickly as we can, starting with "interesting" processes. 5103 firstPids.add(app.pid); 5104 5105 int parentPid = app.pid; 5106 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5107 if (parentPid != app.pid) firstPids.add(parentPid); 5108 5109 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5110 5111 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5112 ProcessRecord r = mLruProcesses.get(i); 5113 if (r != null && r.thread != null) { 5114 int pid = r.pid; 5115 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5116 if (r.persistent) { 5117 firstPids.add(pid); 5118 } else { 5119 lastPids.put(pid, Boolean.TRUE); 5120 } 5121 } 5122 } 5123 } 5124 } 5125 5126 // Log the ANR to the main log. 5127 StringBuilder info = new StringBuilder(); 5128 info.setLength(0); 5129 info.append("ANR in ").append(app.processName); 5130 if (activity != null && activity.shortComponentName != null) { 5131 info.append(" (").append(activity.shortComponentName).append(")"); 5132 } 5133 info.append("\n"); 5134 info.append("PID: ").append(app.pid).append("\n"); 5135 if (annotation != null) { 5136 info.append("Reason: ").append(annotation).append("\n"); 5137 } 5138 if (parent != null && parent != activity) { 5139 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5140 } 5141 5142 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5143 5144 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5145 NATIVE_STACKS_OF_INTEREST); 5146 5147 String cpuInfo = null; 5148 if (MONITOR_CPU_USAGE) { 5149 updateCpuStatsNow(); 5150 synchronized (mProcessCpuTracker) { 5151 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5152 } 5153 info.append(processCpuTracker.printCurrentLoad()); 5154 info.append(cpuInfo); 5155 } 5156 5157 info.append(processCpuTracker.printCurrentState(anrTime)); 5158 5159 Slog.e(TAG, info.toString()); 5160 if (tracesFile == null) { 5161 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5162 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5163 } 5164 5165 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5166 cpuInfo, tracesFile, null); 5167 5168 if (mController != null) { 5169 try { 5170 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5171 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5172 if (res != 0) { 5173 if (res < 0 && app.pid != MY_PID) { 5174 app.kill("anr", true); 5175 } else { 5176 synchronized (this) { 5177 mServices.scheduleServiceTimeoutLocked(app); 5178 } 5179 } 5180 return; 5181 } 5182 } catch (RemoteException e) { 5183 mController = null; 5184 Watchdog.getInstance().setActivityController(null); 5185 } 5186 } 5187 5188 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5189 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5190 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5191 5192 synchronized (this) { 5193 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5194 app.kill("bg anr", true); 5195 return; 5196 } 5197 5198 // Set the app's notResponding state, and look up the errorReportReceiver 5199 makeAppNotRespondingLocked(app, 5200 activity != null ? activity.shortComponentName : null, 5201 annotation != null ? "ANR " + annotation : "ANR", 5202 info.toString()); 5203 5204 // Bring up the infamous App Not Responding dialog 5205 Message msg = Message.obtain(); 5206 HashMap<String, Object> map = new HashMap<String, Object>(); 5207 msg.what = SHOW_NOT_RESPONDING_MSG; 5208 msg.obj = map; 5209 msg.arg1 = aboveSystem ? 1 : 0; 5210 map.put("app", app); 5211 if (activity != null) { 5212 map.put("activity", activity); 5213 } 5214 5215 mHandler.sendMessage(msg); 5216 } 5217 } 5218 5219 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5220 if (!mLaunchWarningShown) { 5221 mLaunchWarningShown = true; 5222 mHandler.post(new Runnable() { 5223 @Override 5224 public void run() { 5225 synchronized (ActivityManagerService.this) { 5226 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5227 d.show(); 5228 mHandler.postDelayed(new Runnable() { 5229 @Override 5230 public void run() { 5231 synchronized (ActivityManagerService.this) { 5232 d.dismiss(); 5233 mLaunchWarningShown = false; 5234 } 5235 } 5236 }, 4000); 5237 } 5238 } 5239 }); 5240 } 5241 } 5242 5243 @Override 5244 public boolean clearApplicationUserData(final String packageName, 5245 final IPackageDataObserver observer, int userId) { 5246 enforceNotIsolatedCaller("clearApplicationUserData"); 5247 int uid = Binder.getCallingUid(); 5248 int pid = Binder.getCallingPid(); 5249 userId = handleIncomingUser(pid, uid, 5250 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5251 long callingId = Binder.clearCallingIdentity(); 5252 try { 5253 IPackageManager pm = AppGlobals.getPackageManager(); 5254 int pkgUid = -1; 5255 synchronized(this) { 5256 try { 5257 pkgUid = pm.getPackageUid(packageName, userId); 5258 } catch (RemoteException e) { 5259 } 5260 if (pkgUid == -1) { 5261 Slog.w(TAG, "Invalid packageName: " + packageName); 5262 if (observer != null) { 5263 try { 5264 observer.onRemoveCompleted(packageName, false); 5265 } catch (RemoteException e) { 5266 Slog.i(TAG, "Observer no longer exists."); 5267 } 5268 } 5269 return false; 5270 } 5271 if (uid == pkgUid || checkComponentPermission( 5272 android.Manifest.permission.CLEAR_APP_USER_DATA, 5273 pid, uid, -1, true) 5274 == PackageManager.PERMISSION_GRANTED) { 5275 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5276 } else { 5277 throw new SecurityException("PID " + pid + " does not have permission " 5278 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5279 + " of package " + packageName); 5280 } 5281 5282 // Remove all tasks match the cleared application package and user 5283 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5284 final TaskRecord tr = mRecentTasks.get(i); 5285 final String taskPackageName = 5286 tr.getBaseIntent().getComponent().getPackageName(); 5287 if (tr.userId != userId) continue; 5288 if (!taskPackageName.equals(packageName)) continue; 5289 removeTaskByIdLocked(tr.taskId, 0); 5290 } 5291 } 5292 5293 try { 5294 // Clear application user data 5295 pm.clearApplicationUserData(packageName, observer, userId); 5296 5297 synchronized(this) { 5298 // Remove all permissions granted from/to this package 5299 removeUriPermissionsForPackageLocked(packageName, userId, true); 5300 } 5301 5302 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5303 Uri.fromParts("package", packageName, null)); 5304 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5305 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5306 null, null, 0, null, null, null, false, false, userId); 5307 } catch (RemoteException e) { 5308 } 5309 } finally { 5310 Binder.restoreCallingIdentity(callingId); 5311 } 5312 return true; 5313 } 5314 5315 @Override 5316 public void killBackgroundProcesses(final String packageName, int userId) { 5317 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5318 != PackageManager.PERMISSION_GRANTED && 5319 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5320 != PackageManager.PERMISSION_GRANTED) { 5321 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5322 + Binder.getCallingPid() 5323 + ", uid=" + Binder.getCallingUid() 5324 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5325 Slog.w(TAG, msg); 5326 throw new SecurityException(msg); 5327 } 5328 5329 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5330 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5331 long callingId = Binder.clearCallingIdentity(); 5332 try { 5333 IPackageManager pm = AppGlobals.getPackageManager(); 5334 synchronized(this) { 5335 int appId = -1; 5336 try { 5337 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5338 } catch (RemoteException e) { 5339 } 5340 if (appId == -1) { 5341 Slog.w(TAG, "Invalid packageName: " + packageName); 5342 return; 5343 } 5344 killPackageProcessesLocked(packageName, appId, userId, 5345 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5346 } 5347 } finally { 5348 Binder.restoreCallingIdentity(callingId); 5349 } 5350 } 5351 5352 @Override 5353 public void killAllBackgroundProcesses() { 5354 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5355 != PackageManager.PERMISSION_GRANTED) { 5356 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5357 + Binder.getCallingPid() 5358 + ", uid=" + Binder.getCallingUid() 5359 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5360 Slog.w(TAG, msg); 5361 throw new SecurityException(msg); 5362 } 5363 5364 long callingId = Binder.clearCallingIdentity(); 5365 try { 5366 synchronized(this) { 5367 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5368 final int NP = mProcessNames.getMap().size(); 5369 for (int ip=0; ip<NP; ip++) { 5370 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5371 final int NA = apps.size(); 5372 for (int ia=0; ia<NA; ia++) { 5373 ProcessRecord app = apps.valueAt(ia); 5374 if (app.persistent) { 5375 // we don't kill persistent processes 5376 continue; 5377 } 5378 if (app.removed) { 5379 procs.add(app); 5380 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5381 app.removed = true; 5382 procs.add(app); 5383 } 5384 } 5385 } 5386 5387 int N = procs.size(); 5388 for (int i=0; i<N; i++) { 5389 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5390 } 5391 mAllowLowerMemLevel = true; 5392 updateOomAdjLocked(); 5393 doLowMemReportIfNeededLocked(null); 5394 } 5395 } finally { 5396 Binder.restoreCallingIdentity(callingId); 5397 } 5398 } 5399 5400 @Override 5401 public void forceStopPackage(final String packageName, int userId) { 5402 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5403 != PackageManager.PERMISSION_GRANTED) { 5404 String msg = "Permission Denial: forceStopPackage() from pid=" 5405 + Binder.getCallingPid() 5406 + ", uid=" + Binder.getCallingUid() 5407 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5408 Slog.w(TAG, msg); 5409 throw new SecurityException(msg); 5410 } 5411 final int callingPid = Binder.getCallingPid(); 5412 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5413 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5414 long callingId = Binder.clearCallingIdentity(); 5415 try { 5416 IPackageManager pm = AppGlobals.getPackageManager(); 5417 synchronized(this) { 5418 int[] users = userId == UserHandle.USER_ALL 5419 ? getUsersLocked() : new int[] { userId }; 5420 for (int user : users) { 5421 int pkgUid = -1; 5422 try { 5423 pkgUid = pm.getPackageUid(packageName, user); 5424 } catch (RemoteException e) { 5425 } 5426 if (pkgUid == -1) { 5427 Slog.w(TAG, "Invalid packageName: " + packageName); 5428 continue; 5429 } 5430 try { 5431 pm.setPackageStoppedState(packageName, true, user); 5432 } catch (RemoteException e) { 5433 } catch (IllegalArgumentException e) { 5434 Slog.w(TAG, "Failed trying to unstop package " 5435 + packageName + ": " + e); 5436 } 5437 if (isUserRunningLocked(user, false)) { 5438 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5439 } 5440 } 5441 } 5442 } finally { 5443 Binder.restoreCallingIdentity(callingId); 5444 } 5445 } 5446 5447 @Override 5448 public void addPackageDependency(String packageName) { 5449 synchronized (this) { 5450 int callingPid = Binder.getCallingPid(); 5451 if (callingPid == Process.myPid()) { 5452 // Yeah, um, no. 5453 Slog.w(TAG, "Can't addPackageDependency on system process"); 5454 return; 5455 } 5456 ProcessRecord proc; 5457 synchronized (mPidsSelfLocked) { 5458 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5459 } 5460 if (proc != null) { 5461 if (proc.pkgDeps == null) { 5462 proc.pkgDeps = new ArraySet<String>(1); 5463 } 5464 proc.pkgDeps.add(packageName); 5465 } 5466 } 5467 } 5468 5469 /* 5470 * The pkg name and app id have to be specified. 5471 */ 5472 @Override 5473 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5474 if (pkg == null) { 5475 return; 5476 } 5477 // Make sure the uid is valid. 5478 if (appid < 0) { 5479 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5480 return; 5481 } 5482 int callerUid = Binder.getCallingUid(); 5483 // Only the system server can kill an application 5484 if (callerUid == Process.SYSTEM_UID) { 5485 // Post an aysnc message to kill the application 5486 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5487 msg.arg1 = appid; 5488 msg.arg2 = 0; 5489 Bundle bundle = new Bundle(); 5490 bundle.putString("pkg", pkg); 5491 bundle.putString("reason", reason); 5492 msg.obj = bundle; 5493 mHandler.sendMessage(msg); 5494 } else { 5495 throw new SecurityException(callerUid + " cannot kill pkg: " + 5496 pkg); 5497 } 5498 } 5499 5500 @Override 5501 public void closeSystemDialogs(String reason) { 5502 enforceNotIsolatedCaller("closeSystemDialogs"); 5503 5504 final int pid = Binder.getCallingPid(); 5505 final int uid = Binder.getCallingUid(); 5506 final long origId = Binder.clearCallingIdentity(); 5507 try { 5508 synchronized (this) { 5509 // Only allow this from foreground processes, so that background 5510 // applications can't abuse it to prevent system UI from being shown. 5511 if (uid >= Process.FIRST_APPLICATION_UID) { 5512 ProcessRecord proc; 5513 synchronized (mPidsSelfLocked) { 5514 proc = mPidsSelfLocked.get(pid); 5515 } 5516 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5517 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5518 + " from background process " + proc); 5519 return; 5520 } 5521 } 5522 closeSystemDialogsLocked(reason); 5523 } 5524 } finally { 5525 Binder.restoreCallingIdentity(origId); 5526 } 5527 } 5528 5529 void closeSystemDialogsLocked(String reason) { 5530 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5531 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5532 | Intent.FLAG_RECEIVER_FOREGROUND); 5533 if (reason != null) { 5534 intent.putExtra("reason", reason); 5535 } 5536 mWindowManager.closeSystemDialogs(reason); 5537 5538 mStackSupervisor.closeSystemDialogsLocked(); 5539 5540 broadcastIntentLocked(null, null, intent, null, 5541 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5542 Process.SYSTEM_UID, UserHandle.USER_ALL); 5543 } 5544 5545 @Override 5546 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5547 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5548 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5549 for (int i=pids.length-1; i>=0; i--) { 5550 ProcessRecord proc; 5551 int oomAdj; 5552 synchronized (this) { 5553 synchronized (mPidsSelfLocked) { 5554 proc = mPidsSelfLocked.get(pids[i]); 5555 oomAdj = proc != null ? proc.setAdj : 0; 5556 } 5557 } 5558 infos[i] = new Debug.MemoryInfo(); 5559 Debug.getMemoryInfo(pids[i], infos[i]); 5560 if (proc != null) { 5561 synchronized (this) { 5562 if (proc.thread != null && proc.setAdj == oomAdj) { 5563 // Record this for posterity if the process has been stable. 5564 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5565 infos[i].getTotalUss(), false, proc.pkgList); 5566 } 5567 } 5568 } 5569 } 5570 return infos; 5571 } 5572 5573 @Override 5574 public long[] getProcessPss(int[] pids) { 5575 enforceNotIsolatedCaller("getProcessPss"); 5576 long[] pss = new long[pids.length]; 5577 for (int i=pids.length-1; i>=0; i--) { 5578 ProcessRecord proc; 5579 int oomAdj; 5580 synchronized (this) { 5581 synchronized (mPidsSelfLocked) { 5582 proc = mPidsSelfLocked.get(pids[i]); 5583 oomAdj = proc != null ? proc.setAdj : 0; 5584 } 5585 } 5586 long[] tmpUss = new long[1]; 5587 pss[i] = Debug.getPss(pids[i], tmpUss); 5588 if (proc != null) { 5589 synchronized (this) { 5590 if (proc.thread != null && proc.setAdj == oomAdj) { 5591 // Record this for posterity if the process has been stable. 5592 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5593 } 5594 } 5595 } 5596 } 5597 return pss; 5598 } 5599 5600 @Override 5601 public void killApplicationProcess(String processName, int uid) { 5602 if (processName == null) { 5603 return; 5604 } 5605 5606 int callerUid = Binder.getCallingUid(); 5607 // Only the system server can kill an application 5608 if (callerUid == Process.SYSTEM_UID) { 5609 synchronized (this) { 5610 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5611 if (app != null && app.thread != null) { 5612 try { 5613 app.thread.scheduleSuicide(); 5614 } catch (RemoteException e) { 5615 // If the other end already died, then our work here is done. 5616 } 5617 } else { 5618 Slog.w(TAG, "Process/uid not found attempting kill of " 5619 + processName + " / " + uid); 5620 } 5621 } 5622 } else { 5623 throw new SecurityException(callerUid + " cannot kill app process: " + 5624 processName); 5625 } 5626 } 5627 5628 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5629 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5630 false, true, false, false, UserHandle.getUserId(uid), reason); 5631 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5632 Uri.fromParts("package", packageName, null)); 5633 if (!mProcessesReady) { 5634 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5635 | Intent.FLAG_RECEIVER_FOREGROUND); 5636 } 5637 intent.putExtra(Intent.EXTRA_UID, uid); 5638 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5639 broadcastIntentLocked(null, null, intent, 5640 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5641 false, false, 5642 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5643 } 5644 5645 private void forceStopUserLocked(int userId, String reason) { 5646 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5647 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5648 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5649 | Intent.FLAG_RECEIVER_FOREGROUND); 5650 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5651 broadcastIntentLocked(null, null, intent, 5652 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5653 false, false, 5654 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5655 } 5656 5657 private final boolean killPackageProcessesLocked(String packageName, int appId, 5658 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5659 boolean doit, boolean evenPersistent, String reason) { 5660 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5661 5662 // Remove all processes this package may have touched: all with the 5663 // same UID (except for the system or root user), and all whose name 5664 // matches the package name. 5665 final int NP = mProcessNames.getMap().size(); 5666 for (int ip=0; ip<NP; ip++) { 5667 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5668 final int NA = apps.size(); 5669 for (int ia=0; ia<NA; ia++) { 5670 ProcessRecord app = apps.valueAt(ia); 5671 if (app.persistent && !evenPersistent) { 5672 // we don't kill persistent processes 5673 continue; 5674 } 5675 if (app.removed) { 5676 if (doit) { 5677 procs.add(app); 5678 } 5679 continue; 5680 } 5681 5682 // Skip process if it doesn't meet our oom adj requirement. 5683 if (app.setAdj < minOomAdj) { 5684 continue; 5685 } 5686 5687 // If no package is specified, we call all processes under the 5688 // give user id. 5689 if (packageName == null) { 5690 if (app.userId != userId) { 5691 continue; 5692 } 5693 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5694 continue; 5695 } 5696 // Package has been specified, we want to hit all processes 5697 // that match it. We need to qualify this by the processes 5698 // that are running under the specified app and user ID. 5699 } else { 5700 final boolean isDep = app.pkgDeps != null 5701 && app.pkgDeps.contains(packageName); 5702 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5703 continue; 5704 } 5705 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5706 continue; 5707 } 5708 if (!app.pkgList.containsKey(packageName) && !isDep) { 5709 continue; 5710 } 5711 } 5712 5713 // Process has passed all conditions, kill it! 5714 if (!doit) { 5715 return true; 5716 } 5717 app.removed = true; 5718 procs.add(app); 5719 } 5720 } 5721 5722 int N = procs.size(); 5723 for (int i=0; i<N; i++) { 5724 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5725 } 5726 updateOomAdjLocked(); 5727 return N > 0; 5728 } 5729 5730 private final boolean forceStopPackageLocked(String name, int appId, 5731 boolean callerWillRestart, boolean purgeCache, boolean doit, 5732 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5733 int i; 5734 int N; 5735 5736 if (userId == UserHandle.USER_ALL && name == null) { 5737 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5738 } 5739 5740 if (appId < 0 && name != null) { 5741 try { 5742 appId = UserHandle.getAppId( 5743 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5744 } catch (RemoteException e) { 5745 } 5746 } 5747 5748 if (doit) { 5749 if (name != null) { 5750 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5751 + " user=" + userId + ": " + reason); 5752 } else { 5753 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5754 } 5755 5756 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5757 for (int ip=pmap.size()-1; ip>=0; ip--) { 5758 SparseArray<Long> ba = pmap.valueAt(ip); 5759 for (i=ba.size()-1; i>=0; i--) { 5760 boolean remove = false; 5761 final int entUid = ba.keyAt(i); 5762 if (name != null) { 5763 if (userId == UserHandle.USER_ALL) { 5764 if (UserHandle.getAppId(entUid) == appId) { 5765 remove = true; 5766 } 5767 } else { 5768 if (entUid == UserHandle.getUid(userId, appId)) { 5769 remove = true; 5770 } 5771 } 5772 } else if (UserHandle.getUserId(entUid) == userId) { 5773 remove = true; 5774 } 5775 if (remove) { 5776 ba.removeAt(i); 5777 } 5778 } 5779 if (ba.size() == 0) { 5780 pmap.removeAt(ip); 5781 } 5782 } 5783 } 5784 5785 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5786 -100, callerWillRestart, true, doit, evenPersistent, 5787 name == null ? ("stop user " + userId) : ("stop " + name)); 5788 5789 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5790 if (!doit) { 5791 return true; 5792 } 5793 didSomething = true; 5794 } 5795 5796 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5797 if (!doit) { 5798 return true; 5799 } 5800 didSomething = true; 5801 } 5802 5803 if (name == null) { 5804 // Remove all sticky broadcasts from this user. 5805 mStickyBroadcasts.remove(userId); 5806 } 5807 5808 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5809 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5810 userId, providers)) { 5811 if (!doit) { 5812 return true; 5813 } 5814 didSomething = true; 5815 } 5816 N = providers.size(); 5817 for (i=0; i<N; i++) { 5818 removeDyingProviderLocked(null, providers.get(i), true); 5819 } 5820 5821 // Remove transient permissions granted from/to this package/user 5822 removeUriPermissionsForPackageLocked(name, userId, false); 5823 5824 if (name == null || uninstalling) { 5825 // Remove pending intents. For now we only do this when force 5826 // stopping users, because we have some problems when doing this 5827 // for packages -- app widgets are not currently cleaned up for 5828 // such packages, so they can be left with bad pending intents. 5829 if (mIntentSenderRecords.size() > 0) { 5830 Iterator<WeakReference<PendingIntentRecord>> it 5831 = mIntentSenderRecords.values().iterator(); 5832 while (it.hasNext()) { 5833 WeakReference<PendingIntentRecord> wpir = it.next(); 5834 if (wpir == null) { 5835 it.remove(); 5836 continue; 5837 } 5838 PendingIntentRecord pir = wpir.get(); 5839 if (pir == null) { 5840 it.remove(); 5841 continue; 5842 } 5843 if (name == null) { 5844 // Stopping user, remove all objects for the user. 5845 if (pir.key.userId != userId) { 5846 // Not the same user, skip it. 5847 continue; 5848 } 5849 } else { 5850 if (UserHandle.getAppId(pir.uid) != appId) { 5851 // Different app id, skip it. 5852 continue; 5853 } 5854 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5855 // Different user, skip it. 5856 continue; 5857 } 5858 if (!pir.key.packageName.equals(name)) { 5859 // Different package, skip it. 5860 continue; 5861 } 5862 } 5863 if (!doit) { 5864 return true; 5865 } 5866 didSomething = true; 5867 it.remove(); 5868 pir.canceled = true; 5869 if (pir.key.activity != null) { 5870 pir.key.activity.pendingResults.remove(pir.ref); 5871 } 5872 } 5873 } 5874 } 5875 5876 if (doit) { 5877 if (purgeCache && name != null) { 5878 AttributeCache ac = AttributeCache.instance(); 5879 if (ac != null) { 5880 ac.removePackage(name); 5881 } 5882 } 5883 if (mBooted) { 5884 mStackSupervisor.resumeTopActivitiesLocked(); 5885 mStackSupervisor.scheduleIdleLocked(); 5886 } 5887 } 5888 5889 return didSomething; 5890 } 5891 5892 private final boolean removeProcessLocked(ProcessRecord app, 5893 boolean callerWillRestart, boolean allowRestart, String reason) { 5894 final String name = app.processName; 5895 final int uid = app.uid; 5896 if (DEBUG_PROCESSES) Slog.d( 5897 TAG, "Force removing proc " + app.toShortString() + " (" + name 5898 + "/" + uid + ")"); 5899 5900 mProcessNames.remove(name, uid); 5901 mIsolatedProcesses.remove(app.uid); 5902 if (mHeavyWeightProcess == app) { 5903 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5904 mHeavyWeightProcess.userId, 0)); 5905 mHeavyWeightProcess = null; 5906 } 5907 boolean needRestart = false; 5908 if (app.pid > 0 && app.pid != MY_PID) { 5909 int pid = app.pid; 5910 synchronized (mPidsSelfLocked) { 5911 mPidsSelfLocked.remove(pid); 5912 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5913 } 5914 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5915 if (app.isolated) { 5916 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5917 } 5918 app.kill(reason, true); 5919 handleAppDiedLocked(app, true, allowRestart); 5920 removeLruProcessLocked(app); 5921 5922 if (app.persistent && !app.isolated) { 5923 if (!callerWillRestart) { 5924 addAppLocked(app.info, false, null /* ABI override */); 5925 } else { 5926 needRestart = true; 5927 } 5928 } 5929 } else { 5930 mRemovedProcesses.add(app); 5931 } 5932 5933 return needRestart; 5934 } 5935 5936 private final void processStartTimedOutLocked(ProcessRecord app) { 5937 final int pid = app.pid; 5938 boolean gone = false; 5939 synchronized (mPidsSelfLocked) { 5940 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5941 if (knownApp != null && knownApp.thread == null) { 5942 mPidsSelfLocked.remove(pid); 5943 gone = true; 5944 } 5945 } 5946 5947 if (gone) { 5948 Slog.w(TAG, "Process " + app + " failed to attach"); 5949 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5950 pid, app.uid, app.processName); 5951 mProcessNames.remove(app.processName, app.uid); 5952 mIsolatedProcesses.remove(app.uid); 5953 if (mHeavyWeightProcess == app) { 5954 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5955 mHeavyWeightProcess.userId, 0)); 5956 mHeavyWeightProcess = null; 5957 } 5958 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5959 if (app.isolated) { 5960 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5961 } 5962 // Take care of any launching providers waiting for this process. 5963 checkAppInLaunchingProvidersLocked(app, true); 5964 // Take care of any services that are waiting for the process. 5965 mServices.processStartTimedOutLocked(app); 5966 app.kill("start timeout", true); 5967 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5968 Slog.w(TAG, "Unattached app died before backup, skipping"); 5969 try { 5970 IBackupManager bm = IBackupManager.Stub.asInterface( 5971 ServiceManager.getService(Context.BACKUP_SERVICE)); 5972 bm.agentDisconnected(app.info.packageName); 5973 } catch (RemoteException e) { 5974 // Can't happen; the backup manager is local 5975 } 5976 } 5977 if (isPendingBroadcastProcessLocked(pid)) { 5978 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5979 skipPendingBroadcastLocked(pid); 5980 } 5981 } else { 5982 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5983 } 5984 } 5985 5986 private final boolean attachApplicationLocked(IApplicationThread thread, 5987 int pid) { 5988 5989 // Find the application record that is being attached... either via 5990 // the pid if we are running in multiple processes, or just pull the 5991 // next app record if we are emulating process with anonymous threads. 5992 ProcessRecord app; 5993 if (pid != MY_PID && pid >= 0) { 5994 synchronized (mPidsSelfLocked) { 5995 app = mPidsSelfLocked.get(pid); 5996 } 5997 } else { 5998 app = null; 5999 } 6000 6001 if (app == null) { 6002 Slog.w(TAG, "No pending application record for pid " + pid 6003 + " (IApplicationThread " + thread + "); dropping process"); 6004 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 6005 if (pid > 0 && pid != MY_PID) { 6006 Process.killProcessQuiet(pid); 6007 //TODO: Process.killProcessGroup(app.info.uid, pid); 6008 } else { 6009 try { 6010 thread.scheduleExit(); 6011 } catch (Exception e) { 6012 // Ignore exceptions. 6013 } 6014 } 6015 return false; 6016 } 6017 6018 // If this application record is still attached to a previous 6019 // process, clean it up now. 6020 if (app.thread != null) { 6021 handleAppDiedLocked(app, true, true); 6022 } 6023 6024 // Tell the process all about itself. 6025 6026 if (localLOGV) Slog.v( 6027 TAG, "Binding process pid " + pid + " to record " + app); 6028 6029 final String processName = app.processName; 6030 try { 6031 AppDeathRecipient adr = new AppDeathRecipient( 6032 app, pid, thread); 6033 thread.asBinder().linkToDeath(adr, 0); 6034 app.deathRecipient = adr; 6035 } catch (RemoteException e) { 6036 app.resetPackageList(mProcessStats); 6037 startProcessLocked(app, "link fail", processName); 6038 return false; 6039 } 6040 6041 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 6042 6043 app.makeActive(thread, mProcessStats); 6044 app.curAdj = app.setAdj = -100; 6045 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 6046 app.forcingToForeground = null; 6047 updateProcessForegroundLocked(app, false, false); 6048 app.hasShownUi = false; 6049 app.debugging = false; 6050 app.cached = false; 6051 6052 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 6053 6054 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 6055 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 6056 6057 if (!normalMode) { 6058 Slog.i(TAG, "Launching preboot mode app: " + app); 6059 } 6060 6061 if (localLOGV) Slog.v( 6062 TAG, "New app record " + app 6063 + " thread=" + thread.asBinder() + " pid=" + pid); 6064 try { 6065 int testMode = IApplicationThread.DEBUG_OFF; 6066 if (mDebugApp != null && mDebugApp.equals(processName)) { 6067 testMode = mWaitForDebugger 6068 ? IApplicationThread.DEBUG_WAIT 6069 : IApplicationThread.DEBUG_ON; 6070 app.debugging = true; 6071 if (mDebugTransient) { 6072 mDebugApp = mOrigDebugApp; 6073 mWaitForDebugger = mOrigWaitForDebugger; 6074 } 6075 } 6076 String profileFile = app.instrumentationProfileFile; 6077 ParcelFileDescriptor profileFd = null; 6078 int samplingInterval = 0; 6079 boolean profileAutoStop = false; 6080 if (mProfileApp != null && mProfileApp.equals(processName)) { 6081 mProfileProc = app; 6082 profileFile = mProfileFile; 6083 profileFd = mProfileFd; 6084 samplingInterval = mSamplingInterval; 6085 profileAutoStop = mAutoStopProfiler; 6086 } 6087 boolean enableOpenGlTrace = false; 6088 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 6089 enableOpenGlTrace = true; 6090 mOpenGlTraceApp = null; 6091 } 6092 6093 // If the app is being launched for restore or full backup, set it up specially 6094 boolean isRestrictedBackupMode = false; 6095 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 6096 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 6097 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 6098 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 6099 } 6100 6101 ensurePackageDexOpt(app.instrumentationInfo != null 6102 ? app.instrumentationInfo.packageName 6103 : app.info.packageName); 6104 if (app.instrumentationClass != null) { 6105 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 6106 } 6107 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6108 + processName + " with config " + mConfiguration); 6109 ApplicationInfo appInfo = app.instrumentationInfo != null 6110 ? app.instrumentationInfo : app.info; 6111 app.compat = compatibilityInfoForPackageLocked(appInfo); 6112 if (profileFd != null) { 6113 profileFd = profileFd.dup(); 6114 } 6115 ProfilerInfo profilerInfo = profileFile == null ? null 6116 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6117 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6118 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6119 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6120 isRestrictedBackupMode || !normalMode, app.persistent, 6121 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6122 mCoreSettingsObserver.getCoreSettingsLocked()); 6123 updateLruProcessLocked(app, false, null); 6124 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6125 } catch (Exception e) { 6126 // todo: Yikes! What should we do? For now we will try to 6127 // start another process, but that could easily get us in 6128 // an infinite loop of restarting processes... 6129 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 6130 6131 app.resetPackageList(mProcessStats); 6132 app.unlinkDeathRecipient(); 6133 startProcessLocked(app, "bind fail", processName); 6134 return false; 6135 } 6136 6137 // Remove this record from the list of starting applications. 6138 mPersistentStartingProcesses.remove(app); 6139 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6140 "Attach application locked removing on hold: " + app); 6141 mProcessesOnHold.remove(app); 6142 6143 boolean badApp = false; 6144 boolean didSomething = false; 6145 6146 // See if the top visible activity is waiting to run in this process... 6147 if (normalMode) { 6148 try { 6149 if (mStackSupervisor.attachApplicationLocked(app)) { 6150 didSomething = true; 6151 } 6152 } catch (Exception e) { 6153 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6154 badApp = true; 6155 } 6156 } 6157 6158 // Find any services that should be running in this process... 6159 if (!badApp) { 6160 try { 6161 didSomething |= mServices.attachApplicationLocked(app, processName); 6162 } catch (Exception e) { 6163 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6164 badApp = true; 6165 } 6166 } 6167 6168 // Check if a next-broadcast receiver is in this process... 6169 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6170 try { 6171 didSomething |= sendPendingBroadcastsLocked(app); 6172 } catch (Exception e) { 6173 // If the app died trying to launch the receiver we declare it 'bad' 6174 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6175 badApp = true; 6176 } 6177 } 6178 6179 // Check whether the next backup agent is in this process... 6180 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6181 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6182 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6183 try { 6184 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6185 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6186 mBackupTarget.backupMode); 6187 } catch (Exception e) { 6188 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6189 badApp = true; 6190 } 6191 } 6192 6193 if (badApp) { 6194 app.kill("error during init", true); 6195 handleAppDiedLocked(app, false, true); 6196 return false; 6197 } 6198 6199 if (!didSomething) { 6200 updateOomAdjLocked(); 6201 } 6202 6203 return true; 6204 } 6205 6206 @Override 6207 public final void attachApplication(IApplicationThread thread) { 6208 synchronized (this) { 6209 int callingPid = Binder.getCallingPid(); 6210 final long origId = Binder.clearCallingIdentity(); 6211 attachApplicationLocked(thread, callingPid); 6212 Binder.restoreCallingIdentity(origId); 6213 } 6214 } 6215 6216 @Override 6217 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6218 final long origId = Binder.clearCallingIdentity(); 6219 synchronized (this) { 6220 ActivityStack stack = ActivityRecord.getStackLocked(token); 6221 if (stack != null) { 6222 ActivityRecord r = 6223 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6224 if (stopProfiling) { 6225 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6226 try { 6227 mProfileFd.close(); 6228 } catch (IOException e) { 6229 } 6230 clearProfilerLocked(); 6231 } 6232 } 6233 } 6234 } 6235 Binder.restoreCallingIdentity(origId); 6236 } 6237 6238 void postEnableScreenAfterBootLocked() { 6239 mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG); 6240 } 6241 6242 void enableScreenAfterBoot() { 6243 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6244 SystemClock.uptimeMillis()); 6245 mWindowManager.enableScreenAfterBoot(); 6246 6247 synchronized (this) { 6248 updateEventDispatchingLocked(); 6249 } 6250 } 6251 6252 @Override 6253 public void showBootMessage(final CharSequence msg, final boolean always) { 6254 enforceNotIsolatedCaller("showBootMessage"); 6255 mWindowManager.showBootMessage(msg, always); 6256 } 6257 6258 @Override 6259 public void keyguardWaitingForActivityDrawn() { 6260 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6261 final long token = Binder.clearCallingIdentity(); 6262 try { 6263 synchronized (this) { 6264 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6265 mWindowManager.keyguardWaitingForActivityDrawn(); 6266 if (mLockScreenShown) { 6267 mLockScreenShown = false; 6268 comeOutOfSleepIfNeededLocked(); 6269 } 6270 } 6271 } finally { 6272 Binder.restoreCallingIdentity(token); 6273 } 6274 } 6275 6276 final void finishBooting() { 6277 synchronized (this) { 6278 if (!mBootAnimationComplete) { 6279 mCallFinishBooting = true; 6280 return; 6281 } 6282 mCallFinishBooting = false; 6283 } 6284 6285 // Register receivers to handle package update events 6286 mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false); 6287 6288 // Let system services know. 6289 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6290 6291 synchronized (this) { 6292 // Ensure that any processes we had put on hold are now started 6293 // up. 6294 final int NP = mProcessesOnHold.size(); 6295 if (NP > 0) { 6296 ArrayList<ProcessRecord> procs = 6297 new ArrayList<ProcessRecord>(mProcessesOnHold); 6298 for (int ip=0; ip<NP; ip++) { 6299 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6300 + procs.get(ip)); 6301 startProcessLocked(procs.get(ip), "on-hold", null); 6302 } 6303 } 6304 6305 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6306 // Start looking for apps that are abusing wake locks. 6307 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6308 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6309 // Tell anyone interested that we are done booting! 6310 SystemProperties.set("sys.boot_completed", "1"); 6311 SystemProperties.set("dev.bootcomplete", "1"); 6312 for (int i=0; i<mStartedUsers.size(); i++) { 6313 UserStartedState uss = mStartedUsers.valueAt(i); 6314 if (uss.mState == UserStartedState.STATE_BOOTING) { 6315 uss.mState = UserStartedState.STATE_RUNNING; 6316 final int userId = mStartedUsers.keyAt(i); 6317 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6318 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6319 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6320 broadcastIntentLocked(null, null, intent, null, 6321 new IIntentReceiver.Stub() { 6322 @Override 6323 public void performReceive(Intent intent, int resultCode, 6324 String data, Bundle extras, boolean ordered, 6325 boolean sticky, int sendingUser) { 6326 synchronized (ActivityManagerService.this) { 6327 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6328 true, false); 6329 } 6330 } 6331 }, 6332 0, null, null, 6333 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6334 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6335 userId); 6336 } 6337 } 6338 scheduleStartProfilesLocked(); 6339 } 6340 } 6341 } 6342 6343 @Override 6344 public void bootAnimationComplete() { 6345 final boolean callFinishBooting; 6346 synchronized (this) { 6347 callFinishBooting = mCallFinishBooting; 6348 mBootAnimationComplete = true; 6349 } 6350 if (callFinishBooting) { 6351 finishBooting(); 6352 } 6353 } 6354 6355 final void ensureBootCompleted() { 6356 boolean booting; 6357 boolean enableScreen; 6358 synchronized (this) { 6359 booting = mBooting; 6360 mBooting = false; 6361 enableScreen = !mBooted; 6362 mBooted = true; 6363 } 6364 6365 if (booting) { 6366 finishBooting(); 6367 } 6368 6369 if (enableScreen) { 6370 enableScreenAfterBoot(); 6371 } 6372 } 6373 6374 @Override 6375 public final void activityResumed(IBinder token) { 6376 final long origId = Binder.clearCallingIdentity(); 6377 synchronized(this) { 6378 ActivityStack stack = ActivityRecord.getStackLocked(token); 6379 if (stack != null) { 6380 ActivityRecord.activityResumedLocked(token); 6381 } 6382 } 6383 Binder.restoreCallingIdentity(origId); 6384 } 6385 6386 @Override 6387 public final void activityPaused(IBinder token) { 6388 final long origId = Binder.clearCallingIdentity(); 6389 synchronized(this) { 6390 ActivityStack stack = ActivityRecord.getStackLocked(token); 6391 if (stack != null) { 6392 stack.activityPausedLocked(token, false); 6393 } 6394 } 6395 Binder.restoreCallingIdentity(origId); 6396 } 6397 6398 @Override 6399 public final void activityStopped(IBinder token, Bundle icicle, 6400 PersistableBundle persistentState, CharSequence description) { 6401 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6402 6403 // Refuse possible leaked file descriptors 6404 if (icicle != null && icicle.hasFileDescriptors()) { 6405 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6406 } 6407 6408 final long origId = Binder.clearCallingIdentity(); 6409 6410 synchronized (this) { 6411 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6412 if (r != null) { 6413 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6414 } 6415 } 6416 6417 trimApplications(); 6418 6419 Binder.restoreCallingIdentity(origId); 6420 } 6421 6422 @Override 6423 public final void activityDestroyed(IBinder token) { 6424 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6425 synchronized (this) { 6426 ActivityStack stack = ActivityRecord.getStackLocked(token); 6427 if (stack != null) { 6428 stack.activityDestroyedLocked(token); 6429 } 6430 } 6431 } 6432 6433 @Override 6434 public final void backgroundResourcesReleased(IBinder token) { 6435 final long origId = Binder.clearCallingIdentity(); 6436 try { 6437 synchronized (this) { 6438 ActivityStack stack = ActivityRecord.getStackLocked(token); 6439 if (stack != null) { 6440 stack.backgroundResourcesReleased(token); 6441 } 6442 } 6443 } finally { 6444 Binder.restoreCallingIdentity(origId); 6445 } 6446 } 6447 6448 @Override 6449 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6450 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6451 } 6452 6453 @Override 6454 public final void notifyEnterAnimationComplete(IBinder token) { 6455 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6456 } 6457 6458 @Override 6459 public String getCallingPackage(IBinder token) { 6460 synchronized (this) { 6461 ActivityRecord r = getCallingRecordLocked(token); 6462 return r != null ? r.info.packageName : null; 6463 } 6464 } 6465 6466 @Override 6467 public ComponentName getCallingActivity(IBinder token) { 6468 synchronized (this) { 6469 ActivityRecord r = getCallingRecordLocked(token); 6470 return r != null ? r.intent.getComponent() : null; 6471 } 6472 } 6473 6474 private ActivityRecord getCallingRecordLocked(IBinder token) { 6475 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6476 if (r == null) { 6477 return null; 6478 } 6479 return r.resultTo; 6480 } 6481 6482 @Override 6483 public ComponentName getActivityClassForToken(IBinder token) { 6484 synchronized(this) { 6485 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6486 if (r == null) { 6487 return null; 6488 } 6489 return r.intent.getComponent(); 6490 } 6491 } 6492 6493 @Override 6494 public String getPackageForToken(IBinder token) { 6495 synchronized(this) { 6496 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6497 if (r == null) { 6498 return null; 6499 } 6500 return r.packageName; 6501 } 6502 } 6503 6504 @Override 6505 public IIntentSender getIntentSender(int type, 6506 String packageName, IBinder token, String resultWho, 6507 int requestCode, Intent[] intents, String[] resolvedTypes, 6508 int flags, Bundle options, int userId) { 6509 enforceNotIsolatedCaller("getIntentSender"); 6510 // Refuse possible leaked file descriptors 6511 if (intents != null) { 6512 if (intents.length < 1) { 6513 throw new IllegalArgumentException("Intents array length must be >= 1"); 6514 } 6515 for (int i=0; i<intents.length; i++) { 6516 Intent intent = intents[i]; 6517 if (intent != null) { 6518 if (intent.hasFileDescriptors()) { 6519 throw new IllegalArgumentException("File descriptors passed in Intent"); 6520 } 6521 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6522 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6523 throw new IllegalArgumentException( 6524 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6525 } 6526 intents[i] = new Intent(intent); 6527 } 6528 } 6529 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6530 throw new IllegalArgumentException( 6531 "Intent array length does not match resolvedTypes length"); 6532 } 6533 } 6534 if (options != null) { 6535 if (options.hasFileDescriptors()) { 6536 throw new IllegalArgumentException("File descriptors passed in options"); 6537 } 6538 } 6539 6540 synchronized(this) { 6541 int callingUid = Binder.getCallingUid(); 6542 int origUserId = userId; 6543 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6544 type == ActivityManager.INTENT_SENDER_BROADCAST, 6545 ALLOW_NON_FULL, "getIntentSender", null); 6546 if (origUserId == UserHandle.USER_CURRENT) { 6547 // We don't want to evaluate this until the pending intent is 6548 // actually executed. However, we do want to always do the 6549 // security checking for it above. 6550 userId = UserHandle.USER_CURRENT; 6551 } 6552 try { 6553 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6554 int uid = AppGlobals.getPackageManager() 6555 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6556 if (!UserHandle.isSameApp(callingUid, uid)) { 6557 String msg = "Permission Denial: getIntentSender() from pid=" 6558 + Binder.getCallingPid() 6559 + ", uid=" + Binder.getCallingUid() 6560 + ", (need uid=" + uid + ")" 6561 + " is not allowed to send as package " + packageName; 6562 Slog.w(TAG, msg); 6563 throw new SecurityException(msg); 6564 } 6565 } 6566 6567 return getIntentSenderLocked(type, packageName, callingUid, userId, 6568 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6569 6570 } catch (RemoteException e) { 6571 throw new SecurityException(e); 6572 } 6573 } 6574 } 6575 6576 IIntentSender getIntentSenderLocked(int type, String packageName, 6577 int callingUid, int userId, IBinder token, String resultWho, 6578 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6579 Bundle options) { 6580 if (DEBUG_MU) 6581 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6582 ActivityRecord activity = null; 6583 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6584 activity = ActivityRecord.isInStackLocked(token); 6585 if (activity == null) { 6586 return null; 6587 } 6588 if (activity.finishing) { 6589 return null; 6590 } 6591 } 6592 6593 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6594 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6595 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6596 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6597 |PendingIntent.FLAG_UPDATE_CURRENT); 6598 6599 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6600 type, packageName, activity, resultWho, 6601 requestCode, intents, resolvedTypes, flags, options, userId); 6602 WeakReference<PendingIntentRecord> ref; 6603 ref = mIntentSenderRecords.get(key); 6604 PendingIntentRecord rec = ref != null ? ref.get() : null; 6605 if (rec != null) { 6606 if (!cancelCurrent) { 6607 if (updateCurrent) { 6608 if (rec.key.requestIntent != null) { 6609 rec.key.requestIntent.replaceExtras(intents != null ? 6610 intents[intents.length - 1] : null); 6611 } 6612 if (intents != null) { 6613 intents[intents.length-1] = rec.key.requestIntent; 6614 rec.key.allIntents = intents; 6615 rec.key.allResolvedTypes = resolvedTypes; 6616 } else { 6617 rec.key.allIntents = null; 6618 rec.key.allResolvedTypes = null; 6619 } 6620 } 6621 return rec; 6622 } 6623 rec.canceled = true; 6624 mIntentSenderRecords.remove(key); 6625 } 6626 if (noCreate) { 6627 return rec; 6628 } 6629 rec = new PendingIntentRecord(this, key, callingUid); 6630 mIntentSenderRecords.put(key, rec.ref); 6631 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6632 if (activity.pendingResults == null) { 6633 activity.pendingResults 6634 = new HashSet<WeakReference<PendingIntentRecord>>(); 6635 } 6636 activity.pendingResults.add(rec.ref); 6637 } 6638 return rec; 6639 } 6640 6641 @Override 6642 public void cancelIntentSender(IIntentSender sender) { 6643 if (!(sender instanceof PendingIntentRecord)) { 6644 return; 6645 } 6646 synchronized(this) { 6647 PendingIntentRecord rec = (PendingIntentRecord)sender; 6648 try { 6649 int uid = AppGlobals.getPackageManager() 6650 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6651 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6652 String msg = "Permission Denial: cancelIntentSender() from pid=" 6653 + Binder.getCallingPid() 6654 + ", uid=" + Binder.getCallingUid() 6655 + " is not allowed to cancel packges " 6656 + rec.key.packageName; 6657 Slog.w(TAG, msg); 6658 throw new SecurityException(msg); 6659 } 6660 } catch (RemoteException e) { 6661 throw new SecurityException(e); 6662 } 6663 cancelIntentSenderLocked(rec, true); 6664 } 6665 } 6666 6667 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6668 rec.canceled = true; 6669 mIntentSenderRecords.remove(rec.key); 6670 if (cleanActivity && rec.key.activity != null) { 6671 rec.key.activity.pendingResults.remove(rec.ref); 6672 } 6673 } 6674 6675 @Override 6676 public String getPackageForIntentSender(IIntentSender pendingResult) { 6677 if (!(pendingResult instanceof PendingIntentRecord)) { 6678 return null; 6679 } 6680 try { 6681 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6682 return res.key.packageName; 6683 } catch (ClassCastException e) { 6684 } 6685 return null; 6686 } 6687 6688 @Override 6689 public int getUidForIntentSender(IIntentSender sender) { 6690 if (sender instanceof PendingIntentRecord) { 6691 try { 6692 PendingIntentRecord res = (PendingIntentRecord)sender; 6693 return res.uid; 6694 } catch (ClassCastException e) { 6695 } 6696 } 6697 return -1; 6698 } 6699 6700 @Override 6701 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6702 if (!(pendingResult instanceof PendingIntentRecord)) { 6703 return false; 6704 } 6705 try { 6706 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6707 if (res.key.allIntents == null) { 6708 return false; 6709 } 6710 for (int i=0; i<res.key.allIntents.length; i++) { 6711 Intent intent = res.key.allIntents[i]; 6712 if (intent.getPackage() != null && intent.getComponent() != null) { 6713 return false; 6714 } 6715 } 6716 return true; 6717 } catch (ClassCastException e) { 6718 } 6719 return false; 6720 } 6721 6722 @Override 6723 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6724 if (!(pendingResult instanceof PendingIntentRecord)) { 6725 return false; 6726 } 6727 try { 6728 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6729 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6730 return true; 6731 } 6732 return false; 6733 } catch (ClassCastException e) { 6734 } 6735 return false; 6736 } 6737 6738 @Override 6739 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6740 if (!(pendingResult instanceof PendingIntentRecord)) { 6741 return null; 6742 } 6743 try { 6744 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6745 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6746 } catch (ClassCastException e) { 6747 } 6748 return null; 6749 } 6750 6751 @Override 6752 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6753 if (!(pendingResult instanceof PendingIntentRecord)) { 6754 return null; 6755 } 6756 try { 6757 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6758 Intent intent = res.key.requestIntent; 6759 if (intent != null) { 6760 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6761 || res.lastTagPrefix.equals(prefix))) { 6762 return res.lastTag; 6763 } 6764 res.lastTagPrefix = prefix; 6765 StringBuilder sb = new StringBuilder(128); 6766 if (prefix != null) { 6767 sb.append(prefix); 6768 } 6769 if (intent.getAction() != null) { 6770 sb.append(intent.getAction()); 6771 } else if (intent.getComponent() != null) { 6772 intent.getComponent().appendShortString(sb); 6773 } else { 6774 sb.append("?"); 6775 } 6776 return res.lastTag = sb.toString(); 6777 } 6778 } catch (ClassCastException e) { 6779 } 6780 return null; 6781 } 6782 6783 @Override 6784 public void setProcessLimit(int max) { 6785 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6786 "setProcessLimit()"); 6787 synchronized (this) { 6788 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6789 mProcessLimitOverride = max; 6790 } 6791 trimApplications(); 6792 } 6793 6794 @Override 6795 public int getProcessLimit() { 6796 synchronized (this) { 6797 return mProcessLimitOverride; 6798 } 6799 } 6800 6801 void foregroundTokenDied(ForegroundToken token) { 6802 synchronized (ActivityManagerService.this) { 6803 synchronized (mPidsSelfLocked) { 6804 ForegroundToken cur 6805 = mForegroundProcesses.get(token.pid); 6806 if (cur != token) { 6807 return; 6808 } 6809 mForegroundProcesses.remove(token.pid); 6810 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6811 if (pr == null) { 6812 return; 6813 } 6814 pr.forcingToForeground = null; 6815 updateProcessForegroundLocked(pr, false, false); 6816 } 6817 updateOomAdjLocked(); 6818 } 6819 } 6820 6821 @Override 6822 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6823 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6824 "setProcessForeground()"); 6825 synchronized(this) { 6826 boolean changed = false; 6827 6828 synchronized (mPidsSelfLocked) { 6829 ProcessRecord pr = mPidsSelfLocked.get(pid); 6830 if (pr == null && isForeground) { 6831 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6832 return; 6833 } 6834 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6835 if (oldToken != null) { 6836 oldToken.token.unlinkToDeath(oldToken, 0); 6837 mForegroundProcesses.remove(pid); 6838 if (pr != null) { 6839 pr.forcingToForeground = null; 6840 } 6841 changed = true; 6842 } 6843 if (isForeground && token != null) { 6844 ForegroundToken newToken = new ForegroundToken() { 6845 @Override 6846 public void binderDied() { 6847 foregroundTokenDied(this); 6848 } 6849 }; 6850 newToken.pid = pid; 6851 newToken.token = token; 6852 try { 6853 token.linkToDeath(newToken, 0); 6854 mForegroundProcesses.put(pid, newToken); 6855 pr.forcingToForeground = token; 6856 changed = true; 6857 } catch (RemoteException e) { 6858 // If the process died while doing this, we will later 6859 // do the cleanup with the process death link. 6860 } 6861 } 6862 } 6863 6864 if (changed) { 6865 updateOomAdjLocked(); 6866 } 6867 } 6868 } 6869 6870 // ========================================================= 6871 // PERMISSIONS 6872 // ========================================================= 6873 6874 static class PermissionController extends IPermissionController.Stub { 6875 ActivityManagerService mActivityManagerService; 6876 PermissionController(ActivityManagerService activityManagerService) { 6877 mActivityManagerService = activityManagerService; 6878 } 6879 6880 @Override 6881 public boolean checkPermission(String permission, int pid, int uid) { 6882 return mActivityManagerService.checkPermission(permission, pid, 6883 uid) == PackageManager.PERMISSION_GRANTED; 6884 } 6885 } 6886 6887 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6888 @Override 6889 public int checkComponentPermission(String permission, int pid, int uid, 6890 int owningUid, boolean exported) { 6891 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6892 owningUid, exported); 6893 } 6894 6895 @Override 6896 public Object getAMSLock() { 6897 return ActivityManagerService.this; 6898 } 6899 } 6900 6901 /** 6902 * This can be called with or without the global lock held. 6903 */ 6904 int checkComponentPermission(String permission, int pid, int uid, 6905 int owningUid, boolean exported) { 6906 // We might be performing an operation on behalf of an indirect binder 6907 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6908 // client identity accordingly before proceeding. 6909 Identity tlsIdentity = sCallerIdentity.get(); 6910 if (tlsIdentity != null) { 6911 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6912 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6913 uid = tlsIdentity.uid; 6914 pid = tlsIdentity.pid; 6915 } 6916 6917 if (pid == MY_PID) { 6918 return PackageManager.PERMISSION_GRANTED; 6919 } 6920 6921 return ActivityManager.checkComponentPermission(permission, uid, 6922 owningUid, exported); 6923 } 6924 6925 /** 6926 * As the only public entry point for permissions checking, this method 6927 * can enforce the semantic that requesting a check on a null global 6928 * permission is automatically denied. (Internally a null permission 6929 * string is used when calling {@link #checkComponentPermission} in cases 6930 * when only uid-based security is needed.) 6931 * 6932 * This can be called with or without the global lock held. 6933 */ 6934 @Override 6935 public int checkPermission(String permission, int pid, int uid) { 6936 if (permission == null) { 6937 return PackageManager.PERMISSION_DENIED; 6938 } 6939 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6940 } 6941 6942 /** 6943 * Binder IPC calls go through the public entry point. 6944 * This can be called with or without the global lock held. 6945 */ 6946 int checkCallingPermission(String permission) { 6947 return checkPermission(permission, 6948 Binder.getCallingPid(), 6949 UserHandle.getAppId(Binder.getCallingUid())); 6950 } 6951 6952 /** 6953 * This can be called with or without the global lock held. 6954 */ 6955 void enforceCallingPermission(String permission, String func) { 6956 if (checkCallingPermission(permission) 6957 == PackageManager.PERMISSION_GRANTED) { 6958 return; 6959 } 6960 6961 String msg = "Permission Denial: " + func + " from pid=" 6962 + Binder.getCallingPid() 6963 + ", uid=" + Binder.getCallingUid() 6964 + " requires " + permission; 6965 Slog.w(TAG, msg); 6966 throw new SecurityException(msg); 6967 } 6968 6969 /** 6970 * Determine if UID is holding permissions required to access {@link Uri} in 6971 * the given {@link ProviderInfo}. Final permission checking is always done 6972 * in {@link ContentProvider}. 6973 */ 6974 private final boolean checkHoldingPermissionsLocked( 6975 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6976 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6977 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6978 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6979 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6980 != PERMISSION_GRANTED) { 6981 return false; 6982 } 6983 } 6984 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6985 } 6986 6987 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6988 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6989 if (pi.applicationInfo.uid == uid) { 6990 return true; 6991 } else if (!pi.exported) { 6992 return false; 6993 } 6994 6995 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6996 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6997 try { 6998 // check if target holds top-level <provider> permissions 6999 if (!readMet && pi.readPermission != null && considerUidPermissions 7000 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 7001 readMet = true; 7002 } 7003 if (!writeMet && pi.writePermission != null && considerUidPermissions 7004 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 7005 writeMet = true; 7006 } 7007 7008 // track if unprotected read/write is allowed; any denied 7009 // <path-permission> below removes this ability 7010 boolean allowDefaultRead = pi.readPermission == null; 7011 boolean allowDefaultWrite = pi.writePermission == null; 7012 7013 // check if target holds any <path-permission> that match uri 7014 final PathPermission[] pps = pi.pathPermissions; 7015 if (pps != null) { 7016 final String path = grantUri.uri.getPath(); 7017 int i = pps.length; 7018 while (i > 0 && (!readMet || !writeMet)) { 7019 i--; 7020 PathPermission pp = pps[i]; 7021 if (pp.match(path)) { 7022 if (!readMet) { 7023 final String pprperm = pp.getReadPermission(); 7024 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 7025 + pprperm + " for " + pp.getPath() 7026 + ": match=" + pp.match(path) 7027 + " check=" + pm.checkUidPermission(pprperm, uid)); 7028 if (pprperm != null) { 7029 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 7030 == PERMISSION_GRANTED) { 7031 readMet = true; 7032 } else { 7033 allowDefaultRead = false; 7034 } 7035 } 7036 } 7037 if (!writeMet) { 7038 final String ppwperm = pp.getWritePermission(); 7039 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 7040 + ppwperm + " for " + pp.getPath() 7041 + ": match=" + pp.match(path) 7042 + " check=" + pm.checkUidPermission(ppwperm, uid)); 7043 if (ppwperm != null) { 7044 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 7045 == PERMISSION_GRANTED) { 7046 writeMet = true; 7047 } else { 7048 allowDefaultWrite = false; 7049 } 7050 } 7051 } 7052 } 7053 } 7054 } 7055 7056 // grant unprotected <provider> read/write, if not blocked by 7057 // <path-permission> above 7058 if (allowDefaultRead) readMet = true; 7059 if (allowDefaultWrite) writeMet = true; 7060 7061 } catch (RemoteException e) { 7062 return false; 7063 } 7064 7065 return readMet && writeMet; 7066 } 7067 7068 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 7069 ProviderInfo pi = null; 7070 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 7071 if (cpr != null) { 7072 pi = cpr.info; 7073 } else { 7074 try { 7075 pi = AppGlobals.getPackageManager().resolveContentProvider( 7076 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 7077 } catch (RemoteException ex) { 7078 } 7079 } 7080 return pi; 7081 } 7082 7083 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 7084 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7085 if (targetUris != null) { 7086 return targetUris.get(grantUri); 7087 } 7088 return null; 7089 } 7090 7091 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7092 String targetPkg, int targetUid, GrantUri grantUri) { 7093 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7094 if (targetUris == null) { 7095 targetUris = Maps.newArrayMap(); 7096 mGrantedUriPermissions.put(targetUid, targetUris); 7097 } 7098 7099 UriPermission perm = targetUris.get(grantUri); 7100 if (perm == null) { 7101 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7102 targetUris.put(grantUri, perm); 7103 } 7104 7105 return perm; 7106 } 7107 7108 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7109 final int modeFlags) { 7110 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7111 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7112 : UriPermission.STRENGTH_OWNED; 7113 7114 // Root gets to do everything. 7115 if (uid == 0) { 7116 return true; 7117 } 7118 7119 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7120 if (perms == null) return false; 7121 7122 // First look for exact match 7123 final UriPermission exactPerm = perms.get(grantUri); 7124 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7125 return true; 7126 } 7127 7128 // No exact match, look for prefixes 7129 final int N = perms.size(); 7130 for (int i = 0; i < N; i++) { 7131 final UriPermission perm = perms.valueAt(i); 7132 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7133 && perm.getStrength(modeFlags) >= minStrength) { 7134 return true; 7135 } 7136 } 7137 7138 return false; 7139 } 7140 7141 /** 7142 * @param uri This uri must NOT contain an embedded userId. 7143 * @param userId The userId in which the uri is to be resolved. 7144 */ 7145 @Override 7146 public int checkUriPermission(Uri uri, int pid, int uid, 7147 final int modeFlags, int userId) { 7148 enforceNotIsolatedCaller("checkUriPermission"); 7149 7150 // Another redirected-binder-call permissions check as in 7151 // {@link checkComponentPermission}. 7152 Identity tlsIdentity = sCallerIdentity.get(); 7153 if (tlsIdentity != null) { 7154 uid = tlsIdentity.uid; 7155 pid = tlsIdentity.pid; 7156 } 7157 7158 // Our own process gets to do everything. 7159 if (pid == MY_PID) { 7160 return PackageManager.PERMISSION_GRANTED; 7161 } 7162 synchronized (this) { 7163 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7164 ? PackageManager.PERMISSION_GRANTED 7165 : PackageManager.PERMISSION_DENIED; 7166 } 7167 } 7168 7169 /** 7170 * Check if the targetPkg can be granted permission to access uri by 7171 * the callingUid using the given modeFlags. Throws a security exception 7172 * if callingUid is not allowed to do this. Returns the uid of the target 7173 * if the URI permission grant should be performed; returns -1 if it is not 7174 * needed (for example targetPkg already has permission to access the URI). 7175 * If you already know the uid of the target, you can supply it in 7176 * lastTargetUid else set that to -1. 7177 */ 7178 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7179 final int modeFlags, int lastTargetUid) { 7180 if (!Intent.isAccessUriMode(modeFlags)) { 7181 return -1; 7182 } 7183 7184 if (targetPkg != null) { 7185 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7186 "Checking grant " + targetPkg + " permission to " + grantUri); 7187 } 7188 7189 final IPackageManager pm = AppGlobals.getPackageManager(); 7190 7191 // If this is not a content: uri, we can't do anything with it. 7192 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7193 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7194 "Can't grant URI permission for non-content URI: " + grantUri); 7195 return -1; 7196 } 7197 7198 final String authority = grantUri.uri.getAuthority(); 7199 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7200 if (pi == null) { 7201 Slog.w(TAG, "No content provider found for permission check: " + 7202 grantUri.uri.toSafeString()); 7203 return -1; 7204 } 7205 7206 int targetUid = lastTargetUid; 7207 if (targetUid < 0 && targetPkg != null) { 7208 try { 7209 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7210 if (targetUid < 0) { 7211 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7212 "Can't grant URI permission no uid for: " + targetPkg); 7213 return -1; 7214 } 7215 } catch (RemoteException ex) { 7216 return -1; 7217 } 7218 } 7219 7220 if (targetUid >= 0) { 7221 // First... does the target actually need this permission? 7222 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7223 // No need to grant the target this permission. 7224 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7225 "Target " + targetPkg + " already has full permission to " + grantUri); 7226 return -1; 7227 } 7228 } else { 7229 // First... there is no target package, so can anyone access it? 7230 boolean allowed = pi.exported; 7231 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7232 if (pi.readPermission != null) { 7233 allowed = false; 7234 } 7235 } 7236 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7237 if (pi.writePermission != null) { 7238 allowed = false; 7239 } 7240 } 7241 if (allowed) { 7242 return -1; 7243 } 7244 } 7245 7246 /* There is a special cross user grant if: 7247 * - The target is on another user. 7248 * - Apps on the current user can access the uri without any uid permissions. 7249 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7250 * grant uri permissions. 7251 */ 7252 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7253 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7254 modeFlags, false /*without considering the uid permissions*/); 7255 7256 // Second... is the provider allowing granting of URI permissions? 7257 if (!specialCrossUserGrant) { 7258 if (!pi.grantUriPermissions) { 7259 throw new SecurityException("Provider " + pi.packageName 7260 + "/" + pi.name 7261 + " does not allow granting of Uri permissions (uri " 7262 + grantUri + ")"); 7263 } 7264 if (pi.uriPermissionPatterns != null) { 7265 final int N = pi.uriPermissionPatterns.length; 7266 boolean allowed = false; 7267 for (int i=0; i<N; i++) { 7268 if (pi.uriPermissionPatterns[i] != null 7269 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7270 allowed = true; 7271 break; 7272 } 7273 } 7274 if (!allowed) { 7275 throw new SecurityException("Provider " + pi.packageName 7276 + "/" + pi.name 7277 + " does not allow granting of permission to path of Uri " 7278 + grantUri); 7279 } 7280 } 7281 } 7282 7283 // Third... does the caller itself have permission to access 7284 // this uri? 7285 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7286 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7287 // Require they hold a strong enough Uri permission 7288 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7289 throw new SecurityException("Uid " + callingUid 7290 + " does not have permission to uri " + grantUri); 7291 } 7292 } 7293 } 7294 return targetUid; 7295 } 7296 7297 /** 7298 * @param uri This uri must NOT contain an embedded userId. 7299 * @param userId The userId in which the uri is to be resolved. 7300 */ 7301 @Override 7302 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7303 final int modeFlags, int userId) { 7304 enforceNotIsolatedCaller("checkGrantUriPermission"); 7305 synchronized(this) { 7306 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7307 new GrantUri(userId, uri, false), modeFlags, -1); 7308 } 7309 } 7310 7311 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7312 final int modeFlags, UriPermissionOwner owner) { 7313 if (!Intent.isAccessUriMode(modeFlags)) { 7314 return; 7315 } 7316 7317 // So here we are: the caller has the assumed permission 7318 // to the uri, and the target doesn't. Let's now give this to 7319 // the target. 7320 7321 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7322 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7323 7324 final String authority = grantUri.uri.getAuthority(); 7325 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7326 if (pi == null) { 7327 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7328 return; 7329 } 7330 7331 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7332 grantUri.prefix = true; 7333 } 7334 final UriPermission perm = findOrCreateUriPermissionLocked( 7335 pi.packageName, targetPkg, targetUid, grantUri); 7336 perm.grantModes(modeFlags, owner); 7337 } 7338 7339 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7340 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7341 if (targetPkg == null) { 7342 throw new NullPointerException("targetPkg"); 7343 } 7344 int targetUid; 7345 final IPackageManager pm = AppGlobals.getPackageManager(); 7346 try { 7347 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7348 } catch (RemoteException ex) { 7349 return; 7350 } 7351 7352 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7353 targetUid); 7354 if (targetUid < 0) { 7355 return; 7356 } 7357 7358 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7359 owner); 7360 } 7361 7362 static class NeededUriGrants extends ArrayList<GrantUri> { 7363 final String targetPkg; 7364 final int targetUid; 7365 final int flags; 7366 7367 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7368 this.targetPkg = targetPkg; 7369 this.targetUid = targetUid; 7370 this.flags = flags; 7371 } 7372 } 7373 7374 /** 7375 * Like checkGrantUriPermissionLocked, but takes an Intent. 7376 */ 7377 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7378 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7379 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7380 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7381 + " clip=" + (intent != null ? intent.getClipData() : null) 7382 + " from " + intent + "; flags=0x" 7383 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7384 7385 if (targetPkg == null) { 7386 throw new NullPointerException("targetPkg"); 7387 } 7388 7389 if (intent == null) { 7390 return null; 7391 } 7392 Uri data = intent.getData(); 7393 ClipData clip = intent.getClipData(); 7394 if (data == null && clip == null) { 7395 return null; 7396 } 7397 // Default userId for uris in the intent (if they don't specify it themselves) 7398 int contentUserHint = intent.getContentUserHint(); 7399 if (contentUserHint == UserHandle.USER_CURRENT) { 7400 contentUserHint = UserHandle.getUserId(callingUid); 7401 } 7402 final IPackageManager pm = AppGlobals.getPackageManager(); 7403 int targetUid; 7404 if (needed != null) { 7405 targetUid = needed.targetUid; 7406 } else { 7407 try { 7408 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7409 } catch (RemoteException ex) { 7410 return null; 7411 } 7412 if (targetUid < 0) { 7413 if (DEBUG_URI_PERMISSION) { 7414 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7415 + " on user " + targetUserId); 7416 } 7417 return null; 7418 } 7419 } 7420 if (data != null) { 7421 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7422 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7423 targetUid); 7424 if (targetUid > 0) { 7425 if (needed == null) { 7426 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7427 } 7428 needed.add(grantUri); 7429 } 7430 } 7431 if (clip != null) { 7432 for (int i=0; i<clip.getItemCount(); i++) { 7433 Uri uri = clip.getItemAt(i).getUri(); 7434 if (uri != null) { 7435 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7436 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7437 targetUid); 7438 if (targetUid > 0) { 7439 if (needed == null) { 7440 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7441 } 7442 needed.add(grantUri); 7443 } 7444 } else { 7445 Intent clipIntent = clip.getItemAt(i).getIntent(); 7446 if (clipIntent != null) { 7447 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7448 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7449 if (newNeeded != null) { 7450 needed = newNeeded; 7451 } 7452 } 7453 } 7454 } 7455 } 7456 7457 return needed; 7458 } 7459 7460 /** 7461 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7462 */ 7463 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7464 UriPermissionOwner owner) { 7465 if (needed != null) { 7466 for (int i=0; i<needed.size(); i++) { 7467 GrantUri grantUri = needed.get(i); 7468 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7469 grantUri, needed.flags, owner); 7470 } 7471 } 7472 } 7473 7474 void grantUriPermissionFromIntentLocked(int callingUid, 7475 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7476 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7477 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7478 if (needed == null) { 7479 return; 7480 } 7481 7482 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7483 } 7484 7485 /** 7486 * @param uri This uri must NOT contain an embedded userId. 7487 * @param userId The userId in which the uri is to be resolved. 7488 */ 7489 @Override 7490 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7491 final int modeFlags, int userId) { 7492 enforceNotIsolatedCaller("grantUriPermission"); 7493 GrantUri grantUri = new GrantUri(userId, uri, false); 7494 synchronized(this) { 7495 final ProcessRecord r = getRecordForAppLocked(caller); 7496 if (r == null) { 7497 throw new SecurityException("Unable to find app for caller " 7498 + caller 7499 + " when granting permission to uri " + grantUri); 7500 } 7501 if (targetPkg == null) { 7502 throw new IllegalArgumentException("null target"); 7503 } 7504 if (grantUri == null) { 7505 throw new IllegalArgumentException("null uri"); 7506 } 7507 7508 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7509 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7510 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7511 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7512 7513 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7514 UserHandle.getUserId(r.uid)); 7515 } 7516 } 7517 7518 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7519 if (perm.modeFlags == 0) { 7520 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7521 perm.targetUid); 7522 if (perms != null) { 7523 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7524 "Removing " + perm.targetUid + " permission to " + perm.uri); 7525 7526 perms.remove(perm.uri); 7527 if (perms.isEmpty()) { 7528 mGrantedUriPermissions.remove(perm.targetUid); 7529 } 7530 } 7531 } 7532 } 7533 7534 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7535 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7536 7537 final IPackageManager pm = AppGlobals.getPackageManager(); 7538 final String authority = grantUri.uri.getAuthority(); 7539 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7540 if (pi == null) { 7541 Slog.w(TAG, "No content provider found for permission revoke: " 7542 + grantUri.toSafeString()); 7543 return; 7544 } 7545 7546 // Does the caller have this permission on the URI? 7547 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7548 // If they don't have direct access to the URI, then revoke any 7549 // ownerless URI permissions that have been granted to them. 7550 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7551 if (perms != null) { 7552 boolean persistChanged = false; 7553 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7554 final UriPermission perm = it.next(); 7555 if (perm.uri.sourceUserId == grantUri.sourceUserId 7556 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7557 if (DEBUG_URI_PERMISSION) 7558 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7559 " permission to " + perm.uri); 7560 persistChanged |= perm.revokeModes( 7561 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7562 if (perm.modeFlags == 0) { 7563 it.remove(); 7564 } 7565 } 7566 } 7567 if (perms.isEmpty()) { 7568 mGrantedUriPermissions.remove(callingUid); 7569 } 7570 if (persistChanged) { 7571 schedulePersistUriGrants(); 7572 } 7573 } 7574 return; 7575 } 7576 7577 boolean persistChanged = false; 7578 7579 // Go through all of the permissions and remove any that match. 7580 int N = mGrantedUriPermissions.size(); 7581 for (int i = 0; i < N; i++) { 7582 final int targetUid = mGrantedUriPermissions.keyAt(i); 7583 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7584 7585 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7586 final UriPermission perm = it.next(); 7587 if (perm.uri.sourceUserId == grantUri.sourceUserId 7588 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7589 if (DEBUG_URI_PERMISSION) 7590 Slog.v(TAG, 7591 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7592 persistChanged |= perm.revokeModes( 7593 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7594 if (perm.modeFlags == 0) { 7595 it.remove(); 7596 } 7597 } 7598 } 7599 7600 if (perms.isEmpty()) { 7601 mGrantedUriPermissions.remove(targetUid); 7602 N--; 7603 i--; 7604 } 7605 } 7606 7607 if (persistChanged) { 7608 schedulePersistUriGrants(); 7609 } 7610 } 7611 7612 /** 7613 * @param uri This uri must NOT contain an embedded userId. 7614 * @param userId The userId in which the uri is to be resolved. 7615 */ 7616 @Override 7617 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7618 int userId) { 7619 enforceNotIsolatedCaller("revokeUriPermission"); 7620 synchronized(this) { 7621 final ProcessRecord r = getRecordForAppLocked(caller); 7622 if (r == null) { 7623 throw new SecurityException("Unable to find app for caller " 7624 + caller 7625 + " when revoking permission to uri " + uri); 7626 } 7627 if (uri == null) { 7628 Slog.w(TAG, "revokeUriPermission: null uri"); 7629 return; 7630 } 7631 7632 if (!Intent.isAccessUriMode(modeFlags)) { 7633 return; 7634 } 7635 7636 final IPackageManager pm = AppGlobals.getPackageManager(); 7637 final String authority = uri.getAuthority(); 7638 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7639 if (pi == null) { 7640 Slog.w(TAG, "No content provider found for permission revoke: " 7641 + uri.toSafeString()); 7642 return; 7643 } 7644 7645 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7646 } 7647 } 7648 7649 /** 7650 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7651 * given package. 7652 * 7653 * @param packageName Package name to match, or {@code null} to apply to all 7654 * packages. 7655 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7656 * to all users. 7657 * @param persistable If persistable grants should be removed. 7658 */ 7659 private void removeUriPermissionsForPackageLocked( 7660 String packageName, int userHandle, boolean persistable) { 7661 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7662 throw new IllegalArgumentException("Must narrow by either package or user"); 7663 } 7664 7665 boolean persistChanged = false; 7666 7667 int N = mGrantedUriPermissions.size(); 7668 for (int i = 0; i < N; i++) { 7669 final int targetUid = mGrantedUriPermissions.keyAt(i); 7670 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7671 7672 // Only inspect grants matching user 7673 if (userHandle == UserHandle.USER_ALL 7674 || userHandle == UserHandle.getUserId(targetUid)) { 7675 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7676 final UriPermission perm = it.next(); 7677 7678 // Only inspect grants matching package 7679 if (packageName == null || perm.sourcePkg.equals(packageName) 7680 || perm.targetPkg.equals(packageName)) { 7681 persistChanged |= perm.revokeModes(persistable 7682 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7683 7684 // Only remove when no modes remain; any persisted grants 7685 // will keep this alive. 7686 if (perm.modeFlags == 0) { 7687 it.remove(); 7688 } 7689 } 7690 } 7691 7692 if (perms.isEmpty()) { 7693 mGrantedUriPermissions.remove(targetUid); 7694 N--; 7695 i--; 7696 } 7697 } 7698 } 7699 7700 if (persistChanged) { 7701 schedulePersistUriGrants(); 7702 } 7703 } 7704 7705 @Override 7706 public IBinder newUriPermissionOwner(String name) { 7707 enforceNotIsolatedCaller("newUriPermissionOwner"); 7708 synchronized(this) { 7709 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7710 return owner.getExternalTokenLocked(); 7711 } 7712 } 7713 7714 /** 7715 * @param uri This uri must NOT contain an embedded userId. 7716 * @param sourceUserId The userId in which the uri is to be resolved. 7717 * @param targetUserId The userId of the app that receives the grant. 7718 */ 7719 @Override 7720 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7721 final int modeFlags, int sourceUserId, int targetUserId) { 7722 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7723 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7724 synchronized(this) { 7725 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7726 if (owner == null) { 7727 throw new IllegalArgumentException("Unknown owner: " + token); 7728 } 7729 if (fromUid != Binder.getCallingUid()) { 7730 if (Binder.getCallingUid() != Process.myUid()) { 7731 // Only system code can grant URI permissions on behalf 7732 // of other users. 7733 throw new SecurityException("nice try"); 7734 } 7735 } 7736 if (targetPkg == null) { 7737 throw new IllegalArgumentException("null target"); 7738 } 7739 if (uri == null) { 7740 throw new IllegalArgumentException("null uri"); 7741 } 7742 7743 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7744 modeFlags, owner, targetUserId); 7745 } 7746 } 7747 7748 /** 7749 * @param uri This uri must NOT contain an embedded userId. 7750 * @param userId The userId in which the uri is to be resolved. 7751 */ 7752 @Override 7753 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7754 synchronized(this) { 7755 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7756 if (owner == null) { 7757 throw new IllegalArgumentException("Unknown owner: " + token); 7758 } 7759 7760 if (uri == null) { 7761 owner.removeUriPermissionsLocked(mode); 7762 } else { 7763 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7764 } 7765 } 7766 } 7767 7768 private void schedulePersistUriGrants() { 7769 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7770 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7771 10 * DateUtils.SECOND_IN_MILLIS); 7772 } 7773 } 7774 7775 private void writeGrantedUriPermissions() { 7776 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7777 7778 // Snapshot permissions so we can persist without lock 7779 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7780 synchronized (this) { 7781 final int size = mGrantedUriPermissions.size(); 7782 for (int i = 0; i < size; i++) { 7783 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7784 for (UriPermission perm : perms.values()) { 7785 if (perm.persistedModeFlags != 0) { 7786 persist.add(perm.snapshot()); 7787 } 7788 } 7789 } 7790 } 7791 7792 FileOutputStream fos = null; 7793 try { 7794 fos = mGrantFile.startWrite(); 7795 7796 XmlSerializer out = new FastXmlSerializer(); 7797 out.setOutput(fos, "utf-8"); 7798 out.startDocument(null, true); 7799 out.startTag(null, TAG_URI_GRANTS); 7800 for (UriPermission.Snapshot perm : persist) { 7801 out.startTag(null, TAG_URI_GRANT); 7802 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7803 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7804 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7805 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7806 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7807 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7808 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7809 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7810 out.endTag(null, TAG_URI_GRANT); 7811 } 7812 out.endTag(null, TAG_URI_GRANTS); 7813 out.endDocument(); 7814 7815 mGrantFile.finishWrite(fos); 7816 } catch (IOException e) { 7817 if (fos != null) { 7818 mGrantFile.failWrite(fos); 7819 } 7820 } 7821 } 7822 7823 private void readGrantedUriPermissionsLocked() { 7824 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7825 7826 final long now = System.currentTimeMillis(); 7827 7828 FileInputStream fis = null; 7829 try { 7830 fis = mGrantFile.openRead(); 7831 final XmlPullParser in = Xml.newPullParser(); 7832 in.setInput(fis, null); 7833 7834 int type; 7835 while ((type = in.next()) != END_DOCUMENT) { 7836 final String tag = in.getName(); 7837 if (type == START_TAG) { 7838 if (TAG_URI_GRANT.equals(tag)) { 7839 final int sourceUserId; 7840 final int targetUserId; 7841 final int userHandle = readIntAttribute(in, 7842 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7843 if (userHandle != UserHandle.USER_NULL) { 7844 // For backwards compatibility. 7845 sourceUserId = userHandle; 7846 targetUserId = userHandle; 7847 } else { 7848 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7849 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7850 } 7851 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7852 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7853 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7854 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7855 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7856 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7857 7858 // Sanity check that provider still belongs to source package 7859 final ProviderInfo pi = getProviderInfoLocked( 7860 uri.getAuthority(), sourceUserId); 7861 if (pi != null && sourcePkg.equals(pi.packageName)) { 7862 int targetUid = -1; 7863 try { 7864 targetUid = AppGlobals.getPackageManager() 7865 .getPackageUid(targetPkg, targetUserId); 7866 } catch (RemoteException e) { 7867 } 7868 if (targetUid != -1) { 7869 final UriPermission perm = findOrCreateUriPermissionLocked( 7870 sourcePkg, targetPkg, targetUid, 7871 new GrantUri(sourceUserId, uri, prefix)); 7872 perm.initPersistedModes(modeFlags, createdTime); 7873 } 7874 } else { 7875 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7876 + " but instead found " + pi); 7877 } 7878 } 7879 } 7880 } 7881 } catch (FileNotFoundException e) { 7882 // Missing grants is okay 7883 } catch (IOException e) { 7884 Log.wtf(TAG, "Failed reading Uri grants", e); 7885 } catch (XmlPullParserException e) { 7886 Log.wtf(TAG, "Failed reading Uri grants", e); 7887 } finally { 7888 IoUtils.closeQuietly(fis); 7889 } 7890 } 7891 7892 /** 7893 * @param uri This uri must NOT contain an embedded userId. 7894 * @param userId The userId in which the uri is to be resolved. 7895 */ 7896 @Override 7897 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7898 enforceNotIsolatedCaller("takePersistableUriPermission"); 7899 7900 Preconditions.checkFlagsArgument(modeFlags, 7901 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7902 7903 synchronized (this) { 7904 final int callingUid = Binder.getCallingUid(); 7905 boolean persistChanged = false; 7906 GrantUri grantUri = new GrantUri(userId, uri, false); 7907 7908 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7909 new GrantUri(userId, uri, false)); 7910 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7911 new GrantUri(userId, uri, true)); 7912 7913 final boolean exactValid = (exactPerm != null) 7914 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7915 final boolean prefixValid = (prefixPerm != null) 7916 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7917 7918 if (!(exactValid || prefixValid)) { 7919 throw new SecurityException("No persistable permission grants found for UID " 7920 + callingUid + " and Uri " + grantUri.toSafeString()); 7921 } 7922 7923 if (exactValid) { 7924 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7925 } 7926 if (prefixValid) { 7927 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7928 } 7929 7930 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7931 7932 if (persistChanged) { 7933 schedulePersistUriGrants(); 7934 } 7935 } 7936 } 7937 7938 /** 7939 * @param uri This uri must NOT contain an embedded userId. 7940 * @param userId The userId in which the uri is to be resolved. 7941 */ 7942 @Override 7943 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7944 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7945 7946 Preconditions.checkFlagsArgument(modeFlags, 7947 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7948 7949 synchronized (this) { 7950 final int callingUid = Binder.getCallingUid(); 7951 boolean persistChanged = false; 7952 7953 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7954 new GrantUri(userId, uri, false)); 7955 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7956 new GrantUri(userId, uri, true)); 7957 if (exactPerm == null && prefixPerm == null) { 7958 throw new SecurityException("No permission grants found for UID " + callingUid 7959 + " and Uri " + uri.toSafeString()); 7960 } 7961 7962 if (exactPerm != null) { 7963 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7964 removeUriPermissionIfNeededLocked(exactPerm); 7965 } 7966 if (prefixPerm != null) { 7967 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7968 removeUriPermissionIfNeededLocked(prefixPerm); 7969 } 7970 7971 if (persistChanged) { 7972 schedulePersistUriGrants(); 7973 } 7974 } 7975 } 7976 7977 /** 7978 * Prune any older {@link UriPermission} for the given UID until outstanding 7979 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7980 * 7981 * @return if any mutations occured that require persisting. 7982 */ 7983 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7984 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7985 if (perms == null) return false; 7986 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7987 7988 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7989 for (UriPermission perm : perms.values()) { 7990 if (perm.persistedModeFlags != 0) { 7991 persisted.add(perm); 7992 } 7993 } 7994 7995 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7996 if (trimCount <= 0) return false; 7997 7998 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7999 for (int i = 0; i < trimCount; i++) { 8000 final UriPermission perm = persisted.get(i); 8001 8002 if (DEBUG_URI_PERMISSION) { 8003 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 8004 } 8005 8006 perm.releasePersistableModes(~0); 8007 removeUriPermissionIfNeededLocked(perm); 8008 } 8009 8010 return true; 8011 } 8012 8013 @Override 8014 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 8015 String packageName, boolean incoming) { 8016 enforceNotIsolatedCaller("getPersistedUriPermissions"); 8017 Preconditions.checkNotNull(packageName, "packageName"); 8018 8019 final int callingUid = Binder.getCallingUid(); 8020 final IPackageManager pm = AppGlobals.getPackageManager(); 8021 try { 8022 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 8023 if (packageUid != callingUid) { 8024 throw new SecurityException( 8025 "Package " + packageName + " does not belong to calling UID " + callingUid); 8026 } 8027 } catch (RemoteException e) { 8028 throw new SecurityException("Failed to verify package name ownership"); 8029 } 8030 8031 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 8032 synchronized (this) { 8033 if (incoming) { 8034 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 8035 callingUid); 8036 if (perms == null) { 8037 Slog.w(TAG, "No permission grants found for " + packageName); 8038 } else { 8039 for (UriPermission perm : perms.values()) { 8040 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 8041 result.add(perm.buildPersistedPublicApiObject()); 8042 } 8043 } 8044 } 8045 } else { 8046 final int size = mGrantedUriPermissions.size(); 8047 for (int i = 0; i < size; i++) { 8048 final ArrayMap<GrantUri, UriPermission> perms = 8049 mGrantedUriPermissions.valueAt(i); 8050 for (UriPermission perm : perms.values()) { 8051 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 8052 result.add(perm.buildPersistedPublicApiObject()); 8053 } 8054 } 8055 } 8056 } 8057 } 8058 return new ParceledListSlice<android.content.UriPermission>(result); 8059 } 8060 8061 @Override 8062 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 8063 synchronized (this) { 8064 ProcessRecord app = 8065 who != null ? getRecordForAppLocked(who) : null; 8066 if (app == null) return; 8067 8068 Message msg = Message.obtain(); 8069 msg.what = WAIT_FOR_DEBUGGER_MSG; 8070 msg.obj = app; 8071 msg.arg1 = waiting ? 1 : 0; 8072 mHandler.sendMessage(msg); 8073 } 8074 } 8075 8076 @Override 8077 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 8078 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 8079 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 8080 outInfo.availMem = Process.getFreeMemory(); 8081 outInfo.totalMem = Process.getTotalMemory(); 8082 outInfo.threshold = homeAppMem; 8083 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 8084 outInfo.hiddenAppThreshold = cachedAppMem; 8085 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 8086 ProcessList.SERVICE_ADJ); 8087 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 8088 ProcessList.VISIBLE_APP_ADJ); 8089 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 8090 ProcessList.FOREGROUND_APP_ADJ); 8091 } 8092 8093 // ========================================================= 8094 // TASK MANAGEMENT 8095 // ========================================================= 8096 8097 @Override 8098 public List<IAppTask> getAppTasks(String callingPackage) { 8099 int callingUid = Binder.getCallingUid(); 8100 long ident = Binder.clearCallingIdentity(); 8101 8102 synchronized(this) { 8103 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8104 try { 8105 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8106 8107 final int N = mRecentTasks.size(); 8108 for (int i = 0; i < N; i++) { 8109 TaskRecord tr = mRecentTasks.get(i); 8110 // Skip tasks that do not match the caller. We don't need to verify 8111 // callingPackage, because we are also limiting to callingUid and know 8112 // that will limit to the correct security sandbox. 8113 if (tr.effectiveUid != callingUid) { 8114 continue; 8115 } 8116 Intent intent = tr.getBaseIntent(); 8117 if (intent == null || 8118 !callingPackage.equals(intent.getComponent().getPackageName())) { 8119 continue; 8120 } 8121 ActivityManager.RecentTaskInfo taskInfo = 8122 createRecentTaskInfoFromTaskRecord(tr); 8123 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8124 list.add(taskImpl); 8125 } 8126 } finally { 8127 Binder.restoreCallingIdentity(ident); 8128 } 8129 return list; 8130 } 8131 } 8132 8133 @Override 8134 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8135 final int callingUid = Binder.getCallingUid(); 8136 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8137 8138 synchronized(this) { 8139 if (localLOGV) Slog.v( 8140 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8141 8142 final boolean allowed = checkCallingPermission( 8143 android.Manifest.permission.GET_TASKS) 8144 == PackageManager.PERMISSION_GRANTED; 8145 if (!allowed) { 8146 Slog.w(TAG, "getTasks: caller " + callingUid 8147 + " does not hold GET_TASKS; limiting output"); 8148 } 8149 8150 // TODO: Improve with MRU list from all ActivityStacks. 8151 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8152 } 8153 8154 return list; 8155 } 8156 8157 TaskRecord getMostRecentTask() { 8158 return mRecentTasks.get(0); 8159 } 8160 8161 /** 8162 * Creates a new RecentTaskInfo from a TaskRecord. 8163 */ 8164 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8165 // Update the task description to reflect any changes in the task stack 8166 tr.updateTaskDescription(); 8167 8168 // Compose the recent task info 8169 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8170 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8171 rti.persistentId = tr.taskId; 8172 rti.baseIntent = new Intent(tr.getBaseIntent()); 8173 rti.origActivity = tr.origActivity; 8174 rti.description = tr.lastDescription; 8175 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8176 rti.userId = tr.userId; 8177 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8178 rti.firstActiveTime = tr.firstActiveTime; 8179 rti.lastActiveTime = tr.lastActiveTime; 8180 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8181 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8182 return rti; 8183 } 8184 8185 @Override 8186 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8187 final int callingUid = Binder.getCallingUid(); 8188 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8189 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8190 8191 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8192 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8193 synchronized (this) { 8194 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 8195 == PackageManager.PERMISSION_GRANTED; 8196 if (!allowed) { 8197 Slog.w(TAG, "getRecentTasks: caller " + callingUid 8198 + " does not hold GET_TASKS; limiting output"); 8199 } 8200 final boolean detailed = checkCallingPermission( 8201 android.Manifest.permission.GET_DETAILED_TASKS) 8202 == PackageManager.PERMISSION_GRANTED; 8203 8204 final int N = mRecentTasks.size(); 8205 ArrayList<ActivityManager.RecentTaskInfo> res 8206 = new ArrayList<ActivityManager.RecentTaskInfo>( 8207 maxNum < N ? maxNum : N); 8208 8209 final Set<Integer> includedUsers; 8210 if (includeProfiles) { 8211 includedUsers = getProfileIdsLocked(userId); 8212 } else { 8213 includedUsers = new HashSet<Integer>(); 8214 } 8215 includedUsers.add(Integer.valueOf(userId)); 8216 8217 for (int i=0; i<N && maxNum > 0; i++) { 8218 TaskRecord tr = mRecentTasks.get(i); 8219 // Only add calling user or related users recent tasks 8220 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8221 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8222 continue; 8223 } 8224 8225 // Return the entry if desired by the caller. We always return 8226 // the first entry, because callers always expect this to be the 8227 // foreground app. We may filter others if the caller has 8228 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8229 // we should exclude the entry. 8230 8231 if (i == 0 8232 || withExcluded 8233 || (tr.intent == null) 8234 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8235 == 0)) { 8236 if (!allowed) { 8237 // If the caller doesn't have the GET_TASKS permission, then only 8238 // allow them to see a small subset of tasks -- their own and home. 8239 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8240 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8241 continue; 8242 } 8243 } 8244 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8245 if (tr.stack != null && tr.stack.isHomeStack()) { 8246 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8247 continue; 8248 } 8249 } 8250 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8251 // Don't include auto remove tasks that are finished or finishing. 8252 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8253 + tr); 8254 continue; 8255 } 8256 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8257 && !tr.isAvailable) { 8258 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8259 continue; 8260 } 8261 8262 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8263 if (!detailed) { 8264 rti.baseIntent.replaceExtras((Bundle)null); 8265 } 8266 8267 res.add(rti); 8268 maxNum--; 8269 } 8270 } 8271 return res; 8272 } 8273 } 8274 8275 private TaskRecord recentTaskForIdLocked(int id) { 8276 final int N = mRecentTasks.size(); 8277 for (int i=0; i<N; i++) { 8278 TaskRecord tr = mRecentTasks.get(i); 8279 if (tr.taskId == id) { 8280 return tr; 8281 } 8282 } 8283 return null; 8284 } 8285 8286 @Override 8287 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8288 synchronized (this) { 8289 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8290 "getTaskThumbnail()"); 8291 TaskRecord tr = recentTaskForIdLocked(id); 8292 if (tr != null) { 8293 return tr.getTaskThumbnailLocked(); 8294 } 8295 } 8296 return null; 8297 } 8298 8299 @Override 8300 public int addAppTask(IBinder activityToken, Intent intent, 8301 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8302 final int callingUid = Binder.getCallingUid(); 8303 final long callingIdent = Binder.clearCallingIdentity(); 8304 8305 try { 8306 synchronized (this) { 8307 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8308 if (r == null) { 8309 throw new IllegalArgumentException("Activity does not exist; token=" 8310 + activityToken); 8311 } 8312 ComponentName comp = intent.getComponent(); 8313 if (comp == null) { 8314 throw new IllegalArgumentException("Intent " + intent 8315 + " must specify explicit component"); 8316 } 8317 if (thumbnail.getWidth() != mThumbnailWidth 8318 || thumbnail.getHeight() != mThumbnailHeight) { 8319 throw new IllegalArgumentException("Bad thumbnail size: got " 8320 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8321 + mThumbnailWidth + "x" + mThumbnailHeight); 8322 } 8323 if (intent.getSelector() != null) { 8324 intent.setSelector(null); 8325 } 8326 if (intent.getSourceBounds() != null) { 8327 intent.setSourceBounds(null); 8328 } 8329 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8330 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8331 // The caller has added this as an auto-remove task... that makes no 8332 // sense, so turn off auto-remove. 8333 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8334 } 8335 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8336 // Must be a new task. 8337 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8338 } 8339 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8340 mLastAddedTaskActivity = null; 8341 } 8342 ActivityInfo ainfo = mLastAddedTaskActivity; 8343 if (ainfo == null) { 8344 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8345 comp, 0, UserHandle.getUserId(callingUid)); 8346 if (ainfo.applicationInfo.uid != callingUid) { 8347 throw new SecurityException( 8348 "Can't add task for another application: target uid=" 8349 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8350 } 8351 } 8352 8353 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8354 intent, description); 8355 8356 int trimIdx = trimRecentsForTask(task, false); 8357 if (trimIdx >= 0) { 8358 // If this would have caused a trim, then we'll abort because that 8359 // means it would be added at the end of the list but then just removed. 8360 return -1; 8361 } 8362 8363 final int N = mRecentTasks.size(); 8364 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8365 final TaskRecord tr = mRecentTasks.remove(N - 1); 8366 tr.removedFromRecents(mTaskPersister); 8367 } 8368 8369 task.inRecents = true; 8370 mRecentTasks.add(task); 8371 r.task.stack.addTask(task, false, false); 8372 8373 task.setLastThumbnail(thumbnail); 8374 task.freeLastThumbnail(); 8375 8376 return task.taskId; 8377 } 8378 } finally { 8379 Binder.restoreCallingIdentity(callingIdent); 8380 } 8381 } 8382 8383 @Override 8384 public Point getAppTaskThumbnailSize() { 8385 synchronized (this) { 8386 return new Point(mThumbnailWidth, mThumbnailHeight); 8387 } 8388 } 8389 8390 @Override 8391 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8392 synchronized (this) { 8393 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8394 if (r != null) { 8395 r.setTaskDescription(td); 8396 r.task.updateTaskDescription(); 8397 } 8398 } 8399 } 8400 8401 @Override 8402 public Bitmap getTaskDescriptionIcon(String filename) { 8403 if (!FileUtils.isValidExtFilename(filename) 8404 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8405 throw new IllegalArgumentException("Bad filename: " + filename); 8406 } 8407 return mTaskPersister.getTaskDescriptionIcon(filename); 8408 } 8409 8410 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8411 mRecentTasks.remove(tr); 8412 tr.removedFromRecents(mTaskPersister); 8413 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8414 Intent baseIntent = new Intent( 8415 tr.intent != null ? tr.intent : tr.affinityIntent); 8416 ComponentName component = baseIntent.getComponent(); 8417 if (component == null) { 8418 Slog.w(TAG, "Now component for base intent of task: " + tr); 8419 return; 8420 } 8421 8422 // Find any running services associated with this app. 8423 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8424 8425 if (killProcesses) { 8426 // Find any running processes associated with this app. 8427 final String pkg = component.getPackageName(); 8428 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8429 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8430 for (int i=0; i<pmap.size(); i++) { 8431 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8432 for (int j=0; j<uids.size(); j++) { 8433 ProcessRecord proc = uids.valueAt(j); 8434 if (proc.userId != tr.userId) { 8435 continue; 8436 } 8437 if (!proc.pkgList.containsKey(pkg)) { 8438 continue; 8439 } 8440 procs.add(proc); 8441 } 8442 } 8443 8444 // Kill the running processes. 8445 for (int i=0; i<procs.size(); i++) { 8446 ProcessRecord pr = procs.get(i); 8447 if (pr == mHomeProcess) { 8448 // Don't kill the home process along with tasks from the same package. 8449 continue; 8450 } 8451 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8452 pr.kill("remove task", true); 8453 } else { 8454 pr.waitingToKill = "remove task"; 8455 } 8456 } 8457 } 8458 } 8459 8460 /** 8461 * Removes the task with the specified task id. 8462 * 8463 * @param taskId Identifier of the task to be removed. 8464 * @param flags Additional operational flags. May be 0 or 8465 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8466 * @return Returns true if the given task was found and removed. 8467 */ 8468 private boolean removeTaskByIdLocked(int taskId, int flags) { 8469 TaskRecord tr = recentTaskForIdLocked(taskId); 8470 if (tr != null) { 8471 tr.removeTaskActivitiesLocked(); 8472 cleanUpRemovedTaskLocked(tr, flags); 8473 if (tr.isPersistable) { 8474 notifyTaskPersisterLocked(null, true); 8475 } 8476 return true; 8477 } 8478 return false; 8479 } 8480 8481 @Override 8482 public boolean removeTask(int taskId, int flags) { 8483 synchronized (this) { 8484 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8485 "removeTask()"); 8486 long ident = Binder.clearCallingIdentity(); 8487 try { 8488 return removeTaskByIdLocked(taskId, flags); 8489 } finally { 8490 Binder.restoreCallingIdentity(ident); 8491 } 8492 } 8493 } 8494 8495 /** 8496 * TODO: Add mController hook 8497 */ 8498 @Override 8499 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8500 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8501 "moveTaskToFront()"); 8502 8503 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8504 synchronized(this) { 8505 moveTaskToFrontLocked(taskId, flags, options); 8506 } 8507 } 8508 8509 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8510 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8511 Binder.getCallingUid(), -1, -1, "Task to front")) { 8512 ActivityOptions.abort(options); 8513 return; 8514 } 8515 final long origId = Binder.clearCallingIdentity(); 8516 try { 8517 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8518 if (task == null) { 8519 return; 8520 } 8521 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8522 mStackSupervisor.showLockTaskToast(); 8523 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8524 return; 8525 } 8526 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8527 if (prev != null && prev.isRecentsActivity()) { 8528 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8529 } 8530 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8531 } finally { 8532 Binder.restoreCallingIdentity(origId); 8533 } 8534 ActivityOptions.abort(options); 8535 } 8536 8537 @Override 8538 public void moveTaskToBack(int taskId) { 8539 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8540 "moveTaskToBack()"); 8541 8542 synchronized(this) { 8543 TaskRecord tr = recentTaskForIdLocked(taskId); 8544 if (tr != null) { 8545 if (tr == mStackSupervisor.mLockTaskModeTask) { 8546 mStackSupervisor.showLockTaskToast(); 8547 return; 8548 } 8549 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8550 ActivityStack stack = tr.stack; 8551 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8552 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8553 Binder.getCallingUid(), -1, -1, "Task to back")) { 8554 return; 8555 } 8556 } 8557 final long origId = Binder.clearCallingIdentity(); 8558 try { 8559 stack.moveTaskToBackLocked(taskId, null); 8560 } finally { 8561 Binder.restoreCallingIdentity(origId); 8562 } 8563 } 8564 } 8565 } 8566 8567 /** 8568 * Moves an activity, and all of the other activities within the same task, to the bottom 8569 * of the history stack. The activity's order within the task is unchanged. 8570 * 8571 * @param token A reference to the activity we wish to move 8572 * @param nonRoot If false then this only works if the activity is the root 8573 * of a task; if true it will work for any activity in a task. 8574 * @return Returns true if the move completed, false if not. 8575 */ 8576 @Override 8577 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8578 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8579 synchronized(this) { 8580 final long origId = Binder.clearCallingIdentity(); 8581 try { 8582 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8583 if (taskId >= 0) { 8584 if ((mStackSupervisor.mLockTaskModeTask != null) 8585 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8586 mStackSupervisor.showLockTaskToast(); 8587 return false; 8588 } 8589 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8590 } 8591 } finally { 8592 Binder.restoreCallingIdentity(origId); 8593 } 8594 } 8595 return false; 8596 } 8597 8598 @Override 8599 public void moveTaskBackwards(int task) { 8600 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8601 "moveTaskBackwards()"); 8602 8603 synchronized(this) { 8604 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8605 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8606 return; 8607 } 8608 final long origId = Binder.clearCallingIdentity(); 8609 moveTaskBackwardsLocked(task); 8610 Binder.restoreCallingIdentity(origId); 8611 } 8612 } 8613 8614 private final void moveTaskBackwardsLocked(int task) { 8615 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8616 } 8617 8618 @Override 8619 public IBinder getHomeActivityToken() throws RemoteException { 8620 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8621 "getHomeActivityToken()"); 8622 synchronized (this) { 8623 return mStackSupervisor.getHomeActivityToken(); 8624 } 8625 } 8626 8627 @Override 8628 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8629 IActivityContainerCallback callback) throws RemoteException { 8630 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8631 "createActivityContainer()"); 8632 synchronized (this) { 8633 if (parentActivityToken == null) { 8634 throw new IllegalArgumentException("parent token must not be null"); 8635 } 8636 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8637 if (r == null) { 8638 return null; 8639 } 8640 if (callback == null) { 8641 throw new IllegalArgumentException("callback must not be null"); 8642 } 8643 return mStackSupervisor.createActivityContainer(r, callback); 8644 } 8645 } 8646 8647 @Override 8648 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8649 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8650 "deleteActivityContainer()"); 8651 synchronized (this) { 8652 mStackSupervisor.deleteActivityContainer(container); 8653 } 8654 } 8655 8656 @Override 8657 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8658 throws RemoteException { 8659 synchronized (this) { 8660 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8661 if (stack != null) { 8662 return stack.mActivityContainer; 8663 } 8664 return null; 8665 } 8666 } 8667 8668 @Override 8669 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8670 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8671 "moveTaskToStack()"); 8672 if (stackId == HOME_STACK_ID) { 8673 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8674 new RuntimeException("here").fillInStackTrace()); 8675 } 8676 synchronized (this) { 8677 long ident = Binder.clearCallingIdentity(); 8678 try { 8679 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8680 + stackId + " toTop=" + toTop); 8681 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8682 } finally { 8683 Binder.restoreCallingIdentity(ident); 8684 } 8685 } 8686 } 8687 8688 @Override 8689 public void resizeStack(int stackBoxId, Rect bounds) { 8690 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8691 "resizeStackBox()"); 8692 long ident = Binder.clearCallingIdentity(); 8693 try { 8694 mWindowManager.resizeStack(stackBoxId, bounds); 8695 } finally { 8696 Binder.restoreCallingIdentity(ident); 8697 } 8698 } 8699 8700 @Override 8701 public List<StackInfo> getAllStackInfos() { 8702 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8703 "getAllStackInfos()"); 8704 long ident = Binder.clearCallingIdentity(); 8705 try { 8706 synchronized (this) { 8707 return mStackSupervisor.getAllStackInfosLocked(); 8708 } 8709 } finally { 8710 Binder.restoreCallingIdentity(ident); 8711 } 8712 } 8713 8714 @Override 8715 public StackInfo getStackInfo(int stackId) { 8716 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8717 "getStackInfo()"); 8718 long ident = Binder.clearCallingIdentity(); 8719 try { 8720 synchronized (this) { 8721 return mStackSupervisor.getStackInfoLocked(stackId); 8722 } 8723 } finally { 8724 Binder.restoreCallingIdentity(ident); 8725 } 8726 } 8727 8728 @Override 8729 public boolean isInHomeStack(int taskId) { 8730 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8731 "getStackInfo()"); 8732 long ident = Binder.clearCallingIdentity(); 8733 try { 8734 synchronized (this) { 8735 TaskRecord tr = recentTaskForIdLocked(taskId); 8736 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8737 } 8738 } finally { 8739 Binder.restoreCallingIdentity(ident); 8740 } 8741 } 8742 8743 @Override 8744 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8745 synchronized(this) { 8746 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8747 } 8748 } 8749 8750 private boolean isLockTaskAuthorized(String pkg) { 8751 final DevicePolicyManager dpm = (DevicePolicyManager) 8752 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8753 try { 8754 int uid = mContext.getPackageManager().getPackageUid(pkg, 8755 Binder.getCallingUserHandle().getIdentifier()); 8756 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8757 } catch (NameNotFoundException e) { 8758 return false; 8759 } 8760 } 8761 8762 void startLockTaskMode(TaskRecord task) { 8763 final String pkg; 8764 synchronized (this) { 8765 pkg = task.intent.getComponent().getPackageName(); 8766 } 8767 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8768 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8769 final TaskRecord taskRecord = task; 8770 mHandler.post(new Runnable() { 8771 @Override 8772 public void run() { 8773 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8774 } 8775 }); 8776 return; 8777 } 8778 long ident = Binder.clearCallingIdentity(); 8779 try { 8780 synchronized (this) { 8781 // Since we lost lock on task, make sure it is still there. 8782 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8783 if (task != null) { 8784 if (!isSystemInitiated 8785 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8786 throw new IllegalArgumentException("Invalid task, not in foreground"); 8787 } 8788 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8789 } 8790 } 8791 } finally { 8792 Binder.restoreCallingIdentity(ident); 8793 } 8794 } 8795 8796 @Override 8797 public void startLockTaskMode(int taskId) { 8798 final TaskRecord task; 8799 long ident = Binder.clearCallingIdentity(); 8800 try { 8801 synchronized (this) { 8802 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8803 } 8804 } finally { 8805 Binder.restoreCallingIdentity(ident); 8806 } 8807 if (task != null) { 8808 startLockTaskMode(task); 8809 } 8810 } 8811 8812 @Override 8813 public void startLockTaskMode(IBinder token) { 8814 final TaskRecord task; 8815 long ident = Binder.clearCallingIdentity(); 8816 try { 8817 synchronized (this) { 8818 final ActivityRecord r = ActivityRecord.forToken(token); 8819 if (r == null) { 8820 return; 8821 } 8822 task = r.task; 8823 } 8824 } finally { 8825 Binder.restoreCallingIdentity(ident); 8826 } 8827 if (task != null) { 8828 startLockTaskMode(task); 8829 } 8830 } 8831 8832 @Override 8833 public void startLockTaskModeOnCurrent() throws RemoteException { 8834 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8835 "startLockTaskModeOnCurrent"); 8836 ActivityRecord r = null; 8837 synchronized (this) { 8838 r = mStackSupervisor.topRunningActivityLocked(); 8839 } 8840 startLockTaskMode(r.task); 8841 } 8842 8843 @Override 8844 public void stopLockTaskMode() { 8845 // Verify that the user matches the package of the intent for the TaskRecord 8846 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8847 // and stopLockTaskMode. 8848 final int callingUid = Binder.getCallingUid(); 8849 if (callingUid != Process.SYSTEM_UID) { 8850 try { 8851 String pkg = 8852 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8853 int uid = mContext.getPackageManager().getPackageUid(pkg, 8854 Binder.getCallingUserHandle().getIdentifier()); 8855 if (uid != callingUid) { 8856 throw new SecurityException("Invalid uid, expected " + uid); 8857 } 8858 } catch (NameNotFoundException e) { 8859 Log.d(TAG, "stopLockTaskMode " + e); 8860 return; 8861 } 8862 } 8863 long ident = Binder.clearCallingIdentity(); 8864 try { 8865 Log.d(TAG, "stopLockTaskMode"); 8866 // Stop lock task 8867 synchronized (this) { 8868 mStackSupervisor.setLockTaskModeLocked(null, false); 8869 } 8870 } finally { 8871 Binder.restoreCallingIdentity(ident); 8872 } 8873 } 8874 8875 @Override 8876 public void stopLockTaskModeOnCurrent() throws RemoteException { 8877 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8878 "stopLockTaskModeOnCurrent"); 8879 long ident = Binder.clearCallingIdentity(); 8880 try { 8881 stopLockTaskMode(); 8882 } finally { 8883 Binder.restoreCallingIdentity(ident); 8884 } 8885 } 8886 8887 @Override 8888 public boolean isInLockTaskMode() { 8889 synchronized (this) { 8890 return mStackSupervisor.isInLockTaskMode(); 8891 } 8892 } 8893 8894 // ========================================================= 8895 // CONTENT PROVIDERS 8896 // ========================================================= 8897 8898 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8899 List<ProviderInfo> providers = null; 8900 try { 8901 providers = AppGlobals.getPackageManager(). 8902 queryContentProviders(app.processName, app.uid, 8903 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8904 } catch (RemoteException ex) { 8905 } 8906 if (DEBUG_MU) 8907 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8908 int userId = app.userId; 8909 if (providers != null) { 8910 int N = providers.size(); 8911 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8912 for (int i=0; i<N; i++) { 8913 ProviderInfo cpi = 8914 (ProviderInfo)providers.get(i); 8915 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8916 cpi.name, cpi.flags); 8917 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8918 // This is a singleton provider, but a user besides the 8919 // default user is asking to initialize a process it runs 8920 // in... well, no, it doesn't actually run in this process, 8921 // it runs in the process of the default user. Get rid of it. 8922 providers.remove(i); 8923 N--; 8924 i--; 8925 continue; 8926 } 8927 8928 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8929 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8930 if (cpr == null) { 8931 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8932 mProviderMap.putProviderByClass(comp, cpr); 8933 } 8934 if (DEBUG_MU) 8935 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8936 app.pubProviders.put(cpi.name, cpr); 8937 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8938 // Don't add this if it is a platform component that is marked 8939 // to run in multiple processes, because this is actually 8940 // part of the framework so doesn't make sense to track as a 8941 // separate apk in the process. 8942 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8943 mProcessStats); 8944 } 8945 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8946 } 8947 } 8948 return providers; 8949 } 8950 8951 /** 8952 * Check if {@link ProcessRecord} has a possible chance at accessing the 8953 * given {@link ProviderInfo}. Final permission checking is always done 8954 * in {@link ContentProvider}. 8955 */ 8956 private final String checkContentProviderPermissionLocked( 8957 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8958 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8959 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8960 boolean checkedGrants = false; 8961 if (checkUser) { 8962 // Looking for cross-user grants before enforcing the typical cross-users permissions 8963 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8964 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8965 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8966 return null; 8967 } 8968 checkedGrants = true; 8969 } 8970 userId = handleIncomingUser(callingPid, callingUid, userId, 8971 false, ALLOW_NON_FULL, 8972 "checkContentProviderPermissionLocked " + cpi.authority, null); 8973 if (userId != tmpTargetUserId) { 8974 // When we actually went to determine the final targer user ID, this ended 8975 // up different than our initial check for the authority. This is because 8976 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8977 // SELF. So we need to re-check the grants again. 8978 checkedGrants = false; 8979 } 8980 } 8981 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8982 cpi.applicationInfo.uid, cpi.exported) 8983 == PackageManager.PERMISSION_GRANTED) { 8984 return null; 8985 } 8986 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8987 cpi.applicationInfo.uid, cpi.exported) 8988 == PackageManager.PERMISSION_GRANTED) { 8989 return null; 8990 } 8991 8992 PathPermission[] pps = cpi.pathPermissions; 8993 if (pps != null) { 8994 int i = pps.length; 8995 while (i > 0) { 8996 i--; 8997 PathPermission pp = pps[i]; 8998 String pprperm = pp.getReadPermission(); 8999 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 9000 cpi.applicationInfo.uid, cpi.exported) 9001 == PackageManager.PERMISSION_GRANTED) { 9002 return null; 9003 } 9004 String ppwperm = pp.getWritePermission(); 9005 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 9006 cpi.applicationInfo.uid, cpi.exported) 9007 == PackageManager.PERMISSION_GRANTED) { 9008 return null; 9009 } 9010 } 9011 } 9012 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 9013 return null; 9014 } 9015 9016 String msg; 9017 if (!cpi.exported) { 9018 msg = "Permission Denial: opening provider " + cpi.name 9019 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9020 + ", uid=" + callingUid + ") that is not exported from uid " 9021 + cpi.applicationInfo.uid; 9022 } else { 9023 msg = "Permission Denial: opening provider " + cpi.name 9024 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9025 + ", uid=" + callingUid + ") requires " 9026 + cpi.readPermission + " or " + cpi.writePermission; 9027 } 9028 Slog.w(TAG, msg); 9029 return msg; 9030 } 9031 9032 /** 9033 * Returns if the ContentProvider has granted a uri to callingUid 9034 */ 9035 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9036 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9037 if (perms != null) { 9038 for (int i=perms.size()-1; i>=0; i--) { 9039 GrantUri grantUri = perms.keyAt(i); 9040 if (grantUri.sourceUserId == userId || !checkUser) { 9041 if (matchesProvider(grantUri.uri, cpi)) { 9042 return true; 9043 } 9044 } 9045 } 9046 } 9047 return false; 9048 } 9049 9050 /** 9051 * Returns true if the uri authority is one of the authorities specified in the provider. 9052 */ 9053 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9054 String uriAuth = uri.getAuthority(); 9055 String cpiAuth = cpi.authority; 9056 if (cpiAuth.indexOf(';') == -1) { 9057 return cpiAuth.equals(uriAuth); 9058 } 9059 String[] cpiAuths = cpiAuth.split(";"); 9060 int length = cpiAuths.length; 9061 for (int i = 0; i < length; i++) { 9062 if (cpiAuths[i].equals(uriAuth)) return true; 9063 } 9064 return false; 9065 } 9066 9067 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9068 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9069 if (r != null) { 9070 for (int i=0; i<r.conProviders.size(); i++) { 9071 ContentProviderConnection conn = r.conProviders.get(i); 9072 if (conn.provider == cpr) { 9073 if (DEBUG_PROVIDER) Slog.v(TAG, 9074 "Adding provider requested by " 9075 + r.processName + " from process " 9076 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9077 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9078 if (stable) { 9079 conn.stableCount++; 9080 conn.numStableIncs++; 9081 } else { 9082 conn.unstableCount++; 9083 conn.numUnstableIncs++; 9084 } 9085 return conn; 9086 } 9087 } 9088 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9089 if (stable) { 9090 conn.stableCount = 1; 9091 conn.numStableIncs = 1; 9092 } else { 9093 conn.unstableCount = 1; 9094 conn.numUnstableIncs = 1; 9095 } 9096 cpr.connections.add(conn); 9097 r.conProviders.add(conn); 9098 return conn; 9099 } 9100 cpr.addExternalProcessHandleLocked(externalProcessToken); 9101 return null; 9102 } 9103 9104 boolean decProviderCountLocked(ContentProviderConnection conn, 9105 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9106 if (conn != null) { 9107 cpr = conn.provider; 9108 if (DEBUG_PROVIDER) Slog.v(TAG, 9109 "Removing provider requested by " 9110 + conn.client.processName + " from process " 9111 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9112 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9113 if (stable) { 9114 conn.stableCount--; 9115 } else { 9116 conn.unstableCount--; 9117 } 9118 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9119 cpr.connections.remove(conn); 9120 conn.client.conProviders.remove(conn); 9121 return true; 9122 } 9123 return false; 9124 } 9125 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9126 return false; 9127 } 9128 9129 private void checkTime(long startTime, String where) { 9130 long now = SystemClock.elapsedRealtime(); 9131 if ((now-startTime) > 1000) { 9132 // If we are taking more than a second, log about it. 9133 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9134 } 9135 } 9136 9137 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9138 String name, IBinder token, boolean stable, int userId) { 9139 ContentProviderRecord cpr; 9140 ContentProviderConnection conn = null; 9141 ProviderInfo cpi = null; 9142 9143 synchronized(this) { 9144 long startTime = SystemClock.elapsedRealtime(); 9145 9146 ProcessRecord r = null; 9147 if (caller != null) { 9148 r = getRecordForAppLocked(caller); 9149 if (r == null) { 9150 throw new SecurityException( 9151 "Unable to find app for caller " + caller 9152 + " (pid=" + Binder.getCallingPid() 9153 + ") when getting content provider " + name); 9154 } 9155 } 9156 9157 boolean checkCrossUser = true; 9158 9159 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9160 9161 // First check if this content provider has been published... 9162 cpr = mProviderMap.getProviderByName(name, userId); 9163 // If that didn't work, check if it exists for user 0 and then 9164 // verify that it's a singleton provider before using it. 9165 if (cpr == null && userId != UserHandle.USER_OWNER) { 9166 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9167 if (cpr != null) { 9168 cpi = cpr.info; 9169 if (isSingleton(cpi.processName, cpi.applicationInfo, 9170 cpi.name, cpi.flags) 9171 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9172 userId = UserHandle.USER_OWNER; 9173 checkCrossUser = false; 9174 } else { 9175 cpr = null; 9176 cpi = null; 9177 } 9178 } 9179 } 9180 9181 boolean providerRunning = cpr != null; 9182 if (providerRunning) { 9183 cpi = cpr.info; 9184 String msg; 9185 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9186 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9187 != null) { 9188 throw new SecurityException(msg); 9189 } 9190 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9191 9192 if (r != null && cpr.canRunHere(r)) { 9193 // This provider has been published or is in the process 9194 // of being published... but it is also allowed to run 9195 // in the caller's process, so don't make a connection 9196 // and just let the caller instantiate its own instance. 9197 ContentProviderHolder holder = cpr.newHolder(null); 9198 // don't give caller the provider object, it needs 9199 // to make its own. 9200 holder.provider = null; 9201 return holder; 9202 } 9203 9204 final long origId = Binder.clearCallingIdentity(); 9205 9206 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9207 9208 // In this case the provider instance already exists, so we can 9209 // return it right away. 9210 conn = incProviderCountLocked(r, cpr, token, stable); 9211 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9212 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9213 // If this is a perceptible app accessing the provider, 9214 // make sure to count it as being accessed and thus 9215 // back up on the LRU list. This is good because 9216 // content providers are often expensive to start. 9217 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9218 updateLruProcessLocked(cpr.proc, false, null); 9219 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9220 } 9221 } 9222 9223 if (cpr.proc != null) { 9224 if (false) { 9225 if (cpr.name.flattenToShortString().equals( 9226 "com.android.providers.calendar/.CalendarProvider2")) { 9227 Slog.v(TAG, "****************** KILLING " 9228 + cpr.name.flattenToShortString()); 9229 Process.killProcess(cpr.proc.pid); 9230 } 9231 } 9232 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9233 boolean success = updateOomAdjLocked(cpr.proc); 9234 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9235 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9236 // NOTE: there is still a race here where a signal could be 9237 // pending on the process even though we managed to update its 9238 // adj level. Not sure what to do about this, but at least 9239 // the race is now smaller. 9240 if (!success) { 9241 // Uh oh... it looks like the provider's process 9242 // has been killed on us. We need to wait for a new 9243 // process to be started, and make sure its death 9244 // doesn't kill our process. 9245 Slog.i(TAG, 9246 "Existing provider " + cpr.name.flattenToShortString() 9247 + " is crashing; detaching " + r); 9248 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9249 checkTime(startTime, "getContentProviderImpl: before appDied"); 9250 appDiedLocked(cpr.proc); 9251 checkTime(startTime, "getContentProviderImpl: after appDied"); 9252 if (!lastRef) { 9253 // This wasn't the last ref our process had on 9254 // the provider... we have now been killed, bail. 9255 return null; 9256 } 9257 providerRunning = false; 9258 conn = null; 9259 } 9260 } 9261 9262 Binder.restoreCallingIdentity(origId); 9263 } 9264 9265 boolean singleton; 9266 if (!providerRunning) { 9267 try { 9268 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9269 cpi = AppGlobals.getPackageManager(). 9270 resolveContentProvider(name, 9271 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9272 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9273 } catch (RemoteException ex) { 9274 } 9275 if (cpi == null) { 9276 return null; 9277 } 9278 // If the provider is a singleton AND 9279 // (it's a call within the same user || the provider is a 9280 // privileged app) 9281 // Then allow connecting to the singleton provider 9282 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9283 cpi.name, cpi.flags) 9284 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9285 if (singleton) { 9286 userId = UserHandle.USER_OWNER; 9287 } 9288 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9289 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9290 9291 String msg; 9292 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9293 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9294 != null) { 9295 throw new SecurityException(msg); 9296 } 9297 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9298 9299 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9300 && !cpi.processName.equals("system")) { 9301 // If this content provider does not run in the system 9302 // process, and the system is not yet ready to run other 9303 // processes, then fail fast instead of hanging. 9304 throw new IllegalArgumentException( 9305 "Attempt to launch content provider before system ready"); 9306 } 9307 9308 // Make sure that the user who owns this provider is started. If not, 9309 // we don't want to allow it to run. 9310 if (mStartedUsers.get(userId) == null) { 9311 Slog.w(TAG, "Unable to launch app " 9312 + cpi.applicationInfo.packageName + "/" 9313 + cpi.applicationInfo.uid + " for provider " 9314 + name + ": user " + userId + " is stopped"); 9315 return null; 9316 } 9317 9318 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9319 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9320 cpr = mProviderMap.getProviderByClass(comp, userId); 9321 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9322 final boolean firstClass = cpr == null; 9323 if (firstClass) { 9324 try { 9325 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9326 ApplicationInfo ai = 9327 AppGlobals.getPackageManager(). 9328 getApplicationInfo( 9329 cpi.applicationInfo.packageName, 9330 STOCK_PM_FLAGS, userId); 9331 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9332 if (ai == null) { 9333 Slog.w(TAG, "No package info for content provider " 9334 + cpi.name); 9335 return null; 9336 } 9337 ai = getAppInfoForUser(ai, userId); 9338 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9339 } catch (RemoteException ex) { 9340 // pm is in same process, this will never happen. 9341 } 9342 } 9343 9344 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9345 9346 if (r != null && cpr.canRunHere(r)) { 9347 // If this is a multiprocess provider, then just return its 9348 // info and allow the caller to instantiate it. Only do 9349 // this if the provider is the same user as the caller's 9350 // process, or can run as root (so can be in any process). 9351 return cpr.newHolder(null); 9352 } 9353 9354 if (DEBUG_PROVIDER) { 9355 RuntimeException e = new RuntimeException("here"); 9356 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9357 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9358 } 9359 9360 // This is single process, and our app is now connecting to it. 9361 // See if we are already in the process of launching this 9362 // provider. 9363 final int N = mLaunchingProviders.size(); 9364 int i; 9365 for (i=0; i<N; i++) { 9366 if (mLaunchingProviders.get(i) == cpr) { 9367 break; 9368 } 9369 } 9370 9371 // If the provider is not already being launched, then get it 9372 // started. 9373 if (i >= N) { 9374 final long origId = Binder.clearCallingIdentity(); 9375 9376 try { 9377 // Content provider is now in use, its package can't be stopped. 9378 try { 9379 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9380 AppGlobals.getPackageManager().setPackageStoppedState( 9381 cpr.appInfo.packageName, false, userId); 9382 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9383 } catch (RemoteException e) { 9384 } catch (IllegalArgumentException e) { 9385 Slog.w(TAG, "Failed trying to unstop package " 9386 + cpr.appInfo.packageName + ": " + e); 9387 } 9388 9389 // Use existing process if already started 9390 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9391 ProcessRecord proc = getProcessRecordLocked( 9392 cpi.processName, cpr.appInfo.uid, false); 9393 if (proc != null && proc.thread != null) { 9394 if (DEBUG_PROVIDER) { 9395 Slog.d(TAG, "Installing in existing process " + proc); 9396 } 9397 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9398 proc.pubProviders.put(cpi.name, cpr); 9399 try { 9400 proc.thread.scheduleInstallProvider(cpi); 9401 } catch (RemoteException e) { 9402 } 9403 } else { 9404 checkTime(startTime, "getContentProviderImpl: before start process"); 9405 proc = startProcessLocked(cpi.processName, 9406 cpr.appInfo, false, 0, "content provider", 9407 new ComponentName(cpi.applicationInfo.packageName, 9408 cpi.name), false, false, false); 9409 checkTime(startTime, "getContentProviderImpl: after start process"); 9410 if (proc == null) { 9411 Slog.w(TAG, "Unable to launch app " 9412 + cpi.applicationInfo.packageName + "/" 9413 + cpi.applicationInfo.uid + " for provider " 9414 + name + ": process is bad"); 9415 return null; 9416 } 9417 } 9418 cpr.launchingApp = proc; 9419 mLaunchingProviders.add(cpr); 9420 } finally { 9421 Binder.restoreCallingIdentity(origId); 9422 } 9423 } 9424 9425 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9426 9427 // Make sure the provider is published (the same provider class 9428 // may be published under multiple names). 9429 if (firstClass) { 9430 mProviderMap.putProviderByClass(comp, cpr); 9431 } 9432 9433 mProviderMap.putProviderByName(name, cpr); 9434 conn = incProviderCountLocked(r, cpr, token, stable); 9435 if (conn != null) { 9436 conn.waiting = true; 9437 } 9438 } 9439 checkTime(startTime, "getContentProviderImpl: done!"); 9440 } 9441 9442 // Wait for the provider to be published... 9443 synchronized (cpr) { 9444 while (cpr.provider == null) { 9445 if (cpr.launchingApp == null) { 9446 Slog.w(TAG, "Unable to launch app " 9447 + cpi.applicationInfo.packageName + "/" 9448 + cpi.applicationInfo.uid + " for provider " 9449 + name + ": launching app became null"); 9450 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9451 UserHandle.getUserId(cpi.applicationInfo.uid), 9452 cpi.applicationInfo.packageName, 9453 cpi.applicationInfo.uid, name); 9454 return null; 9455 } 9456 try { 9457 if (DEBUG_MU) { 9458 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9459 + cpr.launchingApp); 9460 } 9461 if (conn != null) { 9462 conn.waiting = true; 9463 } 9464 cpr.wait(); 9465 } catch (InterruptedException ex) { 9466 } finally { 9467 if (conn != null) { 9468 conn.waiting = false; 9469 } 9470 } 9471 } 9472 } 9473 return cpr != null ? cpr.newHolder(conn) : null; 9474 } 9475 9476 @Override 9477 public final ContentProviderHolder getContentProvider( 9478 IApplicationThread caller, String name, int userId, boolean stable) { 9479 enforceNotIsolatedCaller("getContentProvider"); 9480 if (caller == null) { 9481 String msg = "null IApplicationThread when getting content provider " 9482 + name; 9483 Slog.w(TAG, msg); 9484 throw new SecurityException(msg); 9485 } 9486 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9487 // with cross-user grant. 9488 return getContentProviderImpl(caller, name, null, stable, userId); 9489 } 9490 9491 public ContentProviderHolder getContentProviderExternal( 9492 String name, int userId, IBinder token) { 9493 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9494 "Do not have permission in call getContentProviderExternal()"); 9495 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9496 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9497 return getContentProviderExternalUnchecked(name, token, userId); 9498 } 9499 9500 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9501 IBinder token, int userId) { 9502 return getContentProviderImpl(null, name, token, true, userId); 9503 } 9504 9505 /** 9506 * Drop a content provider from a ProcessRecord's bookkeeping 9507 */ 9508 public void removeContentProvider(IBinder connection, boolean stable) { 9509 enforceNotIsolatedCaller("removeContentProvider"); 9510 long ident = Binder.clearCallingIdentity(); 9511 try { 9512 synchronized (this) { 9513 ContentProviderConnection conn; 9514 try { 9515 conn = (ContentProviderConnection)connection; 9516 } catch (ClassCastException e) { 9517 String msg ="removeContentProvider: " + connection 9518 + " not a ContentProviderConnection"; 9519 Slog.w(TAG, msg); 9520 throw new IllegalArgumentException(msg); 9521 } 9522 if (conn == null) { 9523 throw new NullPointerException("connection is null"); 9524 } 9525 if (decProviderCountLocked(conn, null, null, stable)) { 9526 updateOomAdjLocked(); 9527 } 9528 } 9529 } finally { 9530 Binder.restoreCallingIdentity(ident); 9531 } 9532 } 9533 9534 public void removeContentProviderExternal(String name, IBinder token) { 9535 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9536 "Do not have permission in call removeContentProviderExternal()"); 9537 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 9538 } 9539 9540 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9541 synchronized (this) { 9542 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9543 if(cpr == null) { 9544 //remove from mProvidersByClass 9545 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9546 return; 9547 } 9548 9549 //update content provider record entry info 9550 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9551 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9552 if (localCpr.hasExternalProcessHandles()) { 9553 if (localCpr.removeExternalProcessHandleLocked(token)) { 9554 updateOomAdjLocked(); 9555 } else { 9556 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9557 + " with no external reference for token: " 9558 + token + "."); 9559 } 9560 } else { 9561 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9562 + " with no external references."); 9563 } 9564 } 9565 } 9566 9567 public final void publishContentProviders(IApplicationThread caller, 9568 List<ContentProviderHolder> providers) { 9569 if (providers == null) { 9570 return; 9571 } 9572 9573 enforceNotIsolatedCaller("publishContentProviders"); 9574 synchronized (this) { 9575 final ProcessRecord r = getRecordForAppLocked(caller); 9576 if (DEBUG_MU) 9577 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9578 if (r == null) { 9579 throw new SecurityException( 9580 "Unable to find app for caller " + caller 9581 + " (pid=" + Binder.getCallingPid() 9582 + ") when publishing content providers"); 9583 } 9584 9585 final long origId = Binder.clearCallingIdentity(); 9586 9587 final int N = providers.size(); 9588 for (int i=0; i<N; i++) { 9589 ContentProviderHolder src = providers.get(i); 9590 if (src == null || src.info == null || src.provider == null) { 9591 continue; 9592 } 9593 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9594 if (DEBUG_MU) 9595 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9596 if (dst != null) { 9597 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9598 mProviderMap.putProviderByClass(comp, dst); 9599 String names[] = dst.info.authority.split(";"); 9600 for (int j = 0; j < names.length; j++) { 9601 mProviderMap.putProviderByName(names[j], dst); 9602 } 9603 9604 int NL = mLaunchingProviders.size(); 9605 int j; 9606 for (j=0; j<NL; j++) { 9607 if (mLaunchingProviders.get(j) == dst) { 9608 mLaunchingProviders.remove(j); 9609 j--; 9610 NL--; 9611 } 9612 } 9613 synchronized (dst) { 9614 dst.provider = src.provider; 9615 dst.proc = r; 9616 dst.notifyAll(); 9617 } 9618 updateOomAdjLocked(r); 9619 } 9620 } 9621 9622 Binder.restoreCallingIdentity(origId); 9623 } 9624 } 9625 9626 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9627 ContentProviderConnection conn; 9628 try { 9629 conn = (ContentProviderConnection)connection; 9630 } catch (ClassCastException e) { 9631 String msg ="refContentProvider: " + connection 9632 + " not a ContentProviderConnection"; 9633 Slog.w(TAG, msg); 9634 throw new IllegalArgumentException(msg); 9635 } 9636 if (conn == null) { 9637 throw new NullPointerException("connection is null"); 9638 } 9639 9640 synchronized (this) { 9641 if (stable > 0) { 9642 conn.numStableIncs += stable; 9643 } 9644 stable = conn.stableCount + stable; 9645 if (stable < 0) { 9646 throw new IllegalStateException("stableCount < 0: " + stable); 9647 } 9648 9649 if (unstable > 0) { 9650 conn.numUnstableIncs += unstable; 9651 } 9652 unstable = conn.unstableCount + unstable; 9653 if (unstable < 0) { 9654 throw new IllegalStateException("unstableCount < 0: " + unstable); 9655 } 9656 9657 if ((stable+unstable) <= 0) { 9658 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9659 + stable + " unstable=" + unstable); 9660 } 9661 conn.stableCount = stable; 9662 conn.unstableCount = unstable; 9663 return !conn.dead; 9664 } 9665 } 9666 9667 public void unstableProviderDied(IBinder connection) { 9668 ContentProviderConnection conn; 9669 try { 9670 conn = (ContentProviderConnection)connection; 9671 } catch (ClassCastException e) { 9672 String msg ="refContentProvider: " + connection 9673 + " not a ContentProviderConnection"; 9674 Slog.w(TAG, msg); 9675 throw new IllegalArgumentException(msg); 9676 } 9677 if (conn == null) { 9678 throw new NullPointerException("connection is null"); 9679 } 9680 9681 // Safely retrieve the content provider associated with the connection. 9682 IContentProvider provider; 9683 synchronized (this) { 9684 provider = conn.provider.provider; 9685 } 9686 9687 if (provider == null) { 9688 // Um, yeah, we're way ahead of you. 9689 return; 9690 } 9691 9692 // Make sure the caller is being honest with us. 9693 if (provider.asBinder().pingBinder()) { 9694 // Er, no, still looks good to us. 9695 synchronized (this) { 9696 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9697 + " says " + conn + " died, but we don't agree"); 9698 return; 9699 } 9700 } 9701 9702 // Well look at that! It's dead! 9703 synchronized (this) { 9704 if (conn.provider.provider != provider) { 9705 // But something changed... good enough. 9706 return; 9707 } 9708 9709 ProcessRecord proc = conn.provider.proc; 9710 if (proc == null || proc.thread == null) { 9711 // Seems like the process is already cleaned up. 9712 return; 9713 } 9714 9715 // As far as we're concerned, this is just like receiving a 9716 // death notification... just a bit prematurely. 9717 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9718 + ") early provider death"); 9719 final long ident = Binder.clearCallingIdentity(); 9720 try { 9721 appDiedLocked(proc); 9722 } finally { 9723 Binder.restoreCallingIdentity(ident); 9724 } 9725 } 9726 } 9727 9728 @Override 9729 public void appNotRespondingViaProvider(IBinder connection) { 9730 enforceCallingPermission( 9731 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9732 9733 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9734 if (conn == null) { 9735 Slog.w(TAG, "ContentProviderConnection is null"); 9736 return; 9737 } 9738 9739 final ProcessRecord host = conn.provider.proc; 9740 if (host == null) { 9741 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9742 return; 9743 } 9744 9745 final long token = Binder.clearCallingIdentity(); 9746 try { 9747 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9748 } finally { 9749 Binder.restoreCallingIdentity(token); 9750 } 9751 } 9752 9753 public final void installSystemProviders() { 9754 List<ProviderInfo> providers; 9755 synchronized (this) { 9756 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9757 providers = generateApplicationProvidersLocked(app); 9758 if (providers != null) { 9759 for (int i=providers.size()-1; i>=0; i--) { 9760 ProviderInfo pi = (ProviderInfo)providers.get(i); 9761 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9762 Slog.w(TAG, "Not installing system proc provider " + pi.name 9763 + ": not system .apk"); 9764 providers.remove(i); 9765 } 9766 } 9767 } 9768 } 9769 if (providers != null) { 9770 mSystemThread.installSystemProviders(providers); 9771 } 9772 9773 mCoreSettingsObserver = new CoreSettingsObserver(this); 9774 9775 //mUsageStatsService.monitorPackages(); 9776 } 9777 9778 /** 9779 * Allows apps to retrieve the MIME type of a URI. 9780 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9781 * users, then it does not need permission to access the ContentProvider. 9782 * Either, it needs cross-user uri grants. 9783 * 9784 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9785 * 9786 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9787 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9788 */ 9789 public String getProviderMimeType(Uri uri, int userId) { 9790 enforceNotIsolatedCaller("getProviderMimeType"); 9791 final String name = uri.getAuthority(); 9792 int callingUid = Binder.getCallingUid(); 9793 int callingPid = Binder.getCallingPid(); 9794 long ident = 0; 9795 boolean clearedIdentity = false; 9796 userId = unsafeConvertIncomingUser(userId); 9797 if (canClearIdentity(callingPid, callingUid, userId)) { 9798 clearedIdentity = true; 9799 ident = Binder.clearCallingIdentity(); 9800 } 9801 ContentProviderHolder holder = null; 9802 try { 9803 holder = getContentProviderExternalUnchecked(name, null, userId); 9804 if (holder != null) { 9805 return holder.provider.getType(uri); 9806 } 9807 } catch (RemoteException e) { 9808 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9809 return null; 9810 } finally { 9811 // We need to clear the identity to call removeContentProviderExternalUnchecked 9812 if (!clearedIdentity) { 9813 ident = Binder.clearCallingIdentity(); 9814 } 9815 try { 9816 if (holder != null) { 9817 removeContentProviderExternalUnchecked(name, null, userId); 9818 } 9819 } finally { 9820 Binder.restoreCallingIdentity(ident); 9821 } 9822 } 9823 9824 return null; 9825 } 9826 9827 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9828 if (UserHandle.getUserId(callingUid) == userId) { 9829 return true; 9830 } 9831 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9832 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9833 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9834 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9835 return true; 9836 } 9837 return false; 9838 } 9839 9840 // ========================================================= 9841 // GLOBAL MANAGEMENT 9842 // ========================================================= 9843 9844 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9845 boolean isolated, int isolatedUid) { 9846 String proc = customProcess != null ? customProcess : info.processName; 9847 BatteryStatsImpl.Uid.Proc ps = null; 9848 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9849 int uid = info.uid; 9850 if (isolated) { 9851 if (isolatedUid == 0) { 9852 int userId = UserHandle.getUserId(uid); 9853 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9854 while (true) { 9855 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9856 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9857 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9858 } 9859 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9860 mNextIsolatedProcessUid++; 9861 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9862 // No process for this uid, use it. 9863 break; 9864 } 9865 stepsLeft--; 9866 if (stepsLeft <= 0) { 9867 return null; 9868 } 9869 } 9870 } else { 9871 // Special case for startIsolatedProcess (internal only), where 9872 // the uid of the isolated process is specified by the caller. 9873 uid = isolatedUid; 9874 } 9875 } 9876 return new ProcessRecord(stats, info, proc, uid); 9877 } 9878 9879 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9880 String abiOverride) { 9881 ProcessRecord app; 9882 if (!isolated) { 9883 app = getProcessRecordLocked(info.processName, info.uid, true); 9884 } else { 9885 app = null; 9886 } 9887 9888 if (app == null) { 9889 app = newProcessRecordLocked(info, null, isolated, 0); 9890 mProcessNames.put(info.processName, app.uid, app); 9891 if (isolated) { 9892 mIsolatedProcesses.put(app.uid, app); 9893 } 9894 updateLruProcessLocked(app, false, null); 9895 updateOomAdjLocked(); 9896 } 9897 9898 // This package really, really can not be stopped. 9899 try { 9900 AppGlobals.getPackageManager().setPackageStoppedState( 9901 info.packageName, false, UserHandle.getUserId(app.uid)); 9902 } catch (RemoteException e) { 9903 } catch (IllegalArgumentException e) { 9904 Slog.w(TAG, "Failed trying to unstop package " 9905 + info.packageName + ": " + e); 9906 } 9907 9908 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9909 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9910 app.persistent = true; 9911 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9912 } 9913 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9914 mPersistentStartingProcesses.add(app); 9915 startProcessLocked(app, "added application", app.processName, abiOverride, 9916 null /* entryPoint */, null /* entryPointArgs */); 9917 } 9918 9919 return app; 9920 } 9921 9922 public void unhandledBack() { 9923 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9924 "unhandledBack()"); 9925 9926 synchronized(this) { 9927 final long origId = Binder.clearCallingIdentity(); 9928 try { 9929 getFocusedStack().unhandledBackLocked(); 9930 } finally { 9931 Binder.restoreCallingIdentity(origId); 9932 } 9933 } 9934 } 9935 9936 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9937 enforceNotIsolatedCaller("openContentUri"); 9938 final int userId = UserHandle.getCallingUserId(); 9939 String name = uri.getAuthority(); 9940 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9941 ParcelFileDescriptor pfd = null; 9942 if (cph != null) { 9943 // We record the binder invoker's uid in thread-local storage before 9944 // going to the content provider to open the file. Later, in the code 9945 // that handles all permissions checks, we look for this uid and use 9946 // that rather than the Activity Manager's own uid. The effect is that 9947 // we do the check against the caller's permissions even though it looks 9948 // to the content provider like the Activity Manager itself is making 9949 // the request. 9950 sCallerIdentity.set(new Identity( 9951 Binder.getCallingPid(), Binder.getCallingUid())); 9952 try { 9953 pfd = cph.provider.openFile(null, uri, "r", null); 9954 } catch (FileNotFoundException e) { 9955 // do nothing; pfd will be returned null 9956 } finally { 9957 // Ensure that whatever happens, we clean up the identity state 9958 sCallerIdentity.remove(); 9959 } 9960 9961 // We've got the fd now, so we're done with the provider. 9962 removeContentProviderExternalUnchecked(name, null, userId); 9963 } else { 9964 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9965 } 9966 return pfd; 9967 } 9968 9969 // Actually is sleeping or shutting down or whatever else in the future 9970 // is an inactive state. 9971 public boolean isSleepingOrShuttingDown() { 9972 return isSleeping() || mShuttingDown; 9973 } 9974 9975 public boolean isSleeping() { 9976 return mSleeping; 9977 } 9978 9979 void goingToSleep() { 9980 synchronized(this) { 9981 mWentToSleep = true; 9982 goToSleepIfNeededLocked(); 9983 } 9984 } 9985 9986 void finishRunningVoiceLocked() { 9987 if (mRunningVoice) { 9988 mRunningVoice = false; 9989 goToSleepIfNeededLocked(); 9990 } 9991 } 9992 9993 void goToSleepIfNeededLocked() { 9994 if (mWentToSleep && !mRunningVoice) { 9995 if (!mSleeping) { 9996 mSleeping = true; 9997 mStackSupervisor.goingToSleepLocked(); 9998 9999 // Initialize the wake times of all processes. 10000 checkExcessivePowerUsageLocked(false); 10001 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10002 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10003 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 10004 } 10005 } 10006 } 10007 10008 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10009 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10010 // Never persist the home stack. 10011 return; 10012 } 10013 mTaskPersister.wakeup(task, flush); 10014 } 10015 10016 @Override 10017 public boolean shutdown(int timeout) { 10018 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10019 != PackageManager.PERMISSION_GRANTED) { 10020 throw new SecurityException("Requires permission " 10021 + android.Manifest.permission.SHUTDOWN); 10022 } 10023 10024 boolean timedout = false; 10025 10026 synchronized(this) { 10027 mShuttingDown = true; 10028 updateEventDispatchingLocked(); 10029 timedout = mStackSupervisor.shutdownLocked(timeout); 10030 } 10031 10032 mAppOpsService.shutdown(); 10033 if (mUsageStatsService != null) { 10034 mUsageStatsService.prepareShutdown(); 10035 } 10036 mBatteryStatsService.shutdown(); 10037 synchronized (this) { 10038 mProcessStats.shutdownLocked(); 10039 } 10040 notifyTaskPersisterLocked(null, true); 10041 10042 return timedout; 10043 } 10044 10045 public final void activitySlept(IBinder token) { 10046 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10047 10048 final long origId = Binder.clearCallingIdentity(); 10049 10050 synchronized (this) { 10051 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10052 if (r != null) { 10053 mStackSupervisor.activitySleptLocked(r); 10054 } 10055 } 10056 10057 Binder.restoreCallingIdentity(origId); 10058 } 10059 10060 void logLockScreen(String msg) { 10061 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 10062 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 10063 mWentToSleep + " mSleeping=" + mSleeping); 10064 } 10065 10066 private void comeOutOfSleepIfNeededLocked() { 10067 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 10068 if (mSleeping) { 10069 mSleeping = false; 10070 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10071 } 10072 } 10073 } 10074 10075 void wakingUp() { 10076 synchronized(this) { 10077 mWentToSleep = false; 10078 comeOutOfSleepIfNeededLocked(); 10079 } 10080 } 10081 10082 void startRunningVoiceLocked() { 10083 if (!mRunningVoice) { 10084 mRunningVoice = true; 10085 comeOutOfSleepIfNeededLocked(); 10086 } 10087 } 10088 10089 private void updateEventDispatchingLocked() { 10090 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10091 } 10092 10093 public void setLockScreenShown(boolean shown) { 10094 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10095 != PackageManager.PERMISSION_GRANTED) { 10096 throw new SecurityException("Requires permission " 10097 + android.Manifest.permission.DEVICE_POWER); 10098 } 10099 10100 synchronized(this) { 10101 long ident = Binder.clearCallingIdentity(); 10102 try { 10103 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10104 mLockScreenShown = shown; 10105 comeOutOfSleepIfNeededLocked(); 10106 } finally { 10107 Binder.restoreCallingIdentity(ident); 10108 } 10109 } 10110 } 10111 10112 @Override 10113 public void stopAppSwitches() { 10114 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10115 != PackageManager.PERMISSION_GRANTED) { 10116 throw new SecurityException("Requires permission " 10117 + android.Manifest.permission.STOP_APP_SWITCHES); 10118 } 10119 10120 synchronized(this) { 10121 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10122 + APP_SWITCH_DELAY_TIME; 10123 mDidAppSwitch = false; 10124 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10125 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10126 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10127 } 10128 } 10129 10130 public void resumeAppSwitches() { 10131 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10132 != PackageManager.PERMISSION_GRANTED) { 10133 throw new SecurityException("Requires permission " 10134 + android.Manifest.permission.STOP_APP_SWITCHES); 10135 } 10136 10137 synchronized(this) { 10138 // Note that we don't execute any pending app switches... we will 10139 // let those wait until either the timeout, or the next start 10140 // activity request. 10141 mAppSwitchesAllowedTime = 0; 10142 } 10143 } 10144 10145 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10146 int callingPid, int callingUid, String name) { 10147 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10148 return true; 10149 } 10150 10151 int perm = checkComponentPermission( 10152 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10153 sourceUid, -1, true); 10154 if (perm == PackageManager.PERMISSION_GRANTED) { 10155 return true; 10156 } 10157 10158 // If the actual IPC caller is different from the logical source, then 10159 // also see if they are allowed to control app switches. 10160 if (callingUid != -1 && callingUid != sourceUid) { 10161 perm = checkComponentPermission( 10162 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10163 callingUid, -1, true); 10164 if (perm == PackageManager.PERMISSION_GRANTED) { 10165 return true; 10166 } 10167 } 10168 10169 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10170 return false; 10171 } 10172 10173 public void setDebugApp(String packageName, boolean waitForDebugger, 10174 boolean persistent) { 10175 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10176 "setDebugApp()"); 10177 10178 long ident = Binder.clearCallingIdentity(); 10179 try { 10180 // Note that this is not really thread safe if there are multiple 10181 // callers into it at the same time, but that's not a situation we 10182 // care about. 10183 if (persistent) { 10184 final ContentResolver resolver = mContext.getContentResolver(); 10185 Settings.Global.putString( 10186 resolver, Settings.Global.DEBUG_APP, 10187 packageName); 10188 Settings.Global.putInt( 10189 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10190 waitForDebugger ? 1 : 0); 10191 } 10192 10193 synchronized (this) { 10194 if (!persistent) { 10195 mOrigDebugApp = mDebugApp; 10196 mOrigWaitForDebugger = mWaitForDebugger; 10197 } 10198 mDebugApp = packageName; 10199 mWaitForDebugger = waitForDebugger; 10200 mDebugTransient = !persistent; 10201 if (packageName != null) { 10202 forceStopPackageLocked(packageName, -1, false, false, true, true, 10203 false, UserHandle.USER_ALL, "set debug app"); 10204 } 10205 } 10206 } finally { 10207 Binder.restoreCallingIdentity(ident); 10208 } 10209 } 10210 10211 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10212 synchronized (this) { 10213 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10214 if (!isDebuggable) { 10215 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10216 throw new SecurityException("Process not debuggable: " + app.packageName); 10217 } 10218 } 10219 10220 mOpenGlTraceApp = processName; 10221 } 10222 } 10223 10224 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10225 synchronized (this) { 10226 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10227 if (!isDebuggable) { 10228 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10229 throw new SecurityException("Process not debuggable: " + app.packageName); 10230 } 10231 } 10232 mProfileApp = processName; 10233 mProfileFile = profilerInfo.profileFile; 10234 if (mProfileFd != null) { 10235 try { 10236 mProfileFd.close(); 10237 } catch (IOException e) { 10238 } 10239 mProfileFd = null; 10240 } 10241 mProfileFd = profilerInfo.profileFd; 10242 mSamplingInterval = profilerInfo.samplingInterval; 10243 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10244 mProfileType = 0; 10245 } 10246 } 10247 10248 @Override 10249 public void setAlwaysFinish(boolean enabled) { 10250 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10251 "setAlwaysFinish()"); 10252 10253 Settings.Global.putInt( 10254 mContext.getContentResolver(), 10255 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10256 10257 synchronized (this) { 10258 mAlwaysFinishActivities = enabled; 10259 } 10260 } 10261 10262 @Override 10263 public void setActivityController(IActivityController controller) { 10264 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10265 "setActivityController()"); 10266 synchronized (this) { 10267 mController = controller; 10268 Watchdog.getInstance().setActivityController(controller); 10269 } 10270 } 10271 10272 @Override 10273 public void setUserIsMonkey(boolean userIsMonkey) { 10274 synchronized (this) { 10275 synchronized (mPidsSelfLocked) { 10276 final int callingPid = Binder.getCallingPid(); 10277 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10278 if (precessRecord == null) { 10279 throw new SecurityException("Unknown process: " + callingPid); 10280 } 10281 if (precessRecord.instrumentationUiAutomationConnection == null) { 10282 throw new SecurityException("Only an instrumentation process " 10283 + "with a UiAutomation can call setUserIsMonkey"); 10284 } 10285 } 10286 mUserIsMonkey = userIsMonkey; 10287 } 10288 } 10289 10290 @Override 10291 public boolean isUserAMonkey() { 10292 synchronized (this) { 10293 // If there is a controller also implies the user is a monkey. 10294 return (mUserIsMonkey || mController != null); 10295 } 10296 } 10297 10298 public void requestBugReport() { 10299 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10300 SystemProperties.set("ctl.start", "bugreport"); 10301 } 10302 10303 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10304 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10305 } 10306 10307 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10308 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10309 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10310 } 10311 return KEY_DISPATCHING_TIMEOUT; 10312 } 10313 10314 @Override 10315 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10316 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10317 != PackageManager.PERMISSION_GRANTED) { 10318 throw new SecurityException("Requires permission " 10319 + android.Manifest.permission.FILTER_EVENTS); 10320 } 10321 ProcessRecord proc; 10322 long timeout; 10323 synchronized (this) { 10324 synchronized (mPidsSelfLocked) { 10325 proc = mPidsSelfLocked.get(pid); 10326 } 10327 timeout = getInputDispatchingTimeoutLocked(proc); 10328 } 10329 10330 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10331 return -1; 10332 } 10333 10334 return timeout; 10335 } 10336 10337 /** 10338 * Handle input dispatching timeouts. 10339 * Returns whether input dispatching should be aborted or not. 10340 */ 10341 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10342 final ActivityRecord activity, final ActivityRecord parent, 10343 final boolean aboveSystem, String reason) { 10344 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10345 != PackageManager.PERMISSION_GRANTED) { 10346 throw new SecurityException("Requires permission " 10347 + android.Manifest.permission.FILTER_EVENTS); 10348 } 10349 10350 final String annotation; 10351 if (reason == null) { 10352 annotation = "Input dispatching timed out"; 10353 } else { 10354 annotation = "Input dispatching timed out (" + reason + ")"; 10355 } 10356 10357 if (proc != null) { 10358 synchronized (this) { 10359 if (proc.debugging) { 10360 return false; 10361 } 10362 10363 if (mDidDexOpt) { 10364 // Give more time since we were dexopting. 10365 mDidDexOpt = false; 10366 return false; 10367 } 10368 10369 if (proc.instrumentationClass != null) { 10370 Bundle info = new Bundle(); 10371 info.putString("shortMsg", "keyDispatchingTimedOut"); 10372 info.putString("longMsg", annotation); 10373 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10374 return true; 10375 } 10376 } 10377 mHandler.post(new Runnable() { 10378 @Override 10379 public void run() { 10380 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10381 } 10382 }); 10383 } 10384 10385 return true; 10386 } 10387 10388 public Bundle getAssistContextExtras(int requestType) { 10389 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10390 "getAssistContextExtras()"); 10391 PendingAssistExtras pae; 10392 Bundle extras = new Bundle(); 10393 synchronized (this) { 10394 ActivityRecord activity = getFocusedStack().mResumedActivity; 10395 if (activity == null) { 10396 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10397 return null; 10398 } 10399 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10400 if (activity.app == null || activity.app.thread == null) { 10401 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10402 return extras; 10403 } 10404 if (activity.app.pid == Binder.getCallingPid()) { 10405 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10406 return extras; 10407 } 10408 pae = new PendingAssistExtras(activity); 10409 try { 10410 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10411 requestType); 10412 mPendingAssistExtras.add(pae); 10413 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10414 } catch (RemoteException e) { 10415 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10416 return extras; 10417 } 10418 } 10419 synchronized (pae) { 10420 while (!pae.haveResult) { 10421 try { 10422 pae.wait(); 10423 } catch (InterruptedException e) { 10424 } 10425 } 10426 if (pae.result != null) { 10427 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10428 } 10429 } 10430 synchronized (this) { 10431 mPendingAssistExtras.remove(pae); 10432 mHandler.removeCallbacks(pae); 10433 } 10434 return extras; 10435 } 10436 10437 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10438 PendingAssistExtras pae = (PendingAssistExtras)token; 10439 synchronized (pae) { 10440 pae.result = extras; 10441 pae.haveResult = true; 10442 pae.notifyAll(); 10443 } 10444 } 10445 10446 public void registerProcessObserver(IProcessObserver observer) { 10447 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10448 "registerProcessObserver()"); 10449 synchronized (this) { 10450 mProcessObservers.register(observer); 10451 } 10452 } 10453 10454 @Override 10455 public void unregisterProcessObserver(IProcessObserver observer) { 10456 synchronized (this) { 10457 mProcessObservers.unregister(observer); 10458 } 10459 } 10460 10461 @Override 10462 public boolean convertFromTranslucent(IBinder token) { 10463 final long origId = Binder.clearCallingIdentity(); 10464 try { 10465 synchronized (this) { 10466 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10467 if (r == null) { 10468 return false; 10469 } 10470 final boolean translucentChanged = r.changeWindowTranslucency(true); 10471 if (translucentChanged) { 10472 r.task.stack.releaseBackgroundResources(); 10473 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10474 } 10475 mWindowManager.setAppFullscreen(token, true); 10476 return translucentChanged; 10477 } 10478 } finally { 10479 Binder.restoreCallingIdentity(origId); 10480 } 10481 } 10482 10483 @Override 10484 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10485 final long origId = Binder.clearCallingIdentity(); 10486 try { 10487 synchronized (this) { 10488 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10489 if (r == null) { 10490 return false; 10491 } 10492 int index = r.task.mActivities.lastIndexOf(r); 10493 if (index > 0) { 10494 ActivityRecord under = r.task.mActivities.get(index - 1); 10495 under.returningOptions = options; 10496 } 10497 final boolean translucentChanged = r.changeWindowTranslucency(false); 10498 if (translucentChanged) { 10499 r.task.stack.convertToTranslucent(r); 10500 } 10501 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10502 mWindowManager.setAppFullscreen(token, false); 10503 return translucentChanged; 10504 } 10505 } finally { 10506 Binder.restoreCallingIdentity(origId); 10507 } 10508 } 10509 10510 @Override 10511 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10512 final long origId = Binder.clearCallingIdentity(); 10513 try { 10514 synchronized (this) { 10515 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10516 if (r != null) { 10517 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10518 } 10519 } 10520 return false; 10521 } finally { 10522 Binder.restoreCallingIdentity(origId); 10523 } 10524 } 10525 10526 @Override 10527 public boolean isBackgroundVisibleBehind(IBinder token) { 10528 final long origId = Binder.clearCallingIdentity(); 10529 try { 10530 synchronized (this) { 10531 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10532 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10533 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10534 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10535 return visible; 10536 } 10537 } finally { 10538 Binder.restoreCallingIdentity(origId); 10539 } 10540 } 10541 10542 @Override 10543 public ActivityOptions getActivityOptions(IBinder token) { 10544 final long origId = Binder.clearCallingIdentity(); 10545 try { 10546 synchronized (this) { 10547 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10548 if (r != null) { 10549 final ActivityOptions activityOptions = r.pendingOptions; 10550 r.pendingOptions = null; 10551 return activityOptions; 10552 } 10553 return null; 10554 } 10555 } finally { 10556 Binder.restoreCallingIdentity(origId); 10557 } 10558 } 10559 10560 @Override 10561 public void setImmersive(IBinder token, boolean immersive) { 10562 synchronized(this) { 10563 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10564 if (r == null) { 10565 throw new IllegalArgumentException(); 10566 } 10567 r.immersive = immersive; 10568 10569 // update associated state if we're frontmost 10570 if (r == mFocusedActivity) { 10571 if (DEBUG_IMMERSIVE) { 10572 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10573 } 10574 applyUpdateLockStateLocked(r); 10575 } 10576 } 10577 } 10578 10579 @Override 10580 public boolean isImmersive(IBinder token) { 10581 synchronized (this) { 10582 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10583 if (r == null) { 10584 throw new IllegalArgumentException(); 10585 } 10586 return r.immersive; 10587 } 10588 } 10589 10590 public boolean isTopActivityImmersive() { 10591 enforceNotIsolatedCaller("startActivity"); 10592 synchronized (this) { 10593 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10594 return (r != null) ? r.immersive : false; 10595 } 10596 } 10597 10598 @Override 10599 public boolean isTopOfTask(IBinder token) { 10600 synchronized (this) { 10601 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10602 if (r == null) { 10603 throw new IllegalArgumentException(); 10604 } 10605 return r.task.getTopActivity() == r; 10606 } 10607 } 10608 10609 public final void enterSafeMode() { 10610 synchronized(this) { 10611 // It only makes sense to do this before the system is ready 10612 // and started launching other packages. 10613 if (!mSystemReady) { 10614 try { 10615 AppGlobals.getPackageManager().enterSafeMode(); 10616 } catch (RemoteException e) { 10617 } 10618 } 10619 10620 mSafeMode = true; 10621 } 10622 } 10623 10624 public final void showSafeModeOverlay() { 10625 View v = LayoutInflater.from(mContext).inflate( 10626 com.android.internal.R.layout.safe_mode, null); 10627 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10628 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10629 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10630 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10631 lp.gravity = Gravity.BOTTOM | Gravity.START; 10632 lp.format = v.getBackground().getOpacity(); 10633 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10634 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10635 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10636 ((WindowManager)mContext.getSystemService( 10637 Context.WINDOW_SERVICE)).addView(v, lp); 10638 } 10639 10640 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10641 if (!(sender instanceof PendingIntentRecord)) { 10642 return; 10643 } 10644 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10645 synchronized (stats) { 10646 if (mBatteryStatsService.isOnBattery()) { 10647 mBatteryStatsService.enforceCallingPermission(); 10648 PendingIntentRecord rec = (PendingIntentRecord)sender; 10649 int MY_UID = Binder.getCallingUid(); 10650 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10651 BatteryStatsImpl.Uid.Pkg pkg = 10652 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10653 sourcePkg != null ? sourcePkg : rec.key.packageName); 10654 pkg.incWakeupsLocked(); 10655 } 10656 } 10657 } 10658 10659 public boolean killPids(int[] pids, String pReason, boolean secure) { 10660 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10661 throw new SecurityException("killPids only available to the system"); 10662 } 10663 String reason = (pReason == null) ? "Unknown" : pReason; 10664 // XXX Note: don't acquire main activity lock here, because the window 10665 // manager calls in with its locks held. 10666 10667 boolean killed = false; 10668 synchronized (mPidsSelfLocked) { 10669 int[] types = new int[pids.length]; 10670 int worstType = 0; 10671 for (int i=0; i<pids.length; i++) { 10672 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10673 if (proc != null) { 10674 int type = proc.setAdj; 10675 types[i] = type; 10676 if (type > worstType) { 10677 worstType = type; 10678 } 10679 } 10680 } 10681 10682 // If the worst oom_adj is somewhere in the cached proc LRU range, 10683 // then constrain it so we will kill all cached procs. 10684 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10685 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10686 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10687 } 10688 10689 // If this is not a secure call, don't let it kill processes that 10690 // are important. 10691 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10692 worstType = ProcessList.SERVICE_ADJ; 10693 } 10694 10695 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10696 for (int i=0; i<pids.length; i++) { 10697 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10698 if (proc == null) { 10699 continue; 10700 } 10701 int adj = proc.setAdj; 10702 if (adj >= worstType && !proc.killedByAm) { 10703 proc.kill(reason, true); 10704 killed = true; 10705 } 10706 } 10707 } 10708 return killed; 10709 } 10710 10711 @Override 10712 public void killUid(int uid, String reason) { 10713 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10714 throw new SecurityException("killUid only available to the system"); 10715 } 10716 synchronized (this) { 10717 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10718 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10719 reason != null ? reason : "kill uid"); 10720 } 10721 } 10722 10723 @Override 10724 public boolean killProcessesBelowForeground(String reason) { 10725 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10726 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10727 } 10728 10729 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10730 } 10731 10732 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10733 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10734 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10735 } 10736 10737 boolean killed = false; 10738 synchronized (mPidsSelfLocked) { 10739 final int size = mPidsSelfLocked.size(); 10740 for (int i = 0; i < size; i++) { 10741 final int pid = mPidsSelfLocked.keyAt(i); 10742 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10743 if (proc == null) continue; 10744 10745 final int adj = proc.setAdj; 10746 if (adj > belowAdj && !proc.killedByAm) { 10747 proc.kill(reason, true); 10748 killed = true; 10749 } 10750 } 10751 } 10752 return killed; 10753 } 10754 10755 @Override 10756 public void hang(final IBinder who, boolean allowRestart) { 10757 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10758 != PackageManager.PERMISSION_GRANTED) { 10759 throw new SecurityException("Requires permission " 10760 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10761 } 10762 10763 final IBinder.DeathRecipient death = new DeathRecipient() { 10764 @Override 10765 public void binderDied() { 10766 synchronized (this) { 10767 notifyAll(); 10768 } 10769 } 10770 }; 10771 10772 try { 10773 who.linkToDeath(death, 0); 10774 } catch (RemoteException e) { 10775 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10776 return; 10777 } 10778 10779 synchronized (this) { 10780 Watchdog.getInstance().setAllowRestart(allowRestart); 10781 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10782 synchronized (death) { 10783 while (who.isBinderAlive()) { 10784 try { 10785 death.wait(); 10786 } catch (InterruptedException e) { 10787 } 10788 } 10789 } 10790 Watchdog.getInstance().setAllowRestart(true); 10791 } 10792 } 10793 10794 @Override 10795 public void restart() { 10796 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10797 != PackageManager.PERMISSION_GRANTED) { 10798 throw new SecurityException("Requires permission " 10799 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10800 } 10801 10802 Log.i(TAG, "Sending shutdown broadcast..."); 10803 10804 BroadcastReceiver br = new BroadcastReceiver() { 10805 @Override public void onReceive(Context context, Intent intent) { 10806 // Now the broadcast is done, finish up the low-level shutdown. 10807 Log.i(TAG, "Shutting down activity manager..."); 10808 shutdown(10000); 10809 Log.i(TAG, "Shutdown complete, restarting!"); 10810 Process.killProcess(Process.myPid()); 10811 System.exit(10); 10812 } 10813 }; 10814 10815 // First send the high-level shut down broadcast. 10816 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10817 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10818 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10819 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10820 mContext.sendOrderedBroadcastAsUser(intent, 10821 UserHandle.ALL, null, br, mHandler, 0, null, null); 10822 */ 10823 br.onReceive(mContext, intent); 10824 } 10825 10826 private long getLowRamTimeSinceIdle(long now) { 10827 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10828 } 10829 10830 @Override 10831 public void performIdleMaintenance() { 10832 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10833 != PackageManager.PERMISSION_GRANTED) { 10834 throw new SecurityException("Requires permission " 10835 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10836 } 10837 10838 synchronized (this) { 10839 final long now = SystemClock.uptimeMillis(); 10840 final long timeSinceLastIdle = now - mLastIdleTime; 10841 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10842 mLastIdleTime = now; 10843 mLowRamTimeSinceLastIdle = 0; 10844 if (mLowRamStartTime != 0) { 10845 mLowRamStartTime = now; 10846 } 10847 10848 StringBuilder sb = new StringBuilder(128); 10849 sb.append("Idle maintenance over "); 10850 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10851 sb.append(" low RAM for "); 10852 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10853 Slog.i(TAG, sb.toString()); 10854 10855 // If at least 1/3 of our time since the last idle period has been spent 10856 // with RAM low, then we want to kill processes. 10857 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10858 10859 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10860 ProcessRecord proc = mLruProcesses.get(i); 10861 if (proc.notCachedSinceIdle) { 10862 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10863 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10864 if (doKilling && proc.initialIdlePss != 0 10865 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10866 proc.kill("idle maint (pss " + proc.lastPss 10867 + " from " + proc.initialIdlePss + ")", true); 10868 } 10869 } 10870 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10871 proc.notCachedSinceIdle = true; 10872 proc.initialIdlePss = 0; 10873 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10874 isSleeping(), now); 10875 } 10876 } 10877 10878 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10879 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10880 } 10881 } 10882 10883 private void retrieveSettings() { 10884 final ContentResolver resolver = mContext.getContentResolver(); 10885 String debugApp = Settings.Global.getString( 10886 resolver, Settings.Global.DEBUG_APP); 10887 boolean waitForDebugger = Settings.Global.getInt( 10888 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10889 boolean alwaysFinishActivities = Settings.Global.getInt( 10890 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10891 boolean forceRtl = Settings.Global.getInt( 10892 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10893 // Transfer any global setting for forcing RTL layout, into a System Property 10894 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10895 10896 Configuration configuration = new Configuration(); 10897 Settings.System.getConfiguration(resolver, configuration); 10898 if (forceRtl) { 10899 // This will take care of setting the correct layout direction flags 10900 configuration.setLayoutDirection(configuration.locale); 10901 } 10902 10903 synchronized (this) { 10904 mDebugApp = mOrigDebugApp = debugApp; 10905 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10906 mAlwaysFinishActivities = alwaysFinishActivities; 10907 // This happens before any activities are started, so we can 10908 // change mConfiguration in-place. 10909 updateConfigurationLocked(configuration, null, false, true); 10910 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10911 } 10912 } 10913 10914 /** Loads resources after the current configuration has been set. */ 10915 private void loadResourcesOnSystemReady() { 10916 final Resources res = mContext.getResources(); 10917 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10918 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10919 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10920 } 10921 10922 public boolean testIsSystemReady() { 10923 // no need to synchronize(this) just to read & return the value 10924 return mSystemReady; 10925 } 10926 10927 private static File getCalledPreBootReceiversFile() { 10928 File dataDir = Environment.getDataDirectory(); 10929 File systemDir = new File(dataDir, "system"); 10930 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10931 return fname; 10932 } 10933 10934 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10935 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10936 File file = getCalledPreBootReceiversFile(); 10937 FileInputStream fis = null; 10938 try { 10939 fis = new FileInputStream(file); 10940 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10941 int fvers = dis.readInt(); 10942 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10943 String vers = dis.readUTF(); 10944 String codename = dis.readUTF(); 10945 String build = dis.readUTF(); 10946 if (android.os.Build.VERSION.RELEASE.equals(vers) 10947 && android.os.Build.VERSION.CODENAME.equals(codename) 10948 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10949 int num = dis.readInt(); 10950 while (num > 0) { 10951 num--; 10952 String pkg = dis.readUTF(); 10953 String cls = dis.readUTF(); 10954 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10955 } 10956 } 10957 } 10958 } catch (FileNotFoundException e) { 10959 } catch (IOException e) { 10960 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10961 } finally { 10962 if (fis != null) { 10963 try { 10964 fis.close(); 10965 } catch (IOException e) { 10966 } 10967 } 10968 } 10969 return lastDoneReceivers; 10970 } 10971 10972 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10973 File file = getCalledPreBootReceiversFile(); 10974 FileOutputStream fos = null; 10975 DataOutputStream dos = null; 10976 try { 10977 fos = new FileOutputStream(file); 10978 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10979 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10980 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10981 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10982 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10983 dos.writeInt(list.size()); 10984 for (int i=0; i<list.size(); i++) { 10985 dos.writeUTF(list.get(i).getPackageName()); 10986 dos.writeUTF(list.get(i).getClassName()); 10987 } 10988 } catch (IOException e) { 10989 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10990 file.delete(); 10991 } finally { 10992 FileUtils.sync(fos); 10993 if (dos != null) { 10994 try { 10995 dos.close(); 10996 } catch (IOException e) { 10997 // TODO Auto-generated catch block 10998 e.printStackTrace(); 10999 } 11000 } 11001 } 11002 } 11003 11004 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11005 ArrayList<ComponentName> doneReceivers, int userId) { 11006 boolean waitingUpdate = false; 11007 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11008 List<ResolveInfo> ris = null; 11009 try { 11010 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11011 intent, null, 0, userId); 11012 } catch (RemoteException e) { 11013 } 11014 if (ris != null) { 11015 for (int i=ris.size()-1; i>=0; i--) { 11016 if ((ris.get(i).activityInfo.applicationInfo.flags 11017 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11018 ris.remove(i); 11019 } 11020 } 11021 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11022 11023 // For User 0, load the version number. When delivering to a new user, deliver 11024 // to all receivers. 11025 if (userId == UserHandle.USER_OWNER) { 11026 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11027 for (int i=0; i<ris.size(); i++) { 11028 ActivityInfo ai = ris.get(i).activityInfo; 11029 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11030 if (lastDoneReceivers.contains(comp)) { 11031 // We already did the pre boot receiver for this app with the current 11032 // platform version, so don't do it again... 11033 ris.remove(i); 11034 i--; 11035 // ...however, do keep it as one that has been done, so we don't 11036 // forget about it when rewriting the file of last done receivers. 11037 doneReceivers.add(comp); 11038 } 11039 } 11040 } 11041 11042 // If primary user, send broadcast to all available users, else just to userId 11043 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11044 : new int[] { userId }; 11045 for (int i = 0; i < ris.size(); i++) { 11046 ActivityInfo ai = ris.get(i).activityInfo; 11047 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11048 doneReceivers.add(comp); 11049 intent.setComponent(comp); 11050 for (int j=0; j<users.length; j++) { 11051 IIntentReceiver finisher = null; 11052 // On last receiver and user, set up a completion callback 11053 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11054 finisher = new IIntentReceiver.Stub() { 11055 public void performReceive(Intent intent, int resultCode, 11056 String data, Bundle extras, boolean ordered, 11057 boolean sticky, int sendingUser) { 11058 // The raw IIntentReceiver interface is called 11059 // with the AM lock held, so redispatch to 11060 // execute our code without the lock. 11061 mHandler.post(onFinishCallback); 11062 } 11063 }; 11064 } 11065 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11066 + " for user " + users[j]); 11067 broadcastIntentLocked(null, null, intent, null, finisher, 11068 0, null, null, null, AppOpsManager.OP_NONE, 11069 true, false, MY_PID, Process.SYSTEM_UID, 11070 users[j]); 11071 if (finisher != null) { 11072 waitingUpdate = true; 11073 } 11074 } 11075 } 11076 } 11077 11078 return waitingUpdate; 11079 } 11080 11081 public void systemReady(final Runnable goingCallback) { 11082 synchronized(this) { 11083 if (mSystemReady) { 11084 // If we're done calling all the receivers, run the next "boot phase" passed in 11085 // by the SystemServer 11086 if (goingCallback != null) { 11087 goingCallback.run(); 11088 } 11089 return; 11090 } 11091 11092 // Make sure we have the current profile info, since it is needed for 11093 // security checks. 11094 updateCurrentProfileIdsLocked(); 11095 11096 if (mRecentTasks == null) { 11097 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11098 if (!mRecentTasks.isEmpty()) { 11099 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11100 } 11101 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11102 mTaskPersister.startPersisting(); 11103 } 11104 11105 // Check to see if there are any update receivers to run. 11106 if (!mDidUpdate) { 11107 if (mWaitingUpdate) { 11108 return; 11109 } 11110 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11111 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11112 public void run() { 11113 synchronized (ActivityManagerService.this) { 11114 mDidUpdate = true; 11115 } 11116 writeLastDonePreBootReceivers(doneReceivers); 11117 showBootMessage(mContext.getText( 11118 R.string.android_upgrading_complete), 11119 false); 11120 systemReady(goingCallback); 11121 } 11122 }, doneReceivers, UserHandle.USER_OWNER); 11123 11124 if (mWaitingUpdate) { 11125 return; 11126 } 11127 mDidUpdate = true; 11128 } 11129 11130 mAppOpsService.systemReady(); 11131 mSystemReady = true; 11132 } 11133 11134 ArrayList<ProcessRecord> procsToKill = null; 11135 synchronized(mPidsSelfLocked) { 11136 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11137 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11138 if (!isAllowedWhileBooting(proc.info)){ 11139 if (procsToKill == null) { 11140 procsToKill = new ArrayList<ProcessRecord>(); 11141 } 11142 procsToKill.add(proc); 11143 } 11144 } 11145 } 11146 11147 synchronized(this) { 11148 if (procsToKill != null) { 11149 for (int i=procsToKill.size()-1; i>=0; i--) { 11150 ProcessRecord proc = procsToKill.get(i); 11151 Slog.i(TAG, "Removing system update proc: " + proc); 11152 removeProcessLocked(proc, true, false, "system update done"); 11153 } 11154 } 11155 11156 // Now that we have cleaned up any update processes, we 11157 // are ready to start launching real processes and know that 11158 // we won't trample on them any more. 11159 mProcessesReady = true; 11160 } 11161 11162 Slog.i(TAG, "System now ready"); 11163 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11164 SystemClock.uptimeMillis()); 11165 11166 synchronized(this) { 11167 // Make sure we have no pre-ready processes sitting around. 11168 11169 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11170 ResolveInfo ri = mContext.getPackageManager() 11171 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11172 STOCK_PM_FLAGS); 11173 CharSequence errorMsg = null; 11174 if (ri != null) { 11175 ActivityInfo ai = ri.activityInfo; 11176 ApplicationInfo app = ai.applicationInfo; 11177 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11178 mTopAction = Intent.ACTION_FACTORY_TEST; 11179 mTopData = null; 11180 mTopComponent = new ComponentName(app.packageName, 11181 ai.name); 11182 } else { 11183 errorMsg = mContext.getResources().getText( 11184 com.android.internal.R.string.factorytest_not_system); 11185 } 11186 } else { 11187 errorMsg = mContext.getResources().getText( 11188 com.android.internal.R.string.factorytest_no_action); 11189 } 11190 if (errorMsg != null) { 11191 mTopAction = null; 11192 mTopData = null; 11193 mTopComponent = null; 11194 Message msg = Message.obtain(); 11195 msg.what = SHOW_FACTORY_ERROR_MSG; 11196 msg.getData().putCharSequence("msg", errorMsg); 11197 mHandler.sendMessage(msg); 11198 } 11199 } 11200 } 11201 11202 retrieveSettings(); 11203 loadResourcesOnSystemReady(); 11204 11205 synchronized (this) { 11206 readGrantedUriPermissionsLocked(); 11207 } 11208 11209 if (goingCallback != null) goingCallback.run(); 11210 11211 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11212 Integer.toString(mCurrentUserId), mCurrentUserId); 11213 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11214 Integer.toString(mCurrentUserId), mCurrentUserId); 11215 mSystemServiceManager.startUser(mCurrentUserId); 11216 11217 synchronized (this) { 11218 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11219 try { 11220 List apps = AppGlobals.getPackageManager(). 11221 getPersistentApplications(STOCK_PM_FLAGS); 11222 if (apps != null) { 11223 int N = apps.size(); 11224 int i; 11225 for (i=0; i<N; i++) { 11226 ApplicationInfo info 11227 = (ApplicationInfo)apps.get(i); 11228 if (info != null && 11229 !info.packageName.equals("android")) { 11230 addAppLocked(info, false, null /* ABI override */); 11231 } 11232 } 11233 } 11234 } catch (RemoteException ex) { 11235 // pm is in same process, this will never happen. 11236 } 11237 } 11238 11239 // Start up initial activity. 11240 mBooting = true; 11241 11242 try { 11243 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11244 Message msg = Message.obtain(); 11245 msg.what = SHOW_UID_ERROR_MSG; 11246 mHandler.sendMessage(msg); 11247 } 11248 } catch (RemoteException e) { 11249 } 11250 11251 long ident = Binder.clearCallingIdentity(); 11252 try { 11253 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11254 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11255 | Intent.FLAG_RECEIVER_FOREGROUND); 11256 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11257 broadcastIntentLocked(null, null, intent, 11258 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11259 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11260 intent = new Intent(Intent.ACTION_USER_STARTING); 11261 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11262 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11263 broadcastIntentLocked(null, null, intent, 11264 null, new IIntentReceiver.Stub() { 11265 @Override 11266 public void performReceive(Intent intent, int resultCode, String data, 11267 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11268 throws RemoteException { 11269 } 11270 }, 0, null, null, 11271 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11272 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11273 } catch (Throwable t) { 11274 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11275 } finally { 11276 Binder.restoreCallingIdentity(ident); 11277 } 11278 mStackSupervisor.resumeTopActivitiesLocked(); 11279 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11280 } 11281 } 11282 11283 private boolean makeAppCrashingLocked(ProcessRecord app, 11284 String shortMsg, String longMsg, String stackTrace) { 11285 app.crashing = true; 11286 app.crashingReport = generateProcessError(app, 11287 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11288 startAppProblemLocked(app); 11289 app.stopFreezingAllLocked(); 11290 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11291 } 11292 11293 private void makeAppNotRespondingLocked(ProcessRecord app, 11294 String activity, String shortMsg, String longMsg) { 11295 app.notResponding = true; 11296 app.notRespondingReport = generateProcessError(app, 11297 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11298 activity, shortMsg, longMsg, null); 11299 startAppProblemLocked(app); 11300 app.stopFreezingAllLocked(); 11301 } 11302 11303 /** 11304 * Generate a process error record, suitable for attachment to a ProcessRecord. 11305 * 11306 * @param app The ProcessRecord in which the error occurred. 11307 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11308 * ActivityManager.AppErrorStateInfo 11309 * @param activity The activity associated with the crash, if known. 11310 * @param shortMsg Short message describing the crash. 11311 * @param longMsg Long message describing the crash. 11312 * @param stackTrace Full crash stack trace, may be null. 11313 * 11314 * @return Returns a fully-formed AppErrorStateInfo record. 11315 */ 11316 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11317 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11318 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11319 11320 report.condition = condition; 11321 report.processName = app.processName; 11322 report.pid = app.pid; 11323 report.uid = app.info.uid; 11324 report.tag = activity; 11325 report.shortMsg = shortMsg; 11326 report.longMsg = longMsg; 11327 report.stackTrace = stackTrace; 11328 11329 return report; 11330 } 11331 11332 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11333 synchronized (this) { 11334 app.crashing = false; 11335 app.crashingReport = null; 11336 app.notResponding = false; 11337 app.notRespondingReport = null; 11338 if (app.anrDialog == fromDialog) { 11339 app.anrDialog = null; 11340 } 11341 if (app.waitDialog == fromDialog) { 11342 app.waitDialog = null; 11343 } 11344 if (app.pid > 0 && app.pid != MY_PID) { 11345 handleAppCrashLocked(app, null, null, null); 11346 app.kill("user request after error", true); 11347 } 11348 } 11349 } 11350 11351 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11352 String stackTrace) { 11353 long now = SystemClock.uptimeMillis(); 11354 11355 Long crashTime; 11356 if (!app.isolated) { 11357 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11358 } else { 11359 crashTime = null; 11360 } 11361 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11362 // This process loses! 11363 Slog.w(TAG, "Process " + app.info.processName 11364 + " has crashed too many times: killing!"); 11365 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11366 app.userId, app.info.processName, app.uid); 11367 mStackSupervisor.handleAppCrashLocked(app); 11368 if (!app.persistent) { 11369 // We don't want to start this process again until the user 11370 // explicitly does so... but for persistent process, we really 11371 // need to keep it running. If a persistent process is actually 11372 // repeatedly crashing, then badness for everyone. 11373 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11374 app.info.processName); 11375 if (!app.isolated) { 11376 // XXX We don't have a way to mark isolated processes 11377 // as bad, since they don't have a peristent identity. 11378 mBadProcesses.put(app.info.processName, app.uid, 11379 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11380 mProcessCrashTimes.remove(app.info.processName, app.uid); 11381 } 11382 app.bad = true; 11383 app.removed = true; 11384 // Don't let services in this process be restarted and potentially 11385 // annoy the user repeatedly. Unless it is persistent, since those 11386 // processes run critical code. 11387 removeProcessLocked(app, false, false, "crash"); 11388 mStackSupervisor.resumeTopActivitiesLocked(); 11389 return false; 11390 } 11391 mStackSupervisor.resumeTopActivitiesLocked(); 11392 } else { 11393 mStackSupervisor.finishTopRunningActivityLocked(app); 11394 } 11395 11396 // Bump up the crash count of any services currently running in the proc. 11397 for (int i=app.services.size()-1; i>=0; i--) { 11398 // Any services running in the application need to be placed 11399 // back in the pending list. 11400 ServiceRecord sr = app.services.valueAt(i); 11401 sr.crashCount++; 11402 } 11403 11404 // If the crashing process is what we consider to be the "home process" and it has been 11405 // replaced by a third-party app, clear the package preferred activities from packages 11406 // with a home activity running in the process to prevent a repeatedly crashing app 11407 // from blocking the user to manually clear the list. 11408 final ArrayList<ActivityRecord> activities = app.activities; 11409 if (app == mHomeProcess && activities.size() > 0 11410 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11411 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11412 final ActivityRecord r = activities.get(activityNdx); 11413 if (r.isHomeActivity()) { 11414 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11415 try { 11416 ActivityThread.getPackageManager() 11417 .clearPackagePreferredActivities(r.packageName); 11418 } catch (RemoteException c) { 11419 // pm is in same process, this will never happen. 11420 } 11421 } 11422 } 11423 } 11424 11425 if (!app.isolated) { 11426 // XXX Can't keep track of crash times for isolated processes, 11427 // because they don't have a perisistent identity. 11428 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11429 } 11430 11431 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11432 return true; 11433 } 11434 11435 void startAppProblemLocked(ProcessRecord app) { 11436 // If this app is not running under the current user, then we 11437 // can't give it a report button because that would require 11438 // launching the report UI under a different user. 11439 app.errorReportReceiver = null; 11440 11441 for (int userId : mCurrentProfileIds) { 11442 if (app.userId == userId) { 11443 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11444 mContext, app.info.packageName, app.info.flags); 11445 } 11446 } 11447 skipCurrentReceiverLocked(app); 11448 } 11449 11450 void skipCurrentReceiverLocked(ProcessRecord app) { 11451 for (BroadcastQueue queue : mBroadcastQueues) { 11452 queue.skipCurrentReceiverLocked(app); 11453 } 11454 } 11455 11456 /** 11457 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11458 * The application process will exit immediately after this call returns. 11459 * @param app object of the crashing app, null for the system server 11460 * @param crashInfo describing the exception 11461 */ 11462 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11463 ProcessRecord r = findAppProcess(app, "Crash"); 11464 final String processName = app == null ? "system_server" 11465 : (r == null ? "unknown" : r.processName); 11466 11467 handleApplicationCrashInner("crash", r, processName, crashInfo); 11468 } 11469 11470 /* Native crash reporting uses this inner version because it needs to be somewhat 11471 * decoupled from the AM-managed cleanup lifecycle 11472 */ 11473 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11474 ApplicationErrorReport.CrashInfo crashInfo) { 11475 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11476 UserHandle.getUserId(Binder.getCallingUid()), processName, 11477 r == null ? -1 : r.info.flags, 11478 crashInfo.exceptionClassName, 11479 crashInfo.exceptionMessage, 11480 crashInfo.throwFileName, 11481 crashInfo.throwLineNumber); 11482 11483 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11484 11485 crashApplication(r, crashInfo); 11486 } 11487 11488 public void handleApplicationStrictModeViolation( 11489 IBinder app, 11490 int violationMask, 11491 StrictMode.ViolationInfo info) { 11492 ProcessRecord r = findAppProcess(app, "StrictMode"); 11493 if (r == null) { 11494 return; 11495 } 11496 11497 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11498 Integer stackFingerprint = info.hashCode(); 11499 boolean logIt = true; 11500 synchronized (mAlreadyLoggedViolatedStacks) { 11501 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11502 logIt = false; 11503 // TODO: sub-sample into EventLog for these, with 11504 // the info.durationMillis? Then we'd get 11505 // the relative pain numbers, without logging all 11506 // the stack traces repeatedly. We'd want to do 11507 // likewise in the client code, which also does 11508 // dup suppression, before the Binder call. 11509 } else { 11510 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11511 mAlreadyLoggedViolatedStacks.clear(); 11512 } 11513 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11514 } 11515 } 11516 if (logIt) { 11517 logStrictModeViolationToDropBox(r, info); 11518 } 11519 } 11520 11521 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11522 AppErrorResult result = new AppErrorResult(); 11523 synchronized (this) { 11524 final long origId = Binder.clearCallingIdentity(); 11525 11526 Message msg = Message.obtain(); 11527 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11528 HashMap<String, Object> data = new HashMap<String, Object>(); 11529 data.put("result", result); 11530 data.put("app", r); 11531 data.put("violationMask", violationMask); 11532 data.put("info", info); 11533 msg.obj = data; 11534 mHandler.sendMessage(msg); 11535 11536 Binder.restoreCallingIdentity(origId); 11537 } 11538 int res = result.get(); 11539 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11540 } 11541 } 11542 11543 // Depending on the policy in effect, there could be a bunch of 11544 // these in quick succession so we try to batch these together to 11545 // minimize disk writes, number of dropbox entries, and maximize 11546 // compression, by having more fewer, larger records. 11547 private void logStrictModeViolationToDropBox( 11548 ProcessRecord process, 11549 StrictMode.ViolationInfo info) { 11550 if (info == null) { 11551 return; 11552 } 11553 final boolean isSystemApp = process == null || 11554 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11555 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11556 final String processName = process == null ? "unknown" : process.processName; 11557 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11558 final DropBoxManager dbox = (DropBoxManager) 11559 mContext.getSystemService(Context.DROPBOX_SERVICE); 11560 11561 // Exit early if the dropbox isn't configured to accept this report type. 11562 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11563 11564 boolean bufferWasEmpty; 11565 boolean needsFlush; 11566 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11567 synchronized (sb) { 11568 bufferWasEmpty = sb.length() == 0; 11569 appendDropBoxProcessHeaders(process, processName, sb); 11570 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11571 sb.append("System-App: ").append(isSystemApp).append("\n"); 11572 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11573 if (info.violationNumThisLoop != 0) { 11574 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11575 } 11576 if (info.numAnimationsRunning != 0) { 11577 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11578 } 11579 if (info.broadcastIntentAction != null) { 11580 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11581 } 11582 if (info.durationMillis != -1) { 11583 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11584 } 11585 if (info.numInstances != -1) { 11586 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11587 } 11588 if (info.tags != null) { 11589 for (String tag : info.tags) { 11590 sb.append("Span-Tag: ").append(tag).append("\n"); 11591 } 11592 } 11593 sb.append("\n"); 11594 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11595 sb.append(info.crashInfo.stackTrace); 11596 } 11597 sb.append("\n"); 11598 11599 // Only buffer up to ~64k. Various logging bits truncate 11600 // things at 128k. 11601 needsFlush = (sb.length() > 64 * 1024); 11602 } 11603 11604 // Flush immediately if the buffer's grown too large, or this 11605 // is a non-system app. Non-system apps are isolated with a 11606 // different tag & policy and not batched. 11607 // 11608 // Batching is useful during internal testing with 11609 // StrictMode settings turned up high. Without batching, 11610 // thousands of separate files could be created on boot. 11611 if (!isSystemApp || needsFlush) { 11612 new Thread("Error dump: " + dropboxTag) { 11613 @Override 11614 public void run() { 11615 String report; 11616 synchronized (sb) { 11617 report = sb.toString(); 11618 sb.delete(0, sb.length()); 11619 sb.trimToSize(); 11620 } 11621 if (report.length() != 0) { 11622 dbox.addText(dropboxTag, report); 11623 } 11624 } 11625 }.start(); 11626 return; 11627 } 11628 11629 // System app batching: 11630 if (!bufferWasEmpty) { 11631 // An existing dropbox-writing thread is outstanding, so 11632 // we don't need to start it up. The existing thread will 11633 // catch the buffer appends we just did. 11634 return; 11635 } 11636 11637 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11638 // (After this point, we shouldn't access AMS internal data structures.) 11639 new Thread("Error dump: " + dropboxTag) { 11640 @Override 11641 public void run() { 11642 // 5 second sleep to let stacks arrive and be batched together 11643 try { 11644 Thread.sleep(5000); // 5 seconds 11645 } catch (InterruptedException e) {} 11646 11647 String errorReport; 11648 synchronized (mStrictModeBuffer) { 11649 errorReport = mStrictModeBuffer.toString(); 11650 if (errorReport.length() == 0) { 11651 return; 11652 } 11653 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11654 mStrictModeBuffer.trimToSize(); 11655 } 11656 dbox.addText(dropboxTag, errorReport); 11657 } 11658 }.start(); 11659 } 11660 11661 /** 11662 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11663 * @param app object of the crashing app, null for the system server 11664 * @param tag reported by the caller 11665 * @param system whether this wtf is coming from the system 11666 * @param crashInfo describing the context of the error 11667 * @return true if the process should exit immediately (WTF is fatal) 11668 */ 11669 public boolean handleApplicationWtf(IBinder app, final String tag, boolean system, 11670 final ApplicationErrorReport.CrashInfo crashInfo) { 11671 final ProcessRecord r = findAppProcess(app, "WTF"); 11672 final String processName = app == null ? "system_server" 11673 : (r == null ? "unknown" : r.processName); 11674 11675 EventLog.writeEvent(EventLogTags.AM_WTF, 11676 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 11677 processName, 11678 r == null ? -1 : r.info.flags, 11679 tag, crashInfo.exceptionMessage); 11680 11681 if (system) { 11682 // If this is coming from the system, we could very well have low-level 11683 // system locks held, so we want to do this all asynchronously. And we 11684 // never want this to become fatal, so there is that too. 11685 mHandler.post(new Runnable() { 11686 @Override public void run() { 11687 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, 11688 crashInfo); 11689 } 11690 }); 11691 return false; 11692 } 11693 11694 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11695 11696 if (r != null && r.pid != Process.myPid() && 11697 Settings.Global.getInt(mContext.getContentResolver(), 11698 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11699 crashApplication(r, crashInfo); 11700 return true; 11701 } else { 11702 return false; 11703 } 11704 } 11705 11706 /** 11707 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11708 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11709 */ 11710 private ProcessRecord findAppProcess(IBinder app, String reason) { 11711 if (app == null) { 11712 return null; 11713 } 11714 11715 synchronized (this) { 11716 final int NP = mProcessNames.getMap().size(); 11717 for (int ip=0; ip<NP; ip++) { 11718 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11719 final int NA = apps.size(); 11720 for (int ia=0; ia<NA; ia++) { 11721 ProcessRecord p = apps.valueAt(ia); 11722 if (p.thread != null && p.thread.asBinder() == app) { 11723 return p; 11724 } 11725 } 11726 } 11727 11728 Slog.w(TAG, "Can't find mystery application for " + reason 11729 + " from pid=" + Binder.getCallingPid() 11730 + " uid=" + Binder.getCallingUid() + ": " + app); 11731 return null; 11732 } 11733 } 11734 11735 /** 11736 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11737 * to append various headers to the dropbox log text. 11738 */ 11739 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11740 StringBuilder sb) { 11741 // Watchdog thread ends up invoking this function (with 11742 // a null ProcessRecord) to add the stack file to dropbox. 11743 // Do not acquire a lock on this (am) in such cases, as it 11744 // could cause a potential deadlock, if and when watchdog 11745 // is invoked due to unavailability of lock on am and it 11746 // would prevent watchdog from killing system_server. 11747 if (process == null) { 11748 sb.append("Process: ").append(processName).append("\n"); 11749 return; 11750 } 11751 // Note: ProcessRecord 'process' is guarded by the service 11752 // instance. (notably process.pkgList, which could otherwise change 11753 // concurrently during execution of this method) 11754 synchronized (this) { 11755 sb.append("Process: ").append(processName).append("\n"); 11756 int flags = process.info.flags; 11757 IPackageManager pm = AppGlobals.getPackageManager(); 11758 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11759 for (int ip=0; ip<process.pkgList.size(); ip++) { 11760 String pkg = process.pkgList.keyAt(ip); 11761 sb.append("Package: ").append(pkg); 11762 try { 11763 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11764 if (pi != null) { 11765 sb.append(" v").append(pi.versionCode); 11766 if (pi.versionName != null) { 11767 sb.append(" (").append(pi.versionName).append(")"); 11768 } 11769 } 11770 } catch (RemoteException e) { 11771 Slog.e(TAG, "Error getting package info: " + pkg, e); 11772 } 11773 sb.append("\n"); 11774 } 11775 } 11776 } 11777 11778 private static String processClass(ProcessRecord process) { 11779 if (process == null || process.pid == MY_PID) { 11780 return "system_server"; 11781 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11782 return "system_app"; 11783 } else { 11784 return "data_app"; 11785 } 11786 } 11787 11788 /** 11789 * Write a description of an error (crash, WTF, ANR) to the drop box. 11790 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11791 * @param process which caused the error, null means the system server 11792 * @param activity which triggered the error, null if unknown 11793 * @param parent activity related to the error, null if unknown 11794 * @param subject line related to the error, null if absent 11795 * @param report in long form describing the error, null if absent 11796 * @param logFile to include in the report, null if none 11797 * @param crashInfo giving an application stack trace, null if absent 11798 */ 11799 public void addErrorToDropBox(String eventType, 11800 ProcessRecord process, String processName, ActivityRecord activity, 11801 ActivityRecord parent, String subject, 11802 final String report, final File logFile, 11803 final ApplicationErrorReport.CrashInfo crashInfo) { 11804 // NOTE -- this must never acquire the ActivityManagerService lock, 11805 // otherwise the watchdog may be prevented from resetting the system. 11806 11807 final String dropboxTag = processClass(process) + "_" + eventType; 11808 final DropBoxManager dbox = (DropBoxManager) 11809 mContext.getSystemService(Context.DROPBOX_SERVICE); 11810 11811 // Exit early if the dropbox isn't configured to accept this report type. 11812 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11813 11814 final StringBuilder sb = new StringBuilder(1024); 11815 appendDropBoxProcessHeaders(process, processName, sb); 11816 if (activity != null) { 11817 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11818 } 11819 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11820 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11821 } 11822 if (parent != null && parent != activity) { 11823 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11824 } 11825 if (subject != null) { 11826 sb.append("Subject: ").append(subject).append("\n"); 11827 } 11828 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11829 if (Debug.isDebuggerConnected()) { 11830 sb.append("Debugger: Connected\n"); 11831 } 11832 sb.append("\n"); 11833 11834 // Do the rest in a worker thread to avoid blocking the caller on I/O 11835 // (After this point, we shouldn't access AMS internal data structures.) 11836 Thread worker = new Thread("Error dump: " + dropboxTag) { 11837 @Override 11838 public void run() { 11839 if (report != null) { 11840 sb.append(report); 11841 } 11842 if (logFile != null) { 11843 try { 11844 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11845 "\n\n[[TRUNCATED]]")); 11846 } catch (IOException e) { 11847 Slog.e(TAG, "Error reading " + logFile, e); 11848 } 11849 } 11850 if (crashInfo != null && crashInfo.stackTrace != null) { 11851 sb.append(crashInfo.stackTrace); 11852 } 11853 11854 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11855 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11856 if (lines > 0) { 11857 sb.append("\n"); 11858 11859 // Merge several logcat streams, and take the last N lines 11860 InputStreamReader input = null; 11861 try { 11862 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11863 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11864 "-b", "crash", 11865 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11866 11867 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11868 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11869 input = new InputStreamReader(logcat.getInputStream()); 11870 11871 int num; 11872 char[] buf = new char[8192]; 11873 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11874 } catch (IOException e) { 11875 Slog.e(TAG, "Error running logcat", e); 11876 } finally { 11877 if (input != null) try { input.close(); } catch (IOException e) {} 11878 } 11879 } 11880 11881 dbox.addText(dropboxTag, sb.toString()); 11882 } 11883 }; 11884 11885 if (process == null) { 11886 // If process is null, we are being called from some internal code 11887 // and may be about to die -- run this synchronously. 11888 worker.run(); 11889 } else { 11890 worker.start(); 11891 } 11892 } 11893 11894 /** 11895 * Bring up the "unexpected error" dialog box for a crashing app. 11896 * Deal with edge cases (intercepts from instrumented applications, 11897 * ActivityController, error intent receivers, that sort of thing). 11898 * @param r the application crashing 11899 * @param crashInfo describing the failure 11900 */ 11901 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11902 long timeMillis = System.currentTimeMillis(); 11903 String shortMsg = crashInfo.exceptionClassName; 11904 String longMsg = crashInfo.exceptionMessage; 11905 String stackTrace = crashInfo.stackTrace; 11906 if (shortMsg != null && longMsg != null) { 11907 longMsg = shortMsg + ": " + longMsg; 11908 } else if (shortMsg != null) { 11909 longMsg = shortMsg; 11910 } 11911 11912 AppErrorResult result = new AppErrorResult(); 11913 synchronized (this) { 11914 if (mController != null) { 11915 try { 11916 String name = r != null ? r.processName : null; 11917 int pid = r != null ? r.pid : Binder.getCallingPid(); 11918 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11919 if (!mController.appCrashed(name, pid, 11920 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11921 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11922 && "Native crash".equals(crashInfo.exceptionClassName)) { 11923 Slog.w(TAG, "Skip killing native crashed app " + name 11924 + "(" + pid + ") during testing"); 11925 } else { 11926 Slog.w(TAG, "Force-killing crashed app " + name 11927 + " at watcher's request"); 11928 if (r != null) { 11929 r.kill("crash", true); 11930 } else { 11931 // Huh. 11932 Process.killProcess(pid); 11933 Process.killProcessGroup(uid, pid); 11934 } 11935 } 11936 return; 11937 } 11938 } catch (RemoteException e) { 11939 mController = null; 11940 Watchdog.getInstance().setActivityController(null); 11941 } 11942 } 11943 11944 final long origId = Binder.clearCallingIdentity(); 11945 11946 // If this process is running instrumentation, finish it. 11947 if (r != null && r.instrumentationClass != null) { 11948 Slog.w(TAG, "Error in app " + r.processName 11949 + " running instrumentation " + r.instrumentationClass + ":"); 11950 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11951 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11952 Bundle info = new Bundle(); 11953 info.putString("shortMsg", shortMsg); 11954 info.putString("longMsg", longMsg); 11955 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11956 Binder.restoreCallingIdentity(origId); 11957 return; 11958 } 11959 11960 // If we can't identify the process or it's already exceeded its crash quota, 11961 // quit right away without showing a crash dialog. 11962 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11963 Binder.restoreCallingIdentity(origId); 11964 return; 11965 } 11966 11967 Message msg = Message.obtain(); 11968 msg.what = SHOW_ERROR_MSG; 11969 HashMap data = new HashMap(); 11970 data.put("result", result); 11971 data.put("app", r); 11972 msg.obj = data; 11973 mHandler.sendMessage(msg); 11974 11975 Binder.restoreCallingIdentity(origId); 11976 } 11977 11978 int res = result.get(); 11979 11980 Intent appErrorIntent = null; 11981 synchronized (this) { 11982 if (r != null && !r.isolated) { 11983 // XXX Can't keep track of crash time for isolated processes, 11984 // since they don't have a persistent identity. 11985 mProcessCrashTimes.put(r.info.processName, r.uid, 11986 SystemClock.uptimeMillis()); 11987 } 11988 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11989 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11990 } 11991 } 11992 11993 if (appErrorIntent != null) { 11994 try { 11995 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11996 } catch (ActivityNotFoundException e) { 11997 Slog.w(TAG, "bug report receiver dissappeared", e); 11998 } 11999 } 12000 } 12001 12002 Intent createAppErrorIntentLocked(ProcessRecord r, 12003 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12004 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12005 if (report == null) { 12006 return null; 12007 } 12008 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12009 result.setComponent(r.errorReportReceiver); 12010 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12011 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12012 return result; 12013 } 12014 12015 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12016 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12017 if (r.errorReportReceiver == null) { 12018 return null; 12019 } 12020 12021 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12022 return null; 12023 } 12024 12025 ApplicationErrorReport report = new ApplicationErrorReport(); 12026 report.packageName = r.info.packageName; 12027 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12028 report.processName = r.processName; 12029 report.time = timeMillis; 12030 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12031 12032 if (r.crashing || r.forceCrashReport) { 12033 report.type = ApplicationErrorReport.TYPE_CRASH; 12034 report.crashInfo = crashInfo; 12035 } else if (r.notResponding) { 12036 report.type = ApplicationErrorReport.TYPE_ANR; 12037 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12038 12039 report.anrInfo.activity = r.notRespondingReport.tag; 12040 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12041 report.anrInfo.info = r.notRespondingReport.longMsg; 12042 } 12043 12044 return report; 12045 } 12046 12047 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12048 enforceNotIsolatedCaller("getProcessesInErrorState"); 12049 // assume our apps are happy - lazy create the list 12050 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12051 12052 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12053 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12054 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12055 12056 synchronized (this) { 12057 12058 // iterate across all processes 12059 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12060 ProcessRecord app = mLruProcesses.get(i); 12061 if (!allUsers && app.userId != userId) { 12062 continue; 12063 } 12064 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12065 // This one's in trouble, so we'll generate a report for it 12066 // crashes are higher priority (in case there's a crash *and* an anr) 12067 ActivityManager.ProcessErrorStateInfo report = null; 12068 if (app.crashing) { 12069 report = app.crashingReport; 12070 } else if (app.notResponding) { 12071 report = app.notRespondingReport; 12072 } 12073 12074 if (report != null) { 12075 if (errList == null) { 12076 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12077 } 12078 errList.add(report); 12079 } else { 12080 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12081 " crashing = " + app.crashing + 12082 " notResponding = " + app.notResponding); 12083 } 12084 } 12085 } 12086 } 12087 12088 return errList; 12089 } 12090 12091 static int procStateToImportance(int procState, int memAdj, 12092 ActivityManager.RunningAppProcessInfo currApp) { 12093 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12094 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12095 currApp.lru = memAdj; 12096 } else { 12097 currApp.lru = 0; 12098 } 12099 return imp; 12100 } 12101 12102 private void fillInProcMemInfo(ProcessRecord app, 12103 ActivityManager.RunningAppProcessInfo outInfo) { 12104 outInfo.pid = app.pid; 12105 outInfo.uid = app.info.uid; 12106 if (mHeavyWeightProcess == app) { 12107 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12108 } 12109 if (app.persistent) { 12110 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12111 } 12112 if (app.activities.size() > 0) { 12113 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12114 } 12115 outInfo.lastTrimLevel = app.trimMemoryLevel; 12116 int adj = app.curAdj; 12117 int procState = app.curProcState; 12118 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12119 outInfo.importanceReasonCode = app.adjTypeCode; 12120 outInfo.processState = app.curProcState; 12121 } 12122 12123 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12124 enforceNotIsolatedCaller("getRunningAppProcesses"); 12125 // Lazy instantiation of list 12126 List<ActivityManager.RunningAppProcessInfo> runList = null; 12127 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12128 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12129 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12130 synchronized (this) { 12131 // Iterate across all processes 12132 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12133 ProcessRecord app = mLruProcesses.get(i); 12134 if (!allUsers && app.userId != userId) { 12135 continue; 12136 } 12137 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12138 // Generate process state info for running application 12139 ActivityManager.RunningAppProcessInfo currApp = 12140 new ActivityManager.RunningAppProcessInfo(app.processName, 12141 app.pid, app.getPackageList()); 12142 fillInProcMemInfo(app, currApp); 12143 if (app.adjSource instanceof ProcessRecord) { 12144 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12145 currApp.importanceReasonImportance = 12146 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12147 app.adjSourceProcState); 12148 } else if (app.adjSource instanceof ActivityRecord) { 12149 ActivityRecord r = (ActivityRecord)app.adjSource; 12150 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12151 } 12152 if (app.adjTarget instanceof ComponentName) { 12153 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12154 } 12155 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12156 // + " lru=" + currApp.lru); 12157 if (runList == null) { 12158 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12159 } 12160 runList.add(currApp); 12161 } 12162 } 12163 } 12164 return runList; 12165 } 12166 12167 public List<ApplicationInfo> getRunningExternalApplications() { 12168 enforceNotIsolatedCaller("getRunningExternalApplications"); 12169 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12170 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12171 if (runningApps != null && runningApps.size() > 0) { 12172 Set<String> extList = new HashSet<String>(); 12173 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12174 if (app.pkgList != null) { 12175 for (String pkg : app.pkgList) { 12176 extList.add(pkg); 12177 } 12178 } 12179 } 12180 IPackageManager pm = AppGlobals.getPackageManager(); 12181 for (String pkg : extList) { 12182 try { 12183 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12184 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12185 retList.add(info); 12186 } 12187 } catch (RemoteException e) { 12188 } 12189 } 12190 } 12191 return retList; 12192 } 12193 12194 @Override 12195 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12196 enforceNotIsolatedCaller("getMyMemoryState"); 12197 synchronized (this) { 12198 ProcessRecord proc; 12199 synchronized (mPidsSelfLocked) { 12200 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12201 } 12202 fillInProcMemInfo(proc, outInfo); 12203 } 12204 } 12205 12206 @Override 12207 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12208 if (checkCallingPermission(android.Manifest.permission.DUMP) 12209 != PackageManager.PERMISSION_GRANTED) { 12210 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12211 + Binder.getCallingPid() 12212 + ", uid=" + Binder.getCallingUid() 12213 + " without permission " 12214 + android.Manifest.permission.DUMP); 12215 return; 12216 } 12217 12218 boolean dumpAll = false; 12219 boolean dumpClient = false; 12220 String dumpPackage = null; 12221 12222 int opti = 0; 12223 while (opti < args.length) { 12224 String opt = args[opti]; 12225 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12226 break; 12227 } 12228 opti++; 12229 if ("-a".equals(opt)) { 12230 dumpAll = true; 12231 } else if ("-c".equals(opt)) { 12232 dumpClient = true; 12233 } else if ("-h".equals(opt)) { 12234 pw.println("Activity manager dump options:"); 12235 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12236 pw.println(" cmd may be one of:"); 12237 pw.println(" a[ctivities]: activity stack state"); 12238 pw.println(" r[recents]: recent activities state"); 12239 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12240 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12241 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12242 pw.println(" o[om]: out of memory management"); 12243 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12244 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12245 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12246 pw.println(" service [COMP_SPEC]: service client-side state"); 12247 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12248 pw.println(" all: dump all activities"); 12249 pw.println(" top: dump the top activity"); 12250 pw.println(" write: write all pending state to storage"); 12251 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12252 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12253 pw.println(" a partial substring in a component name, a"); 12254 pw.println(" hex object identifier."); 12255 pw.println(" -a: include all available server state."); 12256 pw.println(" -c: include client state."); 12257 return; 12258 } else { 12259 pw.println("Unknown argument: " + opt + "; use -h for help"); 12260 } 12261 } 12262 12263 long origId = Binder.clearCallingIdentity(); 12264 boolean more = false; 12265 // Is the caller requesting to dump a particular piece of data? 12266 if (opti < args.length) { 12267 String cmd = args[opti]; 12268 opti++; 12269 if ("activities".equals(cmd) || "a".equals(cmd)) { 12270 synchronized (this) { 12271 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12272 } 12273 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12274 synchronized (this) { 12275 dumpRecentsLocked(fd, pw, args, opti, true, null); 12276 } 12277 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12278 String[] newArgs; 12279 String name; 12280 if (opti >= args.length) { 12281 name = null; 12282 newArgs = EMPTY_STRING_ARRAY; 12283 } else { 12284 name = args[opti]; 12285 opti++; 12286 newArgs = new String[args.length - opti]; 12287 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12288 args.length - opti); 12289 } 12290 synchronized (this) { 12291 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12292 } 12293 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12294 String[] newArgs; 12295 String name; 12296 if (opti >= args.length) { 12297 name = null; 12298 newArgs = EMPTY_STRING_ARRAY; 12299 } else { 12300 name = args[opti]; 12301 opti++; 12302 newArgs = new String[args.length - opti]; 12303 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12304 args.length - opti); 12305 } 12306 synchronized (this) { 12307 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12308 } 12309 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12310 String[] newArgs; 12311 String name; 12312 if (opti >= args.length) { 12313 name = null; 12314 newArgs = EMPTY_STRING_ARRAY; 12315 } else { 12316 name = args[opti]; 12317 opti++; 12318 newArgs = new String[args.length - opti]; 12319 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12320 args.length - opti); 12321 } 12322 synchronized (this) { 12323 dumpProcessesLocked(fd, pw, args, opti, true, name); 12324 } 12325 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12326 synchronized (this) { 12327 dumpOomLocked(fd, pw, args, opti, true); 12328 } 12329 } else if ("provider".equals(cmd)) { 12330 String[] newArgs; 12331 String name; 12332 if (opti >= args.length) { 12333 name = null; 12334 newArgs = EMPTY_STRING_ARRAY; 12335 } else { 12336 name = args[opti]; 12337 opti++; 12338 newArgs = new String[args.length - opti]; 12339 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12340 } 12341 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12342 pw.println("No providers match: " + name); 12343 pw.println("Use -h for help."); 12344 } 12345 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12346 synchronized (this) { 12347 dumpProvidersLocked(fd, pw, args, opti, true, null); 12348 } 12349 } else if ("service".equals(cmd)) { 12350 String[] newArgs; 12351 String name; 12352 if (opti >= args.length) { 12353 name = null; 12354 newArgs = EMPTY_STRING_ARRAY; 12355 } else { 12356 name = args[opti]; 12357 opti++; 12358 newArgs = new String[args.length - opti]; 12359 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12360 args.length - opti); 12361 } 12362 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12363 pw.println("No services match: " + name); 12364 pw.println("Use -h for help."); 12365 } 12366 } else if ("package".equals(cmd)) { 12367 String[] newArgs; 12368 if (opti >= args.length) { 12369 pw.println("package: no package name specified"); 12370 pw.println("Use -h for help."); 12371 } else { 12372 dumpPackage = args[opti]; 12373 opti++; 12374 newArgs = new String[args.length - opti]; 12375 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12376 args.length - opti); 12377 args = newArgs; 12378 opti = 0; 12379 more = true; 12380 } 12381 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12382 synchronized (this) { 12383 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12384 } 12385 } else if ("write".equals(cmd)) { 12386 mTaskPersister.flush(); 12387 pw.println("All tasks persisted."); 12388 return; 12389 } else { 12390 // Dumping a single activity? 12391 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12392 pw.println("Bad activity command, or no activities match: " + cmd); 12393 pw.println("Use -h for help."); 12394 } 12395 } 12396 if (!more) { 12397 Binder.restoreCallingIdentity(origId); 12398 return; 12399 } 12400 } 12401 12402 // No piece of data specified, dump everything. 12403 synchronized (this) { 12404 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12405 pw.println(); 12406 if (dumpAll) { 12407 pw.println("-------------------------------------------------------------------------------"); 12408 } 12409 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12410 pw.println(); 12411 if (dumpAll) { 12412 pw.println("-------------------------------------------------------------------------------"); 12413 } 12414 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12415 pw.println(); 12416 if (dumpAll) { 12417 pw.println("-------------------------------------------------------------------------------"); 12418 } 12419 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12420 pw.println(); 12421 if (dumpAll) { 12422 pw.println("-------------------------------------------------------------------------------"); 12423 } 12424 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12425 pw.println(); 12426 if (dumpAll) { 12427 pw.println("-------------------------------------------------------------------------------"); 12428 } 12429 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12430 pw.println(); 12431 if (dumpAll) { 12432 pw.println("-------------------------------------------------------------------------------"); 12433 } 12434 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12435 } 12436 Binder.restoreCallingIdentity(origId); 12437 } 12438 12439 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12440 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12441 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12442 12443 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12444 dumpPackage); 12445 boolean needSep = printedAnything; 12446 12447 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12448 dumpPackage, needSep, " mFocusedActivity: "); 12449 if (printed) { 12450 printedAnything = true; 12451 needSep = false; 12452 } 12453 12454 if (dumpPackage == null) { 12455 if (needSep) { 12456 pw.println(); 12457 } 12458 needSep = true; 12459 printedAnything = true; 12460 mStackSupervisor.dump(pw, " "); 12461 } 12462 12463 if (!printedAnything) { 12464 pw.println(" (nothing)"); 12465 } 12466 } 12467 12468 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12469 int opti, boolean dumpAll, String dumpPackage) { 12470 pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)"); 12471 12472 boolean printedAnything = false; 12473 12474 if (mRecentTasks.size() > 0) { 12475 boolean printedHeader = false; 12476 12477 final int N = mRecentTasks.size(); 12478 for (int i=0; i<N; i++) { 12479 TaskRecord tr = mRecentTasks.get(i); 12480 if (dumpPackage != null) { 12481 if (tr.realActivity == null || 12482 !dumpPackage.equals(tr.realActivity)) { 12483 continue; 12484 } 12485 } 12486 if (!printedHeader) { 12487 pw.println(" Recent tasks:"); 12488 printedHeader = true; 12489 printedAnything = true; 12490 } 12491 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12492 pw.println(tr); 12493 if (dumpAll) { 12494 mRecentTasks.get(i).dump(pw, " "); 12495 } 12496 } 12497 } 12498 12499 if (!printedAnything) { 12500 pw.println(" (nothing)"); 12501 } 12502 } 12503 12504 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12505 int opti, boolean dumpAll, String dumpPackage) { 12506 boolean needSep = false; 12507 boolean printedAnything = false; 12508 int numPers = 0; 12509 12510 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12511 12512 if (dumpAll) { 12513 final int NP = mProcessNames.getMap().size(); 12514 for (int ip=0; ip<NP; ip++) { 12515 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12516 final int NA = procs.size(); 12517 for (int ia=0; ia<NA; ia++) { 12518 ProcessRecord r = procs.valueAt(ia); 12519 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12520 continue; 12521 } 12522 if (!needSep) { 12523 pw.println(" All known processes:"); 12524 needSep = true; 12525 printedAnything = true; 12526 } 12527 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12528 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12529 pw.print(" "); pw.println(r); 12530 r.dump(pw, " "); 12531 if (r.persistent) { 12532 numPers++; 12533 } 12534 } 12535 } 12536 } 12537 12538 if (mIsolatedProcesses.size() > 0) { 12539 boolean printed = false; 12540 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12541 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12542 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12543 continue; 12544 } 12545 if (!printed) { 12546 if (needSep) { 12547 pw.println(); 12548 } 12549 pw.println(" Isolated process list (sorted by uid):"); 12550 printedAnything = true; 12551 printed = true; 12552 needSep = true; 12553 } 12554 pw.println(String.format("%sIsolated #%2d: %s", 12555 " ", i, r.toString())); 12556 } 12557 } 12558 12559 if (mLruProcesses.size() > 0) { 12560 if (needSep) { 12561 pw.println(); 12562 } 12563 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12564 pw.print(" total, non-act at "); 12565 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12566 pw.print(", non-svc at "); 12567 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12568 pw.println("):"); 12569 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12570 needSep = true; 12571 printedAnything = true; 12572 } 12573 12574 if (dumpAll || dumpPackage != null) { 12575 synchronized (mPidsSelfLocked) { 12576 boolean printed = false; 12577 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12578 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12579 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12580 continue; 12581 } 12582 if (!printed) { 12583 if (needSep) pw.println(); 12584 needSep = true; 12585 pw.println(" PID mappings:"); 12586 printed = true; 12587 printedAnything = true; 12588 } 12589 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12590 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12591 } 12592 } 12593 } 12594 12595 if (mForegroundProcesses.size() > 0) { 12596 synchronized (mPidsSelfLocked) { 12597 boolean printed = false; 12598 for (int i=0; i<mForegroundProcesses.size(); i++) { 12599 ProcessRecord r = mPidsSelfLocked.get( 12600 mForegroundProcesses.valueAt(i).pid); 12601 if (dumpPackage != null && (r == null 12602 || !r.pkgList.containsKey(dumpPackage))) { 12603 continue; 12604 } 12605 if (!printed) { 12606 if (needSep) pw.println(); 12607 needSep = true; 12608 pw.println(" Foreground Processes:"); 12609 printed = true; 12610 printedAnything = true; 12611 } 12612 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12613 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12614 } 12615 } 12616 } 12617 12618 if (mPersistentStartingProcesses.size() > 0) { 12619 if (needSep) pw.println(); 12620 needSep = true; 12621 printedAnything = true; 12622 pw.println(" Persisent processes that are starting:"); 12623 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12624 "Starting Norm", "Restarting PERS", dumpPackage); 12625 } 12626 12627 if (mRemovedProcesses.size() > 0) { 12628 if (needSep) pw.println(); 12629 needSep = true; 12630 printedAnything = true; 12631 pw.println(" Processes that are being removed:"); 12632 dumpProcessList(pw, this, mRemovedProcesses, " ", 12633 "Removed Norm", "Removed PERS", dumpPackage); 12634 } 12635 12636 if (mProcessesOnHold.size() > 0) { 12637 if (needSep) pw.println(); 12638 needSep = true; 12639 printedAnything = true; 12640 pw.println(" Processes that are on old until the system is ready:"); 12641 dumpProcessList(pw, this, mProcessesOnHold, " ", 12642 "OnHold Norm", "OnHold PERS", dumpPackage); 12643 } 12644 12645 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12646 12647 if (mProcessCrashTimes.getMap().size() > 0) { 12648 boolean printed = false; 12649 long now = SystemClock.uptimeMillis(); 12650 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12651 final int NP = pmap.size(); 12652 for (int ip=0; ip<NP; ip++) { 12653 String pname = pmap.keyAt(ip); 12654 SparseArray<Long> uids = pmap.valueAt(ip); 12655 final int N = uids.size(); 12656 for (int i=0; i<N; i++) { 12657 int puid = uids.keyAt(i); 12658 ProcessRecord r = mProcessNames.get(pname, puid); 12659 if (dumpPackage != null && (r == null 12660 || !r.pkgList.containsKey(dumpPackage))) { 12661 continue; 12662 } 12663 if (!printed) { 12664 if (needSep) pw.println(); 12665 needSep = true; 12666 pw.println(" Time since processes crashed:"); 12667 printed = true; 12668 printedAnything = true; 12669 } 12670 pw.print(" Process "); pw.print(pname); 12671 pw.print(" uid "); pw.print(puid); 12672 pw.print(": last crashed "); 12673 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12674 pw.println(" ago"); 12675 } 12676 } 12677 } 12678 12679 if (mBadProcesses.getMap().size() > 0) { 12680 boolean printed = false; 12681 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12682 final int NP = pmap.size(); 12683 for (int ip=0; ip<NP; ip++) { 12684 String pname = pmap.keyAt(ip); 12685 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12686 final int N = uids.size(); 12687 for (int i=0; i<N; i++) { 12688 int puid = uids.keyAt(i); 12689 ProcessRecord r = mProcessNames.get(pname, puid); 12690 if (dumpPackage != null && (r == null 12691 || !r.pkgList.containsKey(dumpPackage))) { 12692 continue; 12693 } 12694 if (!printed) { 12695 if (needSep) pw.println(); 12696 needSep = true; 12697 pw.println(" Bad processes:"); 12698 printedAnything = true; 12699 } 12700 BadProcessInfo info = uids.valueAt(i); 12701 pw.print(" Bad process "); pw.print(pname); 12702 pw.print(" uid "); pw.print(puid); 12703 pw.print(": crashed at time "); pw.println(info.time); 12704 if (info.shortMsg != null) { 12705 pw.print(" Short msg: "); pw.println(info.shortMsg); 12706 } 12707 if (info.longMsg != null) { 12708 pw.print(" Long msg: "); pw.println(info.longMsg); 12709 } 12710 if (info.stack != null) { 12711 pw.println(" Stack:"); 12712 int lastPos = 0; 12713 for (int pos=0; pos<info.stack.length(); pos++) { 12714 if (info.stack.charAt(pos) == '\n') { 12715 pw.print(" "); 12716 pw.write(info.stack, lastPos, pos-lastPos); 12717 pw.println(); 12718 lastPos = pos+1; 12719 } 12720 } 12721 if (lastPos < info.stack.length()) { 12722 pw.print(" "); 12723 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12724 pw.println(); 12725 } 12726 } 12727 } 12728 } 12729 } 12730 12731 if (dumpPackage == null) { 12732 pw.println(); 12733 needSep = false; 12734 pw.println(" mStartedUsers:"); 12735 for (int i=0; i<mStartedUsers.size(); i++) { 12736 UserStartedState uss = mStartedUsers.valueAt(i); 12737 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12738 pw.print(": "); uss.dump("", pw); 12739 } 12740 pw.print(" mStartedUserArray: ["); 12741 for (int i=0; i<mStartedUserArray.length; i++) { 12742 if (i > 0) pw.print(", "); 12743 pw.print(mStartedUserArray[i]); 12744 } 12745 pw.println("]"); 12746 pw.print(" mUserLru: ["); 12747 for (int i=0; i<mUserLru.size(); i++) { 12748 if (i > 0) pw.print(", "); 12749 pw.print(mUserLru.get(i)); 12750 } 12751 pw.println("]"); 12752 if (dumpAll) { 12753 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12754 } 12755 synchronized (mUserProfileGroupIdsSelfLocked) { 12756 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12757 pw.println(" mUserProfileGroupIds:"); 12758 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12759 pw.print(" User #"); 12760 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12761 pw.print(" -> profile #"); 12762 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12763 } 12764 } 12765 } 12766 } 12767 if (mHomeProcess != null && (dumpPackage == null 12768 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12769 if (needSep) { 12770 pw.println(); 12771 needSep = false; 12772 } 12773 pw.println(" mHomeProcess: " + mHomeProcess); 12774 } 12775 if (mPreviousProcess != null && (dumpPackage == null 12776 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12777 if (needSep) { 12778 pw.println(); 12779 needSep = false; 12780 } 12781 pw.println(" mPreviousProcess: " + mPreviousProcess); 12782 } 12783 if (dumpAll) { 12784 StringBuilder sb = new StringBuilder(128); 12785 sb.append(" mPreviousProcessVisibleTime: "); 12786 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12787 pw.println(sb); 12788 } 12789 if (mHeavyWeightProcess != null && (dumpPackage == null 12790 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12791 if (needSep) { 12792 pw.println(); 12793 needSep = false; 12794 } 12795 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12796 } 12797 if (dumpPackage == null) { 12798 pw.println(" mConfiguration: " + mConfiguration); 12799 } 12800 if (dumpAll) { 12801 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12802 if (mCompatModePackages.getPackages().size() > 0) { 12803 boolean printed = false; 12804 for (Map.Entry<String, Integer> entry 12805 : mCompatModePackages.getPackages().entrySet()) { 12806 String pkg = entry.getKey(); 12807 int mode = entry.getValue(); 12808 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12809 continue; 12810 } 12811 if (!printed) { 12812 pw.println(" mScreenCompatPackages:"); 12813 printed = true; 12814 } 12815 pw.print(" "); pw.print(pkg); pw.print(": "); 12816 pw.print(mode); pw.println(); 12817 } 12818 } 12819 } 12820 if (dumpPackage == null) { 12821 if (mSleeping || mWentToSleep || mLockScreenShown) { 12822 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12823 + " mLockScreenShown " + mLockScreenShown); 12824 } 12825 if (mShuttingDown || mRunningVoice) { 12826 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12827 } 12828 } 12829 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12830 || mOrigWaitForDebugger) { 12831 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12832 || dumpPackage.equals(mOrigDebugApp)) { 12833 if (needSep) { 12834 pw.println(); 12835 needSep = false; 12836 } 12837 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12838 + " mDebugTransient=" + mDebugTransient 12839 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12840 } 12841 } 12842 if (mOpenGlTraceApp != null) { 12843 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12844 if (needSep) { 12845 pw.println(); 12846 needSep = false; 12847 } 12848 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12849 } 12850 } 12851 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12852 || mProfileFd != null) { 12853 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12854 if (needSep) { 12855 pw.println(); 12856 needSep = false; 12857 } 12858 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12859 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12860 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12861 + mAutoStopProfiler); 12862 pw.println(" mProfileType=" + mProfileType); 12863 } 12864 } 12865 if (dumpPackage == null) { 12866 if (mAlwaysFinishActivities || mController != null) { 12867 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12868 + " mController=" + mController); 12869 } 12870 if (dumpAll) { 12871 pw.println(" Total persistent processes: " + numPers); 12872 pw.println(" mProcessesReady=" + mProcessesReady 12873 + " mSystemReady=" + mSystemReady); 12874 pw.println(" mBooting=" + mBooting 12875 + " mBooted=" + mBooted 12876 + " mFactoryTest=" + mFactoryTest); 12877 pw.print(" mLastPowerCheckRealtime="); 12878 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12879 pw.println(""); 12880 pw.print(" mLastPowerCheckUptime="); 12881 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12882 pw.println(""); 12883 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12884 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12885 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12886 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12887 + " (" + mLruProcesses.size() + " total)" 12888 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12889 + " mNumServiceProcs=" + mNumServiceProcs 12890 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12891 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12892 + " mLastMemoryLevel" + mLastMemoryLevel 12893 + " mLastNumProcesses" + mLastNumProcesses); 12894 long now = SystemClock.uptimeMillis(); 12895 pw.print(" mLastIdleTime="); 12896 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12897 pw.print(" mLowRamSinceLastIdle="); 12898 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12899 pw.println(); 12900 } 12901 } 12902 12903 if (!printedAnything) { 12904 pw.println(" (nothing)"); 12905 } 12906 } 12907 12908 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12909 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12910 if (mProcessesToGc.size() > 0) { 12911 boolean printed = false; 12912 long now = SystemClock.uptimeMillis(); 12913 for (int i=0; i<mProcessesToGc.size(); i++) { 12914 ProcessRecord proc = mProcessesToGc.get(i); 12915 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12916 continue; 12917 } 12918 if (!printed) { 12919 if (needSep) pw.println(); 12920 needSep = true; 12921 pw.println(" Processes that are waiting to GC:"); 12922 printed = true; 12923 } 12924 pw.print(" Process "); pw.println(proc); 12925 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12926 pw.print(", last gced="); 12927 pw.print(now-proc.lastRequestedGc); 12928 pw.print(" ms ago, last lowMem="); 12929 pw.print(now-proc.lastLowMemory); 12930 pw.println(" ms ago"); 12931 12932 } 12933 } 12934 return needSep; 12935 } 12936 12937 void printOomLevel(PrintWriter pw, String name, int adj) { 12938 pw.print(" "); 12939 if (adj >= 0) { 12940 pw.print(' '); 12941 if (adj < 10) pw.print(' '); 12942 } else { 12943 if (adj > -10) pw.print(' '); 12944 } 12945 pw.print(adj); 12946 pw.print(": "); 12947 pw.print(name); 12948 pw.print(" ("); 12949 pw.print(mProcessList.getMemLevel(adj)/1024); 12950 pw.println(" kB)"); 12951 } 12952 12953 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12954 int opti, boolean dumpAll) { 12955 boolean needSep = false; 12956 12957 if (mLruProcesses.size() > 0) { 12958 if (needSep) pw.println(); 12959 needSep = true; 12960 pw.println(" OOM levels:"); 12961 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12962 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12963 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12964 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12965 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12966 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12967 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12968 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12969 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12970 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12971 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12972 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12973 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12974 12975 if (needSep) pw.println(); 12976 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12977 pw.print(" total, non-act at "); 12978 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12979 pw.print(", non-svc at "); 12980 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12981 pw.println("):"); 12982 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12983 needSep = true; 12984 } 12985 12986 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12987 12988 pw.println(); 12989 pw.println(" mHomeProcess: " + mHomeProcess); 12990 pw.println(" mPreviousProcess: " + mPreviousProcess); 12991 if (mHeavyWeightProcess != null) { 12992 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12993 } 12994 12995 return true; 12996 } 12997 12998 /** 12999 * There are three ways to call this: 13000 * - no provider specified: dump all the providers 13001 * - a flattened component name that matched an existing provider was specified as the 13002 * first arg: dump that one provider 13003 * - the first arg isn't the flattened component name of an existing provider: 13004 * dump all providers whose component contains the first arg as a substring 13005 */ 13006 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13007 int opti, boolean dumpAll) { 13008 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13009 } 13010 13011 static class ItemMatcher { 13012 ArrayList<ComponentName> components; 13013 ArrayList<String> strings; 13014 ArrayList<Integer> objects; 13015 boolean all; 13016 13017 ItemMatcher() { 13018 all = true; 13019 } 13020 13021 void build(String name) { 13022 ComponentName componentName = ComponentName.unflattenFromString(name); 13023 if (componentName != null) { 13024 if (components == null) { 13025 components = new ArrayList<ComponentName>(); 13026 } 13027 components.add(componentName); 13028 all = false; 13029 } else { 13030 int objectId = 0; 13031 // Not a '/' separated full component name; maybe an object ID? 13032 try { 13033 objectId = Integer.parseInt(name, 16); 13034 if (objects == null) { 13035 objects = new ArrayList<Integer>(); 13036 } 13037 objects.add(objectId); 13038 all = false; 13039 } catch (RuntimeException e) { 13040 // Not an integer; just do string match. 13041 if (strings == null) { 13042 strings = new ArrayList<String>(); 13043 } 13044 strings.add(name); 13045 all = false; 13046 } 13047 } 13048 } 13049 13050 int build(String[] args, int opti) { 13051 for (; opti<args.length; opti++) { 13052 String name = args[opti]; 13053 if ("--".equals(name)) { 13054 return opti+1; 13055 } 13056 build(name); 13057 } 13058 return opti; 13059 } 13060 13061 boolean match(Object object, ComponentName comp) { 13062 if (all) { 13063 return true; 13064 } 13065 if (components != null) { 13066 for (int i=0; i<components.size(); i++) { 13067 if (components.get(i).equals(comp)) { 13068 return true; 13069 } 13070 } 13071 } 13072 if (objects != null) { 13073 for (int i=0; i<objects.size(); i++) { 13074 if (System.identityHashCode(object) == objects.get(i)) { 13075 return true; 13076 } 13077 } 13078 } 13079 if (strings != null) { 13080 String flat = comp.flattenToString(); 13081 for (int i=0; i<strings.size(); i++) { 13082 if (flat.contains(strings.get(i))) { 13083 return true; 13084 } 13085 } 13086 } 13087 return false; 13088 } 13089 } 13090 13091 /** 13092 * There are three things that cmd can be: 13093 * - a flattened component name that matches an existing activity 13094 * - the cmd arg isn't the flattened component name of an existing activity: 13095 * dump all activity whose component contains the cmd as a substring 13096 * - A hex number of the ActivityRecord object instance. 13097 */ 13098 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13099 int opti, boolean dumpAll) { 13100 ArrayList<ActivityRecord> activities; 13101 13102 synchronized (this) { 13103 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13104 } 13105 13106 if (activities.size() <= 0) { 13107 return false; 13108 } 13109 13110 String[] newArgs = new String[args.length - opti]; 13111 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13112 13113 TaskRecord lastTask = null; 13114 boolean needSep = false; 13115 for (int i=activities.size()-1; i>=0; i--) { 13116 ActivityRecord r = activities.get(i); 13117 if (needSep) { 13118 pw.println(); 13119 } 13120 needSep = true; 13121 synchronized (this) { 13122 if (lastTask != r.task) { 13123 lastTask = r.task; 13124 pw.print("TASK "); pw.print(lastTask.affinity); 13125 pw.print(" id="); pw.println(lastTask.taskId); 13126 if (dumpAll) { 13127 lastTask.dump(pw, " "); 13128 } 13129 } 13130 } 13131 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13132 } 13133 return true; 13134 } 13135 13136 /** 13137 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13138 * there is a thread associated with the activity. 13139 */ 13140 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13141 final ActivityRecord r, String[] args, boolean dumpAll) { 13142 String innerPrefix = prefix + " "; 13143 synchronized (this) { 13144 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13145 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13146 pw.print(" pid="); 13147 if (r.app != null) pw.println(r.app.pid); 13148 else pw.println("(not running)"); 13149 if (dumpAll) { 13150 r.dump(pw, innerPrefix); 13151 } 13152 } 13153 if (r.app != null && r.app.thread != null) { 13154 // flush anything that is already in the PrintWriter since the thread is going 13155 // to write to the file descriptor directly 13156 pw.flush(); 13157 try { 13158 TransferPipe tp = new TransferPipe(); 13159 try { 13160 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13161 r.appToken, innerPrefix, args); 13162 tp.go(fd); 13163 } finally { 13164 tp.kill(); 13165 } 13166 } catch (IOException e) { 13167 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13168 } catch (RemoteException e) { 13169 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13170 } 13171 } 13172 } 13173 13174 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13175 int opti, boolean dumpAll, String dumpPackage) { 13176 boolean needSep = false; 13177 boolean onlyHistory = false; 13178 boolean printedAnything = false; 13179 13180 if ("history".equals(dumpPackage)) { 13181 if (opti < args.length && "-s".equals(args[opti])) { 13182 dumpAll = false; 13183 } 13184 onlyHistory = true; 13185 dumpPackage = null; 13186 } 13187 13188 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13189 if (!onlyHistory && dumpAll) { 13190 if (mRegisteredReceivers.size() > 0) { 13191 boolean printed = false; 13192 Iterator it = mRegisteredReceivers.values().iterator(); 13193 while (it.hasNext()) { 13194 ReceiverList r = (ReceiverList)it.next(); 13195 if (dumpPackage != null && (r.app == null || 13196 !dumpPackage.equals(r.app.info.packageName))) { 13197 continue; 13198 } 13199 if (!printed) { 13200 pw.println(" Registered Receivers:"); 13201 needSep = true; 13202 printed = true; 13203 printedAnything = true; 13204 } 13205 pw.print(" * "); pw.println(r); 13206 r.dump(pw, " "); 13207 } 13208 } 13209 13210 if (mReceiverResolver.dump(pw, needSep ? 13211 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13212 " ", dumpPackage, false)) { 13213 needSep = true; 13214 printedAnything = true; 13215 } 13216 } 13217 13218 for (BroadcastQueue q : mBroadcastQueues) { 13219 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13220 printedAnything |= needSep; 13221 } 13222 13223 needSep = true; 13224 13225 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13226 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13227 if (needSep) { 13228 pw.println(); 13229 } 13230 needSep = true; 13231 printedAnything = true; 13232 pw.print(" Sticky broadcasts for user "); 13233 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13234 StringBuilder sb = new StringBuilder(128); 13235 for (Map.Entry<String, ArrayList<Intent>> ent 13236 : mStickyBroadcasts.valueAt(user).entrySet()) { 13237 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13238 if (dumpAll) { 13239 pw.println(":"); 13240 ArrayList<Intent> intents = ent.getValue(); 13241 final int N = intents.size(); 13242 for (int i=0; i<N; i++) { 13243 sb.setLength(0); 13244 sb.append(" Intent: "); 13245 intents.get(i).toShortString(sb, false, true, false, false); 13246 pw.println(sb.toString()); 13247 Bundle bundle = intents.get(i).getExtras(); 13248 if (bundle != null) { 13249 pw.print(" "); 13250 pw.println(bundle.toString()); 13251 } 13252 } 13253 } else { 13254 pw.println(""); 13255 } 13256 } 13257 } 13258 } 13259 13260 if (!onlyHistory && dumpAll) { 13261 pw.println(); 13262 for (BroadcastQueue queue : mBroadcastQueues) { 13263 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13264 + queue.mBroadcastsScheduled); 13265 } 13266 pw.println(" mHandler:"); 13267 mHandler.dump(new PrintWriterPrinter(pw), " "); 13268 needSep = true; 13269 printedAnything = true; 13270 } 13271 13272 if (!printedAnything) { 13273 pw.println(" (nothing)"); 13274 } 13275 } 13276 13277 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13278 int opti, boolean dumpAll, String dumpPackage) { 13279 boolean needSep; 13280 boolean printedAnything = false; 13281 13282 ItemMatcher matcher = new ItemMatcher(); 13283 matcher.build(args, opti); 13284 13285 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13286 13287 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13288 printedAnything |= needSep; 13289 13290 if (mLaunchingProviders.size() > 0) { 13291 boolean printed = false; 13292 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13293 ContentProviderRecord r = mLaunchingProviders.get(i); 13294 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13295 continue; 13296 } 13297 if (!printed) { 13298 if (needSep) pw.println(); 13299 needSep = true; 13300 pw.println(" Launching content providers:"); 13301 printed = true; 13302 printedAnything = true; 13303 } 13304 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13305 pw.println(r); 13306 } 13307 } 13308 13309 if (mGrantedUriPermissions.size() > 0) { 13310 boolean printed = false; 13311 int dumpUid = -2; 13312 if (dumpPackage != null) { 13313 try { 13314 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13315 } catch (NameNotFoundException e) { 13316 dumpUid = -1; 13317 } 13318 } 13319 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13320 int uid = mGrantedUriPermissions.keyAt(i); 13321 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13322 continue; 13323 } 13324 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13325 if (!printed) { 13326 if (needSep) pw.println(); 13327 needSep = true; 13328 pw.println(" Granted Uri Permissions:"); 13329 printed = true; 13330 printedAnything = true; 13331 } 13332 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13333 for (UriPermission perm : perms.values()) { 13334 pw.print(" "); pw.println(perm); 13335 if (dumpAll) { 13336 perm.dump(pw, " "); 13337 } 13338 } 13339 } 13340 } 13341 13342 if (!printedAnything) { 13343 pw.println(" (nothing)"); 13344 } 13345 } 13346 13347 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13348 int opti, boolean dumpAll, String dumpPackage) { 13349 boolean printed = false; 13350 13351 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13352 13353 if (mIntentSenderRecords.size() > 0) { 13354 Iterator<WeakReference<PendingIntentRecord>> it 13355 = mIntentSenderRecords.values().iterator(); 13356 while (it.hasNext()) { 13357 WeakReference<PendingIntentRecord> ref = it.next(); 13358 PendingIntentRecord rec = ref != null ? ref.get(): null; 13359 if (dumpPackage != null && (rec == null 13360 || !dumpPackage.equals(rec.key.packageName))) { 13361 continue; 13362 } 13363 printed = true; 13364 if (rec != null) { 13365 pw.print(" * "); pw.println(rec); 13366 if (dumpAll) { 13367 rec.dump(pw, " "); 13368 } 13369 } else { 13370 pw.print(" * "); pw.println(ref); 13371 } 13372 } 13373 } 13374 13375 if (!printed) { 13376 pw.println(" (nothing)"); 13377 } 13378 } 13379 13380 private static final int dumpProcessList(PrintWriter pw, 13381 ActivityManagerService service, List list, 13382 String prefix, String normalLabel, String persistentLabel, 13383 String dumpPackage) { 13384 int numPers = 0; 13385 final int N = list.size()-1; 13386 for (int i=N; i>=0; i--) { 13387 ProcessRecord r = (ProcessRecord)list.get(i); 13388 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13389 continue; 13390 } 13391 pw.println(String.format("%s%s #%2d: %s", 13392 prefix, (r.persistent ? persistentLabel : normalLabel), 13393 i, r.toString())); 13394 if (r.persistent) { 13395 numPers++; 13396 } 13397 } 13398 return numPers; 13399 } 13400 13401 private static final boolean dumpProcessOomList(PrintWriter pw, 13402 ActivityManagerService service, List<ProcessRecord> origList, 13403 String prefix, String normalLabel, String persistentLabel, 13404 boolean inclDetails, String dumpPackage) { 13405 13406 ArrayList<Pair<ProcessRecord, Integer>> list 13407 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13408 for (int i=0; i<origList.size(); i++) { 13409 ProcessRecord r = origList.get(i); 13410 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13411 continue; 13412 } 13413 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13414 } 13415 13416 if (list.size() <= 0) { 13417 return false; 13418 } 13419 13420 Comparator<Pair<ProcessRecord, Integer>> comparator 13421 = new Comparator<Pair<ProcessRecord, Integer>>() { 13422 @Override 13423 public int compare(Pair<ProcessRecord, Integer> object1, 13424 Pair<ProcessRecord, Integer> object2) { 13425 if (object1.first.setAdj != object2.first.setAdj) { 13426 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13427 } 13428 if (object1.second.intValue() != object2.second.intValue()) { 13429 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13430 } 13431 return 0; 13432 } 13433 }; 13434 13435 Collections.sort(list, comparator); 13436 13437 final long curRealtime = SystemClock.elapsedRealtime(); 13438 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13439 final long curUptime = SystemClock.uptimeMillis(); 13440 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13441 13442 for (int i=list.size()-1; i>=0; i--) { 13443 ProcessRecord r = list.get(i).first; 13444 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13445 char schedGroup; 13446 switch (r.setSchedGroup) { 13447 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13448 schedGroup = 'B'; 13449 break; 13450 case Process.THREAD_GROUP_DEFAULT: 13451 schedGroup = 'F'; 13452 break; 13453 default: 13454 schedGroup = '?'; 13455 break; 13456 } 13457 char foreground; 13458 if (r.foregroundActivities) { 13459 foreground = 'A'; 13460 } else if (r.foregroundServices) { 13461 foreground = 'S'; 13462 } else { 13463 foreground = ' '; 13464 } 13465 String procState = ProcessList.makeProcStateString(r.curProcState); 13466 pw.print(prefix); 13467 pw.print(r.persistent ? persistentLabel : normalLabel); 13468 pw.print(" #"); 13469 int num = (origList.size()-1)-list.get(i).second; 13470 if (num < 10) pw.print(' '); 13471 pw.print(num); 13472 pw.print(": "); 13473 pw.print(oomAdj); 13474 pw.print(' '); 13475 pw.print(schedGroup); 13476 pw.print('/'); 13477 pw.print(foreground); 13478 pw.print('/'); 13479 pw.print(procState); 13480 pw.print(" trm:"); 13481 if (r.trimMemoryLevel < 10) pw.print(' '); 13482 pw.print(r.trimMemoryLevel); 13483 pw.print(' '); 13484 pw.print(r.toShortString()); 13485 pw.print(" ("); 13486 pw.print(r.adjType); 13487 pw.println(')'); 13488 if (r.adjSource != null || r.adjTarget != null) { 13489 pw.print(prefix); 13490 pw.print(" "); 13491 if (r.adjTarget instanceof ComponentName) { 13492 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13493 } else if (r.adjTarget != null) { 13494 pw.print(r.adjTarget.toString()); 13495 } else { 13496 pw.print("{null}"); 13497 } 13498 pw.print("<="); 13499 if (r.adjSource instanceof ProcessRecord) { 13500 pw.print("Proc{"); 13501 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13502 pw.println("}"); 13503 } else if (r.adjSource != null) { 13504 pw.println(r.adjSource.toString()); 13505 } else { 13506 pw.println("{null}"); 13507 } 13508 } 13509 if (inclDetails) { 13510 pw.print(prefix); 13511 pw.print(" "); 13512 pw.print("oom: max="); pw.print(r.maxAdj); 13513 pw.print(" curRaw="); pw.print(r.curRawAdj); 13514 pw.print(" setRaw="); pw.print(r.setRawAdj); 13515 pw.print(" cur="); pw.print(r.curAdj); 13516 pw.print(" set="); pw.println(r.setAdj); 13517 pw.print(prefix); 13518 pw.print(" "); 13519 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13520 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13521 pw.print(" lastPss="); pw.print(r.lastPss); 13522 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13523 pw.print(prefix); 13524 pw.print(" "); 13525 pw.print("cached="); pw.print(r.cached); 13526 pw.print(" empty="); pw.print(r.empty); 13527 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13528 13529 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13530 if (r.lastWakeTime != 0) { 13531 long wtime; 13532 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13533 synchronized (stats) { 13534 wtime = stats.getProcessWakeTime(r.info.uid, 13535 r.pid, curRealtime); 13536 } 13537 long timeUsed = wtime - r.lastWakeTime; 13538 pw.print(prefix); 13539 pw.print(" "); 13540 pw.print("keep awake over "); 13541 TimeUtils.formatDuration(realtimeSince, pw); 13542 pw.print(" used "); 13543 TimeUtils.formatDuration(timeUsed, pw); 13544 pw.print(" ("); 13545 pw.print((timeUsed*100)/realtimeSince); 13546 pw.println("%)"); 13547 } 13548 if (r.lastCpuTime != 0) { 13549 long timeUsed = r.curCpuTime - r.lastCpuTime; 13550 pw.print(prefix); 13551 pw.print(" "); 13552 pw.print("run cpu over "); 13553 TimeUtils.formatDuration(uptimeSince, pw); 13554 pw.print(" used "); 13555 TimeUtils.formatDuration(timeUsed, pw); 13556 pw.print(" ("); 13557 pw.print((timeUsed*100)/uptimeSince); 13558 pw.println("%)"); 13559 } 13560 } 13561 } 13562 } 13563 return true; 13564 } 13565 13566 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 13567 ArrayList<ProcessRecord> procs; 13568 synchronized (this) { 13569 if (args != null && args.length > start 13570 && args[start].charAt(0) != '-') { 13571 procs = new ArrayList<ProcessRecord>(); 13572 int pid = -1; 13573 try { 13574 pid = Integer.parseInt(args[start]); 13575 } catch (NumberFormatException e) { 13576 } 13577 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13578 ProcessRecord proc = mLruProcesses.get(i); 13579 if (proc.pid == pid) { 13580 procs.add(proc); 13581 } else if (proc.processName.equals(args[start])) { 13582 procs.add(proc); 13583 } 13584 } 13585 if (procs.size() <= 0) { 13586 return null; 13587 } 13588 } else { 13589 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13590 } 13591 } 13592 return procs; 13593 } 13594 13595 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13596 PrintWriter pw, String[] args) { 13597 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13598 if (procs == null) { 13599 pw.println("No process found for: " + args[0]); 13600 return; 13601 } 13602 13603 long uptime = SystemClock.uptimeMillis(); 13604 long realtime = SystemClock.elapsedRealtime(); 13605 pw.println("Applications Graphics Acceleration Info:"); 13606 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13607 13608 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13609 ProcessRecord r = procs.get(i); 13610 if (r.thread != null) { 13611 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13612 pw.flush(); 13613 try { 13614 TransferPipe tp = new TransferPipe(); 13615 try { 13616 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13617 tp.go(fd); 13618 } finally { 13619 tp.kill(); 13620 } 13621 } catch (IOException e) { 13622 pw.println("Failure while dumping the app: " + r); 13623 pw.flush(); 13624 } catch (RemoteException e) { 13625 pw.println("Got a RemoteException while dumping the app " + r); 13626 pw.flush(); 13627 } 13628 } 13629 } 13630 } 13631 13632 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13633 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13634 if (procs == null) { 13635 pw.println("No process found for: " + args[0]); 13636 return; 13637 } 13638 13639 pw.println("Applications Database Info:"); 13640 13641 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13642 ProcessRecord r = procs.get(i); 13643 if (r.thread != null) { 13644 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13645 pw.flush(); 13646 try { 13647 TransferPipe tp = new TransferPipe(); 13648 try { 13649 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13650 tp.go(fd); 13651 } finally { 13652 tp.kill(); 13653 } 13654 } catch (IOException e) { 13655 pw.println("Failure while dumping the app: " + r); 13656 pw.flush(); 13657 } catch (RemoteException e) { 13658 pw.println("Got a RemoteException while dumping the app " + r); 13659 pw.flush(); 13660 } 13661 } 13662 } 13663 } 13664 13665 final static class MemItem { 13666 final boolean isProc; 13667 final String label; 13668 final String shortLabel; 13669 final long pss; 13670 final int id; 13671 final boolean hasActivities; 13672 ArrayList<MemItem> subitems; 13673 13674 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13675 boolean _hasActivities) { 13676 isProc = true; 13677 label = _label; 13678 shortLabel = _shortLabel; 13679 pss = _pss; 13680 id = _id; 13681 hasActivities = _hasActivities; 13682 } 13683 13684 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13685 isProc = false; 13686 label = _label; 13687 shortLabel = _shortLabel; 13688 pss = _pss; 13689 id = _id; 13690 hasActivities = false; 13691 } 13692 } 13693 13694 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13695 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13696 if (sort && !isCompact) { 13697 Collections.sort(items, new Comparator<MemItem>() { 13698 @Override 13699 public int compare(MemItem lhs, MemItem rhs) { 13700 if (lhs.pss < rhs.pss) { 13701 return 1; 13702 } else if (lhs.pss > rhs.pss) { 13703 return -1; 13704 } 13705 return 0; 13706 } 13707 }); 13708 } 13709 13710 for (int i=0; i<items.size(); i++) { 13711 MemItem mi = items.get(i); 13712 if (!isCompact) { 13713 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13714 } else if (mi.isProc) { 13715 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13716 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13717 pw.println(mi.hasActivities ? ",a" : ",e"); 13718 } else { 13719 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13720 pw.println(mi.pss); 13721 } 13722 if (mi.subitems != null) { 13723 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13724 true, isCompact); 13725 } 13726 } 13727 } 13728 13729 // These are in KB. 13730 static final long[] DUMP_MEM_BUCKETS = new long[] { 13731 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13732 120*1024, 160*1024, 200*1024, 13733 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13734 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13735 }; 13736 13737 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13738 boolean stackLike) { 13739 int start = label.lastIndexOf('.'); 13740 if (start >= 0) start++; 13741 else start = 0; 13742 int end = label.length(); 13743 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13744 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13745 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13746 out.append(bucket); 13747 out.append(stackLike ? "MB." : "MB "); 13748 out.append(label, start, end); 13749 return; 13750 } 13751 } 13752 out.append(memKB/1024); 13753 out.append(stackLike ? "MB." : "MB "); 13754 out.append(label, start, end); 13755 } 13756 13757 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13758 ProcessList.NATIVE_ADJ, 13759 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13760 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13761 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13762 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13763 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13764 }; 13765 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13766 "Native", 13767 "System", "Persistent", "Foreground", 13768 "Visible", "Perceptible", 13769 "Heavy Weight", "Backup", 13770 "A Services", "Home", 13771 "Previous", "B Services", "Cached" 13772 }; 13773 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13774 "native", 13775 "sys", "pers", "fore", 13776 "vis", "percept", 13777 "heavy", "backup", 13778 "servicea", "home", 13779 "prev", "serviceb", "cached" 13780 }; 13781 13782 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13783 long realtime, boolean isCheckinRequest, boolean isCompact) { 13784 if (isCheckinRequest || isCompact) { 13785 // short checkin version 13786 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13787 } else { 13788 pw.println("Applications Memory Usage (kB):"); 13789 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13790 } 13791 } 13792 13793 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13794 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13795 boolean dumpDetails = false; 13796 boolean dumpFullDetails = false; 13797 boolean dumpDalvik = false; 13798 boolean oomOnly = false; 13799 boolean isCompact = false; 13800 boolean localOnly = false; 13801 13802 int opti = 0; 13803 while (opti < args.length) { 13804 String opt = args[opti]; 13805 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13806 break; 13807 } 13808 opti++; 13809 if ("-a".equals(opt)) { 13810 dumpDetails = true; 13811 dumpFullDetails = true; 13812 dumpDalvik = true; 13813 } else if ("-d".equals(opt)) { 13814 dumpDalvik = true; 13815 } else if ("-c".equals(opt)) { 13816 isCompact = true; 13817 } else if ("--oom".equals(opt)) { 13818 oomOnly = true; 13819 } else if ("--local".equals(opt)) { 13820 localOnly = true; 13821 } else if ("-h".equals(opt)) { 13822 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13823 pw.println(" -a: include all available information for each process."); 13824 pw.println(" -d: include dalvik details when dumping process details."); 13825 pw.println(" -c: dump in a compact machine-parseable representation."); 13826 pw.println(" --oom: only show processes organized by oom adj."); 13827 pw.println(" --local: only collect details locally, don't call process."); 13828 pw.println("If [process] is specified it can be the name or "); 13829 pw.println("pid of a specific process to dump."); 13830 return; 13831 } else { 13832 pw.println("Unknown argument: " + opt + "; use -h for help"); 13833 } 13834 } 13835 13836 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13837 long uptime = SystemClock.uptimeMillis(); 13838 long realtime = SystemClock.elapsedRealtime(); 13839 final long[] tmpLong = new long[1]; 13840 13841 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 13842 if (procs == null) { 13843 // No Java processes. Maybe they want to print a native process. 13844 if (args != null && args.length > opti 13845 && args[opti].charAt(0) != '-') { 13846 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13847 = new ArrayList<ProcessCpuTracker.Stats>(); 13848 updateCpuStatsNow(); 13849 int findPid = -1; 13850 try { 13851 findPid = Integer.parseInt(args[opti]); 13852 } catch (NumberFormatException e) { 13853 } 13854 synchronized (mProcessCpuTracker) { 13855 final int N = mProcessCpuTracker.countStats(); 13856 for (int i=0; i<N; i++) { 13857 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13858 if (st.pid == findPid || (st.baseName != null 13859 && st.baseName.equals(args[opti]))) { 13860 nativeProcs.add(st); 13861 } 13862 } 13863 } 13864 if (nativeProcs.size() > 0) { 13865 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13866 isCompact); 13867 Debug.MemoryInfo mi = null; 13868 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13869 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13870 final int pid = r.pid; 13871 if (!isCheckinRequest && dumpDetails) { 13872 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13873 } 13874 if (mi == null) { 13875 mi = new Debug.MemoryInfo(); 13876 } 13877 if (dumpDetails || (!brief && !oomOnly)) { 13878 Debug.getMemoryInfo(pid, mi); 13879 } else { 13880 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13881 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13882 } 13883 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13884 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13885 if (isCheckinRequest) { 13886 pw.println(); 13887 } 13888 } 13889 return; 13890 } 13891 } 13892 pw.println("No process found for: " + args[opti]); 13893 return; 13894 } 13895 13896 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 13897 dumpDetails = true; 13898 } 13899 13900 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13901 13902 String[] innerArgs = new String[args.length-opti]; 13903 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13904 13905 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13906 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13907 long nativePss=0, dalvikPss=0, otherPss=0; 13908 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13909 13910 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13911 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13912 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13913 13914 long totalPss = 0; 13915 long cachedPss = 0; 13916 13917 Debug.MemoryInfo mi = null; 13918 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13919 final ProcessRecord r = procs.get(i); 13920 final IApplicationThread thread; 13921 final int pid; 13922 final int oomAdj; 13923 final boolean hasActivities; 13924 synchronized (this) { 13925 thread = r.thread; 13926 pid = r.pid; 13927 oomAdj = r.getSetAdjWithServices(); 13928 hasActivities = r.activities.size() > 0; 13929 } 13930 if (thread != null) { 13931 if (!isCheckinRequest && dumpDetails) { 13932 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13933 } 13934 if (mi == null) { 13935 mi = new Debug.MemoryInfo(); 13936 } 13937 if (dumpDetails || (!brief && !oomOnly)) { 13938 Debug.getMemoryInfo(pid, mi); 13939 } else { 13940 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13941 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13942 } 13943 if (dumpDetails) { 13944 if (localOnly) { 13945 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13946 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13947 if (isCheckinRequest) { 13948 pw.println(); 13949 } 13950 } else { 13951 try { 13952 pw.flush(); 13953 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13954 dumpDalvik, innerArgs); 13955 } catch (RemoteException e) { 13956 if (!isCheckinRequest) { 13957 pw.println("Got RemoteException!"); 13958 pw.flush(); 13959 } 13960 } 13961 } 13962 } 13963 13964 final long myTotalPss = mi.getTotalPss(); 13965 final long myTotalUss = mi.getTotalUss(); 13966 13967 synchronized (this) { 13968 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13969 // Record this for posterity if the process has been stable. 13970 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13971 } 13972 } 13973 13974 if (!isCheckinRequest && mi != null) { 13975 totalPss += myTotalPss; 13976 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13977 (hasActivities ? " / activities)" : ")"), 13978 r.processName, myTotalPss, pid, hasActivities); 13979 procMems.add(pssItem); 13980 procMemsMap.put(pid, pssItem); 13981 13982 nativePss += mi.nativePss; 13983 dalvikPss += mi.dalvikPss; 13984 otherPss += mi.otherPss; 13985 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13986 long mem = mi.getOtherPss(j); 13987 miscPss[j] += mem; 13988 otherPss -= mem; 13989 } 13990 13991 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13992 cachedPss += myTotalPss; 13993 } 13994 13995 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13996 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13997 || oomIndex == (oomPss.length-1)) { 13998 oomPss[oomIndex] += myTotalPss; 13999 if (oomProcs[oomIndex] == null) { 14000 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14001 } 14002 oomProcs[oomIndex].add(pssItem); 14003 break; 14004 } 14005 } 14006 } 14007 } 14008 } 14009 14010 long nativeProcTotalPss = 0; 14011 14012 if (!isCheckinRequest && procs.size() > 1) { 14013 // If we are showing aggregations, also look for native processes to 14014 // include so that our aggregations are more accurate. 14015 updateCpuStatsNow(); 14016 synchronized (mProcessCpuTracker) { 14017 final int N = mProcessCpuTracker.countStats(); 14018 for (int i=0; i<N; i++) { 14019 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14020 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14021 if (mi == null) { 14022 mi = new Debug.MemoryInfo(); 14023 } 14024 if (!brief && !oomOnly) { 14025 Debug.getMemoryInfo(st.pid, mi); 14026 } else { 14027 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14028 mi.nativePrivateDirty = (int)tmpLong[0]; 14029 } 14030 14031 final long myTotalPss = mi.getTotalPss(); 14032 totalPss += myTotalPss; 14033 nativeProcTotalPss += myTotalPss; 14034 14035 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14036 st.name, myTotalPss, st.pid, false); 14037 procMems.add(pssItem); 14038 14039 nativePss += mi.nativePss; 14040 dalvikPss += mi.dalvikPss; 14041 otherPss += mi.otherPss; 14042 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14043 long mem = mi.getOtherPss(j); 14044 miscPss[j] += mem; 14045 otherPss -= mem; 14046 } 14047 oomPss[0] += myTotalPss; 14048 if (oomProcs[0] == null) { 14049 oomProcs[0] = new ArrayList<MemItem>(); 14050 } 14051 oomProcs[0].add(pssItem); 14052 } 14053 } 14054 } 14055 14056 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14057 14058 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14059 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14060 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14061 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14062 String label = Debug.MemoryInfo.getOtherLabel(j); 14063 catMems.add(new MemItem(label, label, miscPss[j], j)); 14064 } 14065 14066 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14067 for (int j=0; j<oomPss.length; j++) { 14068 if (oomPss[j] != 0) { 14069 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14070 : DUMP_MEM_OOM_LABEL[j]; 14071 MemItem item = new MemItem(label, label, oomPss[j], 14072 DUMP_MEM_OOM_ADJ[j]); 14073 item.subitems = oomProcs[j]; 14074 oomMems.add(item); 14075 } 14076 } 14077 14078 if (!brief && !oomOnly && !isCompact) { 14079 pw.println(); 14080 pw.println("Total PSS by process:"); 14081 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14082 pw.println(); 14083 } 14084 if (!isCompact) { 14085 pw.println("Total PSS by OOM adjustment:"); 14086 } 14087 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14088 if (!brief && !oomOnly) { 14089 PrintWriter out = categoryPw != null ? categoryPw : pw; 14090 if (!isCompact) { 14091 out.println(); 14092 out.println("Total PSS by category:"); 14093 } 14094 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14095 } 14096 if (!isCompact) { 14097 pw.println(); 14098 } 14099 MemInfoReader memInfo = new MemInfoReader(); 14100 memInfo.readMemInfo(); 14101 if (nativeProcTotalPss > 0) { 14102 synchronized (this) { 14103 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14104 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14105 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 14106 nativeProcTotalPss); 14107 } 14108 } 14109 if (!brief) { 14110 if (!isCompact) { 14111 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14112 pw.print(" kB (status "); 14113 switch (mLastMemoryLevel) { 14114 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14115 pw.println("normal)"); 14116 break; 14117 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14118 pw.println("moderate)"); 14119 break; 14120 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14121 pw.println("low)"); 14122 break; 14123 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14124 pw.println("critical)"); 14125 break; 14126 default: 14127 pw.print(mLastMemoryLevel); 14128 pw.println(")"); 14129 break; 14130 } 14131 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14132 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14133 pw.print(cachedPss); pw.print(" cached pss + "); 14134 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 14135 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14136 } else { 14137 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14138 pw.print(cachedPss + memInfo.getCachedSizeKb() 14139 + memInfo.getFreeSizeKb()); pw.print(","); 14140 pw.println(totalPss - cachedPss); 14141 } 14142 } 14143 if (!isCompact) { 14144 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14145 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 14146 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 14147 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14148 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 14149 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 14150 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 14151 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14152 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14153 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 14154 - memInfo.getSlabSizeKb()); pw.println(" kB"); 14155 } 14156 if (!brief) { 14157 if (memInfo.getZramTotalSizeKb() != 0) { 14158 if (!isCompact) { 14159 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14160 pw.print(" kB physical used for "); 14161 pw.print(memInfo.getSwapTotalSizeKb() 14162 - memInfo.getSwapFreeSizeKb()); 14163 pw.print(" kB in swap ("); 14164 pw.print(memInfo.getSwapTotalSizeKb()); 14165 pw.println(" kB total swap)"); 14166 } else { 14167 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14168 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14169 pw.println(memInfo.getSwapFreeSizeKb()); 14170 } 14171 } 14172 final int[] SINGLE_LONG_FORMAT = new int[] { 14173 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14174 }; 14175 long[] longOut = new long[1]; 14176 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14177 SINGLE_LONG_FORMAT, null, longOut, null); 14178 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14179 longOut[0] = 0; 14180 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14181 SINGLE_LONG_FORMAT, null, longOut, null); 14182 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14183 longOut[0] = 0; 14184 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14185 SINGLE_LONG_FORMAT, null, longOut, null); 14186 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14187 longOut[0] = 0; 14188 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14189 SINGLE_LONG_FORMAT, null, longOut, null); 14190 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14191 if (!isCompact) { 14192 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14193 pw.print(" KSM: "); pw.print(sharing); 14194 pw.print(" kB saved from shared "); 14195 pw.print(shared); pw.println(" kB"); 14196 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14197 pw.print(voltile); pw.println(" kB volatile"); 14198 } 14199 pw.print(" Tuning: "); 14200 pw.print(ActivityManager.staticGetMemoryClass()); 14201 pw.print(" (large "); 14202 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14203 pw.print("), oom "); 14204 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14205 pw.print(" kB"); 14206 pw.print(", restore limit "); 14207 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14208 pw.print(" kB"); 14209 if (ActivityManager.isLowRamDeviceStatic()) { 14210 pw.print(" (low-ram)"); 14211 } 14212 if (ActivityManager.isHighEndGfx()) { 14213 pw.print(" (high-end-gfx)"); 14214 } 14215 pw.println(); 14216 } else { 14217 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14218 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14219 pw.println(voltile); 14220 pw.print("tuning,"); 14221 pw.print(ActivityManager.staticGetMemoryClass()); 14222 pw.print(','); 14223 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14224 pw.print(','); 14225 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14226 if (ActivityManager.isLowRamDeviceStatic()) { 14227 pw.print(",low-ram"); 14228 } 14229 if (ActivityManager.isHighEndGfx()) { 14230 pw.print(",high-end-gfx"); 14231 } 14232 pw.println(); 14233 } 14234 } 14235 } 14236 } 14237 14238 /** 14239 * Searches array of arguments for the specified string 14240 * @param args array of argument strings 14241 * @param value value to search for 14242 * @return true if the value is contained in the array 14243 */ 14244 private static boolean scanArgs(String[] args, String value) { 14245 if (args != null) { 14246 for (String arg : args) { 14247 if (value.equals(arg)) { 14248 return true; 14249 } 14250 } 14251 } 14252 return false; 14253 } 14254 14255 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14256 ContentProviderRecord cpr, boolean always) { 14257 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14258 14259 if (!inLaunching || always) { 14260 synchronized (cpr) { 14261 cpr.launchingApp = null; 14262 cpr.notifyAll(); 14263 } 14264 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14265 String names[] = cpr.info.authority.split(";"); 14266 for (int j = 0; j < names.length; j++) { 14267 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14268 } 14269 } 14270 14271 for (int i=0; i<cpr.connections.size(); i++) { 14272 ContentProviderConnection conn = cpr.connections.get(i); 14273 if (conn.waiting) { 14274 // If this connection is waiting for the provider, then we don't 14275 // need to mess with its process unless we are always removing 14276 // or for some reason the provider is not currently launching. 14277 if (inLaunching && !always) { 14278 continue; 14279 } 14280 } 14281 ProcessRecord capp = conn.client; 14282 conn.dead = true; 14283 if (conn.stableCount > 0) { 14284 if (!capp.persistent && capp.thread != null 14285 && capp.pid != 0 14286 && capp.pid != MY_PID) { 14287 capp.kill("depends on provider " 14288 + cpr.name.flattenToShortString() 14289 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14290 } 14291 } else if (capp.thread != null && conn.provider.provider != null) { 14292 try { 14293 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14294 } catch (RemoteException e) { 14295 } 14296 // In the protocol here, we don't expect the client to correctly 14297 // clean up this connection, we'll just remove it. 14298 cpr.connections.remove(i); 14299 conn.client.conProviders.remove(conn); 14300 } 14301 } 14302 14303 if (inLaunching && always) { 14304 mLaunchingProviders.remove(cpr); 14305 } 14306 return inLaunching; 14307 } 14308 14309 /** 14310 * Main code for cleaning up a process when it has gone away. This is 14311 * called both as a result of the process dying, or directly when stopping 14312 * a process when running in single process mode. 14313 */ 14314 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 14315 boolean restarting, boolean allowRestart, int index) { 14316 if (index >= 0) { 14317 removeLruProcessLocked(app); 14318 ProcessList.remove(app.pid); 14319 } 14320 14321 mProcessesToGc.remove(app); 14322 mPendingPssProcesses.remove(app); 14323 14324 // Dismiss any open dialogs. 14325 if (app.crashDialog != null && !app.forceCrashReport) { 14326 app.crashDialog.dismiss(); 14327 app.crashDialog = null; 14328 } 14329 if (app.anrDialog != null) { 14330 app.anrDialog.dismiss(); 14331 app.anrDialog = null; 14332 } 14333 if (app.waitDialog != null) { 14334 app.waitDialog.dismiss(); 14335 app.waitDialog = null; 14336 } 14337 14338 app.crashing = false; 14339 app.notResponding = false; 14340 14341 app.resetPackageList(mProcessStats); 14342 app.unlinkDeathRecipient(); 14343 app.makeInactive(mProcessStats); 14344 app.waitingToKill = null; 14345 app.forcingToForeground = null; 14346 updateProcessForegroundLocked(app, false, false); 14347 app.foregroundActivities = false; 14348 app.hasShownUi = false; 14349 app.treatLikeActivity = false; 14350 app.hasAboveClient = false; 14351 app.hasClientActivities = false; 14352 14353 mServices.killServicesLocked(app, allowRestart); 14354 14355 boolean restart = false; 14356 14357 // Remove published content providers. 14358 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14359 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14360 final boolean always = app.bad || !allowRestart; 14361 if (removeDyingProviderLocked(app, cpr, always) || always) { 14362 // We left the provider in the launching list, need to 14363 // restart it. 14364 restart = true; 14365 } 14366 14367 cpr.provider = null; 14368 cpr.proc = null; 14369 } 14370 app.pubProviders.clear(); 14371 14372 // Take care of any launching providers waiting for this process. 14373 if (checkAppInLaunchingProvidersLocked(app, false)) { 14374 restart = true; 14375 } 14376 14377 // Unregister from connected content providers. 14378 if (!app.conProviders.isEmpty()) { 14379 for (int i=0; i<app.conProviders.size(); i++) { 14380 ContentProviderConnection conn = app.conProviders.get(i); 14381 conn.provider.connections.remove(conn); 14382 } 14383 app.conProviders.clear(); 14384 } 14385 14386 // At this point there may be remaining entries in mLaunchingProviders 14387 // where we were the only one waiting, so they are no longer of use. 14388 // Look for these and clean up if found. 14389 // XXX Commented out for now. Trying to figure out a way to reproduce 14390 // the actual situation to identify what is actually going on. 14391 if (false) { 14392 for (int i=0; i<mLaunchingProviders.size(); i++) { 14393 ContentProviderRecord cpr = (ContentProviderRecord) 14394 mLaunchingProviders.get(i); 14395 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14396 synchronized (cpr) { 14397 cpr.launchingApp = null; 14398 cpr.notifyAll(); 14399 } 14400 } 14401 } 14402 } 14403 14404 skipCurrentReceiverLocked(app); 14405 14406 // Unregister any receivers. 14407 for (int i=app.receivers.size()-1; i>=0; i--) { 14408 removeReceiverLocked(app.receivers.valueAt(i)); 14409 } 14410 app.receivers.clear(); 14411 14412 // If the app is undergoing backup, tell the backup manager about it 14413 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14414 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14415 + mBackupTarget.appInfo + " died during backup"); 14416 try { 14417 IBackupManager bm = IBackupManager.Stub.asInterface( 14418 ServiceManager.getService(Context.BACKUP_SERVICE)); 14419 bm.agentDisconnected(app.info.packageName); 14420 } catch (RemoteException e) { 14421 // can't happen; backup manager is local 14422 } 14423 } 14424 14425 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14426 ProcessChangeItem item = mPendingProcessChanges.get(i); 14427 if (item.pid == app.pid) { 14428 mPendingProcessChanges.remove(i); 14429 mAvailProcessChanges.add(item); 14430 } 14431 } 14432 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14433 14434 // If the caller is restarting this app, then leave it in its 14435 // current lists and let the caller take care of it. 14436 if (restarting) { 14437 return; 14438 } 14439 14440 if (!app.persistent || app.isolated) { 14441 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14442 "Removing non-persistent process during cleanup: " + app); 14443 mProcessNames.remove(app.processName, app.uid); 14444 mIsolatedProcesses.remove(app.uid); 14445 if (mHeavyWeightProcess == app) { 14446 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14447 mHeavyWeightProcess.userId, 0)); 14448 mHeavyWeightProcess = null; 14449 } 14450 } else if (!app.removed) { 14451 // This app is persistent, so we need to keep its record around. 14452 // If it is not already on the pending app list, add it there 14453 // and start a new process for it. 14454 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14455 mPersistentStartingProcesses.add(app); 14456 restart = true; 14457 } 14458 } 14459 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14460 "Clean-up removing on hold: " + app); 14461 mProcessesOnHold.remove(app); 14462 14463 if (app == mHomeProcess) { 14464 mHomeProcess = null; 14465 } 14466 if (app == mPreviousProcess) { 14467 mPreviousProcess = null; 14468 } 14469 14470 if (restart && !app.isolated) { 14471 // We have components that still need to be running in the 14472 // process, so re-launch it. 14473 mProcessNames.put(app.processName, app.uid, app); 14474 startProcessLocked(app, "restart", app.processName); 14475 } else if (app.pid > 0 && app.pid != MY_PID) { 14476 // Goodbye! 14477 boolean removed; 14478 synchronized (mPidsSelfLocked) { 14479 mPidsSelfLocked.remove(app.pid); 14480 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14481 } 14482 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14483 if (app.isolated) { 14484 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14485 } 14486 app.setPid(0); 14487 } 14488 } 14489 14490 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14491 // Look through the content providers we are waiting to have launched, 14492 // and if any run in this process then either schedule a restart of 14493 // the process or kill the client waiting for it if this process has 14494 // gone bad. 14495 int NL = mLaunchingProviders.size(); 14496 boolean restart = false; 14497 for (int i=0; i<NL; i++) { 14498 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14499 if (cpr.launchingApp == app) { 14500 if (!alwaysBad && !app.bad) { 14501 restart = true; 14502 } else { 14503 removeDyingProviderLocked(app, cpr, true); 14504 // cpr should have been removed from mLaunchingProviders 14505 NL = mLaunchingProviders.size(); 14506 i--; 14507 } 14508 } 14509 } 14510 return restart; 14511 } 14512 14513 // ========================================================= 14514 // SERVICES 14515 // ========================================================= 14516 14517 @Override 14518 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14519 int flags) { 14520 enforceNotIsolatedCaller("getServices"); 14521 synchronized (this) { 14522 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14523 } 14524 } 14525 14526 @Override 14527 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14528 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14529 synchronized (this) { 14530 return mServices.getRunningServiceControlPanelLocked(name); 14531 } 14532 } 14533 14534 @Override 14535 public ComponentName startService(IApplicationThread caller, Intent service, 14536 String resolvedType, int userId) { 14537 enforceNotIsolatedCaller("startService"); 14538 // Refuse possible leaked file descriptors 14539 if (service != null && service.hasFileDescriptors() == true) { 14540 throw new IllegalArgumentException("File descriptors passed in Intent"); 14541 } 14542 14543 if (DEBUG_SERVICE) 14544 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14545 synchronized(this) { 14546 final int callingPid = Binder.getCallingPid(); 14547 final int callingUid = Binder.getCallingUid(); 14548 final long origId = Binder.clearCallingIdentity(); 14549 ComponentName res = mServices.startServiceLocked(caller, service, 14550 resolvedType, callingPid, callingUid, userId); 14551 Binder.restoreCallingIdentity(origId); 14552 return res; 14553 } 14554 } 14555 14556 ComponentName startServiceInPackage(int uid, 14557 Intent service, String resolvedType, int userId) { 14558 synchronized(this) { 14559 if (DEBUG_SERVICE) 14560 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14561 final long origId = Binder.clearCallingIdentity(); 14562 ComponentName res = mServices.startServiceLocked(null, service, 14563 resolvedType, -1, uid, userId); 14564 Binder.restoreCallingIdentity(origId); 14565 return res; 14566 } 14567 } 14568 14569 @Override 14570 public int stopService(IApplicationThread caller, Intent service, 14571 String resolvedType, int userId) { 14572 enforceNotIsolatedCaller("stopService"); 14573 // Refuse possible leaked file descriptors 14574 if (service != null && service.hasFileDescriptors() == true) { 14575 throw new IllegalArgumentException("File descriptors passed in Intent"); 14576 } 14577 14578 synchronized(this) { 14579 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14580 } 14581 } 14582 14583 @Override 14584 public IBinder peekService(Intent service, String resolvedType) { 14585 enforceNotIsolatedCaller("peekService"); 14586 // Refuse possible leaked file descriptors 14587 if (service != null && service.hasFileDescriptors() == true) { 14588 throw new IllegalArgumentException("File descriptors passed in Intent"); 14589 } 14590 synchronized(this) { 14591 return mServices.peekServiceLocked(service, resolvedType); 14592 } 14593 } 14594 14595 @Override 14596 public boolean stopServiceToken(ComponentName className, IBinder token, 14597 int startId) { 14598 synchronized(this) { 14599 return mServices.stopServiceTokenLocked(className, token, startId); 14600 } 14601 } 14602 14603 @Override 14604 public void setServiceForeground(ComponentName className, IBinder token, 14605 int id, Notification notification, boolean removeNotification) { 14606 synchronized(this) { 14607 mServices.setServiceForegroundLocked(className, token, id, notification, 14608 removeNotification); 14609 } 14610 } 14611 14612 @Override 14613 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14614 boolean requireFull, String name, String callerPackage) { 14615 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14616 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14617 } 14618 14619 int unsafeConvertIncomingUser(int userId) { 14620 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14621 ? mCurrentUserId : userId; 14622 } 14623 14624 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14625 int allowMode, String name, String callerPackage) { 14626 final int callingUserId = UserHandle.getUserId(callingUid); 14627 if (callingUserId == userId) { 14628 return userId; 14629 } 14630 14631 // Note that we may be accessing mCurrentUserId outside of a lock... 14632 // shouldn't be a big deal, if this is being called outside 14633 // of a locked context there is intrinsically a race with 14634 // the value the caller will receive and someone else changing it. 14635 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14636 // we will switch to the calling user if access to the current user fails. 14637 int targetUserId = unsafeConvertIncomingUser(userId); 14638 14639 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14640 final boolean allow; 14641 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14642 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14643 // If the caller has this permission, they always pass go. And collect $200. 14644 allow = true; 14645 } else if (allowMode == ALLOW_FULL_ONLY) { 14646 // We require full access, sucks to be you. 14647 allow = false; 14648 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14649 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14650 // If the caller does not have either permission, they are always doomed. 14651 allow = false; 14652 } else if (allowMode == ALLOW_NON_FULL) { 14653 // We are blanket allowing non-full access, you lucky caller! 14654 allow = true; 14655 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14656 // We may or may not allow this depending on whether the two users are 14657 // in the same profile. 14658 synchronized (mUserProfileGroupIdsSelfLocked) { 14659 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14660 UserInfo.NO_PROFILE_GROUP_ID); 14661 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14662 UserInfo.NO_PROFILE_GROUP_ID); 14663 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14664 && callingProfile == targetProfile; 14665 } 14666 } else { 14667 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14668 } 14669 if (!allow) { 14670 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14671 // In this case, they would like to just execute as their 14672 // owner user instead of failing. 14673 targetUserId = callingUserId; 14674 } else { 14675 StringBuilder builder = new StringBuilder(128); 14676 builder.append("Permission Denial: "); 14677 builder.append(name); 14678 if (callerPackage != null) { 14679 builder.append(" from "); 14680 builder.append(callerPackage); 14681 } 14682 builder.append(" asks to run as user "); 14683 builder.append(userId); 14684 builder.append(" but is calling from user "); 14685 builder.append(UserHandle.getUserId(callingUid)); 14686 builder.append("; this requires "); 14687 builder.append(INTERACT_ACROSS_USERS_FULL); 14688 if (allowMode != ALLOW_FULL_ONLY) { 14689 builder.append(" or "); 14690 builder.append(INTERACT_ACROSS_USERS); 14691 } 14692 String msg = builder.toString(); 14693 Slog.w(TAG, msg); 14694 throw new SecurityException(msg); 14695 } 14696 } 14697 } 14698 if (!allowAll && targetUserId < 0) { 14699 throw new IllegalArgumentException( 14700 "Call does not support special user #" + targetUserId); 14701 } 14702 // Check shell permission 14703 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14704 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14705 targetUserId)) { 14706 throw new SecurityException("Shell does not have permission to access user " 14707 + targetUserId + "\n " + Debug.getCallers(3)); 14708 } 14709 } 14710 return targetUserId; 14711 } 14712 14713 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14714 String className, int flags) { 14715 boolean result = false; 14716 // For apps that don't have pre-defined UIDs, check for permission 14717 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14718 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14719 if (ActivityManager.checkUidPermission( 14720 INTERACT_ACROSS_USERS, 14721 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14722 ComponentName comp = new ComponentName(aInfo.packageName, className); 14723 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14724 + " requests FLAG_SINGLE_USER, but app does not hold " 14725 + INTERACT_ACROSS_USERS; 14726 Slog.w(TAG, msg); 14727 throw new SecurityException(msg); 14728 } 14729 // Permission passed 14730 result = true; 14731 } 14732 } else if ("system".equals(componentProcessName)) { 14733 result = true; 14734 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14735 // Phone app and persistent apps are allowed to export singleuser providers. 14736 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14737 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14738 } 14739 if (DEBUG_MU) { 14740 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14741 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14742 } 14743 return result; 14744 } 14745 14746 /** 14747 * Checks to see if the caller is in the same app as the singleton 14748 * component, or the component is in a special app. It allows special apps 14749 * to export singleton components but prevents exporting singleton 14750 * components for regular apps. 14751 */ 14752 boolean isValidSingletonCall(int callingUid, int componentUid) { 14753 int componentAppId = UserHandle.getAppId(componentUid); 14754 return UserHandle.isSameApp(callingUid, componentUid) 14755 || componentAppId == Process.SYSTEM_UID 14756 || componentAppId == Process.PHONE_UID 14757 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14758 == PackageManager.PERMISSION_GRANTED; 14759 } 14760 14761 public int bindService(IApplicationThread caller, IBinder token, 14762 Intent service, String resolvedType, 14763 IServiceConnection connection, int flags, int userId) { 14764 enforceNotIsolatedCaller("bindService"); 14765 14766 // Refuse possible leaked file descriptors 14767 if (service != null && service.hasFileDescriptors() == true) { 14768 throw new IllegalArgumentException("File descriptors passed in Intent"); 14769 } 14770 14771 synchronized(this) { 14772 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14773 connection, flags, userId); 14774 } 14775 } 14776 14777 public boolean unbindService(IServiceConnection connection) { 14778 synchronized (this) { 14779 return mServices.unbindServiceLocked(connection); 14780 } 14781 } 14782 14783 public void publishService(IBinder token, Intent intent, IBinder service) { 14784 // Refuse possible leaked file descriptors 14785 if (intent != null && intent.hasFileDescriptors() == true) { 14786 throw new IllegalArgumentException("File descriptors passed in Intent"); 14787 } 14788 14789 synchronized(this) { 14790 if (!(token instanceof ServiceRecord)) { 14791 throw new IllegalArgumentException("Invalid service token"); 14792 } 14793 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14794 } 14795 } 14796 14797 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14798 // Refuse possible leaked file descriptors 14799 if (intent != null && intent.hasFileDescriptors() == true) { 14800 throw new IllegalArgumentException("File descriptors passed in Intent"); 14801 } 14802 14803 synchronized(this) { 14804 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14805 } 14806 } 14807 14808 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14809 synchronized(this) { 14810 if (!(token instanceof ServiceRecord)) { 14811 throw new IllegalArgumentException("Invalid service token"); 14812 } 14813 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14814 } 14815 } 14816 14817 // ========================================================= 14818 // BACKUP AND RESTORE 14819 // ========================================================= 14820 14821 // Cause the target app to be launched if necessary and its backup agent 14822 // instantiated. The backup agent will invoke backupAgentCreated() on the 14823 // activity manager to announce its creation. 14824 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14825 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14826 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14827 14828 synchronized(this) { 14829 // !!! TODO: currently no check here that we're already bound 14830 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14831 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14832 synchronized (stats) { 14833 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14834 } 14835 14836 // Backup agent is now in use, its package can't be stopped. 14837 try { 14838 AppGlobals.getPackageManager().setPackageStoppedState( 14839 app.packageName, false, UserHandle.getUserId(app.uid)); 14840 } catch (RemoteException e) { 14841 } catch (IllegalArgumentException e) { 14842 Slog.w(TAG, "Failed trying to unstop package " 14843 + app.packageName + ": " + e); 14844 } 14845 14846 BackupRecord r = new BackupRecord(ss, app, backupMode); 14847 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14848 ? new ComponentName(app.packageName, app.backupAgentName) 14849 : new ComponentName("android", "FullBackupAgent"); 14850 // startProcessLocked() returns existing proc's record if it's already running 14851 ProcessRecord proc = startProcessLocked(app.processName, app, 14852 false, 0, "backup", hostingName, false, false, false); 14853 if (proc == null) { 14854 Slog.e(TAG, "Unable to start backup agent process " + r); 14855 return false; 14856 } 14857 14858 r.app = proc; 14859 mBackupTarget = r; 14860 mBackupAppName = app.packageName; 14861 14862 // Try not to kill the process during backup 14863 updateOomAdjLocked(proc); 14864 14865 // If the process is already attached, schedule the creation of the backup agent now. 14866 // If it is not yet live, this will be done when it attaches to the framework. 14867 if (proc.thread != null) { 14868 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14869 try { 14870 proc.thread.scheduleCreateBackupAgent(app, 14871 compatibilityInfoForPackageLocked(app), backupMode); 14872 } catch (RemoteException e) { 14873 // Will time out on the backup manager side 14874 } 14875 } else { 14876 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14877 } 14878 // Invariants: at this point, the target app process exists and the application 14879 // is either already running or in the process of coming up. mBackupTarget and 14880 // mBackupAppName describe the app, so that when it binds back to the AM we 14881 // know that it's scheduled for a backup-agent operation. 14882 } 14883 14884 return true; 14885 } 14886 14887 @Override 14888 public void clearPendingBackup() { 14889 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14890 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14891 14892 synchronized (this) { 14893 mBackupTarget = null; 14894 mBackupAppName = null; 14895 } 14896 } 14897 14898 // A backup agent has just come up 14899 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14900 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14901 + " = " + agent); 14902 14903 synchronized(this) { 14904 if (!agentPackageName.equals(mBackupAppName)) { 14905 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14906 return; 14907 } 14908 } 14909 14910 long oldIdent = Binder.clearCallingIdentity(); 14911 try { 14912 IBackupManager bm = IBackupManager.Stub.asInterface( 14913 ServiceManager.getService(Context.BACKUP_SERVICE)); 14914 bm.agentConnected(agentPackageName, agent); 14915 } catch (RemoteException e) { 14916 // can't happen; the backup manager service is local 14917 } catch (Exception e) { 14918 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14919 e.printStackTrace(); 14920 } finally { 14921 Binder.restoreCallingIdentity(oldIdent); 14922 } 14923 } 14924 14925 // done with this agent 14926 public void unbindBackupAgent(ApplicationInfo appInfo) { 14927 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14928 if (appInfo == null) { 14929 Slog.w(TAG, "unbind backup agent for null app"); 14930 return; 14931 } 14932 14933 synchronized(this) { 14934 try { 14935 if (mBackupAppName == null) { 14936 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14937 return; 14938 } 14939 14940 if (!mBackupAppName.equals(appInfo.packageName)) { 14941 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14942 return; 14943 } 14944 14945 // Not backing this app up any more; reset its OOM adjustment 14946 final ProcessRecord proc = mBackupTarget.app; 14947 updateOomAdjLocked(proc); 14948 14949 // If the app crashed during backup, 'thread' will be null here 14950 if (proc.thread != null) { 14951 try { 14952 proc.thread.scheduleDestroyBackupAgent(appInfo, 14953 compatibilityInfoForPackageLocked(appInfo)); 14954 } catch (Exception e) { 14955 Slog.e(TAG, "Exception when unbinding backup agent:"); 14956 e.printStackTrace(); 14957 } 14958 } 14959 } finally { 14960 mBackupTarget = null; 14961 mBackupAppName = null; 14962 } 14963 } 14964 } 14965 // ========================================================= 14966 // BROADCASTS 14967 // ========================================================= 14968 14969 private final List getStickiesLocked(String action, IntentFilter filter, 14970 List cur, int userId) { 14971 final ContentResolver resolver = mContext.getContentResolver(); 14972 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14973 if (stickies == null) { 14974 return cur; 14975 } 14976 final ArrayList<Intent> list = stickies.get(action); 14977 if (list == null) { 14978 return cur; 14979 } 14980 int N = list.size(); 14981 for (int i=0; i<N; i++) { 14982 Intent intent = list.get(i); 14983 if (filter.match(resolver, intent, true, TAG) >= 0) { 14984 if (cur == null) { 14985 cur = new ArrayList<Intent>(); 14986 } 14987 cur.add(intent); 14988 } 14989 } 14990 return cur; 14991 } 14992 14993 boolean isPendingBroadcastProcessLocked(int pid) { 14994 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 14995 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 14996 } 14997 14998 void skipPendingBroadcastLocked(int pid) { 14999 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15000 for (BroadcastQueue queue : mBroadcastQueues) { 15001 queue.skipPendingBroadcastLocked(pid); 15002 } 15003 } 15004 15005 // The app just attached; send any pending broadcasts that it should receive 15006 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15007 boolean didSomething = false; 15008 for (BroadcastQueue queue : mBroadcastQueues) { 15009 didSomething |= queue.sendPendingBroadcastsLocked(app); 15010 } 15011 return didSomething; 15012 } 15013 15014 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15015 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15016 enforceNotIsolatedCaller("registerReceiver"); 15017 int callingUid; 15018 int callingPid; 15019 synchronized(this) { 15020 ProcessRecord callerApp = null; 15021 if (caller != null) { 15022 callerApp = getRecordForAppLocked(caller); 15023 if (callerApp == null) { 15024 throw new SecurityException( 15025 "Unable to find app for caller " + caller 15026 + " (pid=" + Binder.getCallingPid() 15027 + ") when registering receiver " + receiver); 15028 } 15029 if (callerApp.info.uid != Process.SYSTEM_UID && 15030 !callerApp.pkgList.containsKey(callerPackage) && 15031 !"android".equals(callerPackage)) { 15032 throw new SecurityException("Given caller package " + callerPackage 15033 + " is not running in process " + callerApp); 15034 } 15035 callingUid = callerApp.info.uid; 15036 callingPid = callerApp.pid; 15037 } else { 15038 callerPackage = null; 15039 callingUid = Binder.getCallingUid(); 15040 callingPid = Binder.getCallingPid(); 15041 } 15042 15043 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15044 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15045 15046 List allSticky = null; 15047 15048 // Look for any matching sticky broadcasts... 15049 Iterator actions = filter.actionsIterator(); 15050 if (actions != null) { 15051 while (actions.hasNext()) { 15052 String action = (String)actions.next(); 15053 allSticky = getStickiesLocked(action, filter, allSticky, 15054 UserHandle.USER_ALL); 15055 allSticky = getStickiesLocked(action, filter, allSticky, 15056 UserHandle.getUserId(callingUid)); 15057 } 15058 } else { 15059 allSticky = getStickiesLocked(null, filter, allSticky, 15060 UserHandle.USER_ALL); 15061 allSticky = getStickiesLocked(null, filter, allSticky, 15062 UserHandle.getUserId(callingUid)); 15063 } 15064 15065 // The first sticky in the list is returned directly back to 15066 // the client. 15067 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15068 15069 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15070 + ": " + sticky); 15071 15072 if (receiver == null) { 15073 return sticky; 15074 } 15075 15076 ReceiverList rl 15077 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15078 if (rl == null) { 15079 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15080 userId, receiver); 15081 if (rl.app != null) { 15082 rl.app.receivers.add(rl); 15083 } else { 15084 try { 15085 receiver.asBinder().linkToDeath(rl, 0); 15086 } catch (RemoteException e) { 15087 return sticky; 15088 } 15089 rl.linkedToDeath = true; 15090 } 15091 mRegisteredReceivers.put(receiver.asBinder(), rl); 15092 } else if (rl.uid != callingUid) { 15093 throw new IllegalArgumentException( 15094 "Receiver requested to register for uid " + callingUid 15095 + " was previously registered for uid " + rl.uid); 15096 } else if (rl.pid != callingPid) { 15097 throw new IllegalArgumentException( 15098 "Receiver requested to register for pid " + callingPid 15099 + " was previously registered for pid " + rl.pid); 15100 } else if (rl.userId != userId) { 15101 throw new IllegalArgumentException( 15102 "Receiver requested to register for user " + userId 15103 + " was previously registered for user " + rl.userId); 15104 } 15105 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15106 permission, callingUid, userId); 15107 rl.add(bf); 15108 if (!bf.debugCheck()) { 15109 Slog.w(TAG, "==> For Dynamic broadast"); 15110 } 15111 mReceiverResolver.addFilter(bf); 15112 15113 // Enqueue broadcasts for all existing stickies that match 15114 // this filter. 15115 if (allSticky != null) { 15116 ArrayList receivers = new ArrayList(); 15117 receivers.add(bf); 15118 15119 int N = allSticky.size(); 15120 for (int i=0; i<N; i++) { 15121 Intent intent = (Intent)allSticky.get(i); 15122 BroadcastQueue queue = broadcastQueueForIntent(intent); 15123 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15124 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15125 null, null, false, true, true, -1); 15126 queue.enqueueParallelBroadcastLocked(r); 15127 queue.scheduleBroadcastsLocked(); 15128 } 15129 } 15130 15131 return sticky; 15132 } 15133 } 15134 15135 public void unregisterReceiver(IIntentReceiver receiver) { 15136 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15137 15138 final long origId = Binder.clearCallingIdentity(); 15139 try { 15140 boolean doTrim = false; 15141 15142 synchronized(this) { 15143 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15144 if (rl != null) { 15145 if (rl.curBroadcast != null) { 15146 BroadcastRecord r = rl.curBroadcast; 15147 final boolean doNext = finishReceiverLocked( 15148 receiver.asBinder(), r.resultCode, r.resultData, 15149 r.resultExtras, r.resultAbort); 15150 if (doNext) { 15151 doTrim = true; 15152 r.queue.processNextBroadcast(false); 15153 } 15154 } 15155 15156 if (rl.app != null) { 15157 rl.app.receivers.remove(rl); 15158 } 15159 removeReceiverLocked(rl); 15160 if (rl.linkedToDeath) { 15161 rl.linkedToDeath = false; 15162 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15163 } 15164 } 15165 } 15166 15167 // If we actually concluded any broadcasts, we might now be able 15168 // to trim the recipients' apps from our working set 15169 if (doTrim) { 15170 trimApplications(); 15171 return; 15172 } 15173 15174 } finally { 15175 Binder.restoreCallingIdentity(origId); 15176 } 15177 } 15178 15179 void removeReceiverLocked(ReceiverList rl) { 15180 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15181 int N = rl.size(); 15182 for (int i=0; i<N; i++) { 15183 mReceiverResolver.removeFilter(rl.get(i)); 15184 } 15185 } 15186 15187 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15188 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15189 ProcessRecord r = mLruProcesses.get(i); 15190 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15191 try { 15192 r.thread.dispatchPackageBroadcast(cmd, packages); 15193 } catch (RemoteException ex) { 15194 } 15195 } 15196 } 15197 } 15198 15199 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15200 int callingUid, int[] users) { 15201 List<ResolveInfo> receivers = null; 15202 try { 15203 HashSet<ComponentName> singleUserReceivers = null; 15204 boolean scannedFirstReceivers = false; 15205 for (int user : users) { 15206 // Skip users that have Shell restrictions 15207 if (callingUid == Process.SHELL_UID 15208 && getUserManagerLocked().hasUserRestriction( 15209 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15210 continue; 15211 } 15212 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15213 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15214 if (user != 0 && newReceivers != null) { 15215 // If this is not the primary user, we need to check for 15216 // any receivers that should be filtered out. 15217 for (int i=0; i<newReceivers.size(); i++) { 15218 ResolveInfo ri = newReceivers.get(i); 15219 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15220 newReceivers.remove(i); 15221 i--; 15222 } 15223 } 15224 } 15225 if (newReceivers != null && newReceivers.size() == 0) { 15226 newReceivers = null; 15227 } 15228 if (receivers == null) { 15229 receivers = newReceivers; 15230 } else if (newReceivers != null) { 15231 // We need to concatenate the additional receivers 15232 // found with what we have do far. This would be easy, 15233 // but we also need to de-dup any receivers that are 15234 // singleUser. 15235 if (!scannedFirstReceivers) { 15236 // Collect any single user receivers we had already retrieved. 15237 scannedFirstReceivers = true; 15238 for (int i=0; i<receivers.size(); i++) { 15239 ResolveInfo ri = receivers.get(i); 15240 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15241 ComponentName cn = new ComponentName( 15242 ri.activityInfo.packageName, ri.activityInfo.name); 15243 if (singleUserReceivers == null) { 15244 singleUserReceivers = new HashSet<ComponentName>(); 15245 } 15246 singleUserReceivers.add(cn); 15247 } 15248 } 15249 } 15250 // Add the new results to the existing results, tracking 15251 // and de-dupping single user receivers. 15252 for (int i=0; i<newReceivers.size(); i++) { 15253 ResolveInfo ri = newReceivers.get(i); 15254 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15255 ComponentName cn = new ComponentName( 15256 ri.activityInfo.packageName, ri.activityInfo.name); 15257 if (singleUserReceivers == null) { 15258 singleUserReceivers = new HashSet<ComponentName>(); 15259 } 15260 if (!singleUserReceivers.contains(cn)) { 15261 singleUserReceivers.add(cn); 15262 receivers.add(ri); 15263 } 15264 } else { 15265 receivers.add(ri); 15266 } 15267 } 15268 } 15269 } 15270 } catch (RemoteException ex) { 15271 // pm is in same process, this will never happen. 15272 } 15273 return receivers; 15274 } 15275 15276 private final int broadcastIntentLocked(ProcessRecord callerApp, 15277 String callerPackage, Intent intent, String resolvedType, 15278 IIntentReceiver resultTo, int resultCode, String resultData, 15279 Bundle map, String requiredPermission, int appOp, 15280 boolean ordered, boolean sticky, int callingPid, int callingUid, 15281 int userId) { 15282 intent = new Intent(intent); 15283 15284 // By default broadcasts do not go to stopped apps. 15285 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15286 15287 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15288 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15289 + " ordered=" + ordered + " userid=" + userId); 15290 if ((resultTo != null) && !ordered) { 15291 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15292 } 15293 15294 userId = handleIncomingUser(callingPid, callingUid, userId, 15295 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15296 15297 // Make sure that the user who is receiving this broadcast is started. 15298 // If not, we will just skip it. 15299 15300 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15301 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15302 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15303 Slog.w(TAG, "Skipping broadcast of " + intent 15304 + ": user " + userId + " is stopped"); 15305 return ActivityManager.BROADCAST_SUCCESS; 15306 } 15307 } 15308 15309 /* 15310 * Prevent non-system code (defined here to be non-persistent 15311 * processes) from sending protected broadcasts. 15312 */ 15313 int callingAppId = UserHandle.getAppId(callingUid); 15314 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15315 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15316 || callingAppId == Process.NFC_UID || callingUid == 0) { 15317 // Always okay. 15318 } else if (callerApp == null || !callerApp.persistent) { 15319 try { 15320 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15321 intent.getAction())) { 15322 String msg = "Permission Denial: not allowed to send broadcast " 15323 + intent.getAction() + " from pid=" 15324 + callingPid + ", uid=" + callingUid; 15325 Slog.w(TAG, msg); 15326 throw new SecurityException(msg); 15327 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15328 // Special case for compatibility: we don't want apps to send this, 15329 // but historically it has not been protected and apps may be using it 15330 // to poke their own app widget. So, instead of making it protected, 15331 // just limit it to the caller. 15332 if (callerApp == null) { 15333 String msg = "Permission Denial: not allowed to send broadcast " 15334 + intent.getAction() + " from unknown caller."; 15335 Slog.w(TAG, msg); 15336 throw new SecurityException(msg); 15337 } else if (intent.getComponent() != null) { 15338 // They are good enough to send to an explicit component... verify 15339 // it is being sent to the calling app. 15340 if (!intent.getComponent().getPackageName().equals( 15341 callerApp.info.packageName)) { 15342 String msg = "Permission Denial: not allowed to send broadcast " 15343 + intent.getAction() + " to " 15344 + intent.getComponent().getPackageName() + " from " 15345 + callerApp.info.packageName; 15346 Slog.w(TAG, msg); 15347 throw new SecurityException(msg); 15348 } 15349 } else { 15350 // Limit broadcast to their own package. 15351 intent.setPackage(callerApp.info.packageName); 15352 } 15353 } 15354 } catch (RemoteException e) { 15355 Slog.w(TAG, "Remote exception", e); 15356 return ActivityManager.BROADCAST_SUCCESS; 15357 } 15358 } 15359 15360 // Handle special intents: if this broadcast is from the package 15361 // manager about a package being removed, we need to remove all of 15362 // its activities from the history stack. 15363 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15364 intent.getAction()); 15365 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15366 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15367 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15368 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15369 || uidRemoved) { 15370 if (checkComponentPermission( 15371 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15372 callingPid, callingUid, -1, true) 15373 == PackageManager.PERMISSION_GRANTED) { 15374 if (uidRemoved) { 15375 final Bundle intentExtras = intent.getExtras(); 15376 final int uid = intentExtras != null 15377 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15378 if (uid >= 0) { 15379 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15380 synchronized (bs) { 15381 bs.removeUidStatsLocked(uid); 15382 } 15383 mAppOpsService.uidRemoved(uid); 15384 } 15385 } else { 15386 // If resources are unavailable just force stop all 15387 // those packages and flush the attribute cache as well. 15388 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15389 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15390 if (list != null && (list.length > 0)) { 15391 for (String pkg : list) { 15392 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15393 "storage unmount"); 15394 } 15395 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15396 sendPackageBroadcastLocked( 15397 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15398 } 15399 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15400 intent.getAction())) { 15401 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15402 } else { 15403 Uri data = intent.getData(); 15404 String ssp; 15405 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15406 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15407 intent.getAction()); 15408 boolean fullUninstall = removed && 15409 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15410 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15411 forceStopPackageLocked(ssp, UserHandle.getAppId( 15412 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15413 false, fullUninstall, userId, 15414 removed ? "pkg removed" : "pkg changed"); 15415 } 15416 if (removed) { 15417 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15418 new String[] {ssp}, userId); 15419 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15420 mAppOpsService.packageRemoved( 15421 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15422 15423 // Remove all permissions granted from/to this package 15424 removeUriPermissionsForPackageLocked(ssp, userId, true); 15425 } 15426 } 15427 } 15428 } 15429 } 15430 } else { 15431 String msg = "Permission Denial: " + intent.getAction() 15432 + " broadcast from " + callerPackage + " (pid=" + callingPid 15433 + ", uid=" + callingUid + ")" 15434 + " requires " 15435 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15436 Slog.w(TAG, msg); 15437 throw new SecurityException(msg); 15438 } 15439 15440 // Special case for adding a package: by default turn on compatibility 15441 // mode. 15442 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15443 Uri data = intent.getData(); 15444 String ssp; 15445 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15446 mCompatModePackages.handlePackageAddedLocked(ssp, 15447 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15448 } 15449 } 15450 15451 /* 15452 * If this is the time zone changed action, queue up a message that will reset the timezone 15453 * of all currently running processes. This message will get queued up before the broadcast 15454 * happens. 15455 */ 15456 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15457 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15458 } 15459 15460 /* 15461 * If the user set the time, let all running processes know. 15462 */ 15463 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15464 final int is24Hour = intent.getBooleanExtra( 15465 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15466 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15467 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15468 synchronized (stats) { 15469 stats.noteCurrentTimeChangedLocked(); 15470 } 15471 } 15472 15473 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15474 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15475 } 15476 15477 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15478 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15479 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15480 } 15481 15482 // Add to the sticky list if requested. 15483 if (sticky) { 15484 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15485 callingPid, callingUid) 15486 != PackageManager.PERMISSION_GRANTED) { 15487 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15488 + callingPid + ", uid=" + callingUid 15489 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15490 Slog.w(TAG, msg); 15491 throw new SecurityException(msg); 15492 } 15493 if (requiredPermission != null) { 15494 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15495 + " and enforce permission " + requiredPermission); 15496 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15497 } 15498 if (intent.getComponent() != null) { 15499 throw new SecurityException( 15500 "Sticky broadcasts can't target a specific component"); 15501 } 15502 // We use userId directly here, since the "all" target is maintained 15503 // as a separate set of sticky broadcasts. 15504 if (userId != UserHandle.USER_ALL) { 15505 // But first, if this is not a broadcast to all users, then 15506 // make sure it doesn't conflict with an existing broadcast to 15507 // all users. 15508 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15509 UserHandle.USER_ALL); 15510 if (stickies != null) { 15511 ArrayList<Intent> list = stickies.get(intent.getAction()); 15512 if (list != null) { 15513 int N = list.size(); 15514 int i; 15515 for (i=0; i<N; i++) { 15516 if (intent.filterEquals(list.get(i))) { 15517 throw new IllegalArgumentException( 15518 "Sticky broadcast " + intent + " for user " 15519 + userId + " conflicts with existing global broadcast"); 15520 } 15521 } 15522 } 15523 } 15524 } 15525 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15526 if (stickies == null) { 15527 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15528 mStickyBroadcasts.put(userId, stickies); 15529 } 15530 ArrayList<Intent> list = stickies.get(intent.getAction()); 15531 if (list == null) { 15532 list = new ArrayList<Intent>(); 15533 stickies.put(intent.getAction(), list); 15534 } 15535 int N = list.size(); 15536 int i; 15537 for (i=0; i<N; i++) { 15538 if (intent.filterEquals(list.get(i))) { 15539 // This sticky already exists, replace it. 15540 list.set(i, new Intent(intent)); 15541 break; 15542 } 15543 } 15544 if (i >= N) { 15545 list.add(new Intent(intent)); 15546 } 15547 } 15548 15549 int[] users; 15550 if (userId == UserHandle.USER_ALL) { 15551 // Caller wants broadcast to go to all started users. 15552 users = mStartedUserArray; 15553 } else { 15554 // Caller wants broadcast to go to one specific user. 15555 users = new int[] {userId}; 15556 } 15557 15558 // Figure out who all will receive this broadcast. 15559 List receivers = null; 15560 List<BroadcastFilter> registeredReceivers = null; 15561 // Need to resolve the intent to interested receivers... 15562 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15563 == 0) { 15564 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15565 } 15566 if (intent.getComponent() == null) { 15567 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15568 // Query one target user at a time, excluding shell-restricted users 15569 UserManagerService ums = getUserManagerLocked(); 15570 for (int i = 0; i < users.length; i++) { 15571 if (ums.hasUserRestriction( 15572 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15573 continue; 15574 } 15575 List<BroadcastFilter> registeredReceiversForUser = 15576 mReceiverResolver.queryIntent(intent, 15577 resolvedType, false, users[i]); 15578 if (registeredReceivers == null) { 15579 registeredReceivers = registeredReceiversForUser; 15580 } else if (registeredReceiversForUser != null) { 15581 registeredReceivers.addAll(registeredReceiversForUser); 15582 } 15583 } 15584 } else { 15585 registeredReceivers = mReceiverResolver.queryIntent(intent, 15586 resolvedType, false, userId); 15587 } 15588 } 15589 15590 final boolean replacePending = 15591 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15592 15593 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15594 + " replacePending=" + replacePending); 15595 15596 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15597 if (!ordered && NR > 0) { 15598 // If we are not serializing this broadcast, then send the 15599 // registered receivers separately so they don't wait for the 15600 // components to be launched. 15601 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15602 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15603 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15604 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15605 ordered, sticky, false, userId); 15606 if (DEBUG_BROADCAST) Slog.v( 15607 TAG, "Enqueueing parallel broadcast " + r); 15608 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15609 if (!replaced) { 15610 queue.enqueueParallelBroadcastLocked(r); 15611 queue.scheduleBroadcastsLocked(); 15612 } 15613 registeredReceivers = null; 15614 NR = 0; 15615 } 15616 15617 // Merge into one list. 15618 int ir = 0; 15619 if (receivers != null) { 15620 // A special case for PACKAGE_ADDED: do not allow the package 15621 // being added to see this broadcast. This prevents them from 15622 // using this as a back door to get run as soon as they are 15623 // installed. Maybe in the future we want to have a special install 15624 // broadcast or such for apps, but we'd like to deliberately make 15625 // this decision. 15626 String skipPackages[] = null; 15627 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15628 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15629 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15630 Uri data = intent.getData(); 15631 if (data != null) { 15632 String pkgName = data.getSchemeSpecificPart(); 15633 if (pkgName != null) { 15634 skipPackages = new String[] { pkgName }; 15635 } 15636 } 15637 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15638 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15639 } 15640 if (skipPackages != null && (skipPackages.length > 0)) { 15641 for (String skipPackage : skipPackages) { 15642 if (skipPackage != null) { 15643 int NT = receivers.size(); 15644 for (int it=0; it<NT; it++) { 15645 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15646 if (curt.activityInfo.packageName.equals(skipPackage)) { 15647 receivers.remove(it); 15648 it--; 15649 NT--; 15650 } 15651 } 15652 } 15653 } 15654 } 15655 15656 int NT = receivers != null ? receivers.size() : 0; 15657 int it = 0; 15658 ResolveInfo curt = null; 15659 BroadcastFilter curr = null; 15660 while (it < NT && ir < NR) { 15661 if (curt == null) { 15662 curt = (ResolveInfo)receivers.get(it); 15663 } 15664 if (curr == null) { 15665 curr = registeredReceivers.get(ir); 15666 } 15667 if (curr.getPriority() >= curt.priority) { 15668 // Insert this broadcast record into the final list. 15669 receivers.add(it, curr); 15670 ir++; 15671 curr = null; 15672 it++; 15673 NT++; 15674 } else { 15675 // Skip to the next ResolveInfo in the final list. 15676 it++; 15677 curt = null; 15678 } 15679 } 15680 } 15681 while (ir < NR) { 15682 if (receivers == null) { 15683 receivers = new ArrayList(); 15684 } 15685 receivers.add(registeredReceivers.get(ir)); 15686 ir++; 15687 } 15688 15689 if ((receivers != null && receivers.size() > 0) 15690 || resultTo != null) { 15691 BroadcastQueue queue = broadcastQueueForIntent(intent); 15692 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15693 callerPackage, callingPid, callingUid, resolvedType, 15694 requiredPermission, appOp, receivers, resultTo, resultCode, 15695 resultData, map, ordered, sticky, false, userId); 15696 if (DEBUG_BROADCAST) Slog.v( 15697 TAG, "Enqueueing ordered broadcast " + r 15698 + ": prev had " + queue.mOrderedBroadcasts.size()); 15699 if (DEBUG_BROADCAST) { 15700 int seq = r.intent.getIntExtra("seq", -1); 15701 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15702 } 15703 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15704 if (!replaced) { 15705 queue.enqueueOrderedBroadcastLocked(r); 15706 queue.scheduleBroadcastsLocked(); 15707 } 15708 } 15709 15710 return ActivityManager.BROADCAST_SUCCESS; 15711 } 15712 15713 final Intent verifyBroadcastLocked(Intent intent) { 15714 // Refuse possible leaked file descriptors 15715 if (intent != null && intent.hasFileDescriptors() == true) { 15716 throw new IllegalArgumentException("File descriptors passed in Intent"); 15717 } 15718 15719 int flags = intent.getFlags(); 15720 15721 if (!mProcessesReady) { 15722 // if the caller really truly claims to know what they're doing, go 15723 // ahead and allow the broadcast without launching any receivers 15724 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15725 intent = new Intent(intent); 15726 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15727 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15728 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15729 + " before boot completion"); 15730 throw new IllegalStateException("Cannot broadcast before boot completed"); 15731 } 15732 } 15733 15734 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15735 throw new IllegalArgumentException( 15736 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15737 } 15738 15739 return intent; 15740 } 15741 15742 public final int broadcastIntent(IApplicationThread caller, 15743 Intent intent, String resolvedType, IIntentReceiver resultTo, 15744 int resultCode, String resultData, Bundle map, 15745 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15746 enforceNotIsolatedCaller("broadcastIntent"); 15747 synchronized(this) { 15748 intent = verifyBroadcastLocked(intent); 15749 15750 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15751 final int callingPid = Binder.getCallingPid(); 15752 final int callingUid = Binder.getCallingUid(); 15753 final long origId = Binder.clearCallingIdentity(); 15754 int res = broadcastIntentLocked(callerApp, 15755 callerApp != null ? callerApp.info.packageName : null, 15756 intent, resolvedType, resultTo, 15757 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15758 callingPid, callingUid, userId); 15759 Binder.restoreCallingIdentity(origId); 15760 return res; 15761 } 15762 } 15763 15764 int broadcastIntentInPackage(String packageName, int uid, 15765 Intent intent, String resolvedType, IIntentReceiver resultTo, 15766 int resultCode, String resultData, Bundle map, 15767 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15768 synchronized(this) { 15769 intent = verifyBroadcastLocked(intent); 15770 15771 final long origId = Binder.clearCallingIdentity(); 15772 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15773 resultTo, resultCode, resultData, map, requiredPermission, 15774 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15775 Binder.restoreCallingIdentity(origId); 15776 return res; 15777 } 15778 } 15779 15780 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15781 // Refuse possible leaked file descriptors 15782 if (intent != null && intent.hasFileDescriptors() == true) { 15783 throw new IllegalArgumentException("File descriptors passed in Intent"); 15784 } 15785 15786 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15787 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15788 15789 synchronized(this) { 15790 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15791 != PackageManager.PERMISSION_GRANTED) { 15792 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15793 + Binder.getCallingPid() 15794 + ", uid=" + Binder.getCallingUid() 15795 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15796 Slog.w(TAG, msg); 15797 throw new SecurityException(msg); 15798 } 15799 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15800 if (stickies != null) { 15801 ArrayList<Intent> list = stickies.get(intent.getAction()); 15802 if (list != null) { 15803 int N = list.size(); 15804 int i; 15805 for (i=0; i<N; i++) { 15806 if (intent.filterEquals(list.get(i))) { 15807 list.remove(i); 15808 break; 15809 } 15810 } 15811 if (list.size() <= 0) { 15812 stickies.remove(intent.getAction()); 15813 } 15814 } 15815 if (stickies.size() <= 0) { 15816 mStickyBroadcasts.remove(userId); 15817 } 15818 } 15819 } 15820 } 15821 15822 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15823 String resultData, Bundle resultExtras, boolean resultAbort) { 15824 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15825 if (r == null) { 15826 Slog.w(TAG, "finishReceiver called but not found on queue"); 15827 return false; 15828 } 15829 15830 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15831 } 15832 15833 void backgroundServicesFinishedLocked(int userId) { 15834 for (BroadcastQueue queue : mBroadcastQueues) { 15835 queue.backgroundServicesFinishedLocked(userId); 15836 } 15837 } 15838 15839 public void finishReceiver(IBinder who, int resultCode, String resultData, 15840 Bundle resultExtras, boolean resultAbort) { 15841 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15842 15843 // Refuse possible leaked file descriptors 15844 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15845 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15846 } 15847 15848 final long origId = Binder.clearCallingIdentity(); 15849 try { 15850 boolean doNext = false; 15851 BroadcastRecord r; 15852 15853 synchronized(this) { 15854 r = broadcastRecordForReceiverLocked(who); 15855 if (r != null) { 15856 doNext = r.queue.finishReceiverLocked(r, resultCode, 15857 resultData, resultExtras, resultAbort, true); 15858 } 15859 } 15860 15861 if (doNext) { 15862 r.queue.processNextBroadcast(false); 15863 } 15864 trimApplications(); 15865 } finally { 15866 Binder.restoreCallingIdentity(origId); 15867 } 15868 } 15869 15870 // ========================================================= 15871 // INSTRUMENTATION 15872 // ========================================================= 15873 15874 public boolean startInstrumentation(ComponentName className, 15875 String profileFile, int flags, Bundle arguments, 15876 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15877 int userId, String abiOverride) { 15878 enforceNotIsolatedCaller("startInstrumentation"); 15879 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15880 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15881 // Refuse possible leaked file descriptors 15882 if (arguments != null && arguments.hasFileDescriptors()) { 15883 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15884 } 15885 15886 synchronized(this) { 15887 InstrumentationInfo ii = null; 15888 ApplicationInfo ai = null; 15889 try { 15890 ii = mContext.getPackageManager().getInstrumentationInfo( 15891 className, STOCK_PM_FLAGS); 15892 ai = AppGlobals.getPackageManager().getApplicationInfo( 15893 ii.targetPackage, STOCK_PM_FLAGS, userId); 15894 } catch (PackageManager.NameNotFoundException e) { 15895 } catch (RemoteException e) { 15896 } 15897 if (ii == null) { 15898 reportStartInstrumentationFailure(watcher, className, 15899 "Unable to find instrumentation info for: " + className); 15900 return false; 15901 } 15902 if (ai == null) { 15903 reportStartInstrumentationFailure(watcher, className, 15904 "Unable to find instrumentation target package: " + ii.targetPackage); 15905 return false; 15906 } 15907 15908 int match = mContext.getPackageManager().checkSignatures( 15909 ii.targetPackage, ii.packageName); 15910 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15911 String msg = "Permission Denial: starting instrumentation " 15912 + className + " from pid=" 15913 + Binder.getCallingPid() 15914 + ", uid=" + Binder.getCallingPid() 15915 + " not allowed because package " + ii.packageName 15916 + " does not have a signature matching the target " 15917 + ii.targetPackage; 15918 reportStartInstrumentationFailure(watcher, className, msg); 15919 throw new SecurityException(msg); 15920 } 15921 15922 final long origId = Binder.clearCallingIdentity(); 15923 // Instrumentation can kill and relaunch even persistent processes 15924 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15925 "start instr"); 15926 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15927 app.instrumentationClass = className; 15928 app.instrumentationInfo = ai; 15929 app.instrumentationProfileFile = profileFile; 15930 app.instrumentationArguments = arguments; 15931 app.instrumentationWatcher = watcher; 15932 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15933 app.instrumentationResultClass = className; 15934 Binder.restoreCallingIdentity(origId); 15935 } 15936 15937 return true; 15938 } 15939 15940 /** 15941 * Report errors that occur while attempting to start Instrumentation. Always writes the 15942 * error to the logs, but if somebody is watching, send the report there too. This enables 15943 * the "am" command to report errors with more information. 15944 * 15945 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15946 * @param cn The component name of the instrumentation. 15947 * @param report The error report. 15948 */ 15949 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15950 ComponentName cn, String report) { 15951 Slog.w(TAG, report); 15952 try { 15953 if (watcher != null) { 15954 Bundle results = new Bundle(); 15955 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15956 results.putString("Error", report); 15957 watcher.instrumentationStatus(cn, -1, results); 15958 } 15959 } catch (RemoteException e) { 15960 Slog.w(TAG, e); 15961 } 15962 } 15963 15964 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15965 if (app.instrumentationWatcher != null) { 15966 try { 15967 // NOTE: IInstrumentationWatcher *must* be oneway here 15968 app.instrumentationWatcher.instrumentationFinished( 15969 app.instrumentationClass, 15970 resultCode, 15971 results); 15972 } catch (RemoteException e) { 15973 } 15974 } 15975 if (app.instrumentationUiAutomationConnection != null) { 15976 try { 15977 app.instrumentationUiAutomationConnection.shutdown(); 15978 } catch (RemoteException re) { 15979 /* ignore */ 15980 } 15981 // Only a UiAutomation can set this flag and now that 15982 // it is finished we make sure it is reset to its default. 15983 mUserIsMonkey = false; 15984 } 15985 app.instrumentationWatcher = null; 15986 app.instrumentationUiAutomationConnection = null; 15987 app.instrumentationClass = null; 15988 app.instrumentationInfo = null; 15989 app.instrumentationProfileFile = null; 15990 app.instrumentationArguments = null; 15991 15992 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 15993 "finished inst"); 15994 } 15995 15996 public void finishInstrumentation(IApplicationThread target, 15997 int resultCode, Bundle results) { 15998 int userId = UserHandle.getCallingUserId(); 15999 // Refuse possible leaked file descriptors 16000 if (results != null && results.hasFileDescriptors()) { 16001 throw new IllegalArgumentException("File descriptors passed in Intent"); 16002 } 16003 16004 synchronized(this) { 16005 ProcessRecord app = getRecordForAppLocked(target); 16006 if (app == null) { 16007 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16008 return; 16009 } 16010 final long origId = Binder.clearCallingIdentity(); 16011 finishInstrumentationLocked(app, resultCode, results); 16012 Binder.restoreCallingIdentity(origId); 16013 } 16014 } 16015 16016 // ========================================================= 16017 // CONFIGURATION 16018 // ========================================================= 16019 16020 public ConfigurationInfo getDeviceConfigurationInfo() { 16021 ConfigurationInfo config = new ConfigurationInfo(); 16022 synchronized (this) { 16023 config.reqTouchScreen = mConfiguration.touchscreen; 16024 config.reqKeyboardType = mConfiguration.keyboard; 16025 config.reqNavigation = mConfiguration.navigation; 16026 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16027 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16028 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16029 } 16030 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16031 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16032 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16033 } 16034 config.reqGlEsVersion = GL_ES_VERSION; 16035 } 16036 return config; 16037 } 16038 16039 ActivityStack getFocusedStack() { 16040 return mStackSupervisor.getFocusedStack(); 16041 } 16042 16043 public Configuration getConfiguration() { 16044 Configuration ci; 16045 synchronized(this) { 16046 ci = new Configuration(mConfiguration); 16047 } 16048 return ci; 16049 } 16050 16051 public void updatePersistentConfiguration(Configuration values) { 16052 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16053 "updateConfiguration()"); 16054 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16055 "updateConfiguration()"); 16056 if (values == null) { 16057 throw new NullPointerException("Configuration must not be null"); 16058 } 16059 16060 synchronized(this) { 16061 final long origId = Binder.clearCallingIdentity(); 16062 updateConfigurationLocked(values, null, true, false); 16063 Binder.restoreCallingIdentity(origId); 16064 } 16065 } 16066 16067 public void updateConfiguration(Configuration values) { 16068 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16069 "updateConfiguration()"); 16070 16071 synchronized(this) { 16072 if (values == null && mWindowManager != null) { 16073 // sentinel: fetch the current configuration from the window manager 16074 values = mWindowManager.computeNewConfiguration(); 16075 } 16076 16077 if (mWindowManager != null) { 16078 mProcessList.applyDisplaySize(mWindowManager); 16079 } 16080 16081 final long origId = Binder.clearCallingIdentity(); 16082 if (values != null) { 16083 Settings.System.clearConfiguration(values); 16084 } 16085 updateConfigurationLocked(values, null, false, false); 16086 Binder.restoreCallingIdentity(origId); 16087 } 16088 } 16089 16090 /** 16091 * Do either or both things: (1) change the current configuration, and (2) 16092 * make sure the given activity is running with the (now) current 16093 * configuration. Returns true if the activity has been left running, or 16094 * false if <var>starting</var> is being destroyed to match the new 16095 * configuration. 16096 * @param persistent TODO 16097 */ 16098 boolean updateConfigurationLocked(Configuration values, 16099 ActivityRecord starting, boolean persistent, boolean initLocale) { 16100 int changes = 0; 16101 16102 if (values != null) { 16103 Configuration newConfig = new Configuration(mConfiguration); 16104 changes = newConfig.updateFrom(values); 16105 if (changes != 0) { 16106 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16107 Slog.i(TAG, "Updating configuration to: " + values); 16108 } 16109 16110 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16111 16112 if (values.locale != null && !initLocale) { 16113 saveLocaleLocked(values.locale, 16114 !values.locale.equals(mConfiguration.locale), 16115 values.userSetLocale); 16116 } 16117 16118 mConfigurationSeq++; 16119 if (mConfigurationSeq <= 0) { 16120 mConfigurationSeq = 1; 16121 } 16122 newConfig.seq = mConfigurationSeq; 16123 mConfiguration = newConfig; 16124 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16125 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16126 //mUsageStatsService.noteStartConfig(newConfig); 16127 16128 final Configuration configCopy = new Configuration(mConfiguration); 16129 16130 // TODO: If our config changes, should we auto dismiss any currently 16131 // showing dialogs? 16132 mShowDialogs = shouldShowDialogs(newConfig); 16133 16134 AttributeCache ac = AttributeCache.instance(); 16135 if (ac != null) { 16136 ac.updateConfiguration(configCopy); 16137 } 16138 16139 // Make sure all resources in our process are updated 16140 // right now, so that anyone who is going to retrieve 16141 // resource values after we return will be sure to get 16142 // the new ones. This is especially important during 16143 // boot, where the first config change needs to guarantee 16144 // all resources have that config before following boot 16145 // code is executed. 16146 mSystemThread.applyConfigurationToResources(configCopy); 16147 16148 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16149 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16150 msg.obj = new Configuration(configCopy); 16151 mHandler.sendMessage(msg); 16152 } 16153 16154 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16155 ProcessRecord app = mLruProcesses.get(i); 16156 try { 16157 if (app.thread != null) { 16158 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16159 + app.processName + " new config " + mConfiguration); 16160 app.thread.scheduleConfigurationChanged(configCopy); 16161 } 16162 } catch (Exception e) { 16163 } 16164 } 16165 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16166 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16167 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16168 | Intent.FLAG_RECEIVER_FOREGROUND); 16169 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16170 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16171 Process.SYSTEM_UID, UserHandle.USER_ALL); 16172 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16173 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16174 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16175 broadcastIntentLocked(null, null, intent, 16176 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16177 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16178 } 16179 } 16180 } 16181 16182 boolean kept = true; 16183 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16184 // mainStack is null during startup. 16185 if (mainStack != null) { 16186 if (changes != 0 && starting == null) { 16187 // If the configuration changed, and the caller is not already 16188 // in the process of starting an activity, then find the top 16189 // activity to check if its configuration needs to change. 16190 starting = mainStack.topRunningActivityLocked(null); 16191 } 16192 16193 if (starting != null) { 16194 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16195 // And we need to make sure at this point that all other activities 16196 // are made visible with the correct configuration. 16197 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16198 } 16199 } 16200 16201 if (values != null && mWindowManager != null) { 16202 mWindowManager.setNewConfiguration(mConfiguration); 16203 } 16204 16205 return kept; 16206 } 16207 16208 /** 16209 * Decide based on the configuration whether we should shouw the ANR, 16210 * crash, etc dialogs. The idea is that if there is no affordnace to 16211 * press the on-screen buttons, we shouldn't show the dialog. 16212 * 16213 * A thought: SystemUI might also want to get told about this, the Power 16214 * dialog / global actions also might want different behaviors. 16215 */ 16216 private static final boolean shouldShowDialogs(Configuration config) { 16217 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16218 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16219 } 16220 16221 /** 16222 * Save the locale. You must be inside a synchronized (this) block. 16223 */ 16224 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16225 if(isDiff) { 16226 SystemProperties.set("user.language", l.getLanguage()); 16227 SystemProperties.set("user.region", l.getCountry()); 16228 } 16229 16230 if(isPersist) { 16231 SystemProperties.set("persist.sys.language", l.getLanguage()); 16232 SystemProperties.set("persist.sys.country", l.getCountry()); 16233 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16234 } 16235 } 16236 16237 @Override 16238 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16239 synchronized (this) { 16240 ActivityRecord srec = ActivityRecord.forToken(token); 16241 if (srec.task != null && srec.task.stack != null) { 16242 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16243 } 16244 } 16245 return false; 16246 } 16247 16248 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16249 Intent resultData) { 16250 16251 synchronized (this) { 16252 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16253 if (stack != null) { 16254 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16255 } 16256 return false; 16257 } 16258 } 16259 16260 public int getLaunchedFromUid(IBinder activityToken) { 16261 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16262 if (srec == null) { 16263 return -1; 16264 } 16265 return srec.launchedFromUid; 16266 } 16267 16268 public String getLaunchedFromPackage(IBinder activityToken) { 16269 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16270 if (srec == null) { 16271 return null; 16272 } 16273 return srec.launchedFromPackage; 16274 } 16275 16276 // ========================================================= 16277 // LIFETIME MANAGEMENT 16278 // ========================================================= 16279 16280 // Returns which broadcast queue the app is the current [or imminent] receiver 16281 // on, or 'null' if the app is not an active broadcast recipient. 16282 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16283 BroadcastRecord r = app.curReceiver; 16284 if (r != null) { 16285 return r.queue; 16286 } 16287 16288 // It's not the current receiver, but it might be starting up to become one 16289 synchronized (this) { 16290 for (BroadcastQueue queue : mBroadcastQueues) { 16291 r = queue.mPendingBroadcast; 16292 if (r != null && r.curApp == app) { 16293 // found it; report which queue it's in 16294 return queue; 16295 } 16296 } 16297 } 16298 16299 return null; 16300 } 16301 16302 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16303 boolean doingAll, long now) { 16304 if (mAdjSeq == app.adjSeq) { 16305 // This adjustment has already been computed. 16306 return app.curRawAdj; 16307 } 16308 16309 if (app.thread == null) { 16310 app.adjSeq = mAdjSeq; 16311 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16312 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16313 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16314 } 16315 16316 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16317 app.adjSource = null; 16318 app.adjTarget = null; 16319 app.empty = false; 16320 app.cached = false; 16321 16322 final int activitiesSize = app.activities.size(); 16323 16324 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16325 // The max adjustment doesn't allow this app to be anything 16326 // below foreground, so it is not worth doing work for it. 16327 app.adjType = "fixed"; 16328 app.adjSeq = mAdjSeq; 16329 app.curRawAdj = app.maxAdj; 16330 app.foregroundActivities = false; 16331 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16332 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16333 // System processes can do UI, and when they do we want to have 16334 // them trim their memory after the user leaves the UI. To 16335 // facilitate this, here we need to determine whether or not it 16336 // is currently showing UI. 16337 app.systemNoUi = true; 16338 if (app == TOP_APP) { 16339 app.systemNoUi = false; 16340 } else if (activitiesSize > 0) { 16341 for (int j = 0; j < activitiesSize; j++) { 16342 final ActivityRecord r = app.activities.get(j); 16343 if (r.visible) { 16344 app.systemNoUi = false; 16345 } 16346 } 16347 } 16348 if (!app.systemNoUi) { 16349 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16350 } 16351 return (app.curAdj=app.maxAdj); 16352 } 16353 16354 app.systemNoUi = false; 16355 16356 // Determine the importance of the process, starting with most 16357 // important to least, and assign an appropriate OOM adjustment. 16358 int adj; 16359 int schedGroup; 16360 int procState; 16361 boolean foregroundActivities = false; 16362 BroadcastQueue queue; 16363 if (app == TOP_APP) { 16364 // The last app on the list is the foreground app. 16365 adj = ProcessList.FOREGROUND_APP_ADJ; 16366 schedGroup = Process.THREAD_GROUP_DEFAULT; 16367 app.adjType = "top-activity"; 16368 foregroundActivities = true; 16369 procState = ActivityManager.PROCESS_STATE_TOP; 16370 } else if (app.instrumentationClass != null) { 16371 // Don't want to kill running instrumentation. 16372 adj = ProcessList.FOREGROUND_APP_ADJ; 16373 schedGroup = Process.THREAD_GROUP_DEFAULT; 16374 app.adjType = "instrumentation"; 16375 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16376 } else if ((queue = isReceivingBroadcast(app)) != null) { 16377 // An app that is currently receiving a broadcast also 16378 // counts as being in the foreground for OOM killer purposes. 16379 // It's placed in a sched group based on the nature of the 16380 // broadcast as reflected by which queue it's active in. 16381 adj = ProcessList.FOREGROUND_APP_ADJ; 16382 schedGroup = (queue == mFgBroadcastQueue) 16383 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16384 app.adjType = "broadcast"; 16385 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16386 } else if (app.executingServices.size() > 0) { 16387 // An app that is currently executing a service callback also 16388 // counts as being in the foreground. 16389 adj = ProcessList.FOREGROUND_APP_ADJ; 16390 schedGroup = app.execServicesFg ? 16391 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16392 app.adjType = "exec-service"; 16393 procState = ActivityManager.PROCESS_STATE_SERVICE; 16394 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16395 } else { 16396 // As far as we know the process is empty. We may change our mind later. 16397 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16398 // At this point we don't actually know the adjustment. Use the cached adj 16399 // value that the caller wants us to. 16400 adj = cachedAdj; 16401 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16402 app.cached = true; 16403 app.empty = true; 16404 app.adjType = "cch-empty"; 16405 } 16406 16407 // Examine all activities if not already foreground. 16408 if (!foregroundActivities && activitiesSize > 0) { 16409 for (int j = 0; j < activitiesSize; j++) { 16410 final ActivityRecord r = app.activities.get(j); 16411 if (r.app != app) { 16412 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16413 + app + "?!?"); 16414 continue; 16415 } 16416 if (r.visible) { 16417 // App has a visible activity; only upgrade adjustment. 16418 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16419 adj = ProcessList.VISIBLE_APP_ADJ; 16420 app.adjType = "visible"; 16421 } 16422 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16423 procState = ActivityManager.PROCESS_STATE_TOP; 16424 } 16425 schedGroup = Process.THREAD_GROUP_DEFAULT; 16426 app.cached = false; 16427 app.empty = false; 16428 foregroundActivities = true; 16429 break; 16430 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16431 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16432 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16433 app.adjType = "pausing"; 16434 } 16435 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16436 procState = ActivityManager.PROCESS_STATE_TOP; 16437 } 16438 schedGroup = Process.THREAD_GROUP_DEFAULT; 16439 app.cached = false; 16440 app.empty = false; 16441 foregroundActivities = true; 16442 } else if (r.state == ActivityState.STOPPING) { 16443 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16444 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16445 app.adjType = "stopping"; 16446 } 16447 // For the process state, we will at this point consider the 16448 // process to be cached. It will be cached either as an activity 16449 // or empty depending on whether the activity is finishing. We do 16450 // this so that we can treat the process as cached for purposes of 16451 // memory trimming (determing current memory level, trim command to 16452 // send to process) since there can be an arbitrary number of stopping 16453 // processes and they should soon all go into the cached state. 16454 if (!r.finishing) { 16455 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16456 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16457 } 16458 } 16459 app.cached = false; 16460 app.empty = false; 16461 foregroundActivities = true; 16462 } else { 16463 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16464 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16465 app.adjType = "cch-act"; 16466 } 16467 } 16468 } 16469 } 16470 16471 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16472 if (app.foregroundServices) { 16473 // The user is aware of this app, so make it visible. 16474 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16475 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16476 app.cached = false; 16477 app.adjType = "fg-service"; 16478 schedGroup = Process.THREAD_GROUP_DEFAULT; 16479 } else if (app.forcingToForeground != null) { 16480 // The user is aware of this app, so make it visible. 16481 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16482 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16483 app.cached = false; 16484 app.adjType = "force-fg"; 16485 app.adjSource = app.forcingToForeground; 16486 schedGroup = Process.THREAD_GROUP_DEFAULT; 16487 } 16488 } 16489 16490 if (app == mHeavyWeightProcess) { 16491 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16492 // We don't want to kill the current heavy-weight process. 16493 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16494 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16495 app.cached = false; 16496 app.adjType = "heavy"; 16497 } 16498 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16499 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16500 } 16501 } 16502 16503 if (app == mHomeProcess) { 16504 if (adj > ProcessList.HOME_APP_ADJ) { 16505 // This process is hosting what we currently consider to be the 16506 // home app, so we don't want to let it go into the background. 16507 adj = ProcessList.HOME_APP_ADJ; 16508 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16509 app.cached = false; 16510 app.adjType = "home"; 16511 } 16512 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16513 procState = ActivityManager.PROCESS_STATE_HOME; 16514 } 16515 } 16516 16517 if (app == mPreviousProcess && app.activities.size() > 0) { 16518 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16519 // This was the previous process that showed UI to the user. 16520 // We want to try to keep it around more aggressively, to give 16521 // a good experience around switching between two apps. 16522 adj = ProcessList.PREVIOUS_APP_ADJ; 16523 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16524 app.cached = false; 16525 app.adjType = "previous"; 16526 } 16527 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16528 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16529 } 16530 } 16531 16532 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16533 + " reason=" + app.adjType); 16534 16535 // By default, we use the computed adjustment. It may be changed if 16536 // there are applications dependent on our services or providers, but 16537 // this gives us a baseline and makes sure we don't get into an 16538 // infinite recursion. 16539 app.adjSeq = mAdjSeq; 16540 app.curRawAdj = adj; 16541 app.hasStartedServices = false; 16542 16543 if (mBackupTarget != null && app == mBackupTarget.app) { 16544 // If possible we want to avoid killing apps while they're being backed up 16545 if (adj > ProcessList.BACKUP_APP_ADJ) { 16546 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16547 adj = ProcessList.BACKUP_APP_ADJ; 16548 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16549 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16550 } 16551 app.adjType = "backup"; 16552 app.cached = false; 16553 } 16554 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16555 procState = ActivityManager.PROCESS_STATE_BACKUP; 16556 } 16557 } 16558 16559 boolean mayBeTop = false; 16560 16561 for (int is = app.services.size()-1; 16562 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16563 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16564 || procState > ActivityManager.PROCESS_STATE_TOP); 16565 is--) { 16566 ServiceRecord s = app.services.valueAt(is); 16567 if (s.startRequested) { 16568 app.hasStartedServices = true; 16569 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16570 procState = ActivityManager.PROCESS_STATE_SERVICE; 16571 } 16572 if (app.hasShownUi && app != mHomeProcess) { 16573 // If this process has shown some UI, let it immediately 16574 // go to the LRU list because it may be pretty heavy with 16575 // UI stuff. We'll tag it with a label just to help 16576 // debug and understand what is going on. 16577 if (adj > ProcessList.SERVICE_ADJ) { 16578 app.adjType = "cch-started-ui-services"; 16579 } 16580 } else { 16581 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16582 // This service has seen some activity within 16583 // recent memory, so we will keep its process ahead 16584 // of the background processes. 16585 if (adj > ProcessList.SERVICE_ADJ) { 16586 adj = ProcessList.SERVICE_ADJ; 16587 app.adjType = "started-services"; 16588 app.cached = false; 16589 } 16590 } 16591 // If we have let the service slide into the background 16592 // state, still have some text describing what it is doing 16593 // even though the service no longer has an impact. 16594 if (adj > ProcessList.SERVICE_ADJ) { 16595 app.adjType = "cch-started-services"; 16596 } 16597 } 16598 } 16599 for (int conni = s.connections.size()-1; 16600 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16601 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16602 || procState > ActivityManager.PROCESS_STATE_TOP); 16603 conni--) { 16604 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16605 for (int i = 0; 16606 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16607 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16608 || procState > ActivityManager.PROCESS_STATE_TOP); 16609 i++) { 16610 // XXX should compute this based on the max of 16611 // all connected clients. 16612 ConnectionRecord cr = clist.get(i); 16613 if (cr.binding.client == app) { 16614 // Binding to ourself is not interesting. 16615 continue; 16616 } 16617 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16618 ProcessRecord client = cr.binding.client; 16619 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16620 TOP_APP, doingAll, now); 16621 int clientProcState = client.curProcState; 16622 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16623 // If the other app is cached for any reason, for purposes here 16624 // we are going to consider it empty. The specific cached state 16625 // doesn't propagate except under certain conditions. 16626 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16627 } 16628 String adjType = null; 16629 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16630 // Not doing bind OOM management, so treat 16631 // this guy more like a started service. 16632 if (app.hasShownUi && app != mHomeProcess) { 16633 // If this process has shown some UI, let it immediately 16634 // go to the LRU list because it may be pretty heavy with 16635 // UI stuff. We'll tag it with a label just to help 16636 // debug and understand what is going on. 16637 if (adj > clientAdj) { 16638 adjType = "cch-bound-ui-services"; 16639 } 16640 app.cached = false; 16641 clientAdj = adj; 16642 clientProcState = procState; 16643 } else { 16644 if (now >= (s.lastActivity 16645 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16646 // This service has not seen activity within 16647 // recent memory, so allow it to drop to the 16648 // LRU list if there is no other reason to keep 16649 // it around. We'll also tag it with a label just 16650 // to help debug and undertand what is going on. 16651 if (adj > clientAdj) { 16652 adjType = "cch-bound-services"; 16653 } 16654 clientAdj = adj; 16655 } 16656 } 16657 } 16658 if (adj > clientAdj) { 16659 // If this process has recently shown UI, and 16660 // the process that is binding to it is less 16661 // important than being visible, then we don't 16662 // care about the binding as much as we care 16663 // about letting this process get into the LRU 16664 // list to be killed and restarted if needed for 16665 // memory. 16666 if (app.hasShownUi && app != mHomeProcess 16667 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16668 adjType = "cch-bound-ui-services"; 16669 } else { 16670 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16671 |Context.BIND_IMPORTANT)) != 0) { 16672 adj = clientAdj; 16673 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16674 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16675 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16676 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16677 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16678 adj = clientAdj; 16679 } else { 16680 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16681 adj = ProcessList.VISIBLE_APP_ADJ; 16682 } 16683 } 16684 if (!client.cached) { 16685 app.cached = false; 16686 } 16687 adjType = "service"; 16688 } 16689 } 16690 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16691 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16692 schedGroup = Process.THREAD_GROUP_DEFAULT; 16693 } 16694 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16695 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16696 // Special handling of clients who are in the top state. 16697 // We *may* want to consider this process to be in the 16698 // top state as well, but only if there is not another 16699 // reason for it to be running. Being on the top is a 16700 // special state, meaning you are specifically running 16701 // for the current top app. If the process is already 16702 // running in the background for some other reason, it 16703 // is more important to continue considering it to be 16704 // in the background state. 16705 mayBeTop = true; 16706 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16707 } else { 16708 // Special handling for above-top states (persistent 16709 // processes). These should not bring the current process 16710 // into the top state, since they are not on top. Instead 16711 // give them the best state after that. 16712 clientProcState = 16713 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16714 } 16715 } 16716 } else { 16717 if (clientProcState < 16718 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16719 clientProcState = 16720 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16721 } 16722 } 16723 if (procState > clientProcState) { 16724 procState = clientProcState; 16725 } 16726 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16727 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16728 app.pendingUiClean = true; 16729 } 16730 if (adjType != null) { 16731 app.adjType = adjType; 16732 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16733 .REASON_SERVICE_IN_USE; 16734 app.adjSource = cr.binding.client; 16735 app.adjSourceProcState = clientProcState; 16736 app.adjTarget = s.name; 16737 } 16738 } 16739 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16740 app.treatLikeActivity = true; 16741 } 16742 final ActivityRecord a = cr.activity; 16743 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16744 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16745 (a.visible || a.state == ActivityState.RESUMED 16746 || a.state == ActivityState.PAUSING)) { 16747 adj = ProcessList.FOREGROUND_APP_ADJ; 16748 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16749 schedGroup = Process.THREAD_GROUP_DEFAULT; 16750 } 16751 app.cached = false; 16752 app.adjType = "service"; 16753 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16754 .REASON_SERVICE_IN_USE; 16755 app.adjSource = a; 16756 app.adjSourceProcState = procState; 16757 app.adjTarget = s.name; 16758 } 16759 } 16760 } 16761 } 16762 } 16763 16764 for (int provi = app.pubProviders.size()-1; 16765 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16766 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16767 || procState > ActivityManager.PROCESS_STATE_TOP); 16768 provi--) { 16769 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16770 for (int i = cpr.connections.size()-1; 16771 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16772 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16773 || procState > ActivityManager.PROCESS_STATE_TOP); 16774 i--) { 16775 ContentProviderConnection conn = cpr.connections.get(i); 16776 ProcessRecord client = conn.client; 16777 if (client == app) { 16778 // Being our own client is not interesting. 16779 continue; 16780 } 16781 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16782 int clientProcState = client.curProcState; 16783 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16784 // If the other app is cached for any reason, for purposes here 16785 // we are going to consider it empty. 16786 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16787 } 16788 if (adj > clientAdj) { 16789 if (app.hasShownUi && app != mHomeProcess 16790 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16791 app.adjType = "cch-ui-provider"; 16792 } else { 16793 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16794 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16795 app.adjType = "provider"; 16796 } 16797 app.cached &= client.cached; 16798 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16799 .REASON_PROVIDER_IN_USE; 16800 app.adjSource = client; 16801 app.adjSourceProcState = clientProcState; 16802 app.adjTarget = cpr.name; 16803 } 16804 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16805 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16806 // Special handling of clients who are in the top state. 16807 // We *may* want to consider this process to be in the 16808 // top state as well, but only if there is not another 16809 // reason for it to be running. Being on the top is a 16810 // special state, meaning you are specifically running 16811 // for the current top app. If the process is already 16812 // running in the background for some other reason, it 16813 // is more important to continue considering it to be 16814 // in the background state. 16815 mayBeTop = true; 16816 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16817 } else { 16818 // Special handling for above-top states (persistent 16819 // processes). These should not bring the current process 16820 // into the top state, since they are not on top. Instead 16821 // give them the best state after that. 16822 clientProcState = 16823 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16824 } 16825 } 16826 if (procState > clientProcState) { 16827 procState = clientProcState; 16828 } 16829 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16830 schedGroup = Process.THREAD_GROUP_DEFAULT; 16831 } 16832 } 16833 // If the provider has external (non-framework) process 16834 // dependencies, ensure that its adjustment is at least 16835 // FOREGROUND_APP_ADJ. 16836 if (cpr.hasExternalProcessHandles()) { 16837 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16838 adj = ProcessList.FOREGROUND_APP_ADJ; 16839 schedGroup = Process.THREAD_GROUP_DEFAULT; 16840 app.cached = false; 16841 app.adjType = "provider"; 16842 app.adjTarget = cpr.name; 16843 } 16844 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16845 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16846 } 16847 } 16848 } 16849 16850 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16851 // A client of one of our services or providers is in the top state. We 16852 // *may* want to be in the top state, but not if we are already running in 16853 // the background for some other reason. For the decision here, we are going 16854 // to pick out a few specific states that we want to remain in when a client 16855 // is top (states that tend to be longer-term) and otherwise allow it to go 16856 // to the top state. 16857 switch (procState) { 16858 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16859 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16860 case ActivityManager.PROCESS_STATE_SERVICE: 16861 // These all are longer-term states, so pull them up to the top 16862 // of the background states, but not all the way to the top state. 16863 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16864 break; 16865 default: 16866 // Otherwise, top is a better choice, so take it. 16867 procState = ActivityManager.PROCESS_STATE_TOP; 16868 break; 16869 } 16870 } 16871 16872 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16873 if (app.hasClientActivities) { 16874 // This is a cached process, but with client activities. Mark it so. 16875 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16876 app.adjType = "cch-client-act"; 16877 } else if (app.treatLikeActivity) { 16878 // This is a cached process, but somebody wants us to treat it like it has 16879 // an activity, okay! 16880 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16881 app.adjType = "cch-as-act"; 16882 } 16883 } 16884 16885 if (adj == ProcessList.SERVICE_ADJ) { 16886 if (doingAll) { 16887 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16888 mNewNumServiceProcs++; 16889 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16890 if (!app.serviceb) { 16891 // This service isn't far enough down on the LRU list to 16892 // normally be a B service, but if we are low on RAM and it 16893 // is large we want to force it down since we would prefer to 16894 // keep launcher over it. 16895 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16896 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16897 app.serviceHighRam = true; 16898 app.serviceb = true; 16899 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16900 } else { 16901 mNewNumAServiceProcs++; 16902 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16903 } 16904 } else { 16905 app.serviceHighRam = false; 16906 } 16907 } 16908 if (app.serviceb) { 16909 adj = ProcessList.SERVICE_B_ADJ; 16910 } 16911 } 16912 16913 app.curRawAdj = adj; 16914 16915 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16916 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 16917 if (adj > app.maxAdj) { 16918 adj = app.maxAdj; 16919 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 16920 schedGroup = Process.THREAD_GROUP_DEFAULT; 16921 } 16922 } 16923 16924 // Do final modification to adj. Everything we do between here and applying 16925 // the final setAdj must be done in this function, because we will also use 16926 // it when computing the final cached adj later. Note that we don't need to 16927 // worry about this for max adj above, since max adj will always be used to 16928 // keep it out of the cached vaues. 16929 app.curAdj = app.modifyRawOomAdj(adj); 16930 app.curSchedGroup = schedGroup; 16931 app.curProcState = procState; 16932 app.foregroundActivities = foregroundActivities; 16933 16934 return app.curRawAdj; 16935 } 16936 16937 /** 16938 * Schedule PSS collection of a process. 16939 */ 16940 void requestPssLocked(ProcessRecord proc, int procState) { 16941 if (mPendingPssProcesses.contains(proc)) { 16942 return; 16943 } 16944 if (mPendingPssProcesses.size() == 0) { 16945 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16946 } 16947 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 16948 proc.pssProcState = procState; 16949 mPendingPssProcesses.add(proc); 16950 } 16951 16952 /** 16953 * Schedule PSS collection of all processes. 16954 */ 16955 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 16956 if (!always) { 16957 if (now < (mLastFullPssTime + 16958 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 16959 return; 16960 } 16961 } 16962 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 16963 mLastFullPssTime = now; 16964 mFullPssPending = true; 16965 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 16966 mPendingPssProcesses.clear(); 16967 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16968 ProcessRecord app = mLruProcesses.get(i); 16969 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 16970 app.pssProcState = app.setProcState; 16971 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16972 isSleeping(), now); 16973 mPendingPssProcesses.add(app); 16974 } 16975 } 16976 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16977 } 16978 16979 /** 16980 * Ask a given process to GC right now. 16981 */ 16982 final void performAppGcLocked(ProcessRecord app) { 16983 try { 16984 app.lastRequestedGc = SystemClock.uptimeMillis(); 16985 if (app.thread != null) { 16986 if (app.reportLowMemory) { 16987 app.reportLowMemory = false; 16988 app.thread.scheduleLowMemory(); 16989 } else { 16990 app.thread.processInBackground(); 16991 } 16992 } 16993 } catch (Exception e) { 16994 // whatever. 16995 } 16996 } 16997 16998 /** 16999 * Returns true if things are idle enough to perform GCs. 17000 */ 17001 private final boolean canGcNowLocked() { 17002 boolean processingBroadcasts = false; 17003 for (BroadcastQueue q : mBroadcastQueues) { 17004 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17005 processingBroadcasts = true; 17006 } 17007 } 17008 return !processingBroadcasts 17009 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17010 } 17011 17012 /** 17013 * Perform GCs on all processes that are waiting for it, but only 17014 * if things are idle. 17015 */ 17016 final void performAppGcsLocked() { 17017 final int N = mProcessesToGc.size(); 17018 if (N <= 0) { 17019 return; 17020 } 17021 if (canGcNowLocked()) { 17022 while (mProcessesToGc.size() > 0) { 17023 ProcessRecord proc = mProcessesToGc.remove(0); 17024 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17025 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17026 <= SystemClock.uptimeMillis()) { 17027 // To avoid spamming the system, we will GC processes one 17028 // at a time, waiting a few seconds between each. 17029 performAppGcLocked(proc); 17030 scheduleAppGcsLocked(); 17031 return; 17032 } else { 17033 // It hasn't been long enough since we last GCed this 17034 // process... put it in the list to wait for its time. 17035 addProcessToGcListLocked(proc); 17036 break; 17037 } 17038 } 17039 } 17040 17041 scheduleAppGcsLocked(); 17042 } 17043 } 17044 17045 /** 17046 * If all looks good, perform GCs on all processes waiting for them. 17047 */ 17048 final void performAppGcsIfAppropriateLocked() { 17049 if (canGcNowLocked()) { 17050 performAppGcsLocked(); 17051 return; 17052 } 17053 // Still not idle, wait some more. 17054 scheduleAppGcsLocked(); 17055 } 17056 17057 /** 17058 * Schedule the execution of all pending app GCs. 17059 */ 17060 final void scheduleAppGcsLocked() { 17061 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17062 17063 if (mProcessesToGc.size() > 0) { 17064 // Schedule a GC for the time to the next process. 17065 ProcessRecord proc = mProcessesToGc.get(0); 17066 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17067 17068 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17069 long now = SystemClock.uptimeMillis(); 17070 if (when < (now+GC_TIMEOUT)) { 17071 when = now + GC_TIMEOUT; 17072 } 17073 mHandler.sendMessageAtTime(msg, when); 17074 } 17075 } 17076 17077 /** 17078 * Add a process to the array of processes waiting to be GCed. Keeps the 17079 * list in sorted order by the last GC time. The process can't already be 17080 * on the list. 17081 */ 17082 final void addProcessToGcListLocked(ProcessRecord proc) { 17083 boolean added = false; 17084 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17085 if (mProcessesToGc.get(i).lastRequestedGc < 17086 proc.lastRequestedGc) { 17087 added = true; 17088 mProcessesToGc.add(i+1, proc); 17089 break; 17090 } 17091 } 17092 if (!added) { 17093 mProcessesToGc.add(0, proc); 17094 } 17095 } 17096 17097 /** 17098 * Set up to ask a process to GC itself. This will either do it 17099 * immediately, or put it on the list of processes to gc the next 17100 * time things are idle. 17101 */ 17102 final void scheduleAppGcLocked(ProcessRecord app) { 17103 long now = SystemClock.uptimeMillis(); 17104 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17105 return; 17106 } 17107 if (!mProcessesToGc.contains(app)) { 17108 addProcessToGcListLocked(app); 17109 scheduleAppGcsLocked(); 17110 } 17111 } 17112 17113 final void checkExcessivePowerUsageLocked(boolean doKills) { 17114 updateCpuStatsNow(); 17115 17116 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17117 boolean doWakeKills = doKills; 17118 boolean doCpuKills = doKills; 17119 if (mLastPowerCheckRealtime == 0) { 17120 doWakeKills = false; 17121 } 17122 if (mLastPowerCheckUptime == 0) { 17123 doCpuKills = false; 17124 } 17125 if (stats.isScreenOn()) { 17126 doWakeKills = false; 17127 } 17128 final long curRealtime = SystemClock.elapsedRealtime(); 17129 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17130 final long curUptime = SystemClock.uptimeMillis(); 17131 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17132 mLastPowerCheckRealtime = curRealtime; 17133 mLastPowerCheckUptime = curUptime; 17134 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17135 doWakeKills = false; 17136 } 17137 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17138 doCpuKills = false; 17139 } 17140 int i = mLruProcesses.size(); 17141 while (i > 0) { 17142 i--; 17143 ProcessRecord app = mLruProcesses.get(i); 17144 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17145 long wtime; 17146 synchronized (stats) { 17147 wtime = stats.getProcessWakeTime(app.info.uid, 17148 app.pid, curRealtime); 17149 } 17150 long wtimeUsed = wtime - app.lastWakeTime; 17151 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17152 if (DEBUG_POWER) { 17153 StringBuilder sb = new StringBuilder(128); 17154 sb.append("Wake for "); 17155 app.toShortString(sb); 17156 sb.append(": over "); 17157 TimeUtils.formatDuration(realtimeSince, sb); 17158 sb.append(" used "); 17159 TimeUtils.formatDuration(wtimeUsed, sb); 17160 sb.append(" ("); 17161 sb.append((wtimeUsed*100)/realtimeSince); 17162 sb.append("%)"); 17163 Slog.i(TAG, sb.toString()); 17164 sb.setLength(0); 17165 sb.append("CPU for "); 17166 app.toShortString(sb); 17167 sb.append(": over "); 17168 TimeUtils.formatDuration(uptimeSince, sb); 17169 sb.append(" used "); 17170 TimeUtils.formatDuration(cputimeUsed, sb); 17171 sb.append(" ("); 17172 sb.append((cputimeUsed*100)/uptimeSince); 17173 sb.append("%)"); 17174 Slog.i(TAG, sb.toString()); 17175 } 17176 // If a process has held a wake lock for more 17177 // than 50% of the time during this period, 17178 // that sounds bad. Kill! 17179 if (doWakeKills && realtimeSince > 0 17180 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17181 synchronized (stats) { 17182 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17183 realtimeSince, wtimeUsed); 17184 } 17185 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17186 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17187 } else if (doCpuKills && uptimeSince > 0 17188 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17189 synchronized (stats) { 17190 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17191 uptimeSince, cputimeUsed); 17192 } 17193 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17194 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17195 } else { 17196 app.lastWakeTime = wtime; 17197 app.lastCpuTime = app.curCpuTime; 17198 } 17199 } 17200 } 17201 } 17202 17203 private final boolean applyOomAdjLocked(ProcessRecord app, 17204 ProcessRecord TOP_APP, boolean doingAll, long now) { 17205 boolean success = true; 17206 17207 if (app.curRawAdj != app.setRawAdj) { 17208 app.setRawAdj = app.curRawAdj; 17209 } 17210 17211 int changes = 0; 17212 17213 if (app.curAdj != app.setAdj) { 17214 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17215 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17216 TAG, "Set " + app.pid + " " + app.processName + 17217 " adj " + app.curAdj + ": " + app.adjType); 17218 app.setAdj = app.curAdj; 17219 } 17220 17221 if (app.setSchedGroup != app.curSchedGroup) { 17222 app.setSchedGroup = app.curSchedGroup; 17223 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17224 "Setting process group of " + app.processName 17225 + " to " + app.curSchedGroup); 17226 if (app.waitingToKill != null && 17227 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17228 app.kill(app.waitingToKill, true); 17229 success = false; 17230 } else { 17231 if (true) { 17232 long oldId = Binder.clearCallingIdentity(); 17233 try { 17234 Process.setProcessGroup(app.pid, app.curSchedGroup); 17235 } catch (Exception e) { 17236 Slog.w(TAG, "Failed setting process group of " + app.pid 17237 + " to " + app.curSchedGroup); 17238 e.printStackTrace(); 17239 } finally { 17240 Binder.restoreCallingIdentity(oldId); 17241 } 17242 } else { 17243 if (app.thread != null) { 17244 try { 17245 app.thread.setSchedulingGroup(app.curSchedGroup); 17246 } catch (RemoteException e) { 17247 } 17248 } 17249 } 17250 Process.setSwappiness(app.pid, 17251 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17252 } 17253 } 17254 if (app.repForegroundActivities != app.foregroundActivities) { 17255 app.repForegroundActivities = app.foregroundActivities; 17256 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17257 } 17258 if (app.repProcState != app.curProcState) { 17259 app.repProcState = app.curProcState; 17260 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17261 if (app.thread != null) { 17262 try { 17263 if (false) { 17264 //RuntimeException h = new RuntimeException("here"); 17265 Slog.i(TAG, "Sending new process state " + app.repProcState 17266 + " to " + app /*, h*/); 17267 } 17268 app.thread.setProcessState(app.repProcState); 17269 } catch (RemoteException e) { 17270 } 17271 } 17272 } 17273 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17274 app.setProcState)) { 17275 app.lastStateTime = now; 17276 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17277 isSleeping(), now); 17278 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17279 + ProcessList.makeProcStateString(app.setProcState) + " to " 17280 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17281 + (app.nextPssTime-now) + ": " + app); 17282 } else { 17283 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17284 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17285 requestPssLocked(app, app.setProcState); 17286 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17287 isSleeping(), now); 17288 } else if (false && DEBUG_PSS) { 17289 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17290 } 17291 } 17292 if (app.setProcState != app.curProcState) { 17293 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17294 "Proc state change of " + app.processName 17295 + " to " + app.curProcState); 17296 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17297 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17298 if (setImportant && !curImportant) { 17299 // This app is no longer something we consider important enough to allow to 17300 // use arbitrary amounts of battery power. Note 17301 // its current wake lock time to later know to kill it if 17302 // it is not behaving well. 17303 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17304 synchronized (stats) { 17305 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17306 app.pid, SystemClock.elapsedRealtime()); 17307 } 17308 app.lastCpuTime = app.curCpuTime; 17309 17310 } 17311 app.setProcState = app.curProcState; 17312 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17313 app.notCachedSinceIdle = false; 17314 } 17315 if (!doingAll) { 17316 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17317 } else { 17318 app.procStateChanged = true; 17319 } 17320 } 17321 17322 if (changes != 0) { 17323 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17324 int i = mPendingProcessChanges.size()-1; 17325 ProcessChangeItem item = null; 17326 while (i >= 0) { 17327 item = mPendingProcessChanges.get(i); 17328 if (item.pid == app.pid) { 17329 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17330 break; 17331 } 17332 i--; 17333 } 17334 if (i < 0) { 17335 // No existing item in pending changes; need a new one. 17336 final int NA = mAvailProcessChanges.size(); 17337 if (NA > 0) { 17338 item = mAvailProcessChanges.remove(NA-1); 17339 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17340 } else { 17341 item = new ProcessChangeItem(); 17342 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17343 } 17344 item.changes = 0; 17345 item.pid = app.pid; 17346 item.uid = app.info.uid; 17347 if (mPendingProcessChanges.size() == 0) { 17348 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17349 "*** Enqueueing dispatch processes changed!"); 17350 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17351 } 17352 mPendingProcessChanges.add(item); 17353 } 17354 item.changes |= changes; 17355 item.processState = app.repProcState; 17356 item.foregroundActivities = app.repForegroundActivities; 17357 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17358 + Integer.toHexString(System.identityHashCode(item)) 17359 + " " + app.toShortString() + ": changes=" + item.changes 17360 + " procState=" + item.processState 17361 + " foreground=" + item.foregroundActivities 17362 + " type=" + app.adjType + " source=" + app.adjSource 17363 + " target=" + app.adjTarget); 17364 } 17365 17366 return success; 17367 } 17368 17369 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17370 if (proc.thread != null) { 17371 if (proc.baseProcessTracker != null) { 17372 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17373 } 17374 if (proc.repProcState >= 0) { 17375 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17376 proc.repProcState); 17377 } 17378 } 17379 } 17380 17381 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17382 ProcessRecord TOP_APP, boolean doingAll, long now) { 17383 if (app.thread == null) { 17384 return false; 17385 } 17386 17387 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17388 17389 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17390 } 17391 17392 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17393 boolean oomAdj) { 17394 if (isForeground != proc.foregroundServices) { 17395 proc.foregroundServices = isForeground; 17396 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17397 proc.info.uid); 17398 if (isForeground) { 17399 if (curProcs == null) { 17400 curProcs = new ArrayList<ProcessRecord>(); 17401 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17402 } 17403 if (!curProcs.contains(proc)) { 17404 curProcs.add(proc); 17405 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17406 proc.info.packageName, proc.info.uid); 17407 } 17408 } else { 17409 if (curProcs != null) { 17410 if (curProcs.remove(proc)) { 17411 mBatteryStatsService.noteEvent( 17412 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17413 proc.info.packageName, proc.info.uid); 17414 if (curProcs.size() <= 0) { 17415 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17416 } 17417 } 17418 } 17419 } 17420 if (oomAdj) { 17421 updateOomAdjLocked(); 17422 } 17423 } 17424 } 17425 17426 private final ActivityRecord resumedAppLocked() { 17427 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17428 String pkg; 17429 int uid; 17430 if (act != null) { 17431 pkg = act.packageName; 17432 uid = act.info.applicationInfo.uid; 17433 } else { 17434 pkg = null; 17435 uid = -1; 17436 } 17437 // Has the UID or resumed package name changed? 17438 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17439 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17440 if (mCurResumedPackage != null) { 17441 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17442 mCurResumedPackage, mCurResumedUid); 17443 } 17444 mCurResumedPackage = pkg; 17445 mCurResumedUid = uid; 17446 if (mCurResumedPackage != null) { 17447 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17448 mCurResumedPackage, mCurResumedUid); 17449 } 17450 } 17451 return act; 17452 } 17453 17454 final boolean updateOomAdjLocked(ProcessRecord app) { 17455 final ActivityRecord TOP_ACT = resumedAppLocked(); 17456 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17457 final boolean wasCached = app.cached; 17458 17459 mAdjSeq++; 17460 17461 // This is the desired cached adjusment we want to tell it to use. 17462 // If our app is currently cached, we know it, and that is it. Otherwise, 17463 // we don't know it yet, and it needs to now be cached we will then 17464 // need to do a complete oom adj. 17465 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17466 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17467 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17468 SystemClock.uptimeMillis()); 17469 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17470 // Changed to/from cached state, so apps after it in the LRU 17471 // list may also be changed. 17472 updateOomAdjLocked(); 17473 } 17474 return success; 17475 } 17476 17477 final void updateOomAdjLocked() { 17478 final ActivityRecord TOP_ACT = resumedAppLocked(); 17479 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17480 final long now = SystemClock.uptimeMillis(); 17481 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17482 final int N = mLruProcesses.size(); 17483 17484 if (false) { 17485 RuntimeException e = new RuntimeException(); 17486 e.fillInStackTrace(); 17487 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17488 } 17489 17490 mAdjSeq++; 17491 mNewNumServiceProcs = 0; 17492 mNewNumAServiceProcs = 0; 17493 17494 final int emptyProcessLimit; 17495 final int cachedProcessLimit; 17496 if (mProcessLimit <= 0) { 17497 emptyProcessLimit = cachedProcessLimit = 0; 17498 } else if (mProcessLimit == 1) { 17499 emptyProcessLimit = 1; 17500 cachedProcessLimit = 0; 17501 } else { 17502 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17503 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17504 } 17505 17506 // Let's determine how many processes we have running vs. 17507 // how many slots we have for background processes; we may want 17508 // to put multiple processes in a slot of there are enough of 17509 // them. 17510 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17511 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17512 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17513 if (numEmptyProcs > cachedProcessLimit) { 17514 // If there are more empty processes than our limit on cached 17515 // processes, then use the cached process limit for the factor. 17516 // This ensures that the really old empty processes get pushed 17517 // down to the bottom, so if we are running low on memory we will 17518 // have a better chance at keeping around more cached processes 17519 // instead of a gazillion empty processes. 17520 numEmptyProcs = cachedProcessLimit; 17521 } 17522 int emptyFactor = numEmptyProcs/numSlots; 17523 if (emptyFactor < 1) emptyFactor = 1; 17524 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17525 if (cachedFactor < 1) cachedFactor = 1; 17526 int stepCached = 0; 17527 int stepEmpty = 0; 17528 int numCached = 0; 17529 int numEmpty = 0; 17530 int numTrimming = 0; 17531 17532 mNumNonCachedProcs = 0; 17533 mNumCachedHiddenProcs = 0; 17534 17535 // First update the OOM adjustment for each of the 17536 // application processes based on their current state. 17537 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17538 int nextCachedAdj = curCachedAdj+1; 17539 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17540 int nextEmptyAdj = curEmptyAdj+2; 17541 for (int i=N-1; i>=0; i--) { 17542 ProcessRecord app = mLruProcesses.get(i); 17543 if (!app.killedByAm && app.thread != null) { 17544 app.procStateChanged = false; 17545 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17546 17547 // If we haven't yet assigned the final cached adj 17548 // to the process, do that now. 17549 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17550 switch (app.curProcState) { 17551 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17552 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17553 // This process is a cached process holding activities... 17554 // assign it the next cached value for that type, and then 17555 // step that cached level. 17556 app.curRawAdj = curCachedAdj; 17557 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17558 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17559 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17560 + ")"); 17561 if (curCachedAdj != nextCachedAdj) { 17562 stepCached++; 17563 if (stepCached >= cachedFactor) { 17564 stepCached = 0; 17565 curCachedAdj = nextCachedAdj; 17566 nextCachedAdj += 2; 17567 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17568 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17569 } 17570 } 17571 } 17572 break; 17573 default: 17574 // For everything else, assign next empty cached process 17575 // level and bump that up. Note that this means that 17576 // long-running services that have dropped down to the 17577 // cached level will be treated as empty (since their process 17578 // state is still as a service), which is what we want. 17579 app.curRawAdj = curEmptyAdj; 17580 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17581 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17582 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17583 + ")"); 17584 if (curEmptyAdj != nextEmptyAdj) { 17585 stepEmpty++; 17586 if (stepEmpty >= emptyFactor) { 17587 stepEmpty = 0; 17588 curEmptyAdj = nextEmptyAdj; 17589 nextEmptyAdj += 2; 17590 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17591 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17592 } 17593 } 17594 } 17595 break; 17596 } 17597 } 17598 17599 applyOomAdjLocked(app, TOP_APP, true, now); 17600 17601 // Count the number of process types. 17602 switch (app.curProcState) { 17603 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17604 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17605 mNumCachedHiddenProcs++; 17606 numCached++; 17607 if (numCached > cachedProcessLimit) { 17608 app.kill("cached #" + numCached, true); 17609 } 17610 break; 17611 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17612 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17613 && app.lastActivityTime < oldTime) { 17614 app.kill("empty for " 17615 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17616 / 1000) + "s", true); 17617 } else { 17618 numEmpty++; 17619 if (numEmpty > emptyProcessLimit) { 17620 app.kill("empty #" + numEmpty, true); 17621 } 17622 } 17623 break; 17624 default: 17625 mNumNonCachedProcs++; 17626 break; 17627 } 17628 17629 if (app.isolated && app.services.size() <= 0) { 17630 // If this is an isolated process, and there are no 17631 // services running in it, then the process is no longer 17632 // needed. We agressively kill these because we can by 17633 // definition not re-use the same process again, and it is 17634 // good to avoid having whatever code was running in them 17635 // left sitting around after no longer needed. 17636 app.kill("isolated not needed", true); 17637 } 17638 17639 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17640 && !app.killedByAm) { 17641 numTrimming++; 17642 } 17643 } 17644 } 17645 17646 mNumServiceProcs = mNewNumServiceProcs; 17647 17648 // Now determine the memory trimming level of background processes. 17649 // Unfortunately we need to start at the back of the list to do this 17650 // properly. We only do this if the number of background apps we 17651 // are managing to keep around is less than half the maximum we desire; 17652 // if we are keeping a good number around, we'll let them use whatever 17653 // memory they want. 17654 final int numCachedAndEmpty = numCached + numEmpty; 17655 int memFactor; 17656 if (numCached <= ProcessList.TRIM_CACHED_APPS 17657 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17658 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17659 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17660 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17661 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17662 } else { 17663 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17664 } 17665 } else { 17666 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17667 } 17668 // We always allow the memory level to go up (better). We only allow it to go 17669 // down if we are in a state where that is allowed, *and* the total number of processes 17670 // has gone down since last time. 17671 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17672 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17673 + " last=" + mLastNumProcesses); 17674 if (memFactor > mLastMemoryLevel) { 17675 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17676 memFactor = mLastMemoryLevel; 17677 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17678 } 17679 } 17680 mLastMemoryLevel = memFactor; 17681 mLastNumProcesses = mLruProcesses.size(); 17682 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17683 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17684 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17685 if (mLowRamStartTime == 0) { 17686 mLowRamStartTime = now; 17687 } 17688 int step = 0; 17689 int fgTrimLevel; 17690 switch (memFactor) { 17691 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17692 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17693 break; 17694 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17695 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17696 break; 17697 default: 17698 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17699 break; 17700 } 17701 int factor = numTrimming/3; 17702 int minFactor = 2; 17703 if (mHomeProcess != null) minFactor++; 17704 if (mPreviousProcess != null) minFactor++; 17705 if (factor < minFactor) factor = minFactor; 17706 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17707 for (int i=N-1; i>=0; i--) { 17708 ProcessRecord app = mLruProcesses.get(i); 17709 if (allChanged || app.procStateChanged) { 17710 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17711 app.procStateChanged = false; 17712 } 17713 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17714 && !app.killedByAm) { 17715 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17716 try { 17717 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17718 "Trimming memory of " + app.processName 17719 + " to " + curLevel); 17720 app.thread.scheduleTrimMemory(curLevel); 17721 } catch (RemoteException e) { 17722 } 17723 if (false) { 17724 // For now we won't do this; our memory trimming seems 17725 // to be good enough at this point that destroying 17726 // activities causes more harm than good. 17727 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17728 && app != mHomeProcess && app != mPreviousProcess) { 17729 // Need to do this on its own message because the stack may not 17730 // be in a consistent state at this point. 17731 // For these apps we will also finish their activities 17732 // to help them free memory. 17733 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17734 } 17735 } 17736 } 17737 app.trimMemoryLevel = curLevel; 17738 step++; 17739 if (step >= factor) { 17740 step = 0; 17741 switch (curLevel) { 17742 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17743 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17744 break; 17745 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17746 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17747 break; 17748 } 17749 } 17750 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17751 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17752 && app.thread != null) { 17753 try { 17754 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17755 "Trimming memory of heavy-weight " + app.processName 17756 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17757 app.thread.scheduleTrimMemory( 17758 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17759 } catch (RemoteException e) { 17760 } 17761 } 17762 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17763 } else { 17764 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17765 || app.systemNoUi) && app.pendingUiClean) { 17766 // If this application is now in the background and it 17767 // had done UI, then give it the special trim level to 17768 // have it free UI resources. 17769 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17770 if (app.trimMemoryLevel < level && app.thread != null) { 17771 try { 17772 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17773 "Trimming memory of bg-ui " + app.processName 17774 + " to " + level); 17775 app.thread.scheduleTrimMemory(level); 17776 } catch (RemoteException e) { 17777 } 17778 } 17779 app.pendingUiClean = false; 17780 } 17781 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17782 try { 17783 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17784 "Trimming memory of fg " + app.processName 17785 + " to " + fgTrimLevel); 17786 app.thread.scheduleTrimMemory(fgTrimLevel); 17787 } catch (RemoteException e) { 17788 } 17789 } 17790 app.trimMemoryLevel = fgTrimLevel; 17791 } 17792 } 17793 } else { 17794 if (mLowRamStartTime != 0) { 17795 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17796 mLowRamStartTime = 0; 17797 } 17798 for (int i=N-1; i>=0; i--) { 17799 ProcessRecord app = mLruProcesses.get(i); 17800 if (allChanged || app.procStateChanged) { 17801 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17802 app.procStateChanged = false; 17803 } 17804 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17805 || app.systemNoUi) && app.pendingUiClean) { 17806 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17807 && app.thread != null) { 17808 try { 17809 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17810 "Trimming memory of ui hidden " + app.processName 17811 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17812 app.thread.scheduleTrimMemory( 17813 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17814 } catch (RemoteException e) { 17815 } 17816 } 17817 app.pendingUiClean = false; 17818 } 17819 app.trimMemoryLevel = 0; 17820 } 17821 } 17822 17823 if (mAlwaysFinishActivities) { 17824 // Need to do this on its own message because the stack may not 17825 // be in a consistent state at this point. 17826 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17827 } 17828 17829 if (allChanged) { 17830 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17831 } 17832 17833 if (mProcessStats.shouldWriteNowLocked(now)) { 17834 mHandler.post(new Runnable() { 17835 @Override public void run() { 17836 synchronized (ActivityManagerService.this) { 17837 mProcessStats.writeStateAsyncLocked(); 17838 } 17839 } 17840 }); 17841 } 17842 17843 if (DEBUG_OOM_ADJ) { 17844 if (false) { 17845 RuntimeException here = new RuntimeException("here"); 17846 here.fillInStackTrace(); 17847 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 17848 } else { 17849 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17850 } 17851 } 17852 } 17853 17854 final void trimApplications() { 17855 synchronized (this) { 17856 int i; 17857 17858 // First remove any unused application processes whose package 17859 // has been removed. 17860 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17861 final ProcessRecord app = mRemovedProcesses.get(i); 17862 if (app.activities.size() == 0 17863 && app.curReceiver == null && app.services.size() == 0) { 17864 Slog.i( 17865 TAG, "Exiting empty application process " 17866 + app.processName + " (" 17867 + (app.thread != null ? app.thread.asBinder() : null) 17868 + ")\n"); 17869 if (app.pid > 0 && app.pid != MY_PID) { 17870 app.kill("empty", false); 17871 } else { 17872 try { 17873 app.thread.scheduleExit(); 17874 } catch (Exception e) { 17875 // Ignore exceptions. 17876 } 17877 } 17878 cleanUpApplicationRecordLocked(app, false, true, -1); 17879 mRemovedProcesses.remove(i); 17880 17881 if (app.persistent) { 17882 addAppLocked(app.info, false, null /* ABI override */); 17883 } 17884 } 17885 } 17886 17887 // Now update the oom adj for all processes. 17888 updateOomAdjLocked(); 17889 } 17890 } 17891 17892 /** This method sends the specified signal to each of the persistent apps */ 17893 public void signalPersistentProcesses(int sig) throws RemoteException { 17894 if (sig != Process.SIGNAL_USR1) { 17895 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 17896 } 17897 17898 synchronized (this) { 17899 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 17900 != PackageManager.PERMISSION_GRANTED) { 17901 throw new SecurityException("Requires permission " 17902 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 17903 } 17904 17905 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 17906 ProcessRecord r = mLruProcesses.get(i); 17907 if (r.thread != null && r.persistent) { 17908 Process.sendSignal(r.pid, sig); 17909 } 17910 } 17911 } 17912 } 17913 17914 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 17915 if (proc == null || proc == mProfileProc) { 17916 proc = mProfileProc; 17917 profileType = mProfileType; 17918 clearProfilerLocked(); 17919 } 17920 if (proc == null) { 17921 return; 17922 } 17923 try { 17924 proc.thread.profilerControl(false, null, profileType); 17925 } catch (RemoteException e) { 17926 throw new IllegalStateException("Process disappeared"); 17927 } 17928 } 17929 17930 private void clearProfilerLocked() { 17931 if (mProfileFd != null) { 17932 try { 17933 mProfileFd.close(); 17934 } catch (IOException e) { 17935 } 17936 } 17937 mProfileApp = null; 17938 mProfileProc = null; 17939 mProfileFile = null; 17940 mProfileType = 0; 17941 mAutoStopProfiler = false; 17942 mSamplingInterval = 0; 17943 } 17944 17945 public boolean profileControl(String process, int userId, boolean start, 17946 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 17947 17948 try { 17949 synchronized (this) { 17950 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17951 // its own permission. 17952 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17953 != PackageManager.PERMISSION_GRANTED) { 17954 throw new SecurityException("Requires permission " 17955 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17956 } 17957 17958 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 17959 throw new IllegalArgumentException("null profile info or fd"); 17960 } 17961 17962 ProcessRecord proc = null; 17963 if (process != null) { 17964 proc = findProcessLocked(process, userId, "profileControl"); 17965 } 17966 17967 if (start && (proc == null || proc.thread == null)) { 17968 throw new IllegalArgumentException("Unknown process: " + process); 17969 } 17970 17971 if (start) { 17972 stopProfilerLocked(null, 0); 17973 setProfileApp(proc.info, proc.processName, profilerInfo); 17974 mProfileProc = proc; 17975 mProfileType = profileType; 17976 ParcelFileDescriptor fd = profilerInfo.profileFd; 17977 try { 17978 fd = fd.dup(); 17979 } catch (IOException e) { 17980 fd = null; 17981 } 17982 profilerInfo.profileFd = fd; 17983 proc.thread.profilerControl(start, profilerInfo, profileType); 17984 fd = null; 17985 mProfileFd = null; 17986 } else { 17987 stopProfilerLocked(proc, profileType); 17988 if (profilerInfo != null && profilerInfo.profileFd != null) { 17989 try { 17990 profilerInfo.profileFd.close(); 17991 } catch (IOException e) { 17992 } 17993 } 17994 } 17995 17996 return true; 17997 } 17998 } catch (RemoteException e) { 17999 throw new IllegalStateException("Process disappeared"); 18000 } finally { 18001 if (profilerInfo != null && profilerInfo.profileFd != null) { 18002 try { 18003 profilerInfo.profileFd.close(); 18004 } catch (IOException e) { 18005 } 18006 } 18007 } 18008 } 18009 18010 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18011 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18012 userId, true, ALLOW_FULL_ONLY, callName, null); 18013 ProcessRecord proc = null; 18014 try { 18015 int pid = Integer.parseInt(process); 18016 synchronized (mPidsSelfLocked) { 18017 proc = mPidsSelfLocked.get(pid); 18018 } 18019 } catch (NumberFormatException e) { 18020 } 18021 18022 if (proc == null) { 18023 ArrayMap<String, SparseArray<ProcessRecord>> all 18024 = mProcessNames.getMap(); 18025 SparseArray<ProcessRecord> procs = all.get(process); 18026 if (procs != null && procs.size() > 0) { 18027 proc = procs.valueAt(0); 18028 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18029 for (int i=1; i<procs.size(); i++) { 18030 ProcessRecord thisProc = procs.valueAt(i); 18031 if (thisProc.userId == userId) { 18032 proc = thisProc; 18033 break; 18034 } 18035 } 18036 } 18037 } 18038 } 18039 18040 return proc; 18041 } 18042 18043 public boolean dumpHeap(String process, int userId, boolean managed, 18044 String path, ParcelFileDescriptor fd) throws RemoteException { 18045 18046 try { 18047 synchronized (this) { 18048 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18049 // its own permission (same as profileControl). 18050 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18051 != PackageManager.PERMISSION_GRANTED) { 18052 throw new SecurityException("Requires permission " 18053 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18054 } 18055 18056 if (fd == null) { 18057 throw new IllegalArgumentException("null fd"); 18058 } 18059 18060 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18061 if (proc == null || proc.thread == null) { 18062 throw new IllegalArgumentException("Unknown process: " + process); 18063 } 18064 18065 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18066 if (!isDebuggable) { 18067 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18068 throw new SecurityException("Process not debuggable: " + proc); 18069 } 18070 } 18071 18072 proc.thread.dumpHeap(managed, path, fd); 18073 fd = null; 18074 return true; 18075 } 18076 } catch (RemoteException e) { 18077 throw new IllegalStateException("Process disappeared"); 18078 } finally { 18079 if (fd != null) { 18080 try { 18081 fd.close(); 18082 } catch (IOException e) { 18083 } 18084 } 18085 } 18086 } 18087 18088 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18089 public void monitor() { 18090 synchronized (this) { } 18091 } 18092 18093 void onCoreSettingsChange(Bundle settings) { 18094 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18095 ProcessRecord processRecord = mLruProcesses.get(i); 18096 try { 18097 if (processRecord.thread != null) { 18098 processRecord.thread.setCoreSettings(settings); 18099 } 18100 } catch (RemoteException re) { 18101 /* ignore */ 18102 } 18103 } 18104 } 18105 18106 // Multi-user methods 18107 18108 /** 18109 * Start user, if its not already running, but don't bring it to foreground. 18110 */ 18111 @Override 18112 public boolean startUserInBackground(final int userId) { 18113 return startUser(userId, /* foreground */ false); 18114 } 18115 18116 /** 18117 * Start user, if its not already running, and bring it to foreground. 18118 */ 18119 boolean startUserInForeground(final int userId, Dialog dlg) { 18120 boolean result = startUser(userId, /* foreground */ true); 18121 dlg.dismiss(); 18122 return result; 18123 } 18124 18125 /** 18126 * Refreshes the list of users related to the current user when either a 18127 * user switch happens or when a new related user is started in the 18128 * background. 18129 */ 18130 private void updateCurrentProfileIdsLocked() { 18131 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18132 mCurrentUserId, false /* enabledOnly */); 18133 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18134 for (int i = 0; i < currentProfileIds.length; i++) { 18135 currentProfileIds[i] = profiles.get(i).id; 18136 } 18137 mCurrentProfileIds = currentProfileIds; 18138 18139 synchronized (mUserProfileGroupIdsSelfLocked) { 18140 mUserProfileGroupIdsSelfLocked.clear(); 18141 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18142 for (int i = 0; i < users.size(); i++) { 18143 UserInfo user = users.get(i); 18144 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18145 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18146 } 18147 } 18148 } 18149 } 18150 18151 private Set getProfileIdsLocked(int userId) { 18152 Set userIds = new HashSet<Integer>(); 18153 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18154 userId, false /* enabledOnly */); 18155 for (UserInfo user : profiles) { 18156 userIds.add(Integer.valueOf(user.id)); 18157 } 18158 return userIds; 18159 } 18160 18161 @Override 18162 public boolean switchUser(final int userId) { 18163 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18164 String userName; 18165 synchronized (this) { 18166 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18167 if (userInfo == null) { 18168 Slog.w(TAG, "No user info for user #" + userId); 18169 return false; 18170 } 18171 if (userInfo.isManagedProfile()) { 18172 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18173 return false; 18174 } 18175 userName = userInfo.name; 18176 mTargetUserId = userId; 18177 } 18178 mHandler.removeMessages(START_USER_SWITCH_MSG); 18179 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18180 return true; 18181 } 18182 18183 private void showUserSwitchDialog(int userId, String userName) { 18184 // The dialog will show and then initiate the user switch by calling startUserInForeground 18185 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18186 true /* above system */); 18187 d.show(); 18188 } 18189 18190 private boolean startUser(final int userId, final boolean foreground) { 18191 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18192 != PackageManager.PERMISSION_GRANTED) { 18193 String msg = "Permission Denial: switchUser() from pid=" 18194 + Binder.getCallingPid() 18195 + ", uid=" + Binder.getCallingUid() 18196 + " requires " + INTERACT_ACROSS_USERS_FULL; 18197 Slog.w(TAG, msg); 18198 throw new SecurityException(msg); 18199 } 18200 18201 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18202 18203 final long ident = Binder.clearCallingIdentity(); 18204 try { 18205 synchronized (this) { 18206 final int oldUserId = mCurrentUserId; 18207 if (oldUserId == userId) { 18208 return true; 18209 } 18210 18211 mStackSupervisor.setLockTaskModeLocked(null, false); 18212 18213 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18214 if (userInfo == null) { 18215 Slog.w(TAG, "No user info for user #" + userId); 18216 return false; 18217 } 18218 if (foreground && userInfo.isManagedProfile()) { 18219 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18220 return false; 18221 } 18222 18223 if (foreground) { 18224 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18225 R.anim.screen_user_enter); 18226 } 18227 18228 boolean needStart = false; 18229 18230 // If the user we are switching to is not currently started, then 18231 // we need to start it now. 18232 if (mStartedUsers.get(userId) == null) { 18233 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18234 updateStartedUserArrayLocked(); 18235 needStart = true; 18236 } 18237 18238 final Integer userIdInt = Integer.valueOf(userId); 18239 mUserLru.remove(userIdInt); 18240 mUserLru.add(userIdInt); 18241 18242 if (foreground) { 18243 mCurrentUserId = userId; 18244 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18245 updateCurrentProfileIdsLocked(); 18246 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18247 // Once the internal notion of the active user has switched, we lock the device 18248 // with the option to show the user switcher on the keyguard. 18249 mWindowManager.lockNow(null); 18250 } else { 18251 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18252 updateCurrentProfileIdsLocked(); 18253 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18254 mUserLru.remove(currentUserIdInt); 18255 mUserLru.add(currentUserIdInt); 18256 } 18257 18258 final UserStartedState uss = mStartedUsers.get(userId); 18259 18260 // Make sure user is in the started state. If it is currently 18261 // stopping, we need to knock that off. 18262 if (uss.mState == UserStartedState.STATE_STOPPING) { 18263 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18264 // so we can just fairly silently bring the user back from 18265 // the almost-dead. 18266 uss.mState = UserStartedState.STATE_RUNNING; 18267 updateStartedUserArrayLocked(); 18268 needStart = true; 18269 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18270 // This means ACTION_SHUTDOWN has been sent, so we will 18271 // need to treat this as a new boot of the user. 18272 uss.mState = UserStartedState.STATE_BOOTING; 18273 updateStartedUserArrayLocked(); 18274 needStart = true; 18275 } 18276 18277 if (uss.mState == UserStartedState.STATE_BOOTING) { 18278 // Booting up a new user, need to tell system services about it. 18279 // Note that this is on the same handler as scheduling of broadcasts, 18280 // which is important because it needs to go first. 18281 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18282 } 18283 18284 if (foreground) { 18285 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18286 oldUserId)); 18287 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18288 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18289 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18290 oldUserId, userId, uss)); 18291 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18292 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18293 } 18294 18295 if (needStart) { 18296 // Send USER_STARTED broadcast 18297 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18298 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18299 | Intent.FLAG_RECEIVER_FOREGROUND); 18300 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18301 broadcastIntentLocked(null, null, intent, 18302 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18303 false, false, MY_PID, Process.SYSTEM_UID, userId); 18304 } 18305 18306 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18307 if (userId != UserHandle.USER_OWNER) { 18308 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18309 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18310 broadcastIntentLocked(null, null, intent, null, 18311 new IIntentReceiver.Stub() { 18312 public void performReceive(Intent intent, int resultCode, 18313 String data, Bundle extras, boolean ordered, 18314 boolean sticky, int sendingUser) { 18315 onUserInitialized(uss, foreground, oldUserId, userId); 18316 } 18317 }, 0, null, null, null, AppOpsManager.OP_NONE, 18318 true, false, MY_PID, Process.SYSTEM_UID, 18319 userId); 18320 uss.initializing = true; 18321 } else { 18322 getUserManagerLocked().makeInitialized(userInfo.id); 18323 } 18324 } 18325 18326 if (foreground) { 18327 if (!uss.initializing) { 18328 moveUserToForeground(uss, oldUserId, userId); 18329 } 18330 } else { 18331 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18332 } 18333 18334 if (needStart) { 18335 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18336 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18337 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18338 broadcastIntentLocked(null, null, intent, 18339 null, new IIntentReceiver.Stub() { 18340 @Override 18341 public void performReceive(Intent intent, int resultCode, String data, 18342 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18343 throws RemoteException { 18344 } 18345 }, 0, null, null, 18346 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18347 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18348 } 18349 } 18350 } finally { 18351 Binder.restoreCallingIdentity(ident); 18352 } 18353 18354 return true; 18355 } 18356 18357 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18358 long ident = Binder.clearCallingIdentity(); 18359 try { 18360 Intent intent; 18361 if (oldUserId >= 0) { 18362 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18363 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18364 int count = profiles.size(); 18365 for (int i = 0; i < count; i++) { 18366 int profileUserId = profiles.get(i).id; 18367 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18368 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18369 | Intent.FLAG_RECEIVER_FOREGROUND); 18370 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18371 broadcastIntentLocked(null, null, intent, 18372 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18373 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18374 } 18375 } 18376 if (newUserId >= 0) { 18377 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18378 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18379 int count = profiles.size(); 18380 for (int i = 0; i < count; i++) { 18381 int profileUserId = profiles.get(i).id; 18382 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18383 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18384 | Intent.FLAG_RECEIVER_FOREGROUND); 18385 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18386 broadcastIntentLocked(null, null, intent, 18387 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18388 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18389 } 18390 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18391 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18392 | Intent.FLAG_RECEIVER_FOREGROUND); 18393 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18394 broadcastIntentLocked(null, null, intent, 18395 null, null, 0, null, null, 18396 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18397 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18398 } 18399 } finally { 18400 Binder.restoreCallingIdentity(ident); 18401 } 18402 } 18403 18404 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18405 final int newUserId) { 18406 final int N = mUserSwitchObservers.beginBroadcast(); 18407 if (N > 0) { 18408 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18409 int mCount = 0; 18410 @Override 18411 public void sendResult(Bundle data) throws RemoteException { 18412 synchronized (ActivityManagerService.this) { 18413 if (mCurUserSwitchCallback == this) { 18414 mCount++; 18415 if (mCount == N) { 18416 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18417 } 18418 } 18419 } 18420 } 18421 }; 18422 synchronized (this) { 18423 uss.switching = true; 18424 mCurUserSwitchCallback = callback; 18425 } 18426 for (int i=0; i<N; i++) { 18427 try { 18428 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18429 newUserId, callback); 18430 } catch (RemoteException e) { 18431 } 18432 } 18433 } else { 18434 synchronized (this) { 18435 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18436 } 18437 } 18438 mUserSwitchObservers.finishBroadcast(); 18439 } 18440 18441 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18442 synchronized (this) { 18443 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18444 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18445 } 18446 } 18447 18448 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18449 mCurUserSwitchCallback = null; 18450 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18451 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18452 oldUserId, newUserId, uss)); 18453 } 18454 18455 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18456 synchronized (this) { 18457 if (foreground) { 18458 moveUserToForeground(uss, oldUserId, newUserId); 18459 } 18460 } 18461 18462 completeSwitchAndInitalize(uss, newUserId, true, false); 18463 } 18464 18465 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18466 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18467 if (homeInFront) { 18468 startHomeActivityLocked(newUserId); 18469 } else { 18470 mStackSupervisor.resumeTopActivitiesLocked(); 18471 } 18472 EventLogTags.writeAmSwitchUser(newUserId); 18473 getUserManagerLocked().userForeground(newUserId); 18474 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18475 } 18476 18477 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18478 completeSwitchAndInitalize(uss, newUserId, false, true); 18479 } 18480 18481 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18482 boolean clearInitializing, boolean clearSwitching) { 18483 boolean unfrozen = false; 18484 synchronized (this) { 18485 if (clearInitializing) { 18486 uss.initializing = false; 18487 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18488 } 18489 if (clearSwitching) { 18490 uss.switching = false; 18491 } 18492 if (!uss.switching && !uss.initializing) { 18493 mWindowManager.stopFreezingScreen(); 18494 unfrozen = true; 18495 } 18496 } 18497 if (unfrozen) { 18498 final int N = mUserSwitchObservers.beginBroadcast(); 18499 for (int i=0; i<N; i++) { 18500 try { 18501 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18502 } catch (RemoteException e) { 18503 } 18504 } 18505 mUserSwitchObservers.finishBroadcast(); 18506 } 18507 } 18508 18509 void scheduleStartProfilesLocked() { 18510 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18511 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18512 DateUtils.SECOND_IN_MILLIS); 18513 } 18514 } 18515 18516 void startProfilesLocked() { 18517 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18518 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18519 mCurrentUserId, false /* enabledOnly */); 18520 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18521 for (UserInfo user : profiles) { 18522 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18523 && user.id != mCurrentUserId) { 18524 toStart.add(user); 18525 } 18526 } 18527 final int n = toStart.size(); 18528 int i = 0; 18529 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18530 startUserInBackground(toStart.get(i).id); 18531 } 18532 if (i < n) { 18533 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18534 } 18535 } 18536 18537 void finishUserBoot(UserStartedState uss) { 18538 synchronized (this) { 18539 if (uss.mState == UserStartedState.STATE_BOOTING 18540 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18541 uss.mState = UserStartedState.STATE_RUNNING; 18542 final int userId = uss.mHandle.getIdentifier(); 18543 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18544 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18545 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18546 broadcastIntentLocked(null, null, intent, 18547 null, null, 0, null, null, 18548 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18549 true, false, MY_PID, Process.SYSTEM_UID, userId); 18550 } 18551 } 18552 } 18553 18554 void finishUserSwitch(UserStartedState uss) { 18555 synchronized (this) { 18556 finishUserBoot(uss); 18557 18558 startProfilesLocked(); 18559 18560 int num = mUserLru.size(); 18561 int i = 0; 18562 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18563 Integer oldUserId = mUserLru.get(i); 18564 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18565 if (oldUss == null) { 18566 // Shouldn't happen, but be sane if it does. 18567 mUserLru.remove(i); 18568 num--; 18569 continue; 18570 } 18571 if (oldUss.mState == UserStartedState.STATE_STOPPING 18572 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18573 // This user is already stopping, doesn't count. 18574 num--; 18575 i++; 18576 continue; 18577 } 18578 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18579 // Owner and current can't be stopped, but count as running. 18580 i++; 18581 continue; 18582 } 18583 // This is a user to be stopped. 18584 stopUserLocked(oldUserId, null); 18585 num--; 18586 i++; 18587 } 18588 } 18589 } 18590 18591 @Override 18592 public int stopUser(final int userId, final IStopUserCallback callback) { 18593 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18594 != PackageManager.PERMISSION_GRANTED) { 18595 String msg = "Permission Denial: switchUser() from pid=" 18596 + Binder.getCallingPid() 18597 + ", uid=" + Binder.getCallingUid() 18598 + " requires " + INTERACT_ACROSS_USERS_FULL; 18599 Slog.w(TAG, msg); 18600 throw new SecurityException(msg); 18601 } 18602 if (userId <= 0) { 18603 throw new IllegalArgumentException("Can't stop primary user " + userId); 18604 } 18605 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18606 synchronized (this) { 18607 return stopUserLocked(userId, callback); 18608 } 18609 } 18610 18611 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18612 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18613 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18614 return ActivityManager.USER_OP_IS_CURRENT; 18615 } 18616 18617 final UserStartedState uss = mStartedUsers.get(userId); 18618 if (uss == null) { 18619 // User is not started, nothing to do... but we do need to 18620 // callback if requested. 18621 if (callback != null) { 18622 mHandler.post(new Runnable() { 18623 @Override 18624 public void run() { 18625 try { 18626 callback.userStopped(userId); 18627 } catch (RemoteException e) { 18628 } 18629 } 18630 }); 18631 } 18632 return ActivityManager.USER_OP_SUCCESS; 18633 } 18634 18635 if (callback != null) { 18636 uss.mStopCallbacks.add(callback); 18637 } 18638 18639 if (uss.mState != UserStartedState.STATE_STOPPING 18640 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18641 uss.mState = UserStartedState.STATE_STOPPING; 18642 updateStartedUserArrayLocked(); 18643 18644 long ident = Binder.clearCallingIdentity(); 18645 try { 18646 // We are going to broadcast ACTION_USER_STOPPING and then 18647 // once that is done send a final ACTION_SHUTDOWN and then 18648 // stop the user. 18649 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18650 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18651 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18652 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18653 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18654 // This is the result receiver for the final shutdown broadcast. 18655 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18656 @Override 18657 public void performReceive(Intent intent, int resultCode, String data, 18658 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18659 finishUserStop(uss); 18660 } 18661 }; 18662 // This is the result receiver for the initial stopping broadcast. 18663 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18664 @Override 18665 public void performReceive(Intent intent, int resultCode, String data, 18666 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18667 // On to the next. 18668 synchronized (ActivityManagerService.this) { 18669 if (uss.mState != UserStartedState.STATE_STOPPING) { 18670 // Whoops, we are being started back up. Abort, abort! 18671 return; 18672 } 18673 uss.mState = UserStartedState.STATE_SHUTDOWN; 18674 } 18675 mBatteryStatsService.noteEvent( 18676 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18677 Integer.toString(userId), userId); 18678 mSystemServiceManager.stopUser(userId); 18679 broadcastIntentLocked(null, null, shutdownIntent, 18680 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18681 true, false, MY_PID, Process.SYSTEM_UID, userId); 18682 } 18683 }; 18684 // Kick things off. 18685 broadcastIntentLocked(null, null, stoppingIntent, 18686 null, stoppingReceiver, 0, null, null, 18687 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18688 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18689 } finally { 18690 Binder.restoreCallingIdentity(ident); 18691 } 18692 } 18693 18694 return ActivityManager.USER_OP_SUCCESS; 18695 } 18696 18697 void finishUserStop(UserStartedState uss) { 18698 final int userId = uss.mHandle.getIdentifier(); 18699 boolean stopped; 18700 ArrayList<IStopUserCallback> callbacks; 18701 synchronized (this) { 18702 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18703 if (mStartedUsers.get(userId) != uss) { 18704 stopped = false; 18705 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18706 stopped = false; 18707 } else { 18708 stopped = true; 18709 // User can no longer run. 18710 mStartedUsers.remove(userId); 18711 mUserLru.remove(Integer.valueOf(userId)); 18712 updateStartedUserArrayLocked(); 18713 18714 // Clean up all state and processes associated with the user. 18715 // Kill all the processes for the user. 18716 forceStopUserLocked(userId, "finish user"); 18717 } 18718 18719 // Explicitly remove the old information in mRecentTasks. 18720 removeRecentTasksForUserLocked(userId); 18721 } 18722 18723 for (int i=0; i<callbacks.size(); i++) { 18724 try { 18725 if (stopped) callbacks.get(i).userStopped(userId); 18726 else callbacks.get(i).userStopAborted(userId); 18727 } catch (RemoteException e) { 18728 } 18729 } 18730 18731 if (stopped) { 18732 mSystemServiceManager.cleanupUser(userId); 18733 synchronized (this) { 18734 mStackSupervisor.removeUserLocked(userId); 18735 } 18736 } 18737 } 18738 18739 @Override 18740 public UserInfo getCurrentUser() { 18741 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18742 != PackageManager.PERMISSION_GRANTED) && ( 18743 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18744 != PackageManager.PERMISSION_GRANTED)) { 18745 String msg = "Permission Denial: getCurrentUser() from pid=" 18746 + Binder.getCallingPid() 18747 + ", uid=" + Binder.getCallingUid() 18748 + " requires " + INTERACT_ACROSS_USERS; 18749 Slog.w(TAG, msg); 18750 throw new SecurityException(msg); 18751 } 18752 synchronized (this) { 18753 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18754 return getUserManagerLocked().getUserInfo(userId); 18755 } 18756 } 18757 18758 int getCurrentUserIdLocked() { 18759 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18760 } 18761 18762 @Override 18763 public boolean isUserRunning(int userId, boolean orStopped) { 18764 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18765 != PackageManager.PERMISSION_GRANTED) { 18766 String msg = "Permission Denial: isUserRunning() from pid=" 18767 + Binder.getCallingPid() 18768 + ", uid=" + Binder.getCallingUid() 18769 + " requires " + INTERACT_ACROSS_USERS; 18770 Slog.w(TAG, msg); 18771 throw new SecurityException(msg); 18772 } 18773 synchronized (this) { 18774 return isUserRunningLocked(userId, orStopped); 18775 } 18776 } 18777 18778 boolean isUserRunningLocked(int userId, boolean orStopped) { 18779 UserStartedState state = mStartedUsers.get(userId); 18780 if (state == null) { 18781 return false; 18782 } 18783 if (orStopped) { 18784 return true; 18785 } 18786 return state.mState != UserStartedState.STATE_STOPPING 18787 && state.mState != UserStartedState.STATE_SHUTDOWN; 18788 } 18789 18790 @Override 18791 public int[] getRunningUserIds() { 18792 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18793 != PackageManager.PERMISSION_GRANTED) { 18794 String msg = "Permission Denial: isUserRunning() from pid=" 18795 + Binder.getCallingPid() 18796 + ", uid=" + Binder.getCallingUid() 18797 + " requires " + INTERACT_ACROSS_USERS; 18798 Slog.w(TAG, msg); 18799 throw new SecurityException(msg); 18800 } 18801 synchronized (this) { 18802 return mStartedUserArray; 18803 } 18804 } 18805 18806 private void updateStartedUserArrayLocked() { 18807 int num = 0; 18808 for (int i=0; i<mStartedUsers.size(); i++) { 18809 UserStartedState uss = mStartedUsers.valueAt(i); 18810 // This list does not include stopping users. 18811 if (uss.mState != UserStartedState.STATE_STOPPING 18812 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18813 num++; 18814 } 18815 } 18816 mStartedUserArray = new int[num]; 18817 num = 0; 18818 for (int i=0; i<mStartedUsers.size(); i++) { 18819 UserStartedState uss = mStartedUsers.valueAt(i); 18820 if (uss.mState != UserStartedState.STATE_STOPPING 18821 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18822 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18823 num++; 18824 } 18825 } 18826 } 18827 18828 @Override 18829 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18830 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18831 != PackageManager.PERMISSION_GRANTED) { 18832 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18833 + Binder.getCallingPid() 18834 + ", uid=" + Binder.getCallingUid() 18835 + " requires " + INTERACT_ACROSS_USERS_FULL; 18836 Slog.w(TAG, msg); 18837 throw new SecurityException(msg); 18838 } 18839 18840 mUserSwitchObservers.register(observer); 18841 } 18842 18843 @Override 18844 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18845 mUserSwitchObservers.unregister(observer); 18846 } 18847 18848 private boolean userExists(int userId) { 18849 if (userId == 0) { 18850 return true; 18851 } 18852 UserManagerService ums = getUserManagerLocked(); 18853 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18854 } 18855 18856 int[] getUsersLocked() { 18857 UserManagerService ums = getUserManagerLocked(); 18858 return ums != null ? ums.getUserIds() : new int[] { 0 }; 18859 } 18860 18861 UserManagerService getUserManagerLocked() { 18862 if (mUserManager == null) { 18863 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 18864 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 18865 } 18866 return mUserManager; 18867 } 18868 18869 private int applyUserId(int uid, int userId) { 18870 return UserHandle.getUid(userId, uid); 18871 } 18872 18873 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 18874 if (info == null) return null; 18875 ApplicationInfo newInfo = new ApplicationInfo(info); 18876 newInfo.uid = applyUserId(info.uid, userId); 18877 newInfo.dataDir = USER_DATA_DIR + userId + "/" 18878 + info.packageName; 18879 return newInfo; 18880 } 18881 18882 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 18883 if (aInfo == null 18884 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 18885 return aInfo; 18886 } 18887 18888 ActivityInfo info = new ActivityInfo(aInfo); 18889 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 18890 return info; 18891 } 18892 18893 private final class LocalService extends ActivityManagerInternal { 18894 @Override 18895 public void goingToSleep() { 18896 ActivityManagerService.this.goingToSleep(); 18897 } 18898 18899 @Override 18900 public void wakingUp() { 18901 ActivityManagerService.this.wakingUp(); 18902 } 18903 18904 @Override 18905 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 18906 String processName, String abiOverride, int uid, Runnable crashHandler) { 18907 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 18908 processName, abiOverride, uid, crashHandler); 18909 } 18910 } 18911 18912 /** 18913 * An implementation of IAppTask, that allows an app to manage its own tasks via 18914 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 18915 * only the process that calls getAppTasks() can call the AppTask methods. 18916 */ 18917 class AppTaskImpl extends IAppTask.Stub { 18918 private int mTaskId; 18919 private int mCallingUid; 18920 18921 public AppTaskImpl(int taskId, int callingUid) { 18922 mTaskId = taskId; 18923 mCallingUid = callingUid; 18924 } 18925 18926 private void checkCaller() { 18927 if (mCallingUid != Binder.getCallingUid()) { 18928 throw new SecurityException("Caller " + mCallingUid 18929 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 18930 } 18931 } 18932 18933 @Override 18934 public void finishAndRemoveTask() { 18935 checkCaller(); 18936 18937 synchronized (ActivityManagerService.this) { 18938 long origId = Binder.clearCallingIdentity(); 18939 try { 18940 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18941 if (tr == null) { 18942 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18943 } 18944 // Only kill the process if we are not a new document 18945 int flags = tr.getBaseIntent().getFlags(); 18946 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 18947 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 18948 removeTaskByIdLocked(mTaskId, 18949 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 18950 } finally { 18951 Binder.restoreCallingIdentity(origId); 18952 } 18953 } 18954 } 18955 18956 @Override 18957 public ActivityManager.RecentTaskInfo getTaskInfo() { 18958 checkCaller(); 18959 18960 synchronized (ActivityManagerService.this) { 18961 long origId = Binder.clearCallingIdentity(); 18962 try { 18963 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18964 if (tr == null) { 18965 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18966 } 18967 return createRecentTaskInfoFromTaskRecord(tr); 18968 } finally { 18969 Binder.restoreCallingIdentity(origId); 18970 } 18971 } 18972 } 18973 18974 @Override 18975 public void moveToFront() { 18976 checkCaller(); 18977 18978 final TaskRecord tr; 18979 synchronized (ActivityManagerService.this) { 18980 tr = recentTaskForIdLocked(mTaskId); 18981 if (tr == null) { 18982 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18983 } 18984 if (tr.getRootActivity() != null) { 18985 moveTaskToFrontLocked(tr.taskId, 0, null); 18986 return; 18987 } 18988 } 18989 18990 startActivityFromRecentsInner(tr.taskId, null); 18991 } 18992 18993 @Override 18994 public int startActivity(IBinder whoThread, String callingPackage, 18995 Intent intent, String resolvedType, Bundle options) { 18996 checkCaller(); 18997 18998 int callingUser = UserHandle.getCallingUserId(); 18999 TaskRecord tr; 19000 IApplicationThread appThread; 19001 synchronized (ActivityManagerService.this) { 19002 tr = recentTaskForIdLocked(mTaskId); 19003 if (tr == null) { 19004 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19005 } 19006 appThread = ApplicationThreadNative.asInterface(whoThread); 19007 if (appThread == null) { 19008 throw new IllegalArgumentException("Bad app thread " + appThread); 19009 } 19010 } 19011 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19012 resolvedType, null, null, null, null, 0, 0, null, null, 19013 null, options, callingUser, null, tr); 19014 } 19015 19016 @Override 19017 public void setExcludeFromRecents(boolean exclude) { 19018 checkCaller(); 19019 19020 synchronized (ActivityManagerService.this) { 19021 long origId = Binder.clearCallingIdentity(); 19022 try { 19023 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19024 if (tr == null) { 19025 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19026 } 19027 Intent intent = tr.getBaseIntent(); 19028 if (exclude) { 19029 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19030 } else { 19031 intent.setFlags(intent.getFlags() 19032 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19033 } 19034 } finally { 19035 Binder.restoreCallingIdentity(origId); 19036 } 19037 } 19038 } 19039 } 19040} 19041