ActivityManagerService.java revision d54b578e47fb410c776bb3a4272c2c523153f657
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.os.storage.IMountService; 52import android.os.storage.StorageManager; 53import android.service.voice.IVoiceInteractionSession; 54import android.util.ArrayMap; 55import android.util.ArraySet; 56import android.util.SparseIntArray; 57 58import com.android.internal.R; 59import com.android.internal.annotations.GuardedBy; 60import com.android.internal.app.IAppOpsService; 61import com.android.internal.app.IVoiceInteractor; 62import com.android.internal.app.ProcessMap; 63import com.android.internal.app.ProcessStats; 64import com.android.internal.content.PackageMonitor; 65import com.android.internal.os.BackgroundThread; 66import com.android.internal.os.BatteryStatsImpl; 67import com.android.internal.os.ProcessCpuTracker; 68import com.android.internal.os.TransferPipe; 69import com.android.internal.os.Zygote; 70import com.android.internal.util.FastPrintWriter; 71import com.android.internal.util.FastXmlSerializer; 72import com.android.internal.util.MemInfoReader; 73import com.android.internal.util.Preconditions; 74import com.android.server.AppOpsService; 75import com.android.server.AttributeCache; 76import com.android.server.IntentResolver; 77import com.android.server.LocalServices; 78import com.android.server.ServiceThread; 79import com.android.server.SystemService; 80import com.android.server.SystemServiceManager; 81import com.android.server.Watchdog; 82import com.android.server.am.ActivityStack.ActivityState; 83import com.android.server.firewall.IntentFirewall; 84import com.android.server.pm.UserManagerService; 85import com.android.server.wm.AppTransition; 86import com.android.server.wm.WindowManagerService; 87import com.google.android.collect.Lists; 88import com.google.android.collect.Maps; 89 90import libcore.io.IoUtils; 91 92import org.xmlpull.v1.XmlPullParser; 93import org.xmlpull.v1.XmlPullParserException; 94import org.xmlpull.v1.XmlSerializer; 95 96import android.app.Activity; 97import android.app.ActivityManager; 98import android.app.ActivityManager.RunningTaskInfo; 99import android.app.ActivityManager.StackInfo; 100import android.app.ActivityManagerInternal; 101import android.app.ActivityManagerNative; 102import android.app.ActivityOptions; 103import android.app.ActivityThread; 104import android.app.AlertDialog; 105import android.app.AppGlobals; 106import android.app.ApplicationErrorReport; 107import android.app.Dialog; 108import android.app.IActivityController; 109import android.app.IApplicationThread; 110import android.app.IInstrumentationWatcher; 111import android.app.INotificationManager; 112import android.app.IProcessObserver; 113import android.app.IServiceConnection; 114import android.app.IStopUserCallback; 115import android.app.IUiAutomationConnection; 116import android.app.IUserSwitchObserver; 117import android.app.Instrumentation; 118import android.app.Notification; 119import android.app.NotificationManager; 120import android.app.PendingIntent; 121import android.app.backup.IBackupManager; 122import android.content.ActivityNotFoundException; 123import android.content.BroadcastReceiver; 124import android.content.ClipData; 125import android.content.ComponentCallbacks2; 126import android.content.ComponentName; 127import android.content.ContentProvider; 128import android.content.ContentResolver; 129import android.content.Context; 130import android.content.DialogInterface; 131import android.content.IContentProvider; 132import android.content.IIntentReceiver; 133import android.content.IIntentSender; 134import android.content.Intent; 135import android.content.IntentFilter; 136import android.content.IntentSender; 137import android.content.pm.ActivityInfo; 138import android.content.pm.ApplicationInfo; 139import android.content.pm.ConfigurationInfo; 140import android.content.pm.IPackageDataObserver; 141import android.content.pm.IPackageManager; 142import android.content.pm.InstrumentationInfo; 143import android.content.pm.PackageInfo; 144import android.content.pm.PackageManager; 145import android.content.pm.ParceledListSlice; 146import android.content.pm.UserInfo; 147import android.content.pm.PackageManager.NameNotFoundException; 148import android.content.pm.PathPermission; 149import android.content.pm.ProviderInfo; 150import android.content.pm.ResolveInfo; 151import android.content.pm.ServiceInfo; 152import android.content.res.CompatibilityInfo; 153import android.content.res.Configuration; 154import android.net.Proxy; 155import android.net.ProxyInfo; 156import android.net.Uri; 157import android.os.Binder; 158import android.os.Build; 159import android.os.Bundle; 160import android.os.Debug; 161import android.os.DropBoxManager; 162import android.os.Environment; 163import android.os.FactoryTest; 164import android.os.FileObserver; 165import android.os.FileUtils; 166import android.os.Handler; 167import android.os.IBinder; 168import android.os.IPermissionController; 169import android.os.IRemoteCallback; 170import android.os.IUserManager; 171import android.os.Looper; 172import android.os.Message; 173import android.os.Parcel; 174import android.os.ParcelFileDescriptor; 175import android.os.Process; 176import android.os.RemoteCallbackList; 177import android.os.RemoteException; 178import android.os.SELinux; 179import android.os.ServiceManager; 180import android.os.StrictMode; 181import android.os.SystemClock; 182import android.os.SystemProperties; 183import android.os.UpdateLock; 184import android.os.UserHandle; 185import android.os.UserManager; 186import android.provider.Settings; 187import android.text.format.DateUtils; 188import android.text.format.Time; 189import android.util.AtomicFile; 190import android.util.EventLog; 191import android.util.Log; 192import android.util.Pair; 193import android.util.PrintWriterPrinter; 194import android.util.Slog; 195import android.util.SparseArray; 196import android.util.TimeUtils; 197import android.util.Xml; 198import android.view.Gravity; 199import android.view.LayoutInflater; 200import android.view.View; 201import android.view.WindowManager; 202import dalvik.system.VMRuntime; 203 204import java.io.BufferedInputStream; 205import java.io.BufferedOutputStream; 206import java.io.DataInputStream; 207import java.io.DataOutputStream; 208import java.io.File; 209import java.io.FileDescriptor; 210import java.io.FileInputStream; 211import java.io.FileNotFoundException; 212import java.io.FileOutputStream; 213import java.io.IOException; 214import java.io.InputStreamReader; 215import java.io.PrintWriter; 216import java.io.StringWriter; 217import java.lang.ref.WeakReference; 218import java.util.ArrayList; 219import java.util.Arrays; 220import java.util.Collections; 221import java.util.Comparator; 222import java.util.HashMap; 223import java.util.HashSet; 224import java.util.Iterator; 225import java.util.List; 226import java.util.Locale; 227import java.util.Map; 228import java.util.Set; 229import java.util.concurrent.atomic.AtomicBoolean; 230import java.util.concurrent.atomic.AtomicLong; 231 232public final class ActivityManagerService extends ActivityManagerNative 233 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 234 235 private static final String USER_DATA_DIR = "/data/user/"; 236 // File that stores last updated system version and called preboot receivers 237 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 238 239 static final String TAG = "ActivityManager"; 240 static final String TAG_MU = "ActivityManagerServiceMU"; 241 static final boolean DEBUG = false; 242 static final boolean localLOGV = DEBUG; 243 static final boolean DEBUG_BACKUP = localLOGV || false; 244 static final boolean DEBUG_BROADCAST = localLOGV || false; 245 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 246 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 247 static final boolean DEBUG_CLEANUP = localLOGV || false; 248 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 249 static final boolean DEBUG_FOCUS = false; 250 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 251 static final boolean DEBUG_MU = localLOGV || false; 252 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 253 static final boolean DEBUG_LRU = localLOGV || false; 254 static final boolean DEBUG_PAUSE = localLOGV || false; 255 static final boolean DEBUG_POWER = localLOGV || false; 256 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 257 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 258 static final boolean DEBUG_PROCESSES = localLOGV || false; 259 static final boolean DEBUG_PROVIDER = localLOGV || false; 260 static final boolean DEBUG_RESULTS = localLOGV || false; 261 static final boolean DEBUG_SERVICE = localLOGV || false; 262 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 263 static final boolean DEBUG_STACK = localLOGV || false; 264 static final boolean DEBUG_SWITCH = localLOGV || false; 265 static final boolean DEBUG_TASKS = localLOGV || false; 266 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 267 static final boolean DEBUG_TRANSITION = localLOGV || false; 268 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 269 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 270 static final boolean DEBUG_VISBILITY = localLOGV || false; 271 static final boolean DEBUG_PSS = localLOGV || false; 272 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 273 static final boolean DEBUG_RECENTS = localLOGV || false; 274 static final boolean VALIDATE_TOKENS = false; 275 static final boolean SHOW_ACTIVITY_START_TIME = true; 276 277 // Control over CPU and battery monitoring. 278 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 279 static final boolean MONITOR_CPU_USAGE = true; 280 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 281 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 282 static final boolean MONITOR_THREAD_CPU_USAGE = false; 283 284 // The flags that are set for all calls we make to the package manager. 285 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 286 287 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 288 289 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 290 291 // Maximum number recent bitmaps to keep in memory. 292 static final int MAX_RECENT_BITMAPS = 5; 293 294 // Amount of time after a call to stopAppSwitches() during which we will 295 // prevent further untrusted switches from happening. 296 static final long APP_SWITCH_DELAY_TIME = 5*1000; 297 298 // How long we wait for a launched process to attach to the activity manager 299 // before we decide it's never going to come up for real. 300 static final int PROC_START_TIMEOUT = 10*1000; 301 302 // How long we wait for a launched process to attach to the activity manager 303 // before we decide it's never going to come up for real, when the process was 304 // started with a wrapper for instrumentation (such as Valgrind) because it 305 // could take much longer than usual. 306 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 307 308 // How long to wait after going idle before forcing apps to GC. 309 static final int GC_TIMEOUT = 5*1000; 310 311 // The minimum amount of time between successive GC requests for a process. 312 static final int GC_MIN_INTERVAL = 60*1000; 313 314 // The minimum amount of time between successive PSS requests for a process. 315 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 316 317 // The minimum amount of time between successive PSS requests for a process 318 // when the request is due to the memory state being lowered. 319 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 320 321 // The rate at which we check for apps using excessive power -- 15 mins. 322 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 323 324 // The minimum sample duration we will allow before deciding we have 325 // enough data on wake locks to start killing things. 326 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 327 328 // The minimum sample duration we will allow before deciding we have 329 // enough data on CPU usage to start killing things. 330 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 331 332 // How long we allow a receiver to run before giving up on it. 333 static final int BROADCAST_FG_TIMEOUT = 10*1000; 334 static final int BROADCAST_BG_TIMEOUT = 60*1000; 335 336 // How long we wait until we timeout on key dispatching. 337 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 338 339 // How long we wait until we timeout on key dispatching during instrumentation. 340 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 341 342 // Amount of time we wait for observers to handle a user switch before 343 // giving up on them and unfreezing the screen. 344 static final int USER_SWITCH_TIMEOUT = 2*1000; 345 346 // Maximum number of users we allow to be running at a time. 347 static final int MAX_RUNNING_USERS = 3; 348 349 // How long to wait in getAssistContextExtras for the activity and foreground services 350 // to respond with the result. 351 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 352 353 // Maximum number of persisted Uri grants a package is allowed 354 static final int MAX_PERSISTED_URI_GRANTS = 128; 355 356 static final int MY_PID = Process.myPid(); 357 358 static final String[] EMPTY_STRING_ARRAY = new String[0]; 359 360 // How many bytes to write into the dropbox log before truncating 361 static final int DROPBOX_MAX_SIZE = 256 * 1024; 362 363 // Access modes for handleIncomingUser. 364 static final int ALLOW_NON_FULL = 0; 365 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 366 static final int ALLOW_FULL_ONLY = 2; 367 368 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 369 370 /** All system services */ 371 SystemServiceManager mSystemServiceManager; 372 373 /** Run all ActivityStacks through this */ 374 ActivityStackSupervisor mStackSupervisor; 375 376 public IntentFirewall mIntentFirewall; 377 378 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 379 // default actuion automatically. Important for devices without direct input 380 // devices. 381 private boolean mShowDialogs = true; 382 383 BroadcastQueue mFgBroadcastQueue; 384 BroadcastQueue mBgBroadcastQueue; 385 // Convenient for easy iteration over the queues. Foreground is first 386 // so that dispatch of foreground broadcasts gets precedence. 387 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 388 389 BroadcastQueue broadcastQueueForIntent(Intent intent) { 390 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 391 if (DEBUG_BACKGROUND_BROADCAST) { 392 Slog.i(TAG, "Broadcast intent " + intent + " on " 393 + (isFg ? "foreground" : "background") 394 + " queue"); 395 } 396 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 397 } 398 399 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 400 for (BroadcastQueue queue : mBroadcastQueues) { 401 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 402 if (r != null) { 403 return r; 404 } 405 } 406 return null; 407 } 408 409 /** 410 * Activity we have told the window manager to have key focus. 411 */ 412 ActivityRecord mFocusedActivity = null; 413 414 /** 415 * List of intents that were used to start the most recent tasks. 416 */ 417 ArrayList<TaskRecord> mRecentTasks; 418 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 419 420 /** 421 * For addAppTask: cached of the last activity component that was added. 422 */ 423 ComponentName mLastAddedTaskComponent; 424 425 /** 426 * For addAppTask: cached of the last activity uid that was added. 427 */ 428 int mLastAddedTaskUid; 429 430 /** 431 * For addAppTask: cached of the last ActivityInfo that was added. 432 */ 433 ActivityInfo mLastAddedTaskActivity; 434 435 public class PendingAssistExtras extends Binder implements Runnable { 436 public final ActivityRecord activity; 437 public final Bundle extras; 438 public final Intent intent; 439 public final String hint; 440 public final int userHandle; 441 public boolean haveResult = false; 442 public Bundle result = null; 443 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 444 String _hint, int _userHandle) { 445 activity = _activity; 446 extras = _extras; 447 intent = _intent; 448 hint = _hint; 449 userHandle = _userHandle; 450 } 451 @Override 452 public void run() { 453 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 454 synchronized (this) { 455 haveResult = true; 456 notifyAll(); 457 } 458 } 459 } 460 461 final ArrayList<PendingAssistExtras> mPendingAssistExtras 462 = new ArrayList<PendingAssistExtras>(); 463 464 /** 465 * Process management. 466 */ 467 final ProcessList mProcessList = new ProcessList(); 468 469 /** 470 * All of the applications we currently have running organized by name. 471 * The keys are strings of the application package name (as 472 * returned by the package manager), and the keys are ApplicationRecord 473 * objects. 474 */ 475 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 476 477 /** 478 * Tracking long-term execution of processes to look for abuse and other 479 * bad app behavior. 480 */ 481 final ProcessStatsService mProcessStats; 482 483 /** 484 * The currently running isolated processes. 485 */ 486 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 487 488 /** 489 * Counter for assigning isolated process uids, to avoid frequently reusing the 490 * same ones. 491 */ 492 int mNextIsolatedProcessUid = 0; 493 494 /** 495 * The currently running heavy-weight process, if any. 496 */ 497 ProcessRecord mHeavyWeightProcess = null; 498 499 /** 500 * The last time that various processes have crashed. 501 */ 502 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 503 504 /** 505 * Information about a process that is currently marked as bad. 506 */ 507 static final class BadProcessInfo { 508 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 509 this.time = time; 510 this.shortMsg = shortMsg; 511 this.longMsg = longMsg; 512 this.stack = stack; 513 } 514 515 final long time; 516 final String shortMsg; 517 final String longMsg; 518 final String stack; 519 } 520 521 /** 522 * Set of applications that we consider to be bad, and will reject 523 * incoming broadcasts from (which the user has no control over). 524 * Processes are added to this set when they have crashed twice within 525 * a minimum amount of time; they are removed from it when they are 526 * later restarted (hopefully due to some user action). The value is the 527 * time it was added to the list. 528 */ 529 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 530 531 /** 532 * All of the processes we currently have running organized by pid. 533 * The keys are the pid running the application. 534 * 535 * <p>NOTE: This object is protected by its own lock, NOT the global 536 * activity manager lock! 537 */ 538 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 539 540 /** 541 * All of the processes that have been forced to be foreground. The key 542 * is the pid of the caller who requested it (we hold a death 543 * link on it). 544 */ 545 abstract class ForegroundToken implements IBinder.DeathRecipient { 546 int pid; 547 IBinder token; 548 } 549 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 550 551 /** 552 * List of records for processes that someone had tried to start before the 553 * system was ready. We don't start them at that point, but ensure they 554 * are started by the time booting is complete. 555 */ 556 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 557 558 /** 559 * List of persistent applications that are in the process 560 * of being started. 561 */ 562 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 563 564 /** 565 * Processes that are being forcibly torn down. 566 */ 567 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 568 569 /** 570 * List of running applications, sorted by recent usage. 571 * The first entry in the list is the least recently used. 572 */ 573 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 574 575 /** 576 * Where in mLruProcesses that the processes hosting activities start. 577 */ 578 int mLruProcessActivityStart = 0; 579 580 /** 581 * Where in mLruProcesses that the processes hosting services start. 582 * This is after (lower index) than mLruProcessesActivityStart. 583 */ 584 int mLruProcessServiceStart = 0; 585 586 /** 587 * List of processes that should gc as soon as things are idle. 588 */ 589 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 590 591 /** 592 * Processes we want to collect PSS data from. 593 */ 594 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 595 596 /** 597 * Last time we requested PSS data of all processes. 598 */ 599 long mLastFullPssTime = SystemClock.uptimeMillis(); 600 601 /** 602 * If set, the next time we collect PSS data we should do a full collection 603 * with data from native processes and the kernel. 604 */ 605 boolean mFullPssPending = false; 606 607 /** 608 * This is the process holding what we currently consider to be 609 * the "home" activity. 610 */ 611 ProcessRecord mHomeProcess; 612 613 /** 614 * This is the process holding the activity the user last visited that 615 * is in a different process from the one they are currently in. 616 */ 617 ProcessRecord mPreviousProcess; 618 619 /** 620 * The time at which the previous process was last visible. 621 */ 622 long mPreviousProcessVisibleTime; 623 624 /** 625 * Which uses have been started, so are allowed to run code. 626 */ 627 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 628 629 /** 630 * LRU list of history of current users. Most recently current is at the end. 631 */ 632 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 633 634 /** 635 * Constant array of the users that are currently started. 636 */ 637 int[] mStartedUserArray = new int[] { 0 }; 638 639 /** 640 * Registered observers of the user switching mechanics. 641 */ 642 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 643 = new RemoteCallbackList<IUserSwitchObserver>(); 644 645 /** 646 * Currently active user switch. 647 */ 648 Object mCurUserSwitchCallback; 649 650 /** 651 * Packages that the user has asked to have run in screen size 652 * compatibility mode instead of filling the screen. 653 */ 654 final CompatModePackages mCompatModePackages; 655 656 /** 657 * Set of IntentSenderRecord objects that are currently active. 658 */ 659 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 660 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 661 662 /** 663 * Fingerprints (hashCode()) of stack traces that we've 664 * already logged DropBox entries for. Guarded by itself. If 665 * something (rogue user app) forces this over 666 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 667 */ 668 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 669 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 670 671 /** 672 * Strict Mode background batched logging state. 673 * 674 * The string buffer is guarded by itself, and its lock is also 675 * used to determine if another batched write is already 676 * in-flight. 677 */ 678 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 679 680 /** 681 * Keeps track of all IIntentReceivers that have been registered for 682 * broadcasts. Hash keys are the receiver IBinder, hash value is 683 * a ReceiverList. 684 */ 685 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 686 new HashMap<IBinder, ReceiverList>(); 687 688 /** 689 * Resolver for broadcast intents to registered receivers. 690 * Holds BroadcastFilter (subclass of IntentFilter). 691 */ 692 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 693 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 694 @Override 695 protected boolean allowFilterResult( 696 BroadcastFilter filter, List<BroadcastFilter> dest) { 697 IBinder target = filter.receiverList.receiver.asBinder(); 698 for (int i=dest.size()-1; i>=0; i--) { 699 if (dest.get(i).receiverList.receiver.asBinder() == target) { 700 return false; 701 } 702 } 703 return true; 704 } 705 706 @Override 707 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 708 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 709 || userId == filter.owningUserId) { 710 return super.newResult(filter, match, userId); 711 } 712 return null; 713 } 714 715 @Override 716 protected BroadcastFilter[] newArray(int size) { 717 return new BroadcastFilter[size]; 718 } 719 720 @Override 721 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 722 return packageName.equals(filter.packageName); 723 } 724 }; 725 726 /** 727 * State of all active sticky broadcasts per user. Keys are the action of the 728 * sticky Intent, values are an ArrayList of all broadcasted intents with 729 * that action (which should usually be one). The SparseArray is keyed 730 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 731 * for stickies that are sent to all users. 732 */ 733 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 734 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 735 736 final ActiveServices mServices; 737 738 /** 739 * Backup/restore process management 740 */ 741 String mBackupAppName = null; 742 BackupRecord mBackupTarget = null; 743 744 final ProviderMap mProviderMap; 745 746 /** 747 * List of content providers who have clients waiting for them. The 748 * application is currently being launched and the provider will be 749 * removed from this list once it is published. 750 */ 751 final ArrayList<ContentProviderRecord> mLaunchingProviders 752 = new ArrayList<ContentProviderRecord>(); 753 754 /** 755 * File storing persisted {@link #mGrantedUriPermissions}. 756 */ 757 private final AtomicFile mGrantFile; 758 759 /** XML constants used in {@link #mGrantFile} */ 760 private static final String TAG_URI_GRANTS = "uri-grants"; 761 private static final String TAG_URI_GRANT = "uri-grant"; 762 private static final String ATTR_USER_HANDLE = "userHandle"; 763 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 764 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 765 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 766 private static final String ATTR_TARGET_PKG = "targetPkg"; 767 private static final String ATTR_URI = "uri"; 768 private static final String ATTR_MODE_FLAGS = "modeFlags"; 769 private static final String ATTR_CREATED_TIME = "createdTime"; 770 private static final String ATTR_PREFIX = "prefix"; 771 772 /** 773 * Global set of specific {@link Uri} permissions that have been granted. 774 * This optimized lookup structure maps from {@link UriPermission#targetUid} 775 * to {@link UriPermission#uri} to {@link UriPermission}. 776 */ 777 @GuardedBy("this") 778 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 779 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 780 781 public static class GrantUri { 782 public final int sourceUserId; 783 public final Uri uri; 784 public boolean prefix; 785 786 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 787 this.sourceUserId = sourceUserId; 788 this.uri = uri; 789 this.prefix = prefix; 790 } 791 792 @Override 793 public int hashCode() { 794 return toString().hashCode(); 795 } 796 797 @Override 798 public boolean equals(Object o) { 799 if (o instanceof GrantUri) { 800 GrantUri other = (GrantUri) o; 801 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 802 && prefix == other.prefix; 803 } 804 return false; 805 } 806 807 @Override 808 public String toString() { 809 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 810 if (prefix) result += " [prefix]"; 811 return result; 812 } 813 814 public String toSafeString() { 815 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 816 if (prefix) result += " [prefix]"; 817 return result; 818 } 819 820 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 821 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 822 ContentProvider.getUriWithoutUserId(uri), false); 823 } 824 } 825 826 CoreSettingsObserver mCoreSettingsObserver; 827 828 /** 829 * Thread-local storage used to carry caller permissions over through 830 * indirect content-provider access. 831 */ 832 private class Identity { 833 public int pid; 834 public int uid; 835 836 Identity(int _pid, int _uid) { 837 pid = _pid; 838 uid = _uid; 839 } 840 } 841 842 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 843 844 /** 845 * All information we have collected about the runtime performance of 846 * any user id that can impact battery performance. 847 */ 848 final BatteryStatsService mBatteryStatsService; 849 850 /** 851 * Information about component usage 852 */ 853 UsageStatsManagerInternal mUsageStatsService; 854 855 /** 856 * Information about and control over application operations 857 */ 858 final AppOpsService mAppOpsService; 859 860 /** 861 * Save recent tasks information across reboots. 862 */ 863 final TaskPersister mTaskPersister; 864 865 /** 866 * Current configuration information. HistoryRecord objects are given 867 * a reference to this object to indicate which configuration they are 868 * currently running in, so this object must be kept immutable. 869 */ 870 Configuration mConfiguration = new Configuration(); 871 872 /** 873 * Current sequencing integer of the configuration, for skipping old 874 * configurations. 875 */ 876 int mConfigurationSeq = 0; 877 878 /** 879 * Hardware-reported OpenGLES version. 880 */ 881 final int GL_ES_VERSION; 882 883 /** 884 * List of initialization arguments to pass to all processes when binding applications to them. 885 * For example, references to the commonly used services. 886 */ 887 HashMap<String, IBinder> mAppBindArgs; 888 889 /** 890 * Temporary to avoid allocations. Protected by main lock. 891 */ 892 final StringBuilder mStringBuilder = new StringBuilder(256); 893 894 /** 895 * Used to control how we initialize the service. 896 */ 897 ComponentName mTopComponent; 898 String mTopAction = Intent.ACTION_MAIN; 899 String mTopData; 900 boolean mProcessesReady = false; 901 boolean mSystemReady = false; 902 boolean mBooting = false; 903 boolean mCallFinishBooting = false; 904 boolean mBootAnimationComplete = false; 905 boolean mWaitingUpdate = false; 906 boolean mDidUpdate = false; 907 boolean mOnBattery = false; 908 boolean mLaunchWarningShown = false; 909 910 Context mContext; 911 912 int mFactoryTest; 913 914 boolean mCheckedForSetup; 915 916 /** 917 * The time at which we will allow normal application switches again, 918 * after a call to {@link #stopAppSwitches()}. 919 */ 920 long mAppSwitchesAllowedTime; 921 922 /** 923 * This is set to true after the first switch after mAppSwitchesAllowedTime 924 * is set; any switches after that will clear the time. 925 */ 926 boolean mDidAppSwitch; 927 928 /** 929 * Last time (in realtime) at which we checked for power usage. 930 */ 931 long mLastPowerCheckRealtime; 932 933 /** 934 * Last time (in uptime) at which we checked for power usage. 935 */ 936 long mLastPowerCheckUptime; 937 938 /** 939 * Set while we are wanting to sleep, to prevent any 940 * activities from being started/resumed. 941 */ 942 private boolean mSleeping = false; 943 944 /** 945 * Set while we are running a voice interaction. This overrides 946 * sleeping while it is active. 947 */ 948 private boolean mRunningVoice = false; 949 950 /** 951 * State of external calls telling us if the device is asleep. 952 */ 953 private boolean mWentToSleep = false; 954 955 /** 956 * State of external call telling us if the lock screen is shown. 957 */ 958 private boolean mLockScreenShown = false; 959 960 /** 961 * Set if we are shutting down the system, similar to sleeping. 962 */ 963 boolean mShuttingDown = false; 964 965 /** 966 * Current sequence id for oom_adj computation traversal. 967 */ 968 int mAdjSeq = 0; 969 970 /** 971 * Current sequence id for process LRU updating. 972 */ 973 int mLruSeq = 0; 974 975 /** 976 * Keep track of the non-cached/empty process we last found, to help 977 * determine how to distribute cached/empty processes next time. 978 */ 979 int mNumNonCachedProcs = 0; 980 981 /** 982 * Keep track of the number of cached hidden procs, to balance oom adj 983 * distribution between those and empty procs. 984 */ 985 int mNumCachedHiddenProcs = 0; 986 987 /** 988 * Keep track of the number of service processes we last found, to 989 * determine on the next iteration which should be B services. 990 */ 991 int mNumServiceProcs = 0; 992 int mNewNumAServiceProcs = 0; 993 int mNewNumServiceProcs = 0; 994 995 /** 996 * Allow the current computed overall memory level of the system to go down? 997 * This is set to false when we are killing processes for reasons other than 998 * memory management, so that the now smaller process list will not be taken as 999 * an indication that memory is tighter. 1000 */ 1001 boolean mAllowLowerMemLevel = false; 1002 1003 /** 1004 * The last computed memory level, for holding when we are in a state that 1005 * processes are going away for other reasons. 1006 */ 1007 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1008 1009 /** 1010 * The last total number of process we have, to determine if changes actually look 1011 * like a shrinking number of process due to lower RAM. 1012 */ 1013 int mLastNumProcesses; 1014 1015 /** 1016 * The uptime of the last time we performed idle maintenance. 1017 */ 1018 long mLastIdleTime = SystemClock.uptimeMillis(); 1019 1020 /** 1021 * Total time spent with RAM that has been added in the past since the last idle time. 1022 */ 1023 long mLowRamTimeSinceLastIdle = 0; 1024 1025 /** 1026 * If RAM is currently low, when that horrible situation started. 1027 */ 1028 long mLowRamStartTime = 0; 1029 1030 /** 1031 * For reporting to battery stats the current top application. 1032 */ 1033 private String mCurResumedPackage = null; 1034 private int mCurResumedUid = -1; 1035 1036 /** 1037 * For reporting to battery stats the apps currently running foreground 1038 * service. The ProcessMap is package/uid tuples; each of these contain 1039 * an array of the currently foreground processes. 1040 */ 1041 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1042 = new ProcessMap<ArrayList<ProcessRecord>>(); 1043 1044 /** 1045 * This is set if we had to do a delayed dexopt of an app before launching 1046 * it, to increase the ANR timeouts in that case. 1047 */ 1048 boolean mDidDexOpt; 1049 1050 /** 1051 * Set if the systemServer made a call to enterSafeMode. 1052 */ 1053 boolean mSafeMode; 1054 1055 String mDebugApp = null; 1056 boolean mWaitForDebugger = false; 1057 boolean mDebugTransient = false; 1058 String mOrigDebugApp = null; 1059 boolean mOrigWaitForDebugger = false; 1060 boolean mAlwaysFinishActivities = false; 1061 IActivityController mController = null; 1062 String mProfileApp = null; 1063 ProcessRecord mProfileProc = null; 1064 String mProfileFile; 1065 ParcelFileDescriptor mProfileFd; 1066 int mSamplingInterval = 0; 1067 boolean mAutoStopProfiler = false; 1068 int mProfileType = 0; 1069 String mOpenGlTraceApp = null; 1070 1071 static class ProcessChangeItem { 1072 static final int CHANGE_ACTIVITIES = 1<<0; 1073 static final int CHANGE_PROCESS_STATE = 1<<1; 1074 int changes; 1075 int uid; 1076 int pid; 1077 int processState; 1078 boolean foregroundActivities; 1079 } 1080 1081 final RemoteCallbackList<IProcessObserver> mProcessObservers 1082 = new RemoteCallbackList<IProcessObserver>(); 1083 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1084 1085 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1086 = new ArrayList<ProcessChangeItem>(); 1087 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1088 = new ArrayList<ProcessChangeItem>(); 1089 1090 /** 1091 * Runtime CPU use collection thread. This object's lock is used to 1092 * perform synchronization with the thread (notifying it to run). 1093 */ 1094 final Thread mProcessCpuThread; 1095 1096 /** 1097 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1098 * Must acquire this object's lock when accessing it. 1099 * NOTE: this lock will be held while doing long operations (trawling 1100 * through all processes in /proc), so it should never be acquired by 1101 * any critical paths such as when holding the main activity manager lock. 1102 */ 1103 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1104 MONITOR_THREAD_CPU_USAGE); 1105 final AtomicLong mLastCpuTime = new AtomicLong(0); 1106 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1107 1108 long mLastWriteTime = 0; 1109 1110 /** 1111 * Used to retain an update lock when the foreground activity is in 1112 * immersive mode. 1113 */ 1114 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1115 1116 /** 1117 * Set to true after the system has finished booting. 1118 */ 1119 boolean mBooted = false; 1120 1121 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1122 int mProcessLimitOverride = -1; 1123 1124 WindowManagerService mWindowManager; 1125 1126 final ActivityThread mSystemThread; 1127 1128 // Holds the current foreground user's id 1129 int mCurrentUserId = 0; 1130 // Holds the target user's id during a user switch 1131 int mTargetUserId = UserHandle.USER_NULL; 1132 // If there are multiple profiles for the current user, their ids are here 1133 // Currently only the primary user can have managed profiles 1134 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1135 1136 /** 1137 * Mapping from each known user ID to the profile group ID it is associated with. 1138 */ 1139 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1140 1141 private UserManagerService mUserManager; 1142 1143 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1144 final ProcessRecord mApp; 1145 final int mPid; 1146 final IApplicationThread mAppThread; 1147 1148 AppDeathRecipient(ProcessRecord app, int pid, 1149 IApplicationThread thread) { 1150 if (localLOGV) Slog.v( 1151 TAG, "New death recipient " + this 1152 + " for thread " + thread.asBinder()); 1153 mApp = app; 1154 mPid = pid; 1155 mAppThread = thread; 1156 } 1157 1158 @Override 1159 public void binderDied() { 1160 if (localLOGV) Slog.v( 1161 TAG, "Death received in " + this 1162 + " for thread " + mAppThread.asBinder()); 1163 synchronized(ActivityManagerService.this) { 1164 appDiedLocked(mApp, mPid, mAppThread); 1165 } 1166 } 1167 } 1168 1169 static final int SHOW_ERROR_MSG = 1; 1170 static final int SHOW_NOT_RESPONDING_MSG = 2; 1171 static final int SHOW_FACTORY_ERROR_MSG = 3; 1172 static final int UPDATE_CONFIGURATION_MSG = 4; 1173 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1174 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1175 static final int SERVICE_TIMEOUT_MSG = 12; 1176 static final int UPDATE_TIME_ZONE = 13; 1177 static final int SHOW_UID_ERROR_MSG = 14; 1178 static final int IM_FEELING_LUCKY_MSG = 15; 1179 static final int PROC_START_TIMEOUT_MSG = 20; 1180 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1181 static final int KILL_APPLICATION_MSG = 22; 1182 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1183 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1184 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1185 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1186 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1187 static final int CLEAR_DNS_CACHE_MSG = 28; 1188 static final int UPDATE_HTTP_PROXY_MSG = 29; 1189 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1190 static final int DISPATCH_PROCESSES_CHANGED = 31; 1191 static final int DISPATCH_PROCESS_DIED = 32; 1192 static final int REPORT_MEM_USAGE_MSG = 33; 1193 static final int REPORT_USER_SWITCH_MSG = 34; 1194 static final int CONTINUE_USER_SWITCH_MSG = 35; 1195 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1196 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1197 static final int PERSIST_URI_GRANTS_MSG = 38; 1198 static final int REQUEST_ALL_PSS_MSG = 39; 1199 static final int START_PROFILES_MSG = 40; 1200 static final int UPDATE_TIME = 41; 1201 static final int SYSTEM_USER_START_MSG = 42; 1202 static final int SYSTEM_USER_CURRENT_MSG = 43; 1203 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1204 static final int FINISH_BOOTING_MSG = 45; 1205 static final int START_USER_SWITCH_MSG = 46; 1206 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1207 1208 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1209 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1210 static final int FIRST_COMPAT_MODE_MSG = 300; 1211 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1212 1213 AlertDialog mUidAlert; 1214 CompatModeDialog mCompatModeDialog; 1215 long mLastMemUsageReportTime = 0; 1216 1217 private LockToAppRequestDialog mLockToAppRequest; 1218 1219 /** 1220 * Flag whether the current user is a "monkey", i.e. whether 1221 * the UI is driven by a UI automation tool. 1222 */ 1223 private boolean mUserIsMonkey; 1224 1225 /** Flag whether the device has a Recents UI */ 1226 boolean mHasRecents; 1227 1228 /** The dimensions of the thumbnails in the Recents UI. */ 1229 int mThumbnailWidth; 1230 int mThumbnailHeight; 1231 1232 final ServiceThread mHandlerThread; 1233 final MainHandler mHandler; 1234 1235 final class MainHandler extends Handler { 1236 public MainHandler(Looper looper) { 1237 super(looper, null, true); 1238 } 1239 1240 @Override 1241 public void handleMessage(Message msg) { 1242 switch (msg.what) { 1243 case SHOW_ERROR_MSG: { 1244 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1245 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1246 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1247 synchronized (ActivityManagerService.this) { 1248 ProcessRecord proc = (ProcessRecord)data.get("app"); 1249 AppErrorResult res = (AppErrorResult) data.get("result"); 1250 if (proc != null && proc.crashDialog != null) { 1251 Slog.e(TAG, "App already has crash dialog: " + proc); 1252 if (res != null) { 1253 res.set(0); 1254 } 1255 return; 1256 } 1257 boolean isBackground = (UserHandle.getAppId(proc.uid) 1258 >= Process.FIRST_APPLICATION_UID 1259 && proc.pid != MY_PID); 1260 for (int userId : mCurrentProfileIds) { 1261 isBackground &= (proc.userId != userId); 1262 } 1263 if (isBackground && !showBackground) { 1264 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1265 if (res != null) { 1266 res.set(0); 1267 } 1268 return; 1269 } 1270 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1271 Dialog d = new AppErrorDialog(mContext, 1272 ActivityManagerService.this, res, proc); 1273 d.show(); 1274 proc.crashDialog = d; 1275 } else { 1276 // The device is asleep, so just pretend that the user 1277 // saw a crash dialog and hit "force quit". 1278 if (res != null) { 1279 res.set(0); 1280 } 1281 } 1282 } 1283 1284 ensureBootCompleted(); 1285 } break; 1286 case SHOW_NOT_RESPONDING_MSG: { 1287 synchronized (ActivityManagerService.this) { 1288 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1289 ProcessRecord proc = (ProcessRecord)data.get("app"); 1290 if (proc != null && proc.anrDialog != null) { 1291 Slog.e(TAG, "App already has anr dialog: " + proc); 1292 return; 1293 } 1294 1295 Intent intent = new Intent("android.intent.action.ANR"); 1296 if (!mProcessesReady) { 1297 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1298 | Intent.FLAG_RECEIVER_FOREGROUND); 1299 } 1300 broadcastIntentLocked(null, null, intent, 1301 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1302 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1303 1304 if (mShowDialogs) { 1305 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1306 mContext, proc, (ActivityRecord)data.get("activity"), 1307 msg.arg1 != 0); 1308 d.show(); 1309 proc.anrDialog = d; 1310 } else { 1311 // Just kill the app if there is no dialog to be shown. 1312 killAppAtUsersRequest(proc, null); 1313 } 1314 } 1315 1316 ensureBootCompleted(); 1317 } break; 1318 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1319 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1320 synchronized (ActivityManagerService.this) { 1321 ProcessRecord proc = (ProcessRecord) data.get("app"); 1322 if (proc == null) { 1323 Slog.e(TAG, "App not found when showing strict mode dialog."); 1324 break; 1325 } 1326 if (proc.crashDialog != null) { 1327 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1328 return; 1329 } 1330 AppErrorResult res = (AppErrorResult) data.get("result"); 1331 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1332 Dialog d = new StrictModeViolationDialog(mContext, 1333 ActivityManagerService.this, res, proc); 1334 d.show(); 1335 proc.crashDialog = d; 1336 } else { 1337 // The device is asleep, so just pretend that the user 1338 // saw a crash dialog and hit "force quit". 1339 res.set(0); 1340 } 1341 } 1342 ensureBootCompleted(); 1343 } break; 1344 case SHOW_FACTORY_ERROR_MSG: { 1345 Dialog d = new FactoryErrorDialog( 1346 mContext, msg.getData().getCharSequence("msg")); 1347 d.show(); 1348 ensureBootCompleted(); 1349 } break; 1350 case UPDATE_CONFIGURATION_MSG: { 1351 final ContentResolver resolver = mContext.getContentResolver(); 1352 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1353 } break; 1354 case GC_BACKGROUND_PROCESSES_MSG: { 1355 synchronized (ActivityManagerService.this) { 1356 performAppGcsIfAppropriateLocked(); 1357 } 1358 } break; 1359 case WAIT_FOR_DEBUGGER_MSG: { 1360 synchronized (ActivityManagerService.this) { 1361 ProcessRecord app = (ProcessRecord)msg.obj; 1362 if (msg.arg1 != 0) { 1363 if (!app.waitedForDebugger) { 1364 Dialog d = new AppWaitingForDebuggerDialog( 1365 ActivityManagerService.this, 1366 mContext, app); 1367 app.waitDialog = d; 1368 app.waitedForDebugger = true; 1369 d.show(); 1370 } 1371 } else { 1372 if (app.waitDialog != null) { 1373 app.waitDialog.dismiss(); 1374 app.waitDialog = null; 1375 } 1376 } 1377 } 1378 } break; 1379 case SERVICE_TIMEOUT_MSG: { 1380 if (mDidDexOpt) { 1381 mDidDexOpt = false; 1382 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1383 nmsg.obj = msg.obj; 1384 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1385 return; 1386 } 1387 mServices.serviceTimeout((ProcessRecord)msg.obj); 1388 } break; 1389 case UPDATE_TIME_ZONE: { 1390 synchronized (ActivityManagerService.this) { 1391 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1392 ProcessRecord r = mLruProcesses.get(i); 1393 if (r.thread != null) { 1394 try { 1395 r.thread.updateTimeZone(); 1396 } catch (RemoteException ex) { 1397 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1398 } 1399 } 1400 } 1401 } 1402 } break; 1403 case CLEAR_DNS_CACHE_MSG: { 1404 synchronized (ActivityManagerService.this) { 1405 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1406 ProcessRecord r = mLruProcesses.get(i); 1407 if (r.thread != null) { 1408 try { 1409 r.thread.clearDnsCache(); 1410 } catch (RemoteException ex) { 1411 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1412 } 1413 } 1414 } 1415 } 1416 } break; 1417 case UPDATE_HTTP_PROXY_MSG: { 1418 ProxyInfo proxy = (ProxyInfo)msg.obj; 1419 String host = ""; 1420 String port = ""; 1421 String exclList = ""; 1422 Uri pacFileUrl = Uri.EMPTY; 1423 if (proxy != null) { 1424 host = proxy.getHost(); 1425 port = Integer.toString(proxy.getPort()); 1426 exclList = proxy.getExclusionListAsString(); 1427 pacFileUrl = proxy.getPacFileUrl(); 1428 } 1429 synchronized (ActivityManagerService.this) { 1430 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1431 ProcessRecord r = mLruProcesses.get(i); 1432 if (r.thread != null) { 1433 try { 1434 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1435 } catch (RemoteException ex) { 1436 Slog.w(TAG, "Failed to update http proxy for: " + 1437 r.info.processName); 1438 } 1439 } 1440 } 1441 } 1442 } break; 1443 case SHOW_UID_ERROR_MSG: { 1444 String title = "System UIDs Inconsistent"; 1445 String text = "UIDs on the system are inconsistent, you need to wipe your" 1446 + " data partition or your device will be unstable."; 1447 Log.e(TAG, title + ": " + text); 1448 if (mShowDialogs) { 1449 // XXX This is a temporary dialog, no need to localize. 1450 AlertDialog d = new BaseErrorDialog(mContext); 1451 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1452 d.setCancelable(false); 1453 d.setTitle(title); 1454 d.setMessage(text); 1455 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1456 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1457 mUidAlert = d; 1458 d.show(); 1459 } 1460 } break; 1461 case IM_FEELING_LUCKY_MSG: { 1462 if (mUidAlert != null) { 1463 mUidAlert.dismiss(); 1464 mUidAlert = null; 1465 } 1466 } break; 1467 case PROC_START_TIMEOUT_MSG: { 1468 if (mDidDexOpt) { 1469 mDidDexOpt = false; 1470 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1471 nmsg.obj = msg.obj; 1472 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1473 return; 1474 } 1475 ProcessRecord app = (ProcessRecord)msg.obj; 1476 synchronized (ActivityManagerService.this) { 1477 processStartTimedOutLocked(app); 1478 } 1479 } break; 1480 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1481 synchronized (ActivityManagerService.this) { 1482 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1483 } 1484 } break; 1485 case KILL_APPLICATION_MSG: { 1486 synchronized (ActivityManagerService.this) { 1487 int appid = msg.arg1; 1488 boolean restart = (msg.arg2 == 1); 1489 Bundle bundle = (Bundle)msg.obj; 1490 String pkg = bundle.getString("pkg"); 1491 String reason = bundle.getString("reason"); 1492 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1493 false, UserHandle.USER_ALL, reason); 1494 } 1495 } break; 1496 case FINALIZE_PENDING_INTENT_MSG: { 1497 ((PendingIntentRecord)msg.obj).completeFinalize(); 1498 } break; 1499 case POST_HEAVY_NOTIFICATION_MSG: { 1500 INotificationManager inm = NotificationManager.getService(); 1501 if (inm == null) { 1502 return; 1503 } 1504 1505 ActivityRecord root = (ActivityRecord)msg.obj; 1506 ProcessRecord process = root.app; 1507 if (process == null) { 1508 return; 1509 } 1510 1511 try { 1512 Context context = mContext.createPackageContext(process.info.packageName, 0); 1513 String text = mContext.getString(R.string.heavy_weight_notification, 1514 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1515 Notification notification = new Notification(); 1516 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1517 notification.when = 0; 1518 notification.flags = Notification.FLAG_ONGOING_EVENT; 1519 notification.tickerText = text; 1520 notification.defaults = 0; // please be quiet 1521 notification.sound = null; 1522 notification.vibrate = null; 1523 notification.color = mContext.getResources().getColor( 1524 com.android.internal.R.color.system_notification_accent_color); 1525 notification.setLatestEventInfo(context, text, 1526 mContext.getText(R.string.heavy_weight_notification_detail), 1527 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1528 PendingIntent.FLAG_CANCEL_CURRENT, null, 1529 new UserHandle(root.userId))); 1530 1531 try { 1532 int[] outId = new int[1]; 1533 inm.enqueueNotificationWithTag("android", "android", null, 1534 R.string.heavy_weight_notification, 1535 notification, outId, root.userId); 1536 } catch (RuntimeException e) { 1537 Slog.w(ActivityManagerService.TAG, 1538 "Error showing notification for heavy-weight app", e); 1539 } catch (RemoteException e) { 1540 } 1541 } catch (NameNotFoundException e) { 1542 Slog.w(TAG, "Unable to create context for heavy notification", e); 1543 } 1544 } break; 1545 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1546 INotificationManager inm = NotificationManager.getService(); 1547 if (inm == null) { 1548 return; 1549 } 1550 try { 1551 inm.cancelNotificationWithTag("android", null, 1552 R.string.heavy_weight_notification, msg.arg1); 1553 } catch (RuntimeException e) { 1554 Slog.w(ActivityManagerService.TAG, 1555 "Error canceling notification for service", e); 1556 } catch (RemoteException e) { 1557 } 1558 } break; 1559 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1560 synchronized (ActivityManagerService.this) { 1561 checkExcessivePowerUsageLocked(true); 1562 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1563 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1564 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1565 } 1566 } break; 1567 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1568 synchronized (ActivityManagerService.this) { 1569 ActivityRecord ar = (ActivityRecord)msg.obj; 1570 if (mCompatModeDialog != null) { 1571 if (mCompatModeDialog.mAppInfo.packageName.equals( 1572 ar.info.applicationInfo.packageName)) { 1573 return; 1574 } 1575 mCompatModeDialog.dismiss(); 1576 mCompatModeDialog = null; 1577 } 1578 if (ar != null && false) { 1579 if (mCompatModePackages.getPackageAskCompatModeLocked( 1580 ar.packageName)) { 1581 int mode = mCompatModePackages.computeCompatModeLocked( 1582 ar.info.applicationInfo); 1583 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1584 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1585 mCompatModeDialog = new CompatModeDialog( 1586 ActivityManagerService.this, mContext, 1587 ar.info.applicationInfo); 1588 mCompatModeDialog.show(); 1589 } 1590 } 1591 } 1592 } 1593 break; 1594 } 1595 case DISPATCH_PROCESSES_CHANGED: { 1596 dispatchProcessesChanged(); 1597 break; 1598 } 1599 case DISPATCH_PROCESS_DIED: { 1600 final int pid = msg.arg1; 1601 final int uid = msg.arg2; 1602 dispatchProcessDied(pid, uid); 1603 break; 1604 } 1605 case REPORT_MEM_USAGE_MSG: { 1606 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1607 Thread thread = new Thread() { 1608 @Override public void run() { 1609 reportMemUsage(memInfos); 1610 } 1611 }; 1612 thread.start(); 1613 break; 1614 } 1615 case START_USER_SWITCH_MSG: { 1616 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1617 break; 1618 } 1619 case REPORT_USER_SWITCH_MSG: { 1620 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1621 break; 1622 } 1623 case CONTINUE_USER_SWITCH_MSG: { 1624 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1625 break; 1626 } 1627 case USER_SWITCH_TIMEOUT_MSG: { 1628 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1629 break; 1630 } 1631 case IMMERSIVE_MODE_LOCK_MSG: { 1632 final boolean nextState = (msg.arg1 != 0); 1633 if (mUpdateLock.isHeld() != nextState) { 1634 if (DEBUG_IMMERSIVE) { 1635 final ActivityRecord r = (ActivityRecord) msg.obj; 1636 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1637 } 1638 if (nextState) { 1639 mUpdateLock.acquire(); 1640 } else { 1641 mUpdateLock.release(); 1642 } 1643 } 1644 break; 1645 } 1646 case PERSIST_URI_GRANTS_MSG: { 1647 writeGrantedUriPermissions(); 1648 break; 1649 } 1650 case REQUEST_ALL_PSS_MSG: { 1651 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1652 break; 1653 } 1654 case START_PROFILES_MSG: { 1655 synchronized (ActivityManagerService.this) { 1656 startProfilesLocked(); 1657 } 1658 break; 1659 } 1660 case UPDATE_TIME: { 1661 synchronized (ActivityManagerService.this) { 1662 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1663 ProcessRecord r = mLruProcesses.get(i); 1664 if (r.thread != null) { 1665 try { 1666 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1667 } catch (RemoteException ex) { 1668 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1669 } 1670 } 1671 } 1672 } 1673 break; 1674 } 1675 case SYSTEM_USER_START_MSG: { 1676 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1677 Integer.toString(msg.arg1), msg.arg1); 1678 mSystemServiceManager.startUser(msg.arg1); 1679 break; 1680 } 1681 case SYSTEM_USER_CURRENT_MSG: { 1682 mBatteryStatsService.noteEvent( 1683 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1684 Integer.toString(msg.arg2), msg.arg2); 1685 mBatteryStatsService.noteEvent( 1686 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1687 Integer.toString(msg.arg1), msg.arg1); 1688 mSystemServiceManager.switchUser(msg.arg1); 1689 mLockToAppRequest.clearPrompt(); 1690 break; 1691 } 1692 case ENTER_ANIMATION_COMPLETE_MSG: { 1693 synchronized (ActivityManagerService.this) { 1694 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1695 if (r != null && r.app != null && r.app.thread != null) { 1696 try { 1697 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1698 } catch (RemoteException e) { 1699 } 1700 } 1701 } 1702 break; 1703 } 1704 case FINISH_BOOTING_MSG: { 1705 if (msg.arg1 != 0) { 1706 finishBooting(); 1707 } 1708 if (msg.arg2 != 0) { 1709 enableScreenAfterBoot(); 1710 } 1711 break; 1712 } 1713 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1714 try { 1715 Locale l = (Locale) msg.obj; 1716 IBinder service = ServiceManager.getService("mount"); 1717 IMountService mountService = IMountService.Stub.asInterface(service); 1718 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1719 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1720 } catch (RemoteException e) { 1721 Log.e(TAG, "Error storing locale for decryption UI", e); 1722 } 1723 break; 1724 } 1725 } 1726 } 1727 }; 1728 1729 static final int COLLECT_PSS_BG_MSG = 1; 1730 1731 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1732 @Override 1733 public void handleMessage(Message msg) { 1734 switch (msg.what) { 1735 case COLLECT_PSS_BG_MSG: { 1736 long start = SystemClock.uptimeMillis(); 1737 MemInfoReader memInfo = null; 1738 synchronized (ActivityManagerService.this) { 1739 if (mFullPssPending) { 1740 mFullPssPending = false; 1741 memInfo = new MemInfoReader(); 1742 } 1743 } 1744 if (memInfo != null) { 1745 updateCpuStatsNow(); 1746 long nativeTotalPss = 0; 1747 synchronized (mProcessCpuTracker) { 1748 final int N = mProcessCpuTracker.countStats(); 1749 for (int j=0; j<N; j++) { 1750 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1751 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1752 // This is definitely an application process; skip it. 1753 continue; 1754 } 1755 synchronized (mPidsSelfLocked) { 1756 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1757 // This is one of our own processes; skip it. 1758 continue; 1759 } 1760 } 1761 nativeTotalPss += Debug.getPss(st.pid, null); 1762 } 1763 } 1764 memInfo.readMemInfo(); 1765 synchronized (ActivityManagerService.this) { 1766 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1767 + (SystemClock.uptimeMillis()-start) + "ms"); 1768 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1769 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1770 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1771 } 1772 } 1773 1774 int i=0, num=0; 1775 long[] tmp = new long[1]; 1776 do { 1777 ProcessRecord proc; 1778 int procState; 1779 int pid; 1780 synchronized (ActivityManagerService.this) { 1781 if (i >= mPendingPssProcesses.size()) { 1782 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1783 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1784 mPendingPssProcesses.clear(); 1785 return; 1786 } 1787 proc = mPendingPssProcesses.get(i); 1788 procState = proc.pssProcState; 1789 if (proc.thread != null && procState == proc.setProcState) { 1790 pid = proc.pid; 1791 } else { 1792 proc = null; 1793 pid = 0; 1794 } 1795 i++; 1796 } 1797 if (proc != null) { 1798 long pss = Debug.getPss(pid, tmp); 1799 synchronized (ActivityManagerService.this) { 1800 if (proc.thread != null && proc.setProcState == procState 1801 && proc.pid == pid) { 1802 num++; 1803 proc.lastPssTime = SystemClock.uptimeMillis(); 1804 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1805 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1806 + ": " + pss + " lastPss=" + proc.lastPss 1807 + " state=" + ProcessList.makeProcStateString(procState)); 1808 if (proc.initialIdlePss == 0) { 1809 proc.initialIdlePss = pss; 1810 } 1811 proc.lastPss = pss; 1812 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1813 proc.lastCachedPss = pss; 1814 } 1815 } 1816 } 1817 } 1818 } while (true); 1819 } 1820 } 1821 } 1822 }; 1823 1824 /** 1825 * Monitor for package changes and update our internal state. 1826 */ 1827 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1828 @Override 1829 public void onPackageRemoved(String packageName, int uid) { 1830 // Remove all tasks with activities in the specified package from the list of recent tasks 1831 final int eventUserId = getChangingUserId(); 1832 synchronized (ActivityManagerService.this) { 1833 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1834 TaskRecord tr = mRecentTasks.get(i); 1835 if (tr.userId != eventUserId) continue; 1836 1837 ComponentName cn = tr.intent.getComponent(); 1838 if (cn != null && cn.getPackageName().equals(packageName)) { 1839 // If the package name matches, remove the task 1840 removeTaskByIdLocked(tr.taskId, true); 1841 } 1842 } 1843 } 1844 } 1845 1846 @Override 1847 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1848 onPackageModified(packageName); 1849 return true; 1850 } 1851 1852 @Override 1853 public void onPackageModified(String packageName) { 1854 final int eventUserId = getChangingUserId(); 1855 final IPackageManager pm = AppGlobals.getPackageManager(); 1856 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1857 new ArrayList<Pair<Intent, Integer>>(); 1858 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 1859 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1860 // Copy the list of recent tasks so that we don't hold onto the lock on 1861 // ActivityManagerService for long periods while checking if components exist. 1862 synchronized (ActivityManagerService.this) { 1863 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1864 TaskRecord tr = mRecentTasks.get(i); 1865 if (tr.userId != eventUserId) continue; 1866 1867 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1868 } 1869 } 1870 // Check the recent tasks and filter out all tasks with components that no longer exist. 1871 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1872 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1873 ComponentName cn = p.first.getComponent(); 1874 if (cn != null && cn.getPackageName().equals(packageName)) { 1875 if (componentsKnownToExist.contains(cn)) { 1876 // If we know that the component still exists in the package, then skip 1877 continue; 1878 } 1879 try { 1880 ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId); 1881 if (info != null) { 1882 componentsKnownToExist.add(cn); 1883 } else { 1884 tasksToRemove.add(p.second); 1885 } 1886 } catch (RemoteException e) { 1887 Log.e(TAG, "Failed to query activity info for component: " + cn, e); 1888 } 1889 } 1890 } 1891 // Prune all the tasks with removed components from the list of recent tasks 1892 synchronized (ActivityManagerService.this) { 1893 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1894 removeTaskByIdLocked(tasksToRemove.get(i), false); 1895 } 1896 } 1897 } 1898 1899 @Override 1900 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1901 // Force stop the specified packages 1902 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 1903 if (packages != null) { 1904 for (String pkg : packages) { 1905 synchronized (ActivityManagerService.this) { 1906 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 1907 userId, "finished booting")) { 1908 return true; 1909 } 1910 } 1911 } 1912 } 1913 return false; 1914 } 1915 }; 1916 1917 public void setSystemProcess() { 1918 try { 1919 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1920 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1921 ServiceManager.addService("meminfo", new MemBinder(this)); 1922 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1923 ServiceManager.addService("dbinfo", new DbBinder(this)); 1924 if (MONITOR_CPU_USAGE) { 1925 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1926 } 1927 ServiceManager.addService("permission", new PermissionController(this)); 1928 1929 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1930 "android", STOCK_PM_FLAGS); 1931 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1932 1933 synchronized (this) { 1934 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1935 app.persistent = true; 1936 app.pid = MY_PID; 1937 app.maxAdj = ProcessList.SYSTEM_ADJ; 1938 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1939 mProcessNames.put(app.processName, app.uid, app); 1940 synchronized (mPidsSelfLocked) { 1941 mPidsSelfLocked.put(app.pid, app); 1942 } 1943 updateLruProcessLocked(app, false, null); 1944 updateOomAdjLocked(); 1945 } 1946 } catch (PackageManager.NameNotFoundException e) { 1947 throw new RuntimeException( 1948 "Unable to find android system package", e); 1949 } 1950 } 1951 1952 public void setWindowManager(WindowManagerService wm) { 1953 mWindowManager = wm; 1954 mStackSupervisor.setWindowManager(wm); 1955 } 1956 1957 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1958 mUsageStatsService = usageStatsManager; 1959 } 1960 1961 public void startObservingNativeCrashes() { 1962 final NativeCrashListener ncl = new NativeCrashListener(this); 1963 ncl.start(); 1964 } 1965 1966 public IAppOpsService getAppOpsService() { 1967 return mAppOpsService; 1968 } 1969 1970 static class MemBinder extends Binder { 1971 ActivityManagerService mActivityManagerService; 1972 MemBinder(ActivityManagerService activityManagerService) { 1973 mActivityManagerService = activityManagerService; 1974 } 1975 1976 @Override 1977 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1978 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1979 != PackageManager.PERMISSION_GRANTED) { 1980 pw.println("Permission Denial: can't dump meminfo from from pid=" 1981 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1982 + " without permission " + android.Manifest.permission.DUMP); 1983 return; 1984 } 1985 1986 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1987 } 1988 } 1989 1990 static class GraphicsBinder extends Binder { 1991 ActivityManagerService mActivityManagerService; 1992 GraphicsBinder(ActivityManagerService activityManagerService) { 1993 mActivityManagerService = activityManagerService; 1994 } 1995 1996 @Override 1997 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1998 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1999 != PackageManager.PERMISSION_GRANTED) { 2000 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2001 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2002 + " without permission " + android.Manifest.permission.DUMP); 2003 return; 2004 } 2005 2006 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2007 } 2008 } 2009 2010 static class DbBinder extends Binder { 2011 ActivityManagerService mActivityManagerService; 2012 DbBinder(ActivityManagerService activityManagerService) { 2013 mActivityManagerService = activityManagerService; 2014 } 2015 2016 @Override 2017 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2018 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2019 != PackageManager.PERMISSION_GRANTED) { 2020 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2021 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2022 + " without permission " + android.Manifest.permission.DUMP); 2023 return; 2024 } 2025 2026 mActivityManagerService.dumpDbInfo(fd, pw, args); 2027 } 2028 } 2029 2030 static class CpuBinder extends Binder { 2031 ActivityManagerService mActivityManagerService; 2032 CpuBinder(ActivityManagerService activityManagerService) { 2033 mActivityManagerService = activityManagerService; 2034 } 2035 2036 @Override 2037 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2038 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2039 != PackageManager.PERMISSION_GRANTED) { 2040 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2041 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2042 + " without permission " + android.Manifest.permission.DUMP); 2043 return; 2044 } 2045 2046 synchronized (mActivityManagerService.mProcessCpuTracker) { 2047 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2048 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2049 SystemClock.uptimeMillis())); 2050 } 2051 } 2052 } 2053 2054 public static final class Lifecycle extends SystemService { 2055 private final ActivityManagerService mService; 2056 2057 public Lifecycle(Context context) { 2058 super(context); 2059 mService = new ActivityManagerService(context); 2060 } 2061 2062 @Override 2063 public void onStart() { 2064 mService.start(); 2065 } 2066 2067 public ActivityManagerService getService() { 2068 return mService; 2069 } 2070 } 2071 2072 // Note: This method is invoked on the main thread but may need to attach various 2073 // handlers to other threads. So take care to be explicit about the looper. 2074 public ActivityManagerService(Context systemContext) { 2075 mContext = systemContext; 2076 mFactoryTest = FactoryTest.getMode(); 2077 mSystemThread = ActivityThread.currentActivityThread(); 2078 2079 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2080 2081 mHandlerThread = new ServiceThread(TAG, 2082 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2083 mHandlerThread.start(); 2084 mHandler = new MainHandler(mHandlerThread.getLooper()); 2085 2086 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2087 "foreground", BROADCAST_FG_TIMEOUT, false); 2088 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2089 "background", BROADCAST_BG_TIMEOUT, true); 2090 mBroadcastQueues[0] = mFgBroadcastQueue; 2091 mBroadcastQueues[1] = mBgBroadcastQueue; 2092 2093 mServices = new ActiveServices(this); 2094 mProviderMap = new ProviderMap(this); 2095 2096 // TODO: Move creation of battery stats service outside of activity manager service. 2097 File dataDir = Environment.getDataDirectory(); 2098 File systemDir = new File(dataDir, "system"); 2099 systemDir.mkdirs(); 2100 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2101 mBatteryStatsService.getActiveStatistics().readLocked(); 2102 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2103 mOnBattery = DEBUG_POWER ? true 2104 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2105 mBatteryStatsService.getActiveStatistics().setCallback(this); 2106 2107 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2108 2109 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2110 2111 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2112 2113 // User 0 is the first and only user that runs at boot. 2114 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2115 mUserLru.add(Integer.valueOf(0)); 2116 updateStartedUserArrayLocked(); 2117 2118 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2119 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2120 2121 mConfiguration.setToDefaults(); 2122 mConfiguration.setLocale(Locale.getDefault()); 2123 2124 mConfigurationSeq = mConfiguration.seq = 1; 2125 mProcessCpuTracker.init(); 2126 2127 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2128 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2129 mStackSupervisor = new ActivityStackSupervisor(this); 2130 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2131 2132 mProcessCpuThread = new Thread("CpuTracker") { 2133 @Override 2134 public void run() { 2135 while (true) { 2136 try { 2137 try { 2138 synchronized(this) { 2139 final long now = SystemClock.uptimeMillis(); 2140 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2141 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2142 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2143 // + ", write delay=" + nextWriteDelay); 2144 if (nextWriteDelay < nextCpuDelay) { 2145 nextCpuDelay = nextWriteDelay; 2146 } 2147 if (nextCpuDelay > 0) { 2148 mProcessCpuMutexFree.set(true); 2149 this.wait(nextCpuDelay); 2150 } 2151 } 2152 } catch (InterruptedException e) { 2153 } 2154 updateCpuStatsNow(); 2155 } catch (Exception e) { 2156 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2157 } 2158 } 2159 } 2160 }; 2161 2162 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2163 2164 Watchdog.getInstance().addMonitor(this); 2165 Watchdog.getInstance().addThread(mHandler); 2166 } 2167 2168 public void setSystemServiceManager(SystemServiceManager mgr) { 2169 mSystemServiceManager = mgr; 2170 } 2171 2172 private void start() { 2173 Process.removeAllProcessGroups(); 2174 mProcessCpuThread.start(); 2175 2176 mBatteryStatsService.publish(mContext); 2177 mAppOpsService.publish(mContext); 2178 Slog.d("AppOps", "AppOpsService published"); 2179 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2180 } 2181 2182 public void initPowerManagement() { 2183 mStackSupervisor.initPowerManagement(); 2184 mBatteryStatsService.initPowerManagement(); 2185 } 2186 2187 @Override 2188 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2189 throws RemoteException { 2190 if (code == SYSPROPS_TRANSACTION) { 2191 // We need to tell all apps about the system property change. 2192 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2193 synchronized(this) { 2194 final int NP = mProcessNames.getMap().size(); 2195 for (int ip=0; ip<NP; ip++) { 2196 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2197 final int NA = apps.size(); 2198 for (int ia=0; ia<NA; ia++) { 2199 ProcessRecord app = apps.valueAt(ia); 2200 if (app.thread != null) { 2201 procs.add(app.thread.asBinder()); 2202 } 2203 } 2204 } 2205 } 2206 2207 int N = procs.size(); 2208 for (int i=0; i<N; i++) { 2209 Parcel data2 = Parcel.obtain(); 2210 try { 2211 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2212 } catch (RemoteException e) { 2213 } 2214 data2.recycle(); 2215 } 2216 } 2217 try { 2218 return super.onTransact(code, data, reply, flags); 2219 } catch (RuntimeException e) { 2220 // The activity manager only throws security exceptions, so let's 2221 // log all others. 2222 if (!(e instanceof SecurityException)) { 2223 Slog.wtf(TAG, "Activity Manager Crash", e); 2224 } 2225 throw e; 2226 } 2227 } 2228 2229 void updateCpuStats() { 2230 final long now = SystemClock.uptimeMillis(); 2231 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2232 return; 2233 } 2234 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2235 synchronized (mProcessCpuThread) { 2236 mProcessCpuThread.notify(); 2237 } 2238 } 2239 } 2240 2241 void updateCpuStatsNow() { 2242 synchronized (mProcessCpuTracker) { 2243 mProcessCpuMutexFree.set(false); 2244 final long now = SystemClock.uptimeMillis(); 2245 boolean haveNewCpuStats = false; 2246 2247 if (MONITOR_CPU_USAGE && 2248 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2249 mLastCpuTime.set(now); 2250 haveNewCpuStats = true; 2251 mProcessCpuTracker.update(); 2252 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2253 //Slog.i(TAG, "Total CPU usage: " 2254 // + mProcessCpu.getTotalCpuPercent() + "%"); 2255 2256 // Slog the cpu usage if the property is set. 2257 if ("true".equals(SystemProperties.get("events.cpu"))) { 2258 int user = mProcessCpuTracker.getLastUserTime(); 2259 int system = mProcessCpuTracker.getLastSystemTime(); 2260 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2261 int irq = mProcessCpuTracker.getLastIrqTime(); 2262 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2263 int idle = mProcessCpuTracker.getLastIdleTime(); 2264 2265 int total = user + system + iowait + irq + softIrq + idle; 2266 if (total == 0) total = 1; 2267 2268 EventLog.writeEvent(EventLogTags.CPU, 2269 ((user+system+iowait+irq+softIrq) * 100) / total, 2270 (user * 100) / total, 2271 (system * 100) / total, 2272 (iowait * 100) / total, 2273 (irq * 100) / total, 2274 (softIrq * 100) / total); 2275 } 2276 } 2277 2278 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2279 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2280 synchronized(bstats) { 2281 synchronized(mPidsSelfLocked) { 2282 if (haveNewCpuStats) { 2283 if (mOnBattery) { 2284 int perc = bstats.startAddingCpuLocked(); 2285 int totalUTime = 0; 2286 int totalSTime = 0; 2287 final int N = mProcessCpuTracker.countStats(); 2288 for (int i=0; i<N; i++) { 2289 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2290 if (!st.working) { 2291 continue; 2292 } 2293 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2294 int otherUTime = (st.rel_utime*perc)/100; 2295 int otherSTime = (st.rel_stime*perc)/100; 2296 totalUTime += otherUTime; 2297 totalSTime += otherSTime; 2298 if (pr != null) { 2299 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2300 if (ps == null || !ps.isActive()) { 2301 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2302 pr.info.uid, pr.processName); 2303 } 2304 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2305 st.rel_stime-otherSTime); 2306 ps.addSpeedStepTimes(cpuSpeedTimes); 2307 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2308 } else { 2309 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2310 if (ps == null || !ps.isActive()) { 2311 st.batteryStats = ps = bstats.getProcessStatsLocked( 2312 bstats.mapUid(st.uid), st.name); 2313 } 2314 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2315 st.rel_stime-otherSTime); 2316 ps.addSpeedStepTimes(cpuSpeedTimes); 2317 } 2318 } 2319 bstats.finishAddingCpuLocked(perc, totalUTime, 2320 totalSTime, cpuSpeedTimes); 2321 } 2322 } 2323 } 2324 2325 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2326 mLastWriteTime = now; 2327 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2328 } 2329 } 2330 } 2331 } 2332 2333 @Override 2334 public void batteryNeedsCpuUpdate() { 2335 updateCpuStatsNow(); 2336 } 2337 2338 @Override 2339 public void batteryPowerChanged(boolean onBattery) { 2340 // When plugging in, update the CPU stats first before changing 2341 // the plug state. 2342 updateCpuStatsNow(); 2343 synchronized (this) { 2344 synchronized(mPidsSelfLocked) { 2345 mOnBattery = DEBUG_POWER ? true : onBattery; 2346 } 2347 } 2348 } 2349 2350 /** 2351 * Initialize the application bind args. These are passed to each 2352 * process when the bindApplication() IPC is sent to the process. They're 2353 * lazily setup to make sure the services are running when they're asked for. 2354 */ 2355 private HashMap<String, IBinder> getCommonServicesLocked() { 2356 if (mAppBindArgs == null) { 2357 mAppBindArgs = new HashMap<String, IBinder>(); 2358 2359 // Setup the application init args 2360 mAppBindArgs.put("package", ServiceManager.getService("package")); 2361 mAppBindArgs.put("window", ServiceManager.getService("window")); 2362 mAppBindArgs.put(Context.ALARM_SERVICE, 2363 ServiceManager.getService(Context.ALARM_SERVICE)); 2364 } 2365 return mAppBindArgs; 2366 } 2367 2368 final void setFocusedActivityLocked(ActivityRecord r) { 2369 if (mFocusedActivity != r) { 2370 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2371 mFocusedActivity = r; 2372 if (r.task != null && r.task.voiceInteractor != null) { 2373 startRunningVoiceLocked(); 2374 } else { 2375 finishRunningVoiceLocked(); 2376 } 2377 mStackSupervisor.setFocusedStack(r); 2378 if (r != null) { 2379 mWindowManager.setFocusedApp(r.appToken, true); 2380 } 2381 applyUpdateLockStateLocked(r); 2382 } 2383 } 2384 2385 final void clearFocusedActivity(ActivityRecord r) { 2386 if (mFocusedActivity == r) { 2387 mFocusedActivity = null; 2388 } 2389 } 2390 2391 @Override 2392 public void setFocusedStack(int stackId) { 2393 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2394 synchronized (ActivityManagerService.this) { 2395 ActivityStack stack = mStackSupervisor.getStack(stackId); 2396 if (stack != null) { 2397 ActivityRecord r = stack.topRunningActivityLocked(null); 2398 if (r != null) { 2399 setFocusedActivityLocked(r); 2400 } 2401 } 2402 } 2403 } 2404 2405 @Override 2406 public void notifyActivityDrawn(IBinder token) { 2407 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2408 synchronized (this) { 2409 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2410 if (r != null) { 2411 r.task.stack.notifyActivityDrawnLocked(r); 2412 } 2413 } 2414 } 2415 2416 final void applyUpdateLockStateLocked(ActivityRecord r) { 2417 // Modifications to the UpdateLock state are done on our handler, outside 2418 // the activity manager's locks. The new state is determined based on the 2419 // state *now* of the relevant activity record. The object is passed to 2420 // the handler solely for logging detail, not to be consulted/modified. 2421 final boolean nextState = r != null && r.immersive; 2422 mHandler.sendMessage( 2423 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2424 } 2425 2426 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2427 Message msg = Message.obtain(); 2428 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2429 msg.obj = r.task.askedCompatMode ? null : r; 2430 mHandler.sendMessage(msg); 2431 } 2432 2433 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2434 String what, Object obj, ProcessRecord srcApp) { 2435 app.lastActivityTime = now; 2436 2437 if (app.activities.size() > 0) { 2438 // Don't want to touch dependent processes that are hosting activities. 2439 return index; 2440 } 2441 2442 int lrui = mLruProcesses.lastIndexOf(app); 2443 if (lrui < 0) { 2444 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2445 + what + " " + obj + " from " + srcApp); 2446 return index; 2447 } 2448 2449 if (lrui >= index) { 2450 // Don't want to cause this to move dependent processes *back* in the 2451 // list as if they were less frequently used. 2452 return index; 2453 } 2454 2455 if (lrui >= mLruProcessActivityStart) { 2456 // Don't want to touch dependent processes that are hosting activities. 2457 return index; 2458 } 2459 2460 mLruProcesses.remove(lrui); 2461 if (index > 0) { 2462 index--; 2463 } 2464 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2465 + " in LRU list: " + app); 2466 mLruProcesses.add(index, app); 2467 return index; 2468 } 2469 2470 final void removeLruProcessLocked(ProcessRecord app) { 2471 int lrui = mLruProcesses.lastIndexOf(app); 2472 if (lrui >= 0) { 2473 if (!app.killed) { 2474 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2475 Process.killProcessQuiet(app.pid); 2476 Process.killProcessGroup(app.info.uid, app.pid); 2477 } 2478 if (lrui <= mLruProcessActivityStart) { 2479 mLruProcessActivityStart--; 2480 } 2481 if (lrui <= mLruProcessServiceStart) { 2482 mLruProcessServiceStart--; 2483 } 2484 mLruProcesses.remove(lrui); 2485 } 2486 } 2487 2488 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2489 ProcessRecord client) { 2490 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2491 || app.treatLikeActivity; 2492 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2493 if (!activityChange && hasActivity) { 2494 // The process has activities, so we are only allowing activity-based adjustments 2495 // to move it. It should be kept in the front of the list with other 2496 // processes that have activities, and we don't want those to change their 2497 // order except due to activity operations. 2498 return; 2499 } 2500 2501 mLruSeq++; 2502 final long now = SystemClock.uptimeMillis(); 2503 app.lastActivityTime = now; 2504 2505 // First a quick reject: if the app is already at the position we will 2506 // put it, then there is nothing to do. 2507 if (hasActivity) { 2508 final int N = mLruProcesses.size(); 2509 if (N > 0 && mLruProcesses.get(N-1) == app) { 2510 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2511 return; 2512 } 2513 } else { 2514 if (mLruProcessServiceStart > 0 2515 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2516 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2517 return; 2518 } 2519 } 2520 2521 int lrui = mLruProcesses.lastIndexOf(app); 2522 2523 if (app.persistent && lrui >= 0) { 2524 // We don't care about the position of persistent processes, as long as 2525 // they are in the list. 2526 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2527 return; 2528 } 2529 2530 /* In progress: compute new position first, so we can avoid doing work 2531 if the process is not actually going to move. Not yet working. 2532 int addIndex; 2533 int nextIndex; 2534 boolean inActivity = false, inService = false; 2535 if (hasActivity) { 2536 // Process has activities, put it at the very tipsy-top. 2537 addIndex = mLruProcesses.size(); 2538 nextIndex = mLruProcessServiceStart; 2539 inActivity = true; 2540 } else if (hasService) { 2541 // Process has services, put it at the top of the service list. 2542 addIndex = mLruProcessActivityStart; 2543 nextIndex = mLruProcessServiceStart; 2544 inActivity = true; 2545 inService = true; 2546 } else { 2547 // Process not otherwise of interest, it goes to the top of the non-service area. 2548 addIndex = mLruProcessServiceStart; 2549 if (client != null) { 2550 int clientIndex = mLruProcesses.lastIndexOf(client); 2551 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2552 + app); 2553 if (clientIndex >= 0 && addIndex > clientIndex) { 2554 addIndex = clientIndex; 2555 } 2556 } 2557 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2558 } 2559 2560 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2561 + mLruProcessActivityStart + "): " + app); 2562 */ 2563 2564 if (lrui >= 0) { 2565 if (lrui < mLruProcessActivityStart) { 2566 mLruProcessActivityStart--; 2567 } 2568 if (lrui < mLruProcessServiceStart) { 2569 mLruProcessServiceStart--; 2570 } 2571 /* 2572 if (addIndex > lrui) { 2573 addIndex--; 2574 } 2575 if (nextIndex > lrui) { 2576 nextIndex--; 2577 } 2578 */ 2579 mLruProcesses.remove(lrui); 2580 } 2581 2582 /* 2583 mLruProcesses.add(addIndex, app); 2584 if (inActivity) { 2585 mLruProcessActivityStart++; 2586 } 2587 if (inService) { 2588 mLruProcessActivityStart++; 2589 } 2590 */ 2591 2592 int nextIndex; 2593 if (hasActivity) { 2594 final int N = mLruProcesses.size(); 2595 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2596 // Process doesn't have activities, but has clients with 2597 // activities... move it up, but one below the top (the top 2598 // should always have a real activity). 2599 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2600 mLruProcesses.add(N-1, app); 2601 // To keep it from spamming the LRU list (by making a bunch of clients), 2602 // we will push down any other entries owned by the app. 2603 final int uid = app.info.uid; 2604 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2605 ProcessRecord subProc = mLruProcesses.get(i); 2606 if (subProc.info.uid == uid) { 2607 // We want to push this one down the list. If the process after 2608 // it is for the same uid, however, don't do so, because we don't 2609 // want them internally to be re-ordered. 2610 if (mLruProcesses.get(i-1).info.uid != uid) { 2611 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2612 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2613 ProcessRecord tmp = mLruProcesses.get(i); 2614 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2615 mLruProcesses.set(i-1, tmp); 2616 i--; 2617 } 2618 } else { 2619 // A gap, we can stop here. 2620 break; 2621 } 2622 } 2623 } else { 2624 // Process has activities, put it at the very tipsy-top. 2625 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2626 mLruProcesses.add(app); 2627 } 2628 nextIndex = mLruProcessServiceStart; 2629 } else if (hasService) { 2630 // Process has services, put it at the top of the service list. 2631 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2632 mLruProcesses.add(mLruProcessActivityStart, app); 2633 nextIndex = mLruProcessServiceStart; 2634 mLruProcessActivityStart++; 2635 } else { 2636 // Process not otherwise of interest, it goes to the top of the non-service area. 2637 int index = mLruProcessServiceStart; 2638 if (client != null) { 2639 // If there is a client, don't allow the process to be moved up higher 2640 // in the list than that client. 2641 int clientIndex = mLruProcesses.lastIndexOf(client); 2642 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2643 + " when updating " + app); 2644 if (clientIndex <= lrui) { 2645 // Don't allow the client index restriction to push it down farther in the 2646 // list than it already is. 2647 clientIndex = lrui; 2648 } 2649 if (clientIndex >= 0 && index > clientIndex) { 2650 index = clientIndex; 2651 } 2652 } 2653 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2654 mLruProcesses.add(index, app); 2655 nextIndex = index-1; 2656 mLruProcessActivityStart++; 2657 mLruProcessServiceStart++; 2658 } 2659 2660 // If the app is currently using a content provider or service, 2661 // bump those processes as well. 2662 for (int j=app.connections.size()-1; j>=0; j--) { 2663 ConnectionRecord cr = app.connections.valueAt(j); 2664 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2665 && cr.binding.service.app != null 2666 && cr.binding.service.app.lruSeq != mLruSeq 2667 && !cr.binding.service.app.persistent) { 2668 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2669 "service connection", cr, app); 2670 } 2671 } 2672 for (int j=app.conProviders.size()-1; j>=0; j--) { 2673 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2674 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2675 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2676 "provider reference", cpr, app); 2677 } 2678 } 2679 } 2680 2681 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2682 if (uid == Process.SYSTEM_UID) { 2683 // The system gets to run in any process. If there are multiple 2684 // processes with the same uid, just pick the first (this 2685 // should never happen). 2686 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2687 if (procs == null) return null; 2688 final int N = procs.size(); 2689 for (int i = 0; i < N; i++) { 2690 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2691 } 2692 } 2693 ProcessRecord proc = mProcessNames.get(processName, uid); 2694 if (false && proc != null && !keepIfLarge 2695 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2696 && proc.lastCachedPss >= 4000) { 2697 // Turn this condition on to cause killing to happen regularly, for testing. 2698 if (proc.baseProcessTracker != null) { 2699 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2700 } 2701 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2702 } else if (proc != null && !keepIfLarge 2703 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2704 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2705 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2706 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2707 if (proc.baseProcessTracker != null) { 2708 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2709 } 2710 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2711 } 2712 } 2713 return proc; 2714 } 2715 2716 void ensurePackageDexOpt(String packageName) { 2717 IPackageManager pm = AppGlobals.getPackageManager(); 2718 try { 2719 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2720 mDidDexOpt = true; 2721 } 2722 } catch (RemoteException e) { 2723 } 2724 } 2725 2726 boolean isNextTransitionForward() { 2727 int transit = mWindowManager.getPendingAppTransition(); 2728 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2729 || transit == AppTransition.TRANSIT_TASK_OPEN 2730 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2731 } 2732 2733 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2734 String processName, String abiOverride, int uid, Runnable crashHandler) { 2735 synchronized(this) { 2736 ApplicationInfo info = new ApplicationInfo(); 2737 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2738 // For isolated processes, the former contains the parent's uid and the latter the 2739 // actual uid of the isolated process. 2740 // In the special case introduced by this method (which is, starting an isolated 2741 // process directly from the SystemServer without an actual parent app process) the 2742 // closest thing to a parent's uid is SYSTEM_UID. 2743 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2744 // the |isolated| logic in the ProcessRecord constructor. 2745 info.uid = Process.SYSTEM_UID; 2746 info.processName = processName; 2747 info.className = entryPoint; 2748 info.packageName = "android"; 2749 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2750 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2751 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2752 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2753 crashHandler); 2754 return proc != null ? proc.pid : 0; 2755 } 2756 } 2757 2758 final ProcessRecord startProcessLocked(String processName, 2759 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2760 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2761 boolean isolated, boolean keepIfLarge) { 2762 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2763 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2764 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2765 null /* crashHandler */); 2766 } 2767 2768 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2769 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2770 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2771 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2772 long startTime = SystemClock.elapsedRealtime(); 2773 ProcessRecord app; 2774 if (!isolated) { 2775 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2776 checkTime(startTime, "startProcess: after getProcessRecord"); 2777 } else { 2778 // If this is an isolated process, it can't re-use an existing process. 2779 app = null; 2780 } 2781 // We don't have to do anything more if: 2782 // (1) There is an existing application record; and 2783 // (2) The caller doesn't think it is dead, OR there is no thread 2784 // object attached to it so we know it couldn't have crashed; and 2785 // (3) There is a pid assigned to it, so it is either starting or 2786 // already running. 2787 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2788 + " app=" + app + " knownToBeDead=" + knownToBeDead 2789 + " thread=" + (app != null ? app.thread : null) 2790 + " pid=" + (app != null ? app.pid : -1)); 2791 if (app != null && app.pid > 0) { 2792 if (!knownToBeDead || app.thread == null) { 2793 // We already have the app running, or are waiting for it to 2794 // come up (we have a pid but not yet its thread), so keep it. 2795 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2796 // If this is a new package in the process, add the package to the list 2797 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2798 checkTime(startTime, "startProcess: done, added package to proc"); 2799 return app; 2800 } 2801 2802 // An application record is attached to a previous process, 2803 // clean it up now. 2804 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2805 checkTime(startTime, "startProcess: bad proc running, killing"); 2806 Process.killProcessGroup(app.info.uid, app.pid); 2807 handleAppDiedLocked(app, true, true); 2808 checkTime(startTime, "startProcess: done killing old proc"); 2809 } 2810 2811 String hostingNameStr = hostingName != null 2812 ? hostingName.flattenToShortString() : null; 2813 2814 if (!isolated) { 2815 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2816 // If we are in the background, then check to see if this process 2817 // is bad. If so, we will just silently fail. 2818 if (mBadProcesses.get(info.processName, info.uid) != null) { 2819 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2820 + "/" + info.processName); 2821 return null; 2822 } 2823 } else { 2824 // When the user is explicitly starting a process, then clear its 2825 // crash count so that we won't make it bad until they see at 2826 // least one crash dialog again, and make the process good again 2827 // if it had been bad. 2828 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2829 + "/" + info.processName); 2830 mProcessCrashTimes.remove(info.processName, info.uid); 2831 if (mBadProcesses.get(info.processName, info.uid) != null) { 2832 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2833 UserHandle.getUserId(info.uid), info.uid, 2834 info.processName); 2835 mBadProcesses.remove(info.processName, info.uid); 2836 if (app != null) { 2837 app.bad = false; 2838 } 2839 } 2840 } 2841 } 2842 2843 if (app == null) { 2844 checkTime(startTime, "startProcess: creating new process record"); 2845 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2846 app.crashHandler = crashHandler; 2847 if (app == null) { 2848 Slog.w(TAG, "Failed making new process record for " 2849 + processName + "/" + info.uid + " isolated=" + isolated); 2850 return null; 2851 } 2852 mProcessNames.put(processName, app.uid, app); 2853 if (isolated) { 2854 mIsolatedProcesses.put(app.uid, app); 2855 } 2856 checkTime(startTime, "startProcess: done creating new process record"); 2857 } else { 2858 // If this is a new package in the process, add the package to the list 2859 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2860 checkTime(startTime, "startProcess: added package to existing proc"); 2861 } 2862 2863 // If the system is not ready yet, then hold off on starting this 2864 // process until it is. 2865 if (!mProcessesReady 2866 && !isAllowedWhileBooting(info) 2867 && !allowWhileBooting) { 2868 if (!mProcessesOnHold.contains(app)) { 2869 mProcessesOnHold.add(app); 2870 } 2871 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2872 checkTime(startTime, "startProcess: returning with proc on hold"); 2873 return app; 2874 } 2875 2876 checkTime(startTime, "startProcess: stepping in to startProcess"); 2877 startProcessLocked( 2878 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2879 checkTime(startTime, "startProcess: done starting proc!"); 2880 return (app.pid != 0) ? app : null; 2881 } 2882 2883 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2884 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2885 } 2886 2887 private final void startProcessLocked(ProcessRecord app, 2888 String hostingType, String hostingNameStr) { 2889 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2890 null /* entryPoint */, null /* entryPointArgs */); 2891 } 2892 2893 private final void startProcessLocked(ProcessRecord app, String hostingType, 2894 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2895 long startTime = SystemClock.elapsedRealtime(); 2896 if (app.pid > 0 && app.pid != MY_PID) { 2897 checkTime(startTime, "startProcess: removing from pids map"); 2898 synchronized (mPidsSelfLocked) { 2899 mPidsSelfLocked.remove(app.pid); 2900 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2901 } 2902 checkTime(startTime, "startProcess: done removing from pids map"); 2903 app.setPid(0); 2904 } 2905 2906 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2907 "startProcessLocked removing on hold: " + app); 2908 mProcessesOnHold.remove(app); 2909 2910 checkTime(startTime, "startProcess: starting to update cpu stats"); 2911 updateCpuStats(); 2912 checkTime(startTime, "startProcess: done updating cpu stats"); 2913 2914 try { 2915 int uid = app.uid; 2916 2917 int[] gids = null; 2918 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2919 if (!app.isolated) { 2920 int[] permGids = null; 2921 try { 2922 checkTime(startTime, "startProcess: getting gids from package manager"); 2923 final PackageManager pm = mContext.getPackageManager(); 2924 permGids = pm.getPackageGids(app.info.packageName); 2925 2926 if (Environment.isExternalStorageEmulated()) { 2927 checkTime(startTime, "startProcess: checking external storage perm"); 2928 if (pm.checkPermission( 2929 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2930 app.info.packageName) == PERMISSION_GRANTED) { 2931 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2932 } else { 2933 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2934 } 2935 } 2936 } catch (PackageManager.NameNotFoundException e) { 2937 Slog.w(TAG, "Unable to retrieve gids", e); 2938 } 2939 2940 /* 2941 * Add shared application and profile GIDs so applications can share some 2942 * resources like shared libraries and access user-wide resources 2943 */ 2944 if (permGids == null) { 2945 gids = new int[2]; 2946 } else { 2947 gids = new int[permGids.length + 2]; 2948 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2949 } 2950 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2951 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2952 } 2953 checkTime(startTime, "startProcess: building args"); 2954 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2955 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2956 && mTopComponent != null 2957 && app.processName.equals(mTopComponent.getPackageName())) { 2958 uid = 0; 2959 } 2960 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2961 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2962 uid = 0; 2963 } 2964 } 2965 int debugFlags = 0; 2966 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2967 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2968 // Also turn on CheckJNI for debuggable apps. It's quite 2969 // awkward to turn on otherwise. 2970 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2971 } 2972 // Run the app in safe mode if its manifest requests so or the 2973 // system is booted in safe mode. 2974 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2975 mSafeMode == true) { 2976 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2977 } 2978 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2979 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2980 } 2981 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2982 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2983 } 2984 if ("1".equals(SystemProperties.get("debug.assert"))) { 2985 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2986 } 2987 2988 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2989 if (requiredAbi == null) { 2990 requiredAbi = Build.SUPPORTED_ABIS[0]; 2991 } 2992 2993 String instructionSet = null; 2994 if (app.info.primaryCpuAbi != null) { 2995 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 2996 } 2997 2998 // Start the process. It will either succeed and return a result containing 2999 // the PID of the new process, or else throw a RuntimeException. 3000 boolean isActivityProcess = (entryPoint == null); 3001 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3002 checkTime(startTime, "startProcess: asking zygote to start proc"); 3003 Process.ProcessStartResult startResult = Process.start(entryPoint, 3004 app.processName, uid, uid, gids, debugFlags, mountExternal, 3005 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3006 app.info.dataDir, entryPointArgs); 3007 checkTime(startTime, "startProcess: returned from zygote!"); 3008 3009 if (app.isolated) { 3010 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3011 } 3012 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3013 checkTime(startTime, "startProcess: done updating battery stats"); 3014 3015 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3016 UserHandle.getUserId(uid), startResult.pid, uid, 3017 app.processName, hostingType, 3018 hostingNameStr != null ? hostingNameStr : ""); 3019 3020 if (app.persistent) { 3021 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3022 } 3023 3024 checkTime(startTime, "startProcess: building log message"); 3025 StringBuilder buf = mStringBuilder; 3026 buf.setLength(0); 3027 buf.append("Start proc "); 3028 buf.append(app.processName); 3029 if (!isActivityProcess) { 3030 buf.append(" ["); 3031 buf.append(entryPoint); 3032 buf.append("]"); 3033 } 3034 buf.append(" for "); 3035 buf.append(hostingType); 3036 if (hostingNameStr != null) { 3037 buf.append(" "); 3038 buf.append(hostingNameStr); 3039 } 3040 buf.append(": pid="); 3041 buf.append(startResult.pid); 3042 buf.append(" uid="); 3043 buf.append(uid); 3044 buf.append(" gids={"); 3045 if (gids != null) { 3046 for (int gi=0; gi<gids.length; gi++) { 3047 if (gi != 0) buf.append(", "); 3048 buf.append(gids[gi]); 3049 3050 } 3051 } 3052 buf.append("}"); 3053 if (requiredAbi != null) { 3054 buf.append(" abi="); 3055 buf.append(requiredAbi); 3056 } 3057 Slog.i(TAG, buf.toString()); 3058 app.setPid(startResult.pid); 3059 app.usingWrapper = startResult.usingWrapper; 3060 app.removed = false; 3061 app.killed = false; 3062 app.killedByAm = false; 3063 checkTime(startTime, "startProcess: starting to update pids map"); 3064 synchronized (mPidsSelfLocked) { 3065 this.mPidsSelfLocked.put(startResult.pid, app); 3066 if (isActivityProcess) { 3067 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3068 msg.obj = app; 3069 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3070 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3071 } 3072 } 3073 checkTime(startTime, "startProcess: done updating pids map"); 3074 } catch (RuntimeException e) { 3075 // XXX do better error recovery. 3076 app.setPid(0); 3077 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3078 if (app.isolated) { 3079 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3080 } 3081 Slog.e(TAG, "Failure starting process " + app.processName, e); 3082 } 3083 } 3084 3085 void updateUsageStats(ActivityRecord component, boolean resumed) { 3086 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3087 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3088 if (resumed) { 3089 if (mUsageStatsService != null) { 3090 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3091 UsageEvents.Event.MOVE_TO_FOREGROUND); 3092 } 3093 synchronized (stats) { 3094 stats.noteActivityResumedLocked(component.app.uid); 3095 } 3096 } else { 3097 if (mUsageStatsService != null) { 3098 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3099 UsageEvents.Event.MOVE_TO_BACKGROUND); 3100 } 3101 synchronized (stats) { 3102 stats.noteActivityPausedLocked(component.app.uid); 3103 } 3104 } 3105 } 3106 3107 Intent getHomeIntent() { 3108 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3109 intent.setComponent(mTopComponent); 3110 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3111 intent.addCategory(Intent.CATEGORY_HOME); 3112 } 3113 return intent; 3114 } 3115 3116 boolean startHomeActivityLocked(int userId) { 3117 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3118 && mTopAction == null) { 3119 // We are running in factory test mode, but unable to find 3120 // the factory test app, so just sit around displaying the 3121 // error message and don't try to start anything. 3122 return false; 3123 } 3124 Intent intent = getHomeIntent(); 3125 ActivityInfo aInfo = 3126 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3127 if (aInfo != null) { 3128 intent.setComponent(new ComponentName( 3129 aInfo.applicationInfo.packageName, aInfo.name)); 3130 // Don't do this if the home app is currently being 3131 // instrumented. 3132 aInfo = new ActivityInfo(aInfo); 3133 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3134 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3135 aInfo.applicationInfo.uid, true); 3136 if (app == null || app.instrumentationClass == null) { 3137 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3138 mStackSupervisor.startHomeActivity(intent, aInfo); 3139 } 3140 } 3141 3142 return true; 3143 } 3144 3145 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3146 ActivityInfo ai = null; 3147 ComponentName comp = intent.getComponent(); 3148 try { 3149 if (comp != null) { 3150 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3151 } else { 3152 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3153 intent, 3154 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3155 flags, userId); 3156 3157 if (info != null) { 3158 ai = info.activityInfo; 3159 } 3160 } 3161 } catch (RemoteException e) { 3162 // ignore 3163 } 3164 3165 return ai; 3166 } 3167 3168 /** 3169 * Starts the "new version setup screen" if appropriate. 3170 */ 3171 void startSetupActivityLocked() { 3172 // Only do this once per boot. 3173 if (mCheckedForSetup) { 3174 return; 3175 } 3176 3177 // We will show this screen if the current one is a different 3178 // version than the last one shown, and we are not running in 3179 // low-level factory test mode. 3180 final ContentResolver resolver = mContext.getContentResolver(); 3181 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3182 Settings.Global.getInt(resolver, 3183 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3184 mCheckedForSetup = true; 3185 3186 // See if we should be showing the platform update setup UI. 3187 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3188 List<ResolveInfo> ris = mContext.getPackageManager() 3189 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3190 3191 // We don't allow third party apps to replace this. 3192 ResolveInfo ri = null; 3193 for (int i=0; ris != null && i<ris.size(); i++) { 3194 if ((ris.get(i).activityInfo.applicationInfo.flags 3195 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3196 ri = ris.get(i); 3197 break; 3198 } 3199 } 3200 3201 if (ri != null) { 3202 String vers = ri.activityInfo.metaData != null 3203 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3204 : null; 3205 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3206 vers = ri.activityInfo.applicationInfo.metaData.getString( 3207 Intent.METADATA_SETUP_VERSION); 3208 } 3209 String lastVers = Settings.Secure.getString( 3210 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3211 if (vers != null && !vers.equals(lastVers)) { 3212 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3213 intent.setComponent(new ComponentName( 3214 ri.activityInfo.packageName, ri.activityInfo.name)); 3215 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3216 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3217 null); 3218 } 3219 } 3220 } 3221 } 3222 3223 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3224 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3225 } 3226 3227 void enforceNotIsolatedCaller(String caller) { 3228 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3229 throw new SecurityException("Isolated process not allowed to call " + caller); 3230 } 3231 } 3232 3233 void enforceShellRestriction(String restriction, int userHandle) { 3234 if (Binder.getCallingUid() == Process.SHELL_UID) { 3235 if (userHandle < 0 3236 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3237 throw new SecurityException("Shell does not have permission to access user " 3238 + userHandle); 3239 } 3240 } 3241 } 3242 3243 @Override 3244 public int getFrontActivityScreenCompatMode() { 3245 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3246 synchronized (this) { 3247 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3248 } 3249 } 3250 3251 @Override 3252 public void setFrontActivityScreenCompatMode(int mode) { 3253 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3254 "setFrontActivityScreenCompatMode"); 3255 synchronized (this) { 3256 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3257 } 3258 } 3259 3260 @Override 3261 public int getPackageScreenCompatMode(String packageName) { 3262 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3263 synchronized (this) { 3264 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3265 } 3266 } 3267 3268 @Override 3269 public void setPackageScreenCompatMode(String packageName, int mode) { 3270 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3271 "setPackageScreenCompatMode"); 3272 synchronized (this) { 3273 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3274 } 3275 } 3276 3277 @Override 3278 public boolean getPackageAskScreenCompat(String packageName) { 3279 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3280 synchronized (this) { 3281 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3282 } 3283 } 3284 3285 @Override 3286 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3287 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3288 "setPackageAskScreenCompat"); 3289 synchronized (this) { 3290 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3291 } 3292 } 3293 3294 private void dispatchProcessesChanged() { 3295 int N; 3296 synchronized (this) { 3297 N = mPendingProcessChanges.size(); 3298 if (mActiveProcessChanges.length < N) { 3299 mActiveProcessChanges = new ProcessChangeItem[N]; 3300 } 3301 mPendingProcessChanges.toArray(mActiveProcessChanges); 3302 mAvailProcessChanges.addAll(mPendingProcessChanges); 3303 mPendingProcessChanges.clear(); 3304 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3305 } 3306 3307 int i = mProcessObservers.beginBroadcast(); 3308 while (i > 0) { 3309 i--; 3310 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3311 if (observer != null) { 3312 try { 3313 for (int j=0; j<N; j++) { 3314 ProcessChangeItem item = mActiveProcessChanges[j]; 3315 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3316 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3317 + item.pid + " uid=" + item.uid + ": " 3318 + item.foregroundActivities); 3319 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3320 item.foregroundActivities); 3321 } 3322 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3323 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3324 + item.pid + " uid=" + item.uid + ": " + item.processState); 3325 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3326 } 3327 } 3328 } catch (RemoteException e) { 3329 } 3330 } 3331 } 3332 mProcessObservers.finishBroadcast(); 3333 } 3334 3335 private void dispatchProcessDied(int pid, int uid) { 3336 int i = mProcessObservers.beginBroadcast(); 3337 while (i > 0) { 3338 i--; 3339 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3340 if (observer != null) { 3341 try { 3342 observer.onProcessDied(pid, uid); 3343 } catch (RemoteException e) { 3344 } 3345 } 3346 } 3347 mProcessObservers.finishBroadcast(); 3348 } 3349 3350 @Override 3351 public final int startActivity(IApplicationThread caller, String callingPackage, 3352 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3353 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3354 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3355 resultWho, requestCode, startFlags, profilerInfo, options, 3356 UserHandle.getCallingUserId()); 3357 } 3358 3359 @Override 3360 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3361 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3362 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3363 enforceNotIsolatedCaller("startActivity"); 3364 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3365 false, ALLOW_FULL_ONLY, "startActivity", null); 3366 // TODO: Switch to user app stacks here. 3367 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3368 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3369 profilerInfo, null, null, options, userId, null, null); 3370 } 3371 3372 @Override 3373 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3374 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3375 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3376 3377 // This is very dangerous -- it allows you to perform a start activity (including 3378 // permission grants) as any app that may launch one of your own activities. So 3379 // we will only allow this to be done from activities that are part of the core framework, 3380 // and then only when they are running as the system. 3381 final ActivityRecord sourceRecord; 3382 final int targetUid; 3383 final String targetPackage; 3384 synchronized (this) { 3385 if (resultTo == null) { 3386 throw new SecurityException("Must be called from an activity"); 3387 } 3388 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3389 if (sourceRecord == null) { 3390 throw new SecurityException("Called with bad activity token: " + resultTo); 3391 } 3392 if (!sourceRecord.info.packageName.equals("android")) { 3393 throw new SecurityException( 3394 "Must be called from an activity that is declared in the android package"); 3395 } 3396 if (sourceRecord.app == null) { 3397 throw new SecurityException("Called without a process attached to activity"); 3398 } 3399 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3400 // This is still okay, as long as this activity is running under the 3401 // uid of the original calling activity. 3402 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3403 throw new SecurityException( 3404 "Calling activity in uid " + sourceRecord.app.uid 3405 + " must be system uid or original calling uid " 3406 + sourceRecord.launchedFromUid); 3407 } 3408 } 3409 targetUid = sourceRecord.launchedFromUid; 3410 targetPackage = sourceRecord.launchedFromPackage; 3411 } 3412 3413 if (userId == UserHandle.USER_NULL) { 3414 userId = UserHandle.getUserId(sourceRecord.app.uid); 3415 } 3416 3417 // TODO: Switch to user app stacks here. 3418 try { 3419 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3420 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3421 null, null, options, userId, null, null); 3422 return ret; 3423 } catch (SecurityException e) { 3424 // XXX need to figure out how to propagate to original app. 3425 // A SecurityException here is generally actually a fault of the original 3426 // calling activity (such as a fairly granting permissions), so propagate it 3427 // back to them. 3428 /* 3429 StringBuilder msg = new StringBuilder(); 3430 msg.append("While launching"); 3431 msg.append(intent.toString()); 3432 msg.append(": "); 3433 msg.append(e.getMessage()); 3434 */ 3435 throw e; 3436 } 3437 } 3438 3439 @Override 3440 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3441 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3442 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3443 enforceNotIsolatedCaller("startActivityAndWait"); 3444 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3445 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3446 WaitResult res = new WaitResult(); 3447 // TODO: Switch to user app stacks here. 3448 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3449 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3450 options, userId, null, null); 3451 return res; 3452 } 3453 3454 @Override 3455 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3456 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3457 int startFlags, Configuration config, Bundle options, int userId) { 3458 enforceNotIsolatedCaller("startActivityWithConfig"); 3459 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3460 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3461 // TODO: Switch to user app stacks here. 3462 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3463 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3464 null, null, config, options, userId, null, null); 3465 return ret; 3466 } 3467 3468 @Override 3469 public int startActivityIntentSender(IApplicationThread caller, 3470 IntentSender intent, Intent fillInIntent, String resolvedType, 3471 IBinder resultTo, String resultWho, int requestCode, 3472 int flagsMask, int flagsValues, Bundle options) { 3473 enforceNotIsolatedCaller("startActivityIntentSender"); 3474 // Refuse possible leaked file descriptors 3475 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3476 throw new IllegalArgumentException("File descriptors passed in Intent"); 3477 } 3478 3479 IIntentSender sender = intent.getTarget(); 3480 if (!(sender instanceof PendingIntentRecord)) { 3481 throw new IllegalArgumentException("Bad PendingIntent object"); 3482 } 3483 3484 PendingIntentRecord pir = (PendingIntentRecord)sender; 3485 3486 synchronized (this) { 3487 // If this is coming from the currently resumed activity, it is 3488 // effectively saying that app switches are allowed at this point. 3489 final ActivityStack stack = getFocusedStack(); 3490 if (stack.mResumedActivity != null && 3491 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3492 mAppSwitchesAllowedTime = 0; 3493 } 3494 } 3495 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3496 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3497 return ret; 3498 } 3499 3500 @Override 3501 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3502 Intent intent, String resolvedType, IVoiceInteractionSession session, 3503 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3504 Bundle options, int userId) { 3505 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3506 != PackageManager.PERMISSION_GRANTED) { 3507 String msg = "Permission Denial: startVoiceActivity() from pid=" 3508 + Binder.getCallingPid() 3509 + ", uid=" + Binder.getCallingUid() 3510 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3511 Slog.w(TAG, msg); 3512 throw new SecurityException(msg); 3513 } 3514 if (session == null || interactor == null) { 3515 throw new NullPointerException("null session or interactor"); 3516 } 3517 userId = handleIncomingUser(callingPid, callingUid, userId, 3518 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3519 // TODO: Switch to user app stacks here. 3520 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3521 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3522 null, options, userId, null, null); 3523 } 3524 3525 @Override 3526 public boolean startNextMatchingActivity(IBinder callingActivity, 3527 Intent intent, Bundle options) { 3528 // Refuse possible leaked file descriptors 3529 if (intent != null && intent.hasFileDescriptors() == true) { 3530 throw new IllegalArgumentException("File descriptors passed in Intent"); 3531 } 3532 3533 synchronized (this) { 3534 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3535 if (r == null) { 3536 ActivityOptions.abort(options); 3537 return false; 3538 } 3539 if (r.app == null || r.app.thread == null) { 3540 // The caller is not running... d'oh! 3541 ActivityOptions.abort(options); 3542 return false; 3543 } 3544 intent = new Intent(intent); 3545 // The caller is not allowed to change the data. 3546 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3547 // And we are resetting to find the next component... 3548 intent.setComponent(null); 3549 3550 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3551 3552 ActivityInfo aInfo = null; 3553 try { 3554 List<ResolveInfo> resolves = 3555 AppGlobals.getPackageManager().queryIntentActivities( 3556 intent, r.resolvedType, 3557 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3558 UserHandle.getCallingUserId()); 3559 3560 // Look for the original activity in the list... 3561 final int N = resolves != null ? resolves.size() : 0; 3562 for (int i=0; i<N; i++) { 3563 ResolveInfo rInfo = resolves.get(i); 3564 if (rInfo.activityInfo.packageName.equals(r.packageName) 3565 && rInfo.activityInfo.name.equals(r.info.name)) { 3566 // We found the current one... the next matching is 3567 // after it. 3568 i++; 3569 if (i<N) { 3570 aInfo = resolves.get(i).activityInfo; 3571 } 3572 if (debug) { 3573 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3574 + "/" + r.info.name); 3575 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3576 + "/" + aInfo.name); 3577 } 3578 break; 3579 } 3580 } 3581 } catch (RemoteException e) { 3582 } 3583 3584 if (aInfo == null) { 3585 // Nobody who is next! 3586 ActivityOptions.abort(options); 3587 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3588 return false; 3589 } 3590 3591 intent.setComponent(new ComponentName( 3592 aInfo.applicationInfo.packageName, aInfo.name)); 3593 intent.setFlags(intent.getFlags()&~( 3594 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3595 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3596 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3597 Intent.FLAG_ACTIVITY_NEW_TASK)); 3598 3599 // Okay now we need to start the new activity, replacing the 3600 // currently running activity. This is a little tricky because 3601 // we want to start the new one as if the current one is finished, 3602 // but not finish the current one first so that there is no flicker. 3603 // And thus... 3604 final boolean wasFinishing = r.finishing; 3605 r.finishing = true; 3606 3607 // Propagate reply information over to the new activity. 3608 final ActivityRecord resultTo = r.resultTo; 3609 final String resultWho = r.resultWho; 3610 final int requestCode = r.requestCode; 3611 r.resultTo = null; 3612 if (resultTo != null) { 3613 resultTo.removeResultsLocked(r, resultWho, requestCode); 3614 } 3615 3616 final long origId = Binder.clearCallingIdentity(); 3617 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3618 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3619 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3620 -1, r.launchedFromUid, 0, options, false, null, null, null); 3621 Binder.restoreCallingIdentity(origId); 3622 3623 r.finishing = wasFinishing; 3624 if (res != ActivityManager.START_SUCCESS) { 3625 return false; 3626 } 3627 return true; 3628 } 3629 } 3630 3631 @Override 3632 public final int startActivityFromRecents(int taskId, Bundle options) { 3633 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3634 String msg = "Permission Denial: startActivityFromRecents called without " + 3635 START_TASKS_FROM_RECENTS; 3636 Slog.w(TAG, msg); 3637 throw new SecurityException(msg); 3638 } 3639 return startActivityFromRecentsInner(taskId, options); 3640 } 3641 3642 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3643 final TaskRecord task; 3644 final int callingUid; 3645 final String callingPackage; 3646 final Intent intent; 3647 final int userId; 3648 synchronized (this) { 3649 task = recentTaskForIdLocked(taskId); 3650 if (task == null) { 3651 throw new IllegalArgumentException("Task " + taskId + " not found."); 3652 } 3653 callingUid = task.mCallingUid; 3654 callingPackage = task.mCallingPackage; 3655 intent = task.intent; 3656 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3657 userId = task.userId; 3658 } 3659 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3660 options, userId, null, task); 3661 } 3662 3663 final int startActivityInPackage(int uid, String callingPackage, 3664 Intent intent, String resolvedType, IBinder resultTo, 3665 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3666 IActivityContainer container, TaskRecord inTask) { 3667 3668 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3669 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3670 3671 // TODO: Switch to user app stacks here. 3672 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3673 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3674 null, null, null, options, userId, container, inTask); 3675 return ret; 3676 } 3677 3678 @Override 3679 public final int startActivities(IApplicationThread caller, String callingPackage, 3680 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3681 int userId) { 3682 enforceNotIsolatedCaller("startActivities"); 3683 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3684 false, ALLOW_FULL_ONLY, "startActivity", null); 3685 // TODO: Switch to user app stacks here. 3686 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3687 resolvedTypes, resultTo, options, userId); 3688 return ret; 3689 } 3690 3691 final int startActivitiesInPackage(int uid, String callingPackage, 3692 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3693 Bundle options, int userId) { 3694 3695 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3696 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3697 // TODO: Switch to user app stacks here. 3698 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3699 resultTo, options, userId); 3700 return ret; 3701 } 3702 3703 //explicitly remove thd old information in mRecentTasks when removing existing user. 3704 private void removeRecentTasksForUserLocked(int userId) { 3705 if(userId <= 0) { 3706 Slog.i(TAG, "Can't remove recent task on user " + userId); 3707 return; 3708 } 3709 3710 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3711 TaskRecord tr = mRecentTasks.get(i); 3712 if (tr.userId == userId) { 3713 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3714 + " when finishing user" + userId); 3715 mRecentTasks.remove(i); 3716 tr.removedFromRecents(mTaskPersister); 3717 } 3718 } 3719 3720 // Remove tasks from persistent storage. 3721 mTaskPersister.wakeup(null, true); 3722 } 3723 3724 // Sort by taskId 3725 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3726 @Override 3727 public int compare(TaskRecord lhs, TaskRecord rhs) { 3728 return rhs.taskId - lhs.taskId; 3729 } 3730 }; 3731 3732 // Extract the affiliates of the chain containing mRecentTasks[start]. 3733 private int processNextAffiliateChain(int start) { 3734 final TaskRecord startTask = mRecentTasks.get(start); 3735 final int affiliateId = startTask.mAffiliatedTaskId; 3736 3737 // Quick identification of isolated tasks. I.e. those not launched behind. 3738 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3739 startTask.mNextAffiliate == null) { 3740 // There is still a slim chance that there are other tasks that point to this task 3741 // and that the chain is so messed up that this task no longer points to them but 3742 // the gain of this optimization outweighs the risk. 3743 startTask.inRecents = true; 3744 return start + 1; 3745 } 3746 3747 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3748 mTmpRecents.clear(); 3749 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3750 final TaskRecord task = mRecentTasks.get(i); 3751 if (task.mAffiliatedTaskId == affiliateId) { 3752 mRecentTasks.remove(i); 3753 mTmpRecents.add(task); 3754 } 3755 } 3756 3757 // Sort them all by taskId. That is the order they were create in and that order will 3758 // always be correct. 3759 Collections.sort(mTmpRecents, mTaskRecordComparator); 3760 3761 // Go through and fix up the linked list. 3762 // The first one is the end of the chain and has no next. 3763 final TaskRecord first = mTmpRecents.get(0); 3764 first.inRecents = true; 3765 if (first.mNextAffiliate != null) { 3766 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3767 first.setNextAffiliate(null); 3768 mTaskPersister.wakeup(first, false); 3769 } 3770 // Everything in the middle is doubly linked from next to prev. 3771 final int tmpSize = mTmpRecents.size(); 3772 for (int i = 0; i < tmpSize - 1; ++i) { 3773 final TaskRecord next = mTmpRecents.get(i); 3774 final TaskRecord prev = mTmpRecents.get(i + 1); 3775 if (next.mPrevAffiliate != prev) { 3776 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3777 " setting prev=" + prev); 3778 next.setPrevAffiliate(prev); 3779 mTaskPersister.wakeup(next, false); 3780 } 3781 if (prev.mNextAffiliate != next) { 3782 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3783 " setting next=" + next); 3784 prev.setNextAffiliate(next); 3785 mTaskPersister.wakeup(prev, false); 3786 } 3787 prev.inRecents = true; 3788 } 3789 // The last one is the beginning of the list and has no prev. 3790 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3791 if (last.mPrevAffiliate != null) { 3792 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3793 last.setPrevAffiliate(null); 3794 mTaskPersister.wakeup(last, false); 3795 } 3796 3797 // Insert the group back into mRecentTasks at start. 3798 mRecentTasks.addAll(start, mTmpRecents); 3799 3800 // Let the caller know where we left off. 3801 return start + tmpSize; 3802 } 3803 3804 /** 3805 * Update the recent tasks lists: make sure tasks should still be here (their 3806 * applications / activities still exist), update their availability, fixup ordering 3807 * of affiliations. 3808 */ 3809 void cleanupRecentTasksLocked(int userId) { 3810 if (mRecentTasks == null) { 3811 // Happens when called from the packagemanager broadcast before boot. 3812 return; 3813 } 3814 3815 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3816 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3817 final IPackageManager pm = AppGlobals.getPackageManager(); 3818 final ActivityInfo dummyAct = new ActivityInfo(); 3819 final ApplicationInfo dummyApp = new ApplicationInfo(); 3820 3821 int N = mRecentTasks.size(); 3822 3823 int[] users = userId == UserHandle.USER_ALL 3824 ? getUsersLocked() : new int[] { userId }; 3825 for (int user : users) { 3826 for (int i = 0; i < N; i++) { 3827 TaskRecord task = mRecentTasks.get(i); 3828 if (task.userId != user) { 3829 // Only look at tasks for the user ID of interest. 3830 continue; 3831 } 3832 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3833 // This situation is broken, and we should just get rid of it now. 3834 mRecentTasks.remove(i); 3835 task.removedFromRecents(mTaskPersister); 3836 i--; 3837 N--; 3838 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3839 continue; 3840 } 3841 // Check whether this activity is currently available. 3842 if (task.realActivity != null) { 3843 ActivityInfo ai = availActCache.get(task.realActivity); 3844 if (ai == null) { 3845 try { 3846 ai = pm.getActivityInfo(task.realActivity, 3847 PackageManager.GET_UNINSTALLED_PACKAGES 3848 | PackageManager.GET_DISABLED_COMPONENTS, user); 3849 } catch (RemoteException e) { 3850 // Will never happen. 3851 continue; 3852 } 3853 if (ai == null) { 3854 ai = dummyAct; 3855 } 3856 availActCache.put(task.realActivity, ai); 3857 } 3858 if (ai == dummyAct) { 3859 // This could be either because the activity no longer exists, or the 3860 // app is temporarily gone. For the former we want to remove the recents 3861 // entry; for the latter we want to mark it as unavailable. 3862 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3863 if (app == null) { 3864 try { 3865 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3866 PackageManager.GET_UNINSTALLED_PACKAGES 3867 | PackageManager.GET_DISABLED_COMPONENTS, user); 3868 } catch (RemoteException e) { 3869 // Will never happen. 3870 continue; 3871 } 3872 if (app == null) { 3873 app = dummyApp; 3874 } 3875 availAppCache.put(task.realActivity.getPackageName(), app); 3876 } 3877 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3878 // Doesn't exist any more! Good-bye. 3879 mRecentTasks.remove(i); 3880 task.removedFromRecents(mTaskPersister); 3881 i--; 3882 N--; 3883 Slog.w(TAG, "Removing no longer valid recent: " + task); 3884 continue; 3885 } else { 3886 // Otherwise just not available for now. 3887 if (task.isAvailable) { 3888 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3889 + task); 3890 } 3891 task.isAvailable = false; 3892 } 3893 } else { 3894 if (!ai.enabled || !ai.applicationInfo.enabled 3895 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3896 if (task.isAvailable) { 3897 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3898 + task + " (enabled=" + ai.enabled + "/" 3899 + ai.applicationInfo.enabled + " flags=" 3900 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3901 } 3902 task.isAvailable = false; 3903 } else { 3904 if (!task.isAvailable) { 3905 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3906 + task); 3907 } 3908 task.isAvailable = true; 3909 } 3910 } 3911 } 3912 } 3913 } 3914 3915 // Verify the affiliate chain for each task. 3916 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 3917 } 3918 3919 mTmpRecents.clear(); 3920 // mRecentTasks is now in sorted, affiliated order. 3921 } 3922 3923 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3924 int N = mRecentTasks.size(); 3925 TaskRecord top = task; 3926 int topIndex = taskIndex; 3927 while (top.mNextAffiliate != null && topIndex > 0) { 3928 top = top.mNextAffiliate; 3929 topIndex--; 3930 } 3931 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3932 + topIndex + " from intial " + taskIndex); 3933 // Find the end of the chain, doing a sanity check along the way. 3934 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3935 int endIndex = topIndex; 3936 TaskRecord prev = top; 3937 while (endIndex < N) { 3938 TaskRecord cur = mRecentTasks.get(endIndex); 3939 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3940 + endIndex + " " + cur); 3941 if (cur == top) { 3942 // Verify start of the chain. 3943 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 3944 Slog.wtf(TAG, "Bad chain @" + endIndex 3945 + ": first task has next affiliate: " + prev); 3946 sane = false; 3947 break; 3948 } 3949 } else { 3950 // Verify middle of the chain's next points back to the one before. 3951 if (cur.mNextAffiliate != prev 3952 || cur.mNextAffiliateTaskId != prev.taskId) { 3953 Slog.wtf(TAG, "Bad chain @" + endIndex 3954 + ": middle task " + cur + " @" + endIndex 3955 + " has bad next affiliate " 3956 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3957 + ", expected " + prev); 3958 sane = false; 3959 break; 3960 } 3961 } 3962 if (cur.mPrevAffiliateTaskId == -1) { 3963 // Chain ends here. 3964 if (cur.mPrevAffiliate != null) { 3965 Slog.wtf(TAG, "Bad chain @" + endIndex 3966 + ": last task " + cur + " has previous affiliate " 3967 + cur.mPrevAffiliate); 3968 sane = false; 3969 } 3970 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3971 break; 3972 } else { 3973 // Verify middle of the chain's prev points to a valid item. 3974 if (cur.mPrevAffiliate == null) { 3975 Slog.wtf(TAG, "Bad chain @" + endIndex 3976 + ": task " + cur + " has previous affiliate " 3977 + cur.mPrevAffiliate + " but should be id " 3978 + cur.mPrevAffiliate); 3979 sane = false; 3980 break; 3981 } 3982 } 3983 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3984 Slog.wtf(TAG, "Bad chain @" + endIndex 3985 + ": task " + cur + " has affiliated id " 3986 + cur.mAffiliatedTaskId + " but should be " 3987 + task.mAffiliatedTaskId); 3988 sane = false; 3989 break; 3990 } 3991 prev = cur; 3992 endIndex++; 3993 if (endIndex >= N) { 3994 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3995 + ": last task " + prev); 3996 sane = false; 3997 break; 3998 } 3999 } 4000 if (sane) { 4001 if (endIndex < taskIndex) { 4002 Slog.wtf(TAG, "Bad chain @" + endIndex 4003 + ": did not extend to task " + task + " @" + taskIndex); 4004 sane = false; 4005 } 4006 } 4007 if (sane) { 4008 // All looks good, we can just move all of the affiliated tasks 4009 // to the top. 4010 for (int i=topIndex; i<=endIndex; i++) { 4011 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4012 + " from " + i + " to " + (i-topIndex)); 4013 TaskRecord cur = mRecentTasks.remove(i); 4014 mRecentTasks.add(i-topIndex, cur); 4015 } 4016 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4017 + " to " + endIndex); 4018 return true; 4019 } 4020 4021 // Whoops, couldn't do it. 4022 return false; 4023 } 4024 4025 final void addRecentTaskLocked(TaskRecord task) { 4026 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4027 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4028 4029 int N = mRecentTasks.size(); 4030 // Quick case: check if the top-most recent task is the same. 4031 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4032 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4033 return; 4034 } 4035 // Another quick case: check if this is part of a set of affiliated 4036 // tasks that are at the top. 4037 if (isAffiliated && N > 0 && task.inRecents 4038 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4039 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4040 + " at top when adding " + task); 4041 return; 4042 } 4043 // Another quick case: never add voice sessions. 4044 if (task.voiceSession != null) { 4045 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4046 return; 4047 } 4048 4049 boolean needAffiliationFix = false; 4050 4051 // Slightly less quick case: the task is already in recents, so all we need 4052 // to do is move it. 4053 if (task.inRecents) { 4054 int taskIndex = mRecentTasks.indexOf(task); 4055 if (taskIndex >= 0) { 4056 if (!isAffiliated) { 4057 // Simple case: this is not an affiliated task, so we just move it to the front. 4058 mRecentTasks.remove(taskIndex); 4059 mRecentTasks.add(0, task); 4060 notifyTaskPersisterLocked(task, false); 4061 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4062 + " from " + taskIndex); 4063 return; 4064 } else { 4065 // More complicated: need to keep all affiliated tasks together. 4066 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4067 // All went well. 4068 return; 4069 } 4070 4071 // Uh oh... something bad in the affiliation chain, try to rebuild 4072 // everything and then go through our general path of adding a new task. 4073 needAffiliationFix = true; 4074 } 4075 } else { 4076 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4077 needAffiliationFix = true; 4078 } 4079 } 4080 4081 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4082 trimRecentsForTask(task, true); 4083 4084 N = mRecentTasks.size(); 4085 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4086 final TaskRecord tr = mRecentTasks.remove(N - 1); 4087 tr.removedFromRecents(mTaskPersister); 4088 N--; 4089 } 4090 task.inRecents = true; 4091 if (!isAffiliated || needAffiliationFix) { 4092 // If this is a simple non-affiliated task, or we had some failure trying to 4093 // handle it as part of an affilated task, then just place it at the top. 4094 mRecentTasks.add(0, task); 4095 } else if (isAffiliated) { 4096 // If this is a new affiliated task, then move all of the affiliated tasks 4097 // to the front and insert this new one. 4098 TaskRecord other = task.mNextAffiliate; 4099 if (other == null) { 4100 other = task.mPrevAffiliate; 4101 } 4102 if (other != null) { 4103 int otherIndex = mRecentTasks.indexOf(other); 4104 if (otherIndex >= 0) { 4105 // Insert new task at appropriate location. 4106 int taskIndex; 4107 if (other == task.mNextAffiliate) { 4108 // We found the index of our next affiliation, which is who is 4109 // before us in the list, so add after that point. 4110 taskIndex = otherIndex+1; 4111 } else { 4112 // We found the index of our previous affiliation, which is who is 4113 // after us in the list, so add at their position. 4114 taskIndex = otherIndex; 4115 } 4116 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4117 + taskIndex + ": " + task); 4118 mRecentTasks.add(taskIndex, task); 4119 4120 // Now move everything to the front. 4121 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4122 // All went well. 4123 return; 4124 } 4125 4126 // Uh oh... something bad in the affiliation chain, try to rebuild 4127 // everything and then go through our general path of adding a new task. 4128 needAffiliationFix = true; 4129 } else { 4130 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4131 + other); 4132 needAffiliationFix = true; 4133 } 4134 } else { 4135 if (DEBUG_RECENTS) Slog.d(TAG, 4136 "addRecent: adding affiliated task without next/prev:" + task); 4137 needAffiliationFix = true; 4138 } 4139 } 4140 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4141 4142 if (needAffiliationFix) { 4143 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4144 cleanupRecentTasksLocked(task.userId); 4145 } 4146 } 4147 4148 /** 4149 * If needed, remove oldest existing entries in recents that are for the same kind 4150 * of task as the given one. 4151 */ 4152 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4153 int N = mRecentTasks.size(); 4154 final Intent intent = task.intent; 4155 final boolean document = intent != null && intent.isDocument(); 4156 4157 int maxRecents = task.maxRecents - 1; 4158 for (int i=0; i<N; i++) { 4159 final TaskRecord tr = mRecentTasks.get(i); 4160 if (task != tr) { 4161 if (task.userId != tr.userId) { 4162 continue; 4163 } 4164 if (i > MAX_RECENT_BITMAPS) { 4165 tr.freeLastThumbnail(); 4166 } 4167 final Intent trIntent = tr.intent; 4168 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4169 (intent == null || !intent.filterEquals(trIntent))) { 4170 continue; 4171 } 4172 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4173 if (document && trIsDocument) { 4174 // These are the same document activity (not necessarily the same doc). 4175 if (maxRecents > 0) { 4176 --maxRecents; 4177 continue; 4178 } 4179 // Hit the maximum number of documents for this task. Fall through 4180 // and remove this document from recents. 4181 } else if (document || trIsDocument) { 4182 // Only one of these is a document. Not the droid we're looking for. 4183 continue; 4184 } 4185 } 4186 4187 if (!doTrim) { 4188 // If the caller is not actually asking for a trim, just tell them we reached 4189 // a point where the trim would happen. 4190 return i; 4191 } 4192 4193 // Either task and tr are the same or, their affinities match or their intents match 4194 // and neither of them is a document, or they are documents using the same activity 4195 // and their maxRecents has been reached. 4196 tr.disposeThumbnail(); 4197 mRecentTasks.remove(i); 4198 if (task != tr) { 4199 tr.removedFromRecents(mTaskPersister); 4200 } 4201 i--; 4202 N--; 4203 if (task.intent == null) { 4204 // If the new recent task we are adding is not fully 4205 // specified, then replace it with the existing recent task. 4206 task = tr; 4207 } 4208 notifyTaskPersisterLocked(tr, false); 4209 } 4210 4211 return -1; 4212 } 4213 4214 @Override 4215 public void reportActivityFullyDrawn(IBinder token) { 4216 synchronized (this) { 4217 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4218 if (r == null) { 4219 return; 4220 } 4221 r.reportFullyDrawnLocked(); 4222 } 4223 } 4224 4225 @Override 4226 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4227 synchronized (this) { 4228 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4229 if (r == null) { 4230 return; 4231 } 4232 final long origId = Binder.clearCallingIdentity(); 4233 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4234 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4235 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4236 if (config != null) { 4237 r.frozenBeforeDestroy = true; 4238 if (!updateConfigurationLocked(config, r, false, false)) { 4239 mStackSupervisor.resumeTopActivitiesLocked(); 4240 } 4241 } 4242 Binder.restoreCallingIdentity(origId); 4243 } 4244 } 4245 4246 @Override 4247 public int getRequestedOrientation(IBinder token) { 4248 synchronized (this) { 4249 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4250 if (r == null) { 4251 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4252 } 4253 return mWindowManager.getAppOrientation(r.appToken); 4254 } 4255 } 4256 4257 /** 4258 * This is the internal entry point for handling Activity.finish(). 4259 * 4260 * @param token The Binder token referencing the Activity we want to finish. 4261 * @param resultCode Result code, if any, from this Activity. 4262 * @param resultData Result data (Intent), if any, from this Activity. 4263 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4264 * the root Activity in the task. 4265 * 4266 * @return Returns true if the activity successfully finished, or false if it is still running. 4267 */ 4268 @Override 4269 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4270 boolean finishTask) { 4271 // Refuse possible leaked file descriptors 4272 if (resultData != null && resultData.hasFileDescriptors() == true) { 4273 throw new IllegalArgumentException("File descriptors passed in Intent"); 4274 } 4275 4276 synchronized(this) { 4277 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4278 if (r == null) { 4279 return true; 4280 } 4281 // Keep track of the root activity of the task before we finish it 4282 TaskRecord tr = r.task; 4283 ActivityRecord rootR = tr.getRootActivity(); 4284 // Do not allow task to finish in Lock Task mode. 4285 if (tr == mStackSupervisor.mLockTaskModeTask) { 4286 if (rootR == r) { 4287 mStackSupervisor.showLockTaskToast(); 4288 return false; 4289 } 4290 } 4291 if (mController != null) { 4292 // Find the first activity that is not finishing. 4293 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4294 if (next != null) { 4295 // ask watcher if this is allowed 4296 boolean resumeOK = true; 4297 try { 4298 resumeOK = mController.activityResuming(next.packageName); 4299 } catch (RemoteException e) { 4300 mController = null; 4301 Watchdog.getInstance().setActivityController(null); 4302 } 4303 4304 if (!resumeOK) { 4305 return false; 4306 } 4307 } 4308 } 4309 final long origId = Binder.clearCallingIdentity(); 4310 try { 4311 boolean res; 4312 if (finishTask && r == rootR) { 4313 // If requested, remove the task that is associated to this activity only if it 4314 // was the root activity in the task. The result code and data is ignored 4315 // because we don't support returning them across task boundaries. 4316 res = removeTaskByIdLocked(tr.taskId, false); 4317 } else { 4318 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4319 resultData, "app-request", true); 4320 } 4321 return res; 4322 } finally { 4323 Binder.restoreCallingIdentity(origId); 4324 } 4325 } 4326 } 4327 4328 @Override 4329 public final void finishHeavyWeightApp() { 4330 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4331 != PackageManager.PERMISSION_GRANTED) { 4332 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4333 + Binder.getCallingPid() 4334 + ", uid=" + Binder.getCallingUid() 4335 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4336 Slog.w(TAG, msg); 4337 throw new SecurityException(msg); 4338 } 4339 4340 synchronized(this) { 4341 if (mHeavyWeightProcess == null) { 4342 return; 4343 } 4344 4345 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4346 mHeavyWeightProcess.activities); 4347 for (int i=0; i<activities.size(); i++) { 4348 ActivityRecord r = activities.get(i); 4349 if (!r.finishing) { 4350 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4351 null, "finish-heavy", true); 4352 } 4353 } 4354 4355 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4356 mHeavyWeightProcess.userId, 0)); 4357 mHeavyWeightProcess = null; 4358 } 4359 } 4360 4361 @Override 4362 public void crashApplication(int uid, int initialPid, String packageName, 4363 String message) { 4364 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4365 != PackageManager.PERMISSION_GRANTED) { 4366 String msg = "Permission Denial: crashApplication() from pid=" 4367 + Binder.getCallingPid() 4368 + ", uid=" + Binder.getCallingUid() 4369 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4370 Slog.w(TAG, msg); 4371 throw new SecurityException(msg); 4372 } 4373 4374 synchronized(this) { 4375 ProcessRecord proc = null; 4376 4377 // Figure out which process to kill. We don't trust that initialPid 4378 // still has any relation to current pids, so must scan through the 4379 // list. 4380 synchronized (mPidsSelfLocked) { 4381 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4382 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4383 if (p.uid != uid) { 4384 continue; 4385 } 4386 if (p.pid == initialPid) { 4387 proc = p; 4388 break; 4389 } 4390 if (p.pkgList.containsKey(packageName)) { 4391 proc = p; 4392 } 4393 } 4394 } 4395 4396 if (proc == null) { 4397 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4398 + " initialPid=" + initialPid 4399 + " packageName=" + packageName); 4400 return; 4401 } 4402 4403 if (proc.thread != null) { 4404 if (proc.pid == Process.myPid()) { 4405 Log.w(TAG, "crashApplication: trying to crash self!"); 4406 return; 4407 } 4408 long ident = Binder.clearCallingIdentity(); 4409 try { 4410 proc.thread.scheduleCrash(message); 4411 } catch (RemoteException e) { 4412 } 4413 Binder.restoreCallingIdentity(ident); 4414 } 4415 } 4416 } 4417 4418 @Override 4419 public final void finishSubActivity(IBinder token, String resultWho, 4420 int requestCode) { 4421 synchronized(this) { 4422 final long origId = Binder.clearCallingIdentity(); 4423 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4424 if (r != null) { 4425 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4426 } 4427 Binder.restoreCallingIdentity(origId); 4428 } 4429 } 4430 4431 @Override 4432 public boolean finishActivityAffinity(IBinder token) { 4433 synchronized(this) { 4434 final long origId = Binder.clearCallingIdentity(); 4435 try { 4436 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4437 4438 ActivityRecord rootR = r.task.getRootActivity(); 4439 // Do not allow task to finish in Lock Task mode. 4440 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4441 if (rootR == r) { 4442 mStackSupervisor.showLockTaskToast(); 4443 return false; 4444 } 4445 } 4446 boolean res = false; 4447 if (r != null) { 4448 res = r.task.stack.finishActivityAffinityLocked(r); 4449 } 4450 return res; 4451 } finally { 4452 Binder.restoreCallingIdentity(origId); 4453 } 4454 } 4455 } 4456 4457 @Override 4458 public void finishVoiceTask(IVoiceInteractionSession session) { 4459 synchronized(this) { 4460 final long origId = Binder.clearCallingIdentity(); 4461 try { 4462 mStackSupervisor.finishVoiceTask(session); 4463 } finally { 4464 Binder.restoreCallingIdentity(origId); 4465 } 4466 } 4467 4468 } 4469 4470 @Override 4471 public boolean releaseActivityInstance(IBinder token) { 4472 synchronized(this) { 4473 final long origId = Binder.clearCallingIdentity(); 4474 try { 4475 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4476 if (r.task == null || r.task.stack == null) { 4477 return false; 4478 } 4479 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4480 } finally { 4481 Binder.restoreCallingIdentity(origId); 4482 } 4483 } 4484 } 4485 4486 @Override 4487 public void releaseSomeActivities(IApplicationThread appInt) { 4488 synchronized(this) { 4489 final long origId = Binder.clearCallingIdentity(); 4490 try { 4491 ProcessRecord app = getRecordForAppLocked(appInt); 4492 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4493 } finally { 4494 Binder.restoreCallingIdentity(origId); 4495 } 4496 } 4497 } 4498 4499 @Override 4500 public boolean willActivityBeVisible(IBinder token) { 4501 synchronized(this) { 4502 ActivityStack stack = ActivityRecord.getStackLocked(token); 4503 if (stack != null) { 4504 return stack.willActivityBeVisibleLocked(token); 4505 } 4506 return false; 4507 } 4508 } 4509 4510 @Override 4511 public void overridePendingTransition(IBinder token, String packageName, 4512 int enterAnim, int exitAnim) { 4513 synchronized(this) { 4514 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4515 if (self == null) { 4516 return; 4517 } 4518 4519 final long origId = Binder.clearCallingIdentity(); 4520 4521 if (self.state == ActivityState.RESUMED 4522 || self.state == ActivityState.PAUSING) { 4523 mWindowManager.overridePendingAppTransition(packageName, 4524 enterAnim, exitAnim, null); 4525 } 4526 4527 Binder.restoreCallingIdentity(origId); 4528 } 4529 } 4530 4531 /** 4532 * Main function for removing an existing process from the activity manager 4533 * as a result of that process going away. Clears out all connections 4534 * to the process. 4535 */ 4536 private final void handleAppDiedLocked(ProcessRecord app, 4537 boolean restarting, boolean allowRestart) { 4538 int pid = app.pid; 4539 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4540 if (!kept && !restarting) { 4541 removeLruProcessLocked(app); 4542 if (pid > 0) { 4543 ProcessList.remove(pid); 4544 } 4545 } 4546 4547 if (mProfileProc == app) { 4548 clearProfilerLocked(); 4549 } 4550 4551 // Remove this application's activities from active lists. 4552 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4553 4554 app.activities.clear(); 4555 4556 if (app.instrumentationClass != null) { 4557 Slog.w(TAG, "Crash of app " + app.processName 4558 + " running instrumentation " + app.instrumentationClass); 4559 Bundle info = new Bundle(); 4560 info.putString("shortMsg", "Process crashed."); 4561 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4562 } 4563 4564 if (!restarting) { 4565 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4566 // If there was nothing to resume, and we are not already 4567 // restarting this process, but there is a visible activity that 4568 // is hosted by the process... then make sure all visible 4569 // activities are running, taking care of restarting this 4570 // process. 4571 if (hasVisibleActivities) { 4572 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4573 } 4574 } 4575 } 4576 } 4577 4578 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4579 IBinder threadBinder = thread.asBinder(); 4580 // Find the application record. 4581 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4582 ProcessRecord rec = mLruProcesses.get(i); 4583 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4584 return i; 4585 } 4586 } 4587 return -1; 4588 } 4589 4590 final ProcessRecord getRecordForAppLocked( 4591 IApplicationThread thread) { 4592 if (thread == null) { 4593 return null; 4594 } 4595 4596 int appIndex = getLRURecordIndexForAppLocked(thread); 4597 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4598 } 4599 4600 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4601 // If there are no longer any background processes running, 4602 // and the app that died was not running instrumentation, 4603 // then tell everyone we are now low on memory. 4604 boolean haveBg = false; 4605 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4606 ProcessRecord rec = mLruProcesses.get(i); 4607 if (rec.thread != null 4608 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4609 haveBg = true; 4610 break; 4611 } 4612 } 4613 4614 if (!haveBg) { 4615 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4616 if (doReport) { 4617 long now = SystemClock.uptimeMillis(); 4618 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4619 doReport = false; 4620 } else { 4621 mLastMemUsageReportTime = now; 4622 } 4623 } 4624 final ArrayList<ProcessMemInfo> memInfos 4625 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4626 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4627 long now = SystemClock.uptimeMillis(); 4628 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4629 ProcessRecord rec = mLruProcesses.get(i); 4630 if (rec == dyingProc || rec.thread == null) { 4631 continue; 4632 } 4633 if (doReport) { 4634 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4635 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4636 } 4637 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4638 // The low memory report is overriding any current 4639 // state for a GC request. Make sure to do 4640 // heavy/important/visible/foreground processes first. 4641 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4642 rec.lastRequestedGc = 0; 4643 } else { 4644 rec.lastRequestedGc = rec.lastLowMemory; 4645 } 4646 rec.reportLowMemory = true; 4647 rec.lastLowMemory = now; 4648 mProcessesToGc.remove(rec); 4649 addProcessToGcListLocked(rec); 4650 } 4651 } 4652 if (doReport) { 4653 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4654 mHandler.sendMessage(msg); 4655 } 4656 scheduleAppGcsLocked(); 4657 } 4658 } 4659 4660 final void appDiedLocked(ProcessRecord app) { 4661 appDiedLocked(app, app.pid, app.thread); 4662 } 4663 4664 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4665 // First check if this ProcessRecord is actually active for the pid. 4666 synchronized (mPidsSelfLocked) { 4667 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4668 if (curProc != app) { 4669 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4670 return; 4671 } 4672 } 4673 4674 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4675 synchronized (stats) { 4676 stats.noteProcessDiedLocked(app.info.uid, pid); 4677 } 4678 4679 Process.killProcessQuiet(pid); 4680 Process.killProcessGroup(app.info.uid, pid); 4681 app.killed = true; 4682 4683 // Clean up already done if the process has been re-started. 4684 if (app.pid == pid && app.thread != null && 4685 app.thread.asBinder() == thread.asBinder()) { 4686 boolean doLowMem = app.instrumentationClass == null; 4687 boolean doOomAdj = doLowMem; 4688 if (!app.killedByAm) { 4689 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4690 + ") has died"); 4691 mAllowLowerMemLevel = true; 4692 } else { 4693 // Note that we always want to do oom adj to update our state with the 4694 // new number of procs. 4695 mAllowLowerMemLevel = false; 4696 doLowMem = false; 4697 } 4698 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4699 if (DEBUG_CLEANUP) Slog.v( 4700 TAG, "Dying app: " + app + ", pid: " + pid 4701 + ", thread: " + thread.asBinder()); 4702 handleAppDiedLocked(app, false, true); 4703 4704 if (doOomAdj) { 4705 updateOomAdjLocked(); 4706 } 4707 if (doLowMem) { 4708 doLowMemReportIfNeededLocked(app); 4709 } 4710 } else if (app.pid != pid) { 4711 // A new process has already been started. 4712 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4713 + ") has died and restarted (pid " + app.pid + ")."); 4714 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4715 } else if (DEBUG_PROCESSES) { 4716 Slog.d(TAG, "Received spurious death notification for thread " 4717 + thread.asBinder()); 4718 } 4719 } 4720 4721 /** 4722 * If a stack trace dump file is configured, dump process stack traces. 4723 * @param clearTraces causes the dump file to be erased prior to the new 4724 * traces being written, if true; when false, the new traces will be 4725 * appended to any existing file content. 4726 * @param firstPids of dalvik VM processes to dump stack traces for first 4727 * @param lastPids of dalvik VM processes to dump stack traces for last 4728 * @param nativeProcs optional list of native process names to dump stack crawls 4729 * @return file containing stack traces, or null if no dump file is configured 4730 */ 4731 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4732 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4733 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4734 if (tracesPath == null || tracesPath.length() == 0) { 4735 return null; 4736 } 4737 4738 File tracesFile = new File(tracesPath); 4739 try { 4740 File tracesDir = tracesFile.getParentFile(); 4741 if (!tracesDir.exists()) { 4742 tracesDir.mkdirs(); 4743 if (!SELinux.restorecon(tracesDir)) { 4744 return null; 4745 } 4746 } 4747 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4748 4749 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4750 tracesFile.createNewFile(); 4751 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4752 } catch (IOException e) { 4753 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4754 return null; 4755 } 4756 4757 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4758 return tracesFile; 4759 } 4760 4761 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4762 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4763 // Use a FileObserver to detect when traces finish writing. 4764 // The order of traces is considered important to maintain for legibility. 4765 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4766 @Override 4767 public synchronized void onEvent(int event, String path) { notify(); } 4768 }; 4769 4770 try { 4771 observer.startWatching(); 4772 4773 // First collect all of the stacks of the most important pids. 4774 if (firstPids != null) { 4775 try { 4776 int num = firstPids.size(); 4777 for (int i = 0; i < num; i++) { 4778 synchronized (observer) { 4779 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4780 observer.wait(200); // Wait for write-close, give up after 200msec 4781 } 4782 } 4783 } catch (InterruptedException e) { 4784 Slog.wtf(TAG, e); 4785 } 4786 } 4787 4788 // Next collect the stacks of the native pids 4789 if (nativeProcs != null) { 4790 int[] pids = Process.getPidsForCommands(nativeProcs); 4791 if (pids != null) { 4792 for (int pid : pids) { 4793 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4794 } 4795 } 4796 } 4797 4798 // Lastly, measure CPU usage. 4799 if (processCpuTracker != null) { 4800 processCpuTracker.init(); 4801 System.gc(); 4802 processCpuTracker.update(); 4803 try { 4804 synchronized (processCpuTracker) { 4805 processCpuTracker.wait(500); // measure over 1/2 second. 4806 } 4807 } catch (InterruptedException e) { 4808 } 4809 processCpuTracker.update(); 4810 4811 // We'll take the stack crawls of just the top apps using CPU. 4812 final int N = processCpuTracker.countWorkingStats(); 4813 int numProcs = 0; 4814 for (int i=0; i<N && numProcs<5; i++) { 4815 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4816 if (lastPids.indexOfKey(stats.pid) >= 0) { 4817 numProcs++; 4818 try { 4819 synchronized (observer) { 4820 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4821 observer.wait(200); // Wait for write-close, give up after 200msec 4822 } 4823 } catch (InterruptedException e) { 4824 Slog.wtf(TAG, e); 4825 } 4826 4827 } 4828 } 4829 } 4830 } finally { 4831 observer.stopWatching(); 4832 } 4833 } 4834 4835 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4836 if (true || IS_USER_BUILD) { 4837 return; 4838 } 4839 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4840 if (tracesPath == null || tracesPath.length() == 0) { 4841 return; 4842 } 4843 4844 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4845 StrictMode.allowThreadDiskWrites(); 4846 try { 4847 final File tracesFile = new File(tracesPath); 4848 final File tracesDir = tracesFile.getParentFile(); 4849 final File tracesTmp = new File(tracesDir, "__tmp__"); 4850 try { 4851 if (!tracesDir.exists()) { 4852 tracesDir.mkdirs(); 4853 if (!SELinux.restorecon(tracesDir.getPath())) { 4854 return; 4855 } 4856 } 4857 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4858 4859 if (tracesFile.exists()) { 4860 tracesTmp.delete(); 4861 tracesFile.renameTo(tracesTmp); 4862 } 4863 StringBuilder sb = new StringBuilder(); 4864 Time tobj = new Time(); 4865 tobj.set(System.currentTimeMillis()); 4866 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4867 sb.append(": "); 4868 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4869 sb.append(" since "); 4870 sb.append(msg); 4871 FileOutputStream fos = new FileOutputStream(tracesFile); 4872 fos.write(sb.toString().getBytes()); 4873 if (app == null) { 4874 fos.write("\n*** No application process!".getBytes()); 4875 } 4876 fos.close(); 4877 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4878 } catch (IOException e) { 4879 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4880 return; 4881 } 4882 4883 if (app != null) { 4884 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4885 firstPids.add(app.pid); 4886 dumpStackTraces(tracesPath, firstPids, null, null, null); 4887 } 4888 4889 File lastTracesFile = null; 4890 File curTracesFile = null; 4891 for (int i=9; i>=0; i--) { 4892 String name = String.format(Locale.US, "slow%02d.txt", i); 4893 curTracesFile = new File(tracesDir, name); 4894 if (curTracesFile.exists()) { 4895 if (lastTracesFile != null) { 4896 curTracesFile.renameTo(lastTracesFile); 4897 } else { 4898 curTracesFile.delete(); 4899 } 4900 } 4901 lastTracesFile = curTracesFile; 4902 } 4903 tracesFile.renameTo(curTracesFile); 4904 if (tracesTmp.exists()) { 4905 tracesTmp.renameTo(tracesFile); 4906 } 4907 } finally { 4908 StrictMode.setThreadPolicy(oldPolicy); 4909 } 4910 } 4911 4912 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4913 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4914 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4915 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4916 4917 if (mController != null) { 4918 try { 4919 // 0 == continue, -1 = kill process immediately 4920 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4921 if (res < 0 && app.pid != MY_PID) { 4922 app.kill("anr", true); 4923 } 4924 } catch (RemoteException e) { 4925 mController = null; 4926 Watchdog.getInstance().setActivityController(null); 4927 } 4928 } 4929 4930 long anrTime = SystemClock.uptimeMillis(); 4931 if (MONITOR_CPU_USAGE) { 4932 updateCpuStatsNow(); 4933 } 4934 4935 synchronized (this) { 4936 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4937 if (mShuttingDown) { 4938 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4939 return; 4940 } else if (app.notResponding) { 4941 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4942 return; 4943 } else if (app.crashing) { 4944 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4945 return; 4946 } 4947 4948 // In case we come through here for the same app before completing 4949 // this one, mark as anring now so we will bail out. 4950 app.notResponding = true; 4951 4952 // Log the ANR to the event log. 4953 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4954 app.processName, app.info.flags, annotation); 4955 4956 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4957 firstPids.add(app.pid); 4958 4959 int parentPid = app.pid; 4960 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4961 if (parentPid != app.pid) firstPids.add(parentPid); 4962 4963 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4964 4965 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4966 ProcessRecord r = mLruProcesses.get(i); 4967 if (r != null && r.thread != null) { 4968 int pid = r.pid; 4969 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4970 if (r.persistent) { 4971 firstPids.add(pid); 4972 } else { 4973 lastPids.put(pid, Boolean.TRUE); 4974 } 4975 } 4976 } 4977 } 4978 } 4979 4980 // Log the ANR to the main log. 4981 StringBuilder info = new StringBuilder(); 4982 info.setLength(0); 4983 info.append("ANR in ").append(app.processName); 4984 if (activity != null && activity.shortComponentName != null) { 4985 info.append(" (").append(activity.shortComponentName).append(")"); 4986 } 4987 info.append("\n"); 4988 info.append("PID: ").append(app.pid).append("\n"); 4989 if (annotation != null) { 4990 info.append("Reason: ").append(annotation).append("\n"); 4991 } 4992 if (parent != null && parent != activity) { 4993 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4994 } 4995 4996 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4997 4998 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4999 NATIVE_STACKS_OF_INTEREST); 5000 5001 String cpuInfo = null; 5002 if (MONITOR_CPU_USAGE) { 5003 updateCpuStatsNow(); 5004 synchronized (mProcessCpuTracker) { 5005 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5006 } 5007 info.append(processCpuTracker.printCurrentLoad()); 5008 info.append(cpuInfo); 5009 } 5010 5011 info.append(processCpuTracker.printCurrentState(anrTime)); 5012 5013 Slog.e(TAG, info.toString()); 5014 if (tracesFile == null) { 5015 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5016 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5017 } 5018 5019 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5020 cpuInfo, tracesFile, null); 5021 5022 if (mController != null) { 5023 try { 5024 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5025 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5026 if (res != 0) { 5027 if (res < 0 && app.pid != MY_PID) { 5028 app.kill("anr", true); 5029 } else { 5030 synchronized (this) { 5031 mServices.scheduleServiceTimeoutLocked(app); 5032 } 5033 } 5034 return; 5035 } 5036 } catch (RemoteException e) { 5037 mController = null; 5038 Watchdog.getInstance().setActivityController(null); 5039 } 5040 } 5041 5042 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5043 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5044 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5045 5046 synchronized (this) { 5047 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5048 app.kill("bg anr", true); 5049 return; 5050 } 5051 5052 // Set the app's notResponding state, and look up the errorReportReceiver 5053 makeAppNotRespondingLocked(app, 5054 activity != null ? activity.shortComponentName : null, 5055 annotation != null ? "ANR " + annotation : "ANR", 5056 info.toString()); 5057 5058 // Bring up the infamous App Not Responding dialog 5059 Message msg = Message.obtain(); 5060 HashMap<String, Object> map = new HashMap<String, Object>(); 5061 msg.what = SHOW_NOT_RESPONDING_MSG; 5062 msg.obj = map; 5063 msg.arg1 = aboveSystem ? 1 : 0; 5064 map.put("app", app); 5065 if (activity != null) { 5066 map.put("activity", activity); 5067 } 5068 5069 mHandler.sendMessage(msg); 5070 } 5071 } 5072 5073 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5074 if (!mLaunchWarningShown) { 5075 mLaunchWarningShown = true; 5076 mHandler.post(new Runnable() { 5077 @Override 5078 public void run() { 5079 synchronized (ActivityManagerService.this) { 5080 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5081 d.show(); 5082 mHandler.postDelayed(new Runnable() { 5083 @Override 5084 public void run() { 5085 synchronized (ActivityManagerService.this) { 5086 d.dismiss(); 5087 mLaunchWarningShown = false; 5088 } 5089 } 5090 }, 4000); 5091 } 5092 } 5093 }); 5094 } 5095 } 5096 5097 @Override 5098 public boolean clearApplicationUserData(final String packageName, 5099 final IPackageDataObserver observer, int userId) { 5100 enforceNotIsolatedCaller("clearApplicationUserData"); 5101 int uid = Binder.getCallingUid(); 5102 int pid = Binder.getCallingPid(); 5103 userId = handleIncomingUser(pid, uid, 5104 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5105 long callingId = Binder.clearCallingIdentity(); 5106 try { 5107 IPackageManager pm = AppGlobals.getPackageManager(); 5108 int pkgUid = -1; 5109 synchronized(this) { 5110 try { 5111 pkgUid = pm.getPackageUid(packageName, userId); 5112 } catch (RemoteException e) { 5113 } 5114 if (pkgUid == -1) { 5115 Slog.w(TAG, "Invalid packageName: " + packageName); 5116 if (observer != null) { 5117 try { 5118 observer.onRemoveCompleted(packageName, false); 5119 } catch (RemoteException e) { 5120 Slog.i(TAG, "Observer no longer exists."); 5121 } 5122 } 5123 return false; 5124 } 5125 if (uid == pkgUid || checkComponentPermission( 5126 android.Manifest.permission.CLEAR_APP_USER_DATA, 5127 pid, uid, -1, true) 5128 == PackageManager.PERMISSION_GRANTED) { 5129 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5130 } else { 5131 throw new SecurityException("PID " + pid + " does not have permission " 5132 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5133 + " of package " + packageName); 5134 } 5135 5136 // Remove all tasks match the cleared application package and user 5137 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5138 final TaskRecord tr = mRecentTasks.get(i); 5139 final String taskPackageName = 5140 tr.getBaseIntent().getComponent().getPackageName(); 5141 if (tr.userId != userId) continue; 5142 if (!taskPackageName.equals(packageName)) continue; 5143 removeTaskByIdLocked(tr.taskId, false); 5144 } 5145 } 5146 5147 try { 5148 // Clear application user data 5149 pm.clearApplicationUserData(packageName, observer, userId); 5150 5151 synchronized(this) { 5152 // Remove all permissions granted from/to this package 5153 removeUriPermissionsForPackageLocked(packageName, userId, true); 5154 } 5155 5156 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5157 Uri.fromParts("package", packageName, null)); 5158 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5159 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5160 null, null, 0, null, null, null, false, false, userId); 5161 } catch (RemoteException e) { 5162 } 5163 } finally { 5164 Binder.restoreCallingIdentity(callingId); 5165 } 5166 return true; 5167 } 5168 5169 @Override 5170 public void killBackgroundProcesses(final String packageName, int userId) { 5171 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5172 != PackageManager.PERMISSION_GRANTED && 5173 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5174 != PackageManager.PERMISSION_GRANTED) { 5175 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5176 + Binder.getCallingPid() 5177 + ", uid=" + Binder.getCallingUid() 5178 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5179 Slog.w(TAG, msg); 5180 throw new SecurityException(msg); 5181 } 5182 5183 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5184 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5185 long callingId = Binder.clearCallingIdentity(); 5186 try { 5187 IPackageManager pm = AppGlobals.getPackageManager(); 5188 synchronized(this) { 5189 int appId = -1; 5190 try { 5191 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5192 } catch (RemoteException e) { 5193 } 5194 if (appId == -1) { 5195 Slog.w(TAG, "Invalid packageName: " + packageName); 5196 return; 5197 } 5198 killPackageProcessesLocked(packageName, appId, userId, 5199 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5200 } 5201 } finally { 5202 Binder.restoreCallingIdentity(callingId); 5203 } 5204 } 5205 5206 @Override 5207 public void killAllBackgroundProcesses() { 5208 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5209 != PackageManager.PERMISSION_GRANTED) { 5210 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5211 + Binder.getCallingPid() 5212 + ", uid=" + Binder.getCallingUid() 5213 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5214 Slog.w(TAG, msg); 5215 throw new SecurityException(msg); 5216 } 5217 5218 long callingId = Binder.clearCallingIdentity(); 5219 try { 5220 synchronized(this) { 5221 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5222 final int NP = mProcessNames.getMap().size(); 5223 for (int ip=0; ip<NP; ip++) { 5224 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5225 final int NA = apps.size(); 5226 for (int ia=0; ia<NA; ia++) { 5227 ProcessRecord app = apps.valueAt(ia); 5228 if (app.persistent) { 5229 // we don't kill persistent processes 5230 continue; 5231 } 5232 if (app.removed) { 5233 procs.add(app); 5234 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5235 app.removed = true; 5236 procs.add(app); 5237 } 5238 } 5239 } 5240 5241 int N = procs.size(); 5242 for (int i=0; i<N; i++) { 5243 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5244 } 5245 mAllowLowerMemLevel = true; 5246 updateOomAdjLocked(); 5247 doLowMemReportIfNeededLocked(null); 5248 } 5249 } finally { 5250 Binder.restoreCallingIdentity(callingId); 5251 } 5252 } 5253 5254 @Override 5255 public void forceStopPackage(final String packageName, int userId) { 5256 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5257 != PackageManager.PERMISSION_GRANTED) { 5258 String msg = "Permission Denial: forceStopPackage() from pid=" 5259 + Binder.getCallingPid() 5260 + ", uid=" + Binder.getCallingUid() 5261 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5262 Slog.w(TAG, msg); 5263 throw new SecurityException(msg); 5264 } 5265 final int callingPid = Binder.getCallingPid(); 5266 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5267 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5268 long callingId = Binder.clearCallingIdentity(); 5269 try { 5270 IPackageManager pm = AppGlobals.getPackageManager(); 5271 synchronized(this) { 5272 int[] users = userId == UserHandle.USER_ALL 5273 ? getUsersLocked() : new int[] { userId }; 5274 for (int user : users) { 5275 int pkgUid = -1; 5276 try { 5277 pkgUid = pm.getPackageUid(packageName, user); 5278 } catch (RemoteException e) { 5279 } 5280 if (pkgUid == -1) { 5281 Slog.w(TAG, "Invalid packageName: " + packageName); 5282 continue; 5283 } 5284 try { 5285 pm.setPackageStoppedState(packageName, true, user); 5286 } catch (RemoteException e) { 5287 } catch (IllegalArgumentException e) { 5288 Slog.w(TAG, "Failed trying to unstop package " 5289 + packageName + ": " + e); 5290 } 5291 if (isUserRunningLocked(user, false)) { 5292 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5293 } 5294 } 5295 } 5296 } finally { 5297 Binder.restoreCallingIdentity(callingId); 5298 } 5299 } 5300 5301 @Override 5302 public void addPackageDependency(String packageName) { 5303 synchronized (this) { 5304 int callingPid = Binder.getCallingPid(); 5305 if (callingPid == Process.myPid()) { 5306 // Yeah, um, no. 5307 Slog.w(TAG, "Can't addPackageDependency on system process"); 5308 return; 5309 } 5310 ProcessRecord proc; 5311 synchronized (mPidsSelfLocked) { 5312 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5313 } 5314 if (proc != null) { 5315 if (proc.pkgDeps == null) { 5316 proc.pkgDeps = new ArraySet<String>(1); 5317 } 5318 proc.pkgDeps.add(packageName); 5319 } 5320 } 5321 } 5322 5323 /* 5324 * The pkg name and app id have to be specified. 5325 */ 5326 @Override 5327 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5328 if (pkg == null) { 5329 return; 5330 } 5331 // Make sure the uid is valid. 5332 if (appid < 0) { 5333 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5334 return; 5335 } 5336 int callerUid = Binder.getCallingUid(); 5337 // Only the system server can kill an application 5338 if (callerUid == Process.SYSTEM_UID) { 5339 // Post an aysnc message to kill the application 5340 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5341 msg.arg1 = appid; 5342 msg.arg2 = 0; 5343 Bundle bundle = new Bundle(); 5344 bundle.putString("pkg", pkg); 5345 bundle.putString("reason", reason); 5346 msg.obj = bundle; 5347 mHandler.sendMessage(msg); 5348 } else { 5349 throw new SecurityException(callerUid + " cannot kill pkg: " + 5350 pkg); 5351 } 5352 } 5353 5354 @Override 5355 public void closeSystemDialogs(String reason) { 5356 enforceNotIsolatedCaller("closeSystemDialogs"); 5357 5358 final int pid = Binder.getCallingPid(); 5359 final int uid = Binder.getCallingUid(); 5360 final long origId = Binder.clearCallingIdentity(); 5361 try { 5362 synchronized (this) { 5363 // Only allow this from foreground processes, so that background 5364 // applications can't abuse it to prevent system UI from being shown. 5365 if (uid >= Process.FIRST_APPLICATION_UID) { 5366 ProcessRecord proc; 5367 synchronized (mPidsSelfLocked) { 5368 proc = mPidsSelfLocked.get(pid); 5369 } 5370 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5371 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5372 + " from background process " + proc); 5373 return; 5374 } 5375 } 5376 closeSystemDialogsLocked(reason); 5377 } 5378 } finally { 5379 Binder.restoreCallingIdentity(origId); 5380 } 5381 } 5382 5383 void closeSystemDialogsLocked(String reason) { 5384 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5385 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5386 | Intent.FLAG_RECEIVER_FOREGROUND); 5387 if (reason != null) { 5388 intent.putExtra("reason", reason); 5389 } 5390 mWindowManager.closeSystemDialogs(reason); 5391 5392 mStackSupervisor.closeSystemDialogsLocked(); 5393 5394 broadcastIntentLocked(null, null, intent, null, 5395 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5396 Process.SYSTEM_UID, UserHandle.USER_ALL); 5397 } 5398 5399 @Override 5400 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5401 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5402 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5403 for (int i=pids.length-1; i>=0; i--) { 5404 ProcessRecord proc; 5405 int oomAdj; 5406 synchronized (this) { 5407 synchronized (mPidsSelfLocked) { 5408 proc = mPidsSelfLocked.get(pids[i]); 5409 oomAdj = proc != null ? proc.setAdj : 0; 5410 } 5411 } 5412 infos[i] = new Debug.MemoryInfo(); 5413 Debug.getMemoryInfo(pids[i], infos[i]); 5414 if (proc != null) { 5415 synchronized (this) { 5416 if (proc.thread != null && proc.setAdj == oomAdj) { 5417 // Record this for posterity if the process has been stable. 5418 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5419 infos[i].getTotalUss(), false, proc.pkgList); 5420 } 5421 } 5422 } 5423 } 5424 return infos; 5425 } 5426 5427 @Override 5428 public long[] getProcessPss(int[] pids) { 5429 enforceNotIsolatedCaller("getProcessPss"); 5430 long[] pss = new long[pids.length]; 5431 for (int i=pids.length-1; i>=0; i--) { 5432 ProcessRecord proc; 5433 int oomAdj; 5434 synchronized (this) { 5435 synchronized (mPidsSelfLocked) { 5436 proc = mPidsSelfLocked.get(pids[i]); 5437 oomAdj = proc != null ? proc.setAdj : 0; 5438 } 5439 } 5440 long[] tmpUss = new long[1]; 5441 pss[i] = Debug.getPss(pids[i], tmpUss); 5442 if (proc != null) { 5443 synchronized (this) { 5444 if (proc.thread != null && proc.setAdj == oomAdj) { 5445 // Record this for posterity if the process has been stable. 5446 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5447 } 5448 } 5449 } 5450 } 5451 return pss; 5452 } 5453 5454 @Override 5455 public void killApplicationProcess(String processName, int uid) { 5456 if (processName == null) { 5457 return; 5458 } 5459 5460 int callerUid = Binder.getCallingUid(); 5461 // Only the system server can kill an application 5462 if (callerUid == Process.SYSTEM_UID) { 5463 synchronized (this) { 5464 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5465 if (app != null && app.thread != null) { 5466 try { 5467 app.thread.scheduleSuicide(); 5468 } catch (RemoteException e) { 5469 // If the other end already died, then our work here is done. 5470 } 5471 } else { 5472 Slog.w(TAG, "Process/uid not found attempting kill of " 5473 + processName + " / " + uid); 5474 } 5475 } 5476 } else { 5477 throw new SecurityException(callerUid + " cannot kill app process: " + 5478 processName); 5479 } 5480 } 5481 5482 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5483 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5484 false, true, false, false, UserHandle.getUserId(uid), reason); 5485 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5486 Uri.fromParts("package", packageName, null)); 5487 if (!mProcessesReady) { 5488 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5489 | Intent.FLAG_RECEIVER_FOREGROUND); 5490 } 5491 intent.putExtra(Intent.EXTRA_UID, uid); 5492 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5493 broadcastIntentLocked(null, null, intent, 5494 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5495 false, false, 5496 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5497 } 5498 5499 private void forceStopUserLocked(int userId, String reason) { 5500 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5501 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5502 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5503 | Intent.FLAG_RECEIVER_FOREGROUND); 5504 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5505 broadcastIntentLocked(null, null, intent, 5506 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5507 false, false, 5508 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5509 } 5510 5511 private final boolean killPackageProcessesLocked(String packageName, int appId, 5512 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5513 boolean doit, boolean evenPersistent, String reason) { 5514 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5515 5516 // Remove all processes this package may have touched: all with the 5517 // same UID (except for the system or root user), and all whose name 5518 // matches the package name. 5519 final int NP = mProcessNames.getMap().size(); 5520 for (int ip=0; ip<NP; ip++) { 5521 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5522 final int NA = apps.size(); 5523 for (int ia=0; ia<NA; ia++) { 5524 ProcessRecord app = apps.valueAt(ia); 5525 if (app.persistent && !evenPersistent) { 5526 // we don't kill persistent processes 5527 continue; 5528 } 5529 if (app.removed) { 5530 if (doit) { 5531 procs.add(app); 5532 } 5533 continue; 5534 } 5535 5536 // Skip process if it doesn't meet our oom adj requirement. 5537 if (app.setAdj < minOomAdj) { 5538 continue; 5539 } 5540 5541 // If no package is specified, we call all processes under the 5542 // give user id. 5543 if (packageName == null) { 5544 if (app.userId != userId) { 5545 continue; 5546 } 5547 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5548 continue; 5549 } 5550 // Package has been specified, we want to hit all processes 5551 // that match it. We need to qualify this by the processes 5552 // that are running under the specified app and user ID. 5553 } else { 5554 final boolean isDep = app.pkgDeps != null 5555 && app.pkgDeps.contains(packageName); 5556 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5557 continue; 5558 } 5559 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5560 continue; 5561 } 5562 if (!app.pkgList.containsKey(packageName) && !isDep) { 5563 continue; 5564 } 5565 } 5566 5567 // Process has passed all conditions, kill it! 5568 if (!doit) { 5569 return true; 5570 } 5571 app.removed = true; 5572 procs.add(app); 5573 } 5574 } 5575 5576 int N = procs.size(); 5577 for (int i=0; i<N; i++) { 5578 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5579 } 5580 updateOomAdjLocked(); 5581 return N > 0; 5582 } 5583 5584 private final boolean forceStopPackageLocked(String name, int appId, 5585 boolean callerWillRestart, boolean purgeCache, boolean doit, 5586 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5587 int i; 5588 int N; 5589 5590 if (userId == UserHandle.USER_ALL && name == null) { 5591 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5592 } 5593 5594 if (appId < 0 && name != null) { 5595 try { 5596 appId = UserHandle.getAppId( 5597 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5598 } catch (RemoteException e) { 5599 } 5600 } 5601 5602 if (doit) { 5603 if (name != null) { 5604 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5605 + " user=" + userId + ": " + reason); 5606 } else { 5607 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5608 } 5609 5610 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5611 for (int ip=pmap.size()-1; ip>=0; ip--) { 5612 SparseArray<Long> ba = pmap.valueAt(ip); 5613 for (i=ba.size()-1; i>=0; i--) { 5614 boolean remove = false; 5615 final int entUid = ba.keyAt(i); 5616 if (name != null) { 5617 if (userId == UserHandle.USER_ALL) { 5618 if (UserHandle.getAppId(entUid) == appId) { 5619 remove = true; 5620 } 5621 } else { 5622 if (entUid == UserHandle.getUid(userId, appId)) { 5623 remove = true; 5624 } 5625 } 5626 } else if (UserHandle.getUserId(entUid) == userId) { 5627 remove = true; 5628 } 5629 if (remove) { 5630 ba.removeAt(i); 5631 } 5632 } 5633 if (ba.size() == 0) { 5634 pmap.removeAt(ip); 5635 } 5636 } 5637 } 5638 5639 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5640 -100, callerWillRestart, true, doit, evenPersistent, 5641 name == null ? ("stop user " + userId) : ("stop " + name)); 5642 5643 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5644 if (!doit) { 5645 return true; 5646 } 5647 didSomething = true; 5648 } 5649 5650 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5651 if (!doit) { 5652 return true; 5653 } 5654 didSomething = true; 5655 } 5656 5657 if (name == null) { 5658 // Remove all sticky broadcasts from this user. 5659 mStickyBroadcasts.remove(userId); 5660 } 5661 5662 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5663 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5664 userId, providers)) { 5665 if (!doit) { 5666 return true; 5667 } 5668 didSomething = true; 5669 } 5670 N = providers.size(); 5671 for (i=0; i<N; i++) { 5672 removeDyingProviderLocked(null, providers.get(i), true); 5673 } 5674 5675 // Remove transient permissions granted from/to this package/user 5676 removeUriPermissionsForPackageLocked(name, userId, false); 5677 5678 if (name == null || uninstalling) { 5679 // Remove pending intents. For now we only do this when force 5680 // stopping users, because we have some problems when doing this 5681 // for packages -- app widgets are not currently cleaned up for 5682 // such packages, so they can be left with bad pending intents. 5683 if (mIntentSenderRecords.size() > 0) { 5684 Iterator<WeakReference<PendingIntentRecord>> it 5685 = mIntentSenderRecords.values().iterator(); 5686 while (it.hasNext()) { 5687 WeakReference<PendingIntentRecord> wpir = it.next(); 5688 if (wpir == null) { 5689 it.remove(); 5690 continue; 5691 } 5692 PendingIntentRecord pir = wpir.get(); 5693 if (pir == null) { 5694 it.remove(); 5695 continue; 5696 } 5697 if (name == null) { 5698 // Stopping user, remove all objects for the user. 5699 if (pir.key.userId != userId) { 5700 // Not the same user, skip it. 5701 continue; 5702 } 5703 } else { 5704 if (UserHandle.getAppId(pir.uid) != appId) { 5705 // Different app id, skip it. 5706 continue; 5707 } 5708 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5709 // Different user, skip it. 5710 continue; 5711 } 5712 if (!pir.key.packageName.equals(name)) { 5713 // Different package, skip it. 5714 continue; 5715 } 5716 } 5717 if (!doit) { 5718 return true; 5719 } 5720 didSomething = true; 5721 it.remove(); 5722 pir.canceled = true; 5723 if (pir.key.activity != null) { 5724 pir.key.activity.pendingResults.remove(pir.ref); 5725 } 5726 } 5727 } 5728 } 5729 5730 if (doit) { 5731 if (purgeCache && name != null) { 5732 AttributeCache ac = AttributeCache.instance(); 5733 if (ac != null) { 5734 ac.removePackage(name); 5735 } 5736 } 5737 if (mBooted) { 5738 mStackSupervisor.resumeTopActivitiesLocked(); 5739 mStackSupervisor.scheduleIdleLocked(); 5740 } 5741 } 5742 5743 return didSomething; 5744 } 5745 5746 private final boolean removeProcessLocked(ProcessRecord app, 5747 boolean callerWillRestart, boolean allowRestart, String reason) { 5748 final String name = app.processName; 5749 final int uid = app.uid; 5750 if (DEBUG_PROCESSES) Slog.d( 5751 TAG, "Force removing proc " + app.toShortString() + " (" + name 5752 + "/" + uid + ")"); 5753 5754 mProcessNames.remove(name, uid); 5755 mIsolatedProcesses.remove(app.uid); 5756 if (mHeavyWeightProcess == app) { 5757 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5758 mHeavyWeightProcess.userId, 0)); 5759 mHeavyWeightProcess = null; 5760 } 5761 boolean needRestart = false; 5762 if (app.pid > 0 && app.pid != MY_PID) { 5763 int pid = app.pid; 5764 synchronized (mPidsSelfLocked) { 5765 mPidsSelfLocked.remove(pid); 5766 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5767 } 5768 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5769 if (app.isolated) { 5770 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5771 } 5772 app.kill(reason, true); 5773 handleAppDiedLocked(app, true, allowRestart); 5774 removeLruProcessLocked(app); 5775 5776 if (app.persistent && !app.isolated) { 5777 if (!callerWillRestart) { 5778 addAppLocked(app.info, false, null /* ABI override */); 5779 } else { 5780 needRestart = true; 5781 } 5782 } 5783 } else { 5784 mRemovedProcesses.add(app); 5785 } 5786 5787 return needRestart; 5788 } 5789 5790 private final void processStartTimedOutLocked(ProcessRecord app) { 5791 final int pid = app.pid; 5792 boolean gone = false; 5793 synchronized (mPidsSelfLocked) { 5794 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5795 if (knownApp != null && knownApp.thread == null) { 5796 mPidsSelfLocked.remove(pid); 5797 gone = true; 5798 } 5799 } 5800 5801 if (gone) { 5802 Slog.w(TAG, "Process " + app + " failed to attach"); 5803 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5804 pid, app.uid, app.processName); 5805 mProcessNames.remove(app.processName, app.uid); 5806 mIsolatedProcesses.remove(app.uid); 5807 if (mHeavyWeightProcess == app) { 5808 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5809 mHeavyWeightProcess.userId, 0)); 5810 mHeavyWeightProcess = null; 5811 } 5812 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5813 if (app.isolated) { 5814 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5815 } 5816 // Take care of any launching providers waiting for this process. 5817 checkAppInLaunchingProvidersLocked(app, true); 5818 // Take care of any services that are waiting for the process. 5819 mServices.processStartTimedOutLocked(app); 5820 app.kill("start timeout", true); 5821 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5822 Slog.w(TAG, "Unattached app died before backup, skipping"); 5823 try { 5824 IBackupManager bm = IBackupManager.Stub.asInterface( 5825 ServiceManager.getService(Context.BACKUP_SERVICE)); 5826 bm.agentDisconnected(app.info.packageName); 5827 } catch (RemoteException e) { 5828 // Can't happen; the backup manager is local 5829 } 5830 } 5831 if (isPendingBroadcastProcessLocked(pid)) { 5832 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5833 skipPendingBroadcastLocked(pid); 5834 } 5835 } else { 5836 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5837 } 5838 } 5839 5840 private final boolean attachApplicationLocked(IApplicationThread thread, 5841 int pid) { 5842 5843 // Find the application record that is being attached... either via 5844 // the pid if we are running in multiple processes, or just pull the 5845 // next app record if we are emulating process with anonymous threads. 5846 ProcessRecord app; 5847 if (pid != MY_PID && pid >= 0) { 5848 synchronized (mPidsSelfLocked) { 5849 app = mPidsSelfLocked.get(pid); 5850 } 5851 } else { 5852 app = null; 5853 } 5854 5855 if (app == null) { 5856 Slog.w(TAG, "No pending application record for pid " + pid 5857 + " (IApplicationThread " + thread + "); dropping process"); 5858 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5859 if (pid > 0 && pid != MY_PID) { 5860 Process.killProcessQuiet(pid); 5861 //TODO: Process.killProcessGroup(app.info.uid, pid); 5862 } else { 5863 try { 5864 thread.scheduleExit(); 5865 } catch (Exception e) { 5866 // Ignore exceptions. 5867 } 5868 } 5869 return false; 5870 } 5871 5872 // If this application record is still attached to a previous 5873 // process, clean it up now. 5874 if (app.thread != null) { 5875 handleAppDiedLocked(app, true, true); 5876 } 5877 5878 // Tell the process all about itself. 5879 5880 if (localLOGV) Slog.v( 5881 TAG, "Binding process pid " + pid + " to record " + app); 5882 5883 final String processName = app.processName; 5884 try { 5885 AppDeathRecipient adr = new AppDeathRecipient( 5886 app, pid, thread); 5887 thread.asBinder().linkToDeath(adr, 0); 5888 app.deathRecipient = adr; 5889 } catch (RemoteException e) { 5890 app.resetPackageList(mProcessStats); 5891 startProcessLocked(app, "link fail", processName); 5892 return false; 5893 } 5894 5895 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5896 5897 app.makeActive(thread, mProcessStats); 5898 app.curAdj = app.setAdj = -100; 5899 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5900 app.forcingToForeground = null; 5901 updateProcessForegroundLocked(app, false, false); 5902 app.hasShownUi = false; 5903 app.debugging = false; 5904 app.cached = false; 5905 5906 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5907 5908 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5909 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5910 5911 if (!normalMode) { 5912 Slog.i(TAG, "Launching preboot mode app: " + app); 5913 } 5914 5915 if (localLOGV) Slog.v( 5916 TAG, "New app record " + app 5917 + " thread=" + thread.asBinder() + " pid=" + pid); 5918 try { 5919 int testMode = IApplicationThread.DEBUG_OFF; 5920 if (mDebugApp != null && mDebugApp.equals(processName)) { 5921 testMode = mWaitForDebugger 5922 ? IApplicationThread.DEBUG_WAIT 5923 : IApplicationThread.DEBUG_ON; 5924 app.debugging = true; 5925 if (mDebugTransient) { 5926 mDebugApp = mOrigDebugApp; 5927 mWaitForDebugger = mOrigWaitForDebugger; 5928 } 5929 } 5930 String profileFile = app.instrumentationProfileFile; 5931 ParcelFileDescriptor profileFd = null; 5932 int samplingInterval = 0; 5933 boolean profileAutoStop = false; 5934 if (mProfileApp != null && mProfileApp.equals(processName)) { 5935 mProfileProc = app; 5936 profileFile = mProfileFile; 5937 profileFd = mProfileFd; 5938 samplingInterval = mSamplingInterval; 5939 profileAutoStop = mAutoStopProfiler; 5940 } 5941 boolean enableOpenGlTrace = false; 5942 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5943 enableOpenGlTrace = true; 5944 mOpenGlTraceApp = null; 5945 } 5946 5947 // If the app is being launched for restore or full backup, set it up specially 5948 boolean isRestrictedBackupMode = false; 5949 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5950 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5951 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5952 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5953 } 5954 5955 ensurePackageDexOpt(app.instrumentationInfo != null 5956 ? app.instrumentationInfo.packageName 5957 : app.info.packageName); 5958 if (app.instrumentationClass != null) { 5959 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5960 } 5961 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5962 + processName + " with config " + mConfiguration); 5963 ApplicationInfo appInfo = app.instrumentationInfo != null 5964 ? app.instrumentationInfo : app.info; 5965 app.compat = compatibilityInfoForPackageLocked(appInfo); 5966 if (profileFd != null) { 5967 profileFd = profileFd.dup(); 5968 } 5969 ProfilerInfo profilerInfo = profileFile == null ? null 5970 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5971 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5972 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5973 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5974 isRestrictedBackupMode || !normalMode, app.persistent, 5975 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5976 mCoreSettingsObserver.getCoreSettingsLocked()); 5977 updateLruProcessLocked(app, false, null); 5978 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5979 } catch (Exception e) { 5980 // todo: Yikes! What should we do? For now we will try to 5981 // start another process, but that could easily get us in 5982 // an infinite loop of restarting processes... 5983 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 5984 5985 app.resetPackageList(mProcessStats); 5986 app.unlinkDeathRecipient(); 5987 startProcessLocked(app, "bind fail", processName); 5988 return false; 5989 } 5990 5991 // Remove this record from the list of starting applications. 5992 mPersistentStartingProcesses.remove(app); 5993 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5994 "Attach application locked removing on hold: " + app); 5995 mProcessesOnHold.remove(app); 5996 5997 boolean badApp = false; 5998 boolean didSomething = false; 5999 6000 // See if the top visible activity is waiting to run in this process... 6001 if (normalMode) { 6002 try { 6003 if (mStackSupervisor.attachApplicationLocked(app)) { 6004 didSomething = true; 6005 } 6006 } catch (Exception e) { 6007 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6008 badApp = true; 6009 } 6010 } 6011 6012 // Find any services that should be running in this process... 6013 if (!badApp) { 6014 try { 6015 didSomething |= mServices.attachApplicationLocked(app, processName); 6016 } catch (Exception e) { 6017 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6018 badApp = true; 6019 } 6020 } 6021 6022 // Check if a next-broadcast receiver is in this process... 6023 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6024 try { 6025 didSomething |= sendPendingBroadcastsLocked(app); 6026 } catch (Exception e) { 6027 // If the app died trying to launch the receiver we declare it 'bad' 6028 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6029 badApp = true; 6030 } 6031 } 6032 6033 // Check whether the next backup agent is in this process... 6034 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6035 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6036 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6037 try { 6038 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6039 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6040 mBackupTarget.backupMode); 6041 } catch (Exception e) { 6042 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6043 badApp = true; 6044 } 6045 } 6046 6047 if (badApp) { 6048 app.kill("error during init", true); 6049 handleAppDiedLocked(app, false, true); 6050 return false; 6051 } 6052 6053 if (!didSomething) { 6054 updateOomAdjLocked(); 6055 } 6056 6057 return true; 6058 } 6059 6060 @Override 6061 public final void attachApplication(IApplicationThread thread) { 6062 synchronized (this) { 6063 int callingPid = Binder.getCallingPid(); 6064 final long origId = Binder.clearCallingIdentity(); 6065 attachApplicationLocked(thread, callingPid); 6066 Binder.restoreCallingIdentity(origId); 6067 } 6068 } 6069 6070 @Override 6071 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6072 final long origId = Binder.clearCallingIdentity(); 6073 synchronized (this) { 6074 ActivityStack stack = ActivityRecord.getStackLocked(token); 6075 if (stack != null) { 6076 ActivityRecord r = 6077 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6078 if (stopProfiling) { 6079 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6080 try { 6081 mProfileFd.close(); 6082 } catch (IOException e) { 6083 } 6084 clearProfilerLocked(); 6085 } 6086 } 6087 } 6088 } 6089 Binder.restoreCallingIdentity(origId); 6090 } 6091 6092 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6093 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6094 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6095 } 6096 6097 void enableScreenAfterBoot() { 6098 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6099 SystemClock.uptimeMillis()); 6100 mWindowManager.enableScreenAfterBoot(); 6101 6102 synchronized (this) { 6103 updateEventDispatchingLocked(); 6104 } 6105 } 6106 6107 @Override 6108 public void showBootMessage(final CharSequence msg, final boolean always) { 6109 enforceNotIsolatedCaller("showBootMessage"); 6110 mWindowManager.showBootMessage(msg, always); 6111 } 6112 6113 @Override 6114 public void keyguardWaitingForActivityDrawn() { 6115 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6116 final long token = Binder.clearCallingIdentity(); 6117 try { 6118 synchronized (this) { 6119 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6120 mWindowManager.keyguardWaitingForActivityDrawn(); 6121 if (mLockScreenShown) { 6122 mLockScreenShown = false; 6123 comeOutOfSleepIfNeededLocked(); 6124 } 6125 } 6126 } finally { 6127 Binder.restoreCallingIdentity(token); 6128 } 6129 } 6130 6131 final void finishBooting() { 6132 synchronized (this) { 6133 if (!mBootAnimationComplete) { 6134 mCallFinishBooting = true; 6135 return; 6136 } 6137 mCallFinishBooting = false; 6138 } 6139 6140 // Register receivers to handle package update events 6141 mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false); 6142 6143 // Let system services know. 6144 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6145 6146 synchronized (this) { 6147 // Ensure that any processes we had put on hold are now started 6148 // up. 6149 final int NP = mProcessesOnHold.size(); 6150 if (NP > 0) { 6151 ArrayList<ProcessRecord> procs = 6152 new ArrayList<ProcessRecord>(mProcessesOnHold); 6153 for (int ip=0; ip<NP; ip++) { 6154 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6155 + procs.get(ip)); 6156 startProcessLocked(procs.get(ip), "on-hold", null); 6157 } 6158 } 6159 6160 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6161 // Start looking for apps that are abusing wake locks. 6162 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6163 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6164 // Tell anyone interested that we are done booting! 6165 SystemProperties.set("sys.boot_completed", "1"); 6166 6167 // And trigger dev.bootcomplete if we are not showing encryption progress 6168 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6169 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6170 SystemProperties.set("dev.bootcomplete", "1"); 6171 } 6172 for (int i=0; i<mStartedUsers.size(); i++) { 6173 UserStartedState uss = mStartedUsers.valueAt(i); 6174 if (uss.mState == UserStartedState.STATE_BOOTING) { 6175 uss.mState = UserStartedState.STATE_RUNNING; 6176 final int userId = mStartedUsers.keyAt(i); 6177 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6178 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6179 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6180 broadcastIntentLocked(null, null, intent, null, 6181 new IIntentReceiver.Stub() { 6182 @Override 6183 public void performReceive(Intent intent, int resultCode, 6184 String data, Bundle extras, boolean ordered, 6185 boolean sticky, int sendingUser) { 6186 synchronized (ActivityManagerService.this) { 6187 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6188 true, false); 6189 } 6190 } 6191 }, 6192 0, null, null, 6193 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6194 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6195 userId); 6196 } 6197 } 6198 scheduleStartProfilesLocked(); 6199 } 6200 } 6201 } 6202 6203 @Override 6204 public void bootAnimationComplete() { 6205 final boolean callFinishBooting; 6206 synchronized (this) { 6207 callFinishBooting = mCallFinishBooting; 6208 mBootAnimationComplete = true; 6209 } 6210 if (callFinishBooting) { 6211 finishBooting(); 6212 } 6213 } 6214 6215 final void ensureBootCompleted() { 6216 boolean booting; 6217 boolean enableScreen; 6218 synchronized (this) { 6219 booting = mBooting; 6220 mBooting = false; 6221 enableScreen = !mBooted; 6222 mBooted = true; 6223 } 6224 6225 if (booting) { 6226 finishBooting(); 6227 } 6228 6229 if (enableScreen) { 6230 enableScreenAfterBoot(); 6231 } 6232 } 6233 6234 @Override 6235 public final void activityResumed(IBinder token) { 6236 final long origId = Binder.clearCallingIdentity(); 6237 synchronized(this) { 6238 ActivityStack stack = ActivityRecord.getStackLocked(token); 6239 if (stack != null) { 6240 ActivityRecord.activityResumedLocked(token); 6241 } 6242 } 6243 Binder.restoreCallingIdentity(origId); 6244 } 6245 6246 @Override 6247 public final void activityPaused(IBinder token) { 6248 final long origId = Binder.clearCallingIdentity(); 6249 synchronized(this) { 6250 ActivityStack stack = ActivityRecord.getStackLocked(token); 6251 if (stack != null) { 6252 stack.activityPausedLocked(token, false); 6253 } 6254 } 6255 Binder.restoreCallingIdentity(origId); 6256 } 6257 6258 @Override 6259 public final void activityStopped(IBinder token, Bundle icicle, 6260 PersistableBundle persistentState, CharSequence description) { 6261 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6262 6263 // Refuse possible leaked file descriptors 6264 if (icicle != null && icicle.hasFileDescriptors()) { 6265 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6266 } 6267 6268 final long origId = Binder.clearCallingIdentity(); 6269 6270 synchronized (this) { 6271 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6272 if (r != null) { 6273 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6274 } 6275 } 6276 6277 trimApplications(); 6278 6279 Binder.restoreCallingIdentity(origId); 6280 } 6281 6282 @Override 6283 public final void activityDestroyed(IBinder token) { 6284 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6285 synchronized (this) { 6286 ActivityStack stack = ActivityRecord.getStackLocked(token); 6287 if (stack != null) { 6288 stack.activityDestroyedLocked(token); 6289 } 6290 } 6291 } 6292 6293 @Override 6294 public final void backgroundResourcesReleased(IBinder token) { 6295 final long origId = Binder.clearCallingIdentity(); 6296 try { 6297 synchronized (this) { 6298 ActivityStack stack = ActivityRecord.getStackLocked(token); 6299 if (stack != null) { 6300 stack.backgroundResourcesReleased(token); 6301 } 6302 } 6303 } finally { 6304 Binder.restoreCallingIdentity(origId); 6305 } 6306 } 6307 6308 @Override 6309 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6310 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6311 } 6312 6313 @Override 6314 public final void notifyEnterAnimationComplete(IBinder token) { 6315 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6316 } 6317 6318 @Override 6319 public String getCallingPackage(IBinder token) { 6320 synchronized (this) { 6321 ActivityRecord r = getCallingRecordLocked(token); 6322 return r != null ? r.info.packageName : null; 6323 } 6324 } 6325 6326 @Override 6327 public ComponentName getCallingActivity(IBinder token) { 6328 synchronized (this) { 6329 ActivityRecord r = getCallingRecordLocked(token); 6330 return r != null ? r.intent.getComponent() : null; 6331 } 6332 } 6333 6334 private ActivityRecord getCallingRecordLocked(IBinder token) { 6335 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6336 if (r == null) { 6337 return null; 6338 } 6339 return r.resultTo; 6340 } 6341 6342 @Override 6343 public ComponentName getActivityClassForToken(IBinder token) { 6344 synchronized(this) { 6345 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6346 if (r == null) { 6347 return null; 6348 } 6349 return r.intent.getComponent(); 6350 } 6351 } 6352 6353 @Override 6354 public String getPackageForToken(IBinder token) { 6355 synchronized(this) { 6356 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6357 if (r == null) { 6358 return null; 6359 } 6360 return r.packageName; 6361 } 6362 } 6363 6364 @Override 6365 public IIntentSender getIntentSender(int type, 6366 String packageName, IBinder token, String resultWho, 6367 int requestCode, Intent[] intents, String[] resolvedTypes, 6368 int flags, Bundle options, int userId) { 6369 enforceNotIsolatedCaller("getIntentSender"); 6370 // Refuse possible leaked file descriptors 6371 if (intents != null) { 6372 if (intents.length < 1) { 6373 throw new IllegalArgumentException("Intents array length must be >= 1"); 6374 } 6375 for (int i=0; i<intents.length; i++) { 6376 Intent intent = intents[i]; 6377 if (intent != null) { 6378 if (intent.hasFileDescriptors()) { 6379 throw new IllegalArgumentException("File descriptors passed in Intent"); 6380 } 6381 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6382 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6383 throw new IllegalArgumentException( 6384 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6385 } 6386 intents[i] = new Intent(intent); 6387 } 6388 } 6389 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6390 throw new IllegalArgumentException( 6391 "Intent array length does not match resolvedTypes length"); 6392 } 6393 } 6394 if (options != null) { 6395 if (options.hasFileDescriptors()) { 6396 throw new IllegalArgumentException("File descriptors passed in options"); 6397 } 6398 } 6399 6400 synchronized(this) { 6401 int callingUid = Binder.getCallingUid(); 6402 int origUserId = userId; 6403 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6404 type == ActivityManager.INTENT_SENDER_BROADCAST, 6405 ALLOW_NON_FULL, "getIntentSender", null); 6406 if (origUserId == UserHandle.USER_CURRENT) { 6407 // We don't want to evaluate this until the pending intent is 6408 // actually executed. However, we do want to always do the 6409 // security checking for it above. 6410 userId = UserHandle.USER_CURRENT; 6411 } 6412 try { 6413 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6414 int uid = AppGlobals.getPackageManager() 6415 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6416 if (!UserHandle.isSameApp(callingUid, uid)) { 6417 String msg = "Permission Denial: getIntentSender() from pid=" 6418 + Binder.getCallingPid() 6419 + ", uid=" + Binder.getCallingUid() 6420 + ", (need uid=" + uid + ")" 6421 + " is not allowed to send as package " + packageName; 6422 Slog.w(TAG, msg); 6423 throw new SecurityException(msg); 6424 } 6425 } 6426 6427 return getIntentSenderLocked(type, packageName, callingUid, userId, 6428 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6429 6430 } catch (RemoteException e) { 6431 throw new SecurityException(e); 6432 } 6433 } 6434 } 6435 6436 IIntentSender getIntentSenderLocked(int type, String packageName, 6437 int callingUid, int userId, IBinder token, String resultWho, 6438 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6439 Bundle options) { 6440 if (DEBUG_MU) 6441 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6442 ActivityRecord activity = null; 6443 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6444 activity = ActivityRecord.isInStackLocked(token); 6445 if (activity == null) { 6446 return null; 6447 } 6448 if (activity.finishing) { 6449 return null; 6450 } 6451 } 6452 6453 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6454 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6455 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6456 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6457 |PendingIntent.FLAG_UPDATE_CURRENT); 6458 6459 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6460 type, packageName, activity, resultWho, 6461 requestCode, intents, resolvedTypes, flags, options, userId); 6462 WeakReference<PendingIntentRecord> ref; 6463 ref = mIntentSenderRecords.get(key); 6464 PendingIntentRecord rec = ref != null ? ref.get() : null; 6465 if (rec != null) { 6466 if (!cancelCurrent) { 6467 if (updateCurrent) { 6468 if (rec.key.requestIntent != null) { 6469 rec.key.requestIntent.replaceExtras(intents != null ? 6470 intents[intents.length - 1] : null); 6471 } 6472 if (intents != null) { 6473 intents[intents.length-1] = rec.key.requestIntent; 6474 rec.key.allIntents = intents; 6475 rec.key.allResolvedTypes = resolvedTypes; 6476 } else { 6477 rec.key.allIntents = null; 6478 rec.key.allResolvedTypes = null; 6479 } 6480 } 6481 return rec; 6482 } 6483 rec.canceled = true; 6484 mIntentSenderRecords.remove(key); 6485 } 6486 if (noCreate) { 6487 return rec; 6488 } 6489 rec = new PendingIntentRecord(this, key, callingUid); 6490 mIntentSenderRecords.put(key, rec.ref); 6491 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6492 if (activity.pendingResults == null) { 6493 activity.pendingResults 6494 = new HashSet<WeakReference<PendingIntentRecord>>(); 6495 } 6496 activity.pendingResults.add(rec.ref); 6497 } 6498 return rec; 6499 } 6500 6501 @Override 6502 public void cancelIntentSender(IIntentSender sender) { 6503 if (!(sender instanceof PendingIntentRecord)) { 6504 return; 6505 } 6506 synchronized(this) { 6507 PendingIntentRecord rec = (PendingIntentRecord)sender; 6508 try { 6509 int uid = AppGlobals.getPackageManager() 6510 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6511 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6512 String msg = "Permission Denial: cancelIntentSender() from pid=" 6513 + Binder.getCallingPid() 6514 + ", uid=" + Binder.getCallingUid() 6515 + " is not allowed to cancel packges " 6516 + rec.key.packageName; 6517 Slog.w(TAG, msg); 6518 throw new SecurityException(msg); 6519 } 6520 } catch (RemoteException e) { 6521 throw new SecurityException(e); 6522 } 6523 cancelIntentSenderLocked(rec, true); 6524 } 6525 } 6526 6527 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6528 rec.canceled = true; 6529 mIntentSenderRecords.remove(rec.key); 6530 if (cleanActivity && rec.key.activity != null) { 6531 rec.key.activity.pendingResults.remove(rec.ref); 6532 } 6533 } 6534 6535 @Override 6536 public String getPackageForIntentSender(IIntentSender pendingResult) { 6537 if (!(pendingResult instanceof PendingIntentRecord)) { 6538 return null; 6539 } 6540 try { 6541 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6542 return res.key.packageName; 6543 } catch (ClassCastException e) { 6544 } 6545 return null; 6546 } 6547 6548 @Override 6549 public int getUidForIntentSender(IIntentSender sender) { 6550 if (sender instanceof PendingIntentRecord) { 6551 try { 6552 PendingIntentRecord res = (PendingIntentRecord)sender; 6553 return res.uid; 6554 } catch (ClassCastException e) { 6555 } 6556 } 6557 return -1; 6558 } 6559 6560 @Override 6561 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6562 if (!(pendingResult instanceof PendingIntentRecord)) { 6563 return false; 6564 } 6565 try { 6566 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6567 if (res.key.allIntents == null) { 6568 return false; 6569 } 6570 for (int i=0; i<res.key.allIntents.length; i++) { 6571 Intent intent = res.key.allIntents[i]; 6572 if (intent.getPackage() != null && intent.getComponent() != null) { 6573 return false; 6574 } 6575 } 6576 return true; 6577 } catch (ClassCastException e) { 6578 } 6579 return false; 6580 } 6581 6582 @Override 6583 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6584 if (!(pendingResult instanceof PendingIntentRecord)) { 6585 return false; 6586 } 6587 try { 6588 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6589 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6590 return true; 6591 } 6592 return false; 6593 } catch (ClassCastException e) { 6594 } 6595 return false; 6596 } 6597 6598 @Override 6599 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6600 if (!(pendingResult instanceof PendingIntentRecord)) { 6601 return null; 6602 } 6603 try { 6604 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6605 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6606 } catch (ClassCastException e) { 6607 } 6608 return null; 6609 } 6610 6611 @Override 6612 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6613 if (!(pendingResult instanceof PendingIntentRecord)) { 6614 return null; 6615 } 6616 try { 6617 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6618 Intent intent = res.key.requestIntent; 6619 if (intent != null) { 6620 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6621 || res.lastTagPrefix.equals(prefix))) { 6622 return res.lastTag; 6623 } 6624 res.lastTagPrefix = prefix; 6625 StringBuilder sb = new StringBuilder(128); 6626 if (prefix != null) { 6627 sb.append(prefix); 6628 } 6629 if (intent.getAction() != null) { 6630 sb.append(intent.getAction()); 6631 } else if (intent.getComponent() != null) { 6632 intent.getComponent().appendShortString(sb); 6633 } else { 6634 sb.append("?"); 6635 } 6636 return res.lastTag = sb.toString(); 6637 } 6638 } catch (ClassCastException e) { 6639 } 6640 return null; 6641 } 6642 6643 @Override 6644 public void setProcessLimit(int max) { 6645 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6646 "setProcessLimit()"); 6647 synchronized (this) { 6648 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6649 mProcessLimitOverride = max; 6650 } 6651 trimApplications(); 6652 } 6653 6654 @Override 6655 public int getProcessLimit() { 6656 synchronized (this) { 6657 return mProcessLimitOverride; 6658 } 6659 } 6660 6661 void foregroundTokenDied(ForegroundToken token) { 6662 synchronized (ActivityManagerService.this) { 6663 synchronized (mPidsSelfLocked) { 6664 ForegroundToken cur 6665 = mForegroundProcesses.get(token.pid); 6666 if (cur != token) { 6667 return; 6668 } 6669 mForegroundProcesses.remove(token.pid); 6670 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6671 if (pr == null) { 6672 return; 6673 } 6674 pr.forcingToForeground = null; 6675 updateProcessForegroundLocked(pr, false, false); 6676 } 6677 updateOomAdjLocked(); 6678 } 6679 } 6680 6681 @Override 6682 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6683 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6684 "setProcessForeground()"); 6685 synchronized(this) { 6686 boolean changed = false; 6687 6688 synchronized (mPidsSelfLocked) { 6689 ProcessRecord pr = mPidsSelfLocked.get(pid); 6690 if (pr == null && isForeground) { 6691 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6692 return; 6693 } 6694 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6695 if (oldToken != null) { 6696 oldToken.token.unlinkToDeath(oldToken, 0); 6697 mForegroundProcesses.remove(pid); 6698 if (pr != null) { 6699 pr.forcingToForeground = null; 6700 } 6701 changed = true; 6702 } 6703 if (isForeground && token != null) { 6704 ForegroundToken newToken = new ForegroundToken() { 6705 @Override 6706 public void binderDied() { 6707 foregroundTokenDied(this); 6708 } 6709 }; 6710 newToken.pid = pid; 6711 newToken.token = token; 6712 try { 6713 token.linkToDeath(newToken, 0); 6714 mForegroundProcesses.put(pid, newToken); 6715 pr.forcingToForeground = token; 6716 changed = true; 6717 } catch (RemoteException e) { 6718 // If the process died while doing this, we will later 6719 // do the cleanup with the process death link. 6720 } 6721 } 6722 } 6723 6724 if (changed) { 6725 updateOomAdjLocked(); 6726 } 6727 } 6728 } 6729 6730 // ========================================================= 6731 // PERMISSIONS 6732 // ========================================================= 6733 6734 static class PermissionController extends IPermissionController.Stub { 6735 ActivityManagerService mActivityManagerService; 6736 PermissionController(ActivityManagerService activityManagerService) { 6737 mActivityManagerService = activityManagerService; 6738 } 6739 6740 @Override 6741 public boolean checkPermission(String permission, int pid, int uid) { 6742 return mActivityManagerService.checkPermission(permission, pid, 6743 uid) == PackageManager.PERMISSION_GRANTED; 6744 } 6745 } 6746 6747 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6748 @Override 6749 public int checkComponentPermission(String permission, int pid, int uid, 6750 int owningUid, boolean exported) { 6751 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6752 owningUid, exported); 6753 } 6754 6755 @Override 6756 public Object getAMSLock() { 6757 return ActivityManagerService.this; 6758 } 6759 } 6760 6761 /** 6762 * This can be called with or without the global lock held. 6763 */ 6764 int checkComponentPermission(String permission, int pid, int uid, 6765 int owningUid, boolean exported) { 6766 // We might be performing an operation on behalf of an indirect binder 6767 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6768 // client identity accordingly before proceeding. 6769 Identity tlsIdentity = sCallerIdentity.get(); 6770 if (tlsIdentity != null) { 6771 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6772 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6773 uid = tlsIdentity.uid; 6774 pid = tlsIdentity.pid; 6775 } 6776 6777 if (pid == MY_PID) { 6778 return PackageManager.PERMISSION_GRANTED; 6779 } 6780 6781 return ActivityManager.checkComponentPermission(permission, uid, 6782 owningUid, exported); 6783 } 6784 6785 /** 6786 * As the only public entry point for permissions checking, this method 6787 * can enforce the semantic that requesting a check on a null global 6788 * permission is automatically denied. (Internally a null permission 6789 * string is used when calling {@link #checkComponentPermission} in cases 6790 * when only uid-based security is needed.) 6791 * 6792 * This can be called with or without the global lock held. 6793 */ 6794 @Override 6795 public int checkPermission(String permission, int pid, int uid) { 6796 if (permission == null) { 6797 return PackageManager.PERMISSION_DENIED; 6798 } 6799 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6800 } 6801 6802 /** 6803 * Binder IPC calls go through the public entry point. 6804 * This can be called with or without the global lock held. 6805 */ 6806 int checkCallingPermission(String permission) { 6807 return checkPermission(permission, 6808 Binder.getCallingPid(), 6809 UserHandle.getAppId(Binder.getCallingUid())); 6810 } 6811 6812 /** 6813 * This can be called with or without the global lock held. 6814 */ 6815 void enforceCallingPermission(String permission, String func) { 6816 if (checkCallingPermission(permission) 6817 == PackageManager.PERMISSION_GRANTED) { 6818 return; 6819 } 6820 6821 String msg = "Permission Denial: " + func + " from pid=" 6822 + Binder.getCallingPid() 6823 + ", uid=" + Binder.getCallingUid() 6824 + " requires " + permission; 6825 Slog.w(TAG, msg); 6826 throw new SecurityException(msg); 6827 } 6828 6829 /** 6830 * Determine if UID is holding permissions required to access {@link Uri} in 6831 * the given {@link ProviderInfo}. Final permission checking is always done 6832 * in {@link ContentProvider}. 6833 */ 6834 private final boolean checkHoldingPermissionsLocked( 6835 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6836 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6837 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6838 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6839 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6840 != PERMISSION_GRANTED) { 6841 return false; 6842 } 6843 } 6844 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6845 } 6846 6847 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6848 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6849 if (pi.applicationInfo.uid == uid) { 6850 return true; 6851 } else if (!pi.exported) { 6852 return false; 6853 } 6854 6855 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6856 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6857 try { 6858 // check if target holds top-level <provider> permissions 6859 if (!readMet && pi.readPermission != null && considerUidPermissions 6860 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6861 readMet = true; 6862 } 6863 if (!writeMet && pi.writePermission != null && considerUidPermissions 6864 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6865 writeMet = true; 6866 } 6867 6868 // track if unprotected read/write is allowed; any denied 6869 // <path-permission> below removes this ability 6870 boolean allowDefaultRead = pi.readPermission == null; 6871 boolean allowDefaultWrite = pi.writePermission == null; 6872 6873 // check if target holds any <path-permission> that match uri 6874 final PathPermission[] pps = pi.pathPermissions; 6875 if (pps != null) { 6876 final String path = grantUri.uri.getPath(); 6877 int i = pps.length; 6878 while (i > 0 && (!readMet || !writeMet)) { 6879 i--; 6880 PathPermission pp = pps[i]; 6881 if (pp.match(path)) { 6882 if (!readMet) { 6883 final String pprperm = pp.getReadPermission(); 6884 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6885 + pprperm + " for " + pp.getPath() 6886 + ": match=" + pp.match(path) 6887 + " check=" + pm.checkUidPermission(pprperm, uid)); 6888 if (pprperm != null) { 6889 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6890 == PERMISSION_GRANTED) { 6891 readMet = true; 6892 } else { 6893 allowDefaultRead = false; 6894 } 6895 } 6896 } 6897 if (!writeMet) { 6898 final String ppwperm = pp.getWritePermission(); 6899 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6900 + ppwperm + " for " + pp.getPath() 6901 + ": match=" + pp.match(path) 6902 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6903 if (ppwperm != null) { 6904 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6905 == PERMISSION_GRANTED) { 6906 writeMet = true; 6907 } else { 6908 allowDefaultWrite = false; 6909 } 6910 } 6911 } 6912 } 6913 } 6914 } 6915 6916 // grant unprotected <provider> read/write, if not blocked by 6917 // <path-permission> above 6918 if (allowDefaultRead) readMet = true; 6919 if (allowDefaultWrite) writeMet = true; 6920 6921 } catch (RemoteException e) { 6922 return false; 6923 } 6924 6925 return readMet && writeMet; 6926 } 6927 6928 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6929 ProviderInfo pi = null; 6930 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6931 if (cpr != null) { 6932 pi = cpr.info; 6933 } else { 6934 try { 6935 pi = AppGlobals.getPackageManager().resolveContentProvider( 6936 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6937 } catch (RemoteException ex) { 6938 } 6939 } 6940 return pi; 6941 } 6942 6943 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6944 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6945 if (targetUris != null) { 6946 return targetUris.get(grantUri); 6947 } 6948 return null; 6949 } 6950 6951 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6952 String targetPkg, int targetUid, GrantUri grantUri) { 6953 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6954 if (targetUris == null) { 6955 targetUris = Maps.newArrayMap(); 6956 mGrantedUriPermissions.put(targetUid, targetUris); 6957 } 6958 6959 UriPermission perm = targetUris.get(grantUri); 6960 if (perm == null) { 6961 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6962 targetUris.put(grantUri, perm); 6963 } 6964 6965 return perm; 6966 } 6967 6968 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6969 final int modeFlags) { 6970 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6971 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6972 : UriPermission.STRENGTH_OWNED; 6973 6974 // Root gets to do everything. 6975 if (uid == 0) { 6976 return true; 6977 } 6978 6979 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6980 if (perms == null) return false; 6981 6982 // First look for exact match 6983 final UriPermission exactPerm = perms.get(grantUri); 6984 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6985 return true; 6986 } 6987 6988 // No exact match, look for prefixes 6989 final int N = perms.size(); 6990 for (int i = 0; i < N; i++) { 6991 final UriPermission perm = perms.valueAt(i); 6992 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6993 && perm.getStrength(modeFlags) >= minStrength) { 6994 return true; 6995 } 6996 } 6997 6998 return false; 6999 } 7000 7001 /** 7002 * @param uri This uri must NOT contain an embedded userId. 7003 * @param userId The userId in which the uri is to be resolved. 7004 */ 7005 @Override 7006 public int checkUriPermission(Uri uri, int pid, int uid, 7007 final int modeFlags, int userId) { 7008 enforceNotIsolatedCaller("checkUriPermission"); 7009 7010 // Another redirected-binder-call permissions check as in 7011 // {@link checkComponentPermission}. 7012 Identity tlsIdentity = sCallerIdentity.get(); 7013 if (tlsIdentity != null) { 7014 uid = tlsIdentity.uid; 7015 pid = tlsIdentity.pid; 7016 } 7017 7018 // Our own process gets to do everything. 7019 if (pid == MY_PID) { 7020 return PackageManager.PERMISSION_GRANTED; 7021 } 7022 synchronized (this) { 7023 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7024 ? PackageManager.PERMISSION_GRANTED 7025 : PackageManager.PERMISSION_DENIED; 7026 } 7027 } 7028 7029 /** 7030 * Check if the targetPkg can be granted permission to access uri by 7031 * the callingUid using the given modeFlags. Throws a security exception 7032 * if callingUid is not allowed to do this. Returns the uid of the target 7033 * if the URI permission grant should be performed; returns -1 if it is not 7034 * needed (for example targetPkg already has permission to access the URI). 7035 * If you already know the uid of the target, you can supply it in 7036 * lastTargetUid else set that to -1. 7037 */ 7038 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7039 final int modeFlags, int lastTargetUid) { 7040 if (!Intent.isAccessUriMode(modeFlags)) { 7041 return -1; 7042 } 7043 7044 if (targetPkg != null) { 7045 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7046 "Checking grant " + targetPkg + " permission to " + grantUri); 7047 } 7048 7049 final IPackageManager pm = AppGlobals.getPackageManager(); 7050 7051 // If this is not a content: uri, we can't do anything with it. 7052 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7053 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7054 "Can't grant URI permission for non-content URI: " + grantUri); 7055 return -1; 7056 } 7057 7058 final String authority = grantUri.uri.getAuthority(); 7059 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7060 if (pi == null) { 7061 Slog.w(TAG, "No content provider found for permission check: " + 7062 grantUri.uri.toSafeString()); 7063 return -1; 7064 } 7065 7066 int targetUid = lastTargetUid; 7067 if (targetUid < 0 && targetPkg != null) { 7068 try { 7069 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7070 if (targetUid < 0) { 7071 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7072 "Can't grant URI permission no uid for: " + targetPkg); 7073 return -1; 7074 } 7075 } catch (RemoteException ex) { 7076 return -1; 7077 } 7078 } 7079 7080 if (targetUid >= 0) { 7081 // First... does the target actually need this permission? 7082 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7083 // No need to grant the target this permission. 7084 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7085 "Target " + targetPkg + " already has full permission to " + grantUri); 7086 return -1; 7087 } 7088 } else { 7089 // First... there is no target package, so can anyone access it? 7090 boolean allowed = pi.exported; 7091 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7092 if (pi.readPermission != null) { 7093 allowed = false; 7094 } 7095 } 7096 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7097 if (pi.writePermission != null) { 7098 allowed = false; 7099 } 7100 } 7101 if (allowed) { 7102 return -1; 7103 } 7104 } 7105 7106 /* There is a special cross user grant if: 7107 * - The target is on another user. 7108 * - Apps on the current user can access the uri without any uid permissions. 7109 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7110 * grant uri permissions. 7111 */ 7112 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7113 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7114 modeFlags, false /*without considering the uid permissions*/); 7115 7116 // Second... is the provider allowing granting of URI permissions? 7117 if (!specialCrossUserGrant) { 7118 if (!pi.grantUriPermissions) { 7119 throw new SecurityException("Provider " + pi.packageName 7120 + "/" + pi.name 7121 + " does not allow granting of Uri permissions (uri " 7122 + grantUri + ")"); 7123 } 7124 if (pi.uriPermissionPatterns != null) { 7125 final int N = pi.uriPermissionPatterns.length; 7126 boolean allowed = false; 7127 for (int i=0; i<N; i++) { 7128 if (pi.uriPermissionPatterns[i] != null 7129 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7130 allowed = true; 7131 break; 7132 } 7133 } 7134 if (!allowed) { 7135 throw new SecurityException("Provider " + pi.packageName 7136 + "/" + pi.name 7137 + " does not allow granting of permission to path of Uri " 7138 + grantUri); 7139 } 7140 } 7141 } 7142 7143 // Third... does the caller itself have permission to access 7144 // this uri? 7145 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7146 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7147 // Require they hold a strong enough Uri permission 7148 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7149 throw new SecurityException("Uid " + callingUid 7150 + " does not have permission to uri " + grantUri); 7151 } 7152 } 7153 } 7154 return targetUid; 7155 } 7156 7157 /** 7158 * @param uri This uri must NOT contain an embedded userId. 7159 * @param userId The userId in which the uri is to be resolved. 7160 */ 7161 @Override 7162 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7163 final int modeFlags, int userId) { 7164 enforceNotIsolatedCaller("checkGrantUriPermission"); 7165 synchronized(this) { 7166 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7167 new GrantUri(userId, uri, false), modeFlags, -1); 7168 } 7169 } 7170 7171 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7172 final int modeFlags, UriPermissionOwner owner) { 7173 if (!Intent.isAccessUriMode(modeFlags)) { 7174 return; 7175 } 7176 7177 // So here we are: the caller has the assumed permission 7178 // to the uri, and the target doesn't. Let's now give this to 7179 // the target. 7180 7181 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7182 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7183 7184 final String authority = grantUri.uri.getAuthority(); 7185 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7186 if (pi == null) { 7187 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7188 return; 7189 } 7190 7191 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7192 grantUri.prefix = true; 7193 } 7194 final UriPermission perm = findOrCreateUriPermissionLocked( 7195 pi.packageName, targetPkg, targetUid, grantUri); 7196 perm.grantModes(modeFlags, owner); 7197 } 7198 7199 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7200 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7201 if (targetPkg == null) { 7202 throw new NullPointerException("targetPkg"); 7203 } 7204 int targetUid; 7205 final IPackageManager pm = AppGlobals.getPackageManager(); 7206 try { 7207 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7208 } catch (RemoteException ex) { 7209 return; 7210 } 7211 7212 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7213 targetUid); 7214 if (targetUid < 0) { 7215 return; 7216 } 7217 7218 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7219 owner); 7220 } 7221 7222 static class NeededUriGrants extends ArrayList<GrantUri> { 7223 final String targetPkg; 7224 final int targetUid; 7225 final int flags; 7226 7227 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7228 this.targetPkg = targetPkg; 7229 this.targetUid = targetUid; 7230 this.flags = flags; 7231 } 7232 } 7233 7234 /** 7235 * Like checkGrantUriPermissionLocked, but takes an Intent. 7236 */ 7237 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7238 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7239 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7240 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7241 + " clip=" + (intent != null ? intent.getClipData() : null) 7242 + " from " + intent + "; flags=0x" 7243 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7244 7245 if (targetPkg == null) { 7246 throw new NullPointerException("targetPkg"); 7247 } 7248 7249 if (intent == null) { 7250 return null; 7251 } 7252 Uri data = intent.getData(); 7253 ClipData clip = intent.getClipData(); 7254 if (data == null && clip == null) { 7255 return null; 7256 } 7257 // Default userId for uris in the intent (if they don't specify it themselves) 7258 int contentUserHint = intent.getContentUserHint(); 7259 if (contentUserHint == UserHandle.USER_CURRENT) { 7260 contentUserHint = UserHandle.getUserId(callingUid); 7261 } 7262 final IPackageManager pm = AppGlobals.getPackageManager(); 7263 int targetUid; 7264 if (needed != null) { 7265 targetUid = needed.targetUid; 7266 } else { 7267 try { 7268 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7269 } catch (RemoteException ex) { 7270 return null; 7271 } 7272 if (targetUid < 0) { 7273 if (DEBUG_URI_PERMISSION) { 7274 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7275 + " on user " + targetUserId); 7276 } 7277 return null; 7278 } 7279 } 7280 if (data != null) { 7281 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7282 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7283 targetUid); 7284 if (targetUid > 0) { 7285 if (needed == null) { 7286 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7287 } 7288 needed.add(grantUri); 7289 } 7290 } 7291 if (clip != null) { 7292 for (int i=0; i<clip.getItemCount(); i++) { 7293 Uri uri = clip.getItemAt(i).getUri(); 7294 if (uri != null) { 7295 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7296 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7297 targetUid); 7298 if (targetUid > 0) { 7299 if (needed == null) { 7300 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7301 } 7302 needed.add(grantUri); 7303 } 7304 } else { 7305 Intent clipIntent = clip.getItemAt(i).getIntent(); 7306 if (clipIntent != null) { 7307 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7308 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7309 if (newNeeded != null) { 7310 needed = newNeeded; 7311 } 7312 } 7313 } 7314 } 7315 } 7316 7317 return needed; 7318 } 7319 7320 /** 7321 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7322 */ 7323 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7324 UriPermissionOwner owner) { 7325 if (needed != null) { 7326 for (int i=0; i<needed.size(); i++) { 7327 GrantUri grantUri = needed.get(i); 7328 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7329 grantUri, needed.flags, owner); 7330 } 7331 } 7332 } 7333 7334 void grantUriPermissionFromIntentLocked(int callingUid, 7335 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7336 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7337 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7338 if (needed == null) { 7339 return; 7340 } 7341 7342 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7343 } 7344 7345 /** 7346 * @param uri This uri must NOT contain an embedded userId. 7347 * @param userId The userId in which the uri is to be resolved. 7348 */ 7349 @Override 7350 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7351 final int modeFlags, int userId) { 7352 enforceNotIsolatedCaller("grantUriPermission"); 7353 GrantUri grantUri = new GrantUri(userId, uri, false); 7354 synchronized(this) { 7355 final ProcessRecord r = getRecordForAppLocked(caller); 7356 if (r == null) { 7357 throw new SecurityException("Unable to find app for caller " 7358 + caller 7359 + " when granting permission to uri " + grantUri); 7360 } 7361 if (targetPkg == null) { 7362 throw new IllegalArgumentException("null target"); 7363 } 7364 if (grantUri == null) { 7365 throw new IllegalArgumentException("null uri"); 7366 } 7367 7368 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7369 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7370 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7371 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7372 7373 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7374 UserHandle.getUserId(r.uid)); 7375 } 7376 } 7377 7378 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7379 if (perm.modeFlags == 0) { 7380 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7381 perm.targetUid); 7382 if (perms != null) { 7383 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7384 "Removing " + perm.targetUid + " permission to " + perm.uri); 7385 7386 perms.remove(perm.uri); 7387 if (perms.isEmpty()) { 7388 mGrantedUriPermissions.remove(perm.targetUid); 7389 } 7390 } 7391 } 7392 } 7393 7394 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7395 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7396 7397 final IPackageManager pm = AppGlobals.getPackageManager(); 7398 final String authority = grantUri.uri.getAuthority(); 7399 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7400 if (pi == null) { 7401 Slog.w(TAG, "No content provider found for permission revoke: " 7402 + grantUri.toSafeString()); 7403 return; 7404 } 7405 7406 // Does the caller have this permission on the URI? 7407 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7408 // If they don't have direct access to the URI, then revoke any 7409 // ownerless URI permissions that have been granted to them. 7410 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7411 if (perms != null) { 7412 boolean persistChanged = false; 7413 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7414 final UriPermission perm = it.next(); 7415 if (perm.uri.sourceUserId == grantUri.sourceUserId 7416 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7417 if (DEBUG_URI_PERMISSION) 7418 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7419 " permission to " + perm.uri); 7420 persistChanged |= perm.revokeModes( 7421 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7422 if (perm.modeFlags == 0) { 7423 it.remove(); 7424 } 7425 } 7426 } 7427 if (perms.isEmpty()) { 7428 mGrantedUriPermissions.remove(callingUid); 7429 } 7430 if (persistChanged) { 7431 schedulePersistUriGrants(); 7432 } 7433 } 7434 return; 7435 } 7436 7437 boolean persistChanged = false; 7438 7439 // Go through all of the permissions and remove any that match. 7440 int N = mGrantedUriPermissions.size(); 7441 for (int i = 0; i < N; i++) { 7442 final int targetUid = mGrantedUriPermissions.keyAt(i); 7443 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7444 7445 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7446 final UriPermission perm = it.next(); 7447 if (perm.uri.sourceUserId == grantUri.sourceUserId 7448 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7449 if (DEBUG_URI_PERMISSION) 7450 Slog.v(TAG, 7451 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7452 persistChanged |= perm.revokeModes( 7453 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7454 if (perm.modeFlags == 0) { 7455 it.remove(); 7456 } 7457 } 7458 } 7459 7460 if (perms.isEmpty()) { 7461 mGrantedUriPermissions.remove(targetUid); 7462 N--; 7463 i--; 7464 } 7465 } 7466 7467 if (persistChanged) { 7468 schedulePersistUriGrants(); 7469 } 7470 } 7471 7472 /** 7473 * @param uri This uri must NOT contain an embedded userId. 7474 * @param userId The userId in which the uri is to be resolved. 7475 */ 7476 @Override 7477 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7478 int userId) { 7479 enforceNotIsolatedCaller("revokeUriPermission"); 7480 synchronized(this) { 7481 final ProcessRecord r = getRecordForAppLocked(caller); 7482 if (r == null) { 7483 throw new SecurityException("Unable to find app for caller " 7484 + caller 7485 + " when revoking permission to uri " + uri); 7486 } 7487 if (uri == null) { 7488 Slog.w(TAG, "revokeUriPermission: null uri"); 7489 return; 7490 } 7491 7492 if (!Intent.isAccessUriMode(modeFlags)) { 7493 return; 7494 } 7495 7496 final IPackageManager pm = AppGlobals.getPackageManager(); 7497 final String authority = uri.getAuthority(); 7498 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7499 if (pi == null) { 7500 Slog.w(TAG, "No content provider found for permission revoke: " 7501 + uri.toSafeString()); 7502 return; 7503 } 7504 7505 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7506 } 7507 } 7508 7509 /** 7510 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7511 * given package. 7512 * 7513 * @param packageName Package name to match, or {@code null} to apply to all 7514 * packages. 7515 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7516 * to all users. 7517 * @param persistable If persistable grants should be removed. 7518 */ 7519 private void removeUriPermissionsForPackageLocked( 7520 String packageName, int userHandle, boolean persistable) { 7521 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7522 throw new IllegalArgumentException("Must narrow by either package or user"); 7523 } 7524 7525 boolean persistChanged = false; 7526 7527 int N = mGrantedUriPermissions.size(); 7528 for (int i = 0; i < N; i++) { 7529 final int targetUid = mGrantedUriPermissions.keyAt(i); 7530 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7531 7532 // Only inspect grants matching user 7533 if (userHandle == UserHandle.USER_ALL 7534 || userHandle == UserHandle.getUserId(targetUid)) { 7535 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7536 final UriPermission perm = it.next(); 7537 7538 // Only inspect grants matching package 7539 if (packageName == null || perm.sourcePkg.equals(packageName) 7540 || perm.targetPkg.equals(packageName)) { 7541 persistChanged |= perm.revokeModes(persistable 7542 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7543 7544 // Only remove when no modes remain; any persisted grants 7545 // will keep this alive. 7546 if (perm.modeFlags == 0) { 7547 it.remove(); 7548 } 7549 } 7550 } 7551 7552 if (perms.isEmpty()) { 7553 mGrantedUriPermissions.remove(targetUid); 7554 N--; 7555 i--; 7556 } 7557 } 7558 } 7559 7560 if (persistChanged) { 7561 schedulePersistUriGrants(); 7562 } 7563 } 7564 7565 @Override 7566 public IBinder newUriPermissionOwner(String name) { 7567 enforceNotIsolatedCaller("newUriPermissionOwner"); 7568 synchronized(this) { 7569 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7570 return owner.getExternalTokenLocked(); 7571 } 7572 } 7573 7574 /** 7575 * @param uri This uri must NOT contain an embedded userId. 7576 * @param sourceUserId The userId in which the uri is to be resolved. 7577 * @param targetUserId The userId of the app that receives the grant. 7578 */ 7579 @Override 7580 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7581 final int modeFlags, int sourceUserId, int targetUserId) { 7582 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7583 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7584 synchronized(this) { 7585 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7586 if (owner == null) { 7587 throw new IllegalArgumentException("Unknown owner: " + token); 7588 } 7589 if (fromUid != Binder.getCallingUid()) { 7590 if (Binder.getCallingUid() != Process.myUid()) { 7591 // Only system code can grant URI permissions on behalf 7592 // of other users. 7593 throw new SecurityException("nice try"); 7594 } 7595 } 7596 if (targetPkg == null) { 7597 throw new IllegalArgumentException("null target"); 7598 } 7599 if (uri == null) { 7600 throw new IllegalArgumentException("null uri"); 7601 } 7602 7603 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7604 modeFlags, owner, targetUserId); 7605 } 7606 } 7607 7608 /** 7609 * @param uri This uri must NOT contain an embedded userId. 7610 * @param userId The userId in which the uri is to be resolved. 7611 */ 7612 @Override 7613 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7614 synchronized(this) { 7615 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7616 if (owner == null) { 7617 throw new IllegalArgumentException("Unknown owner: " + token); 7618 } 7619 7620 if (uri == null) { 7621 owner.removeUriPermissionsLocked(mode); 7622 } else { 7623 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7624 } 7625 } 7626 } 7627 7628 private void schedulePersistUriGrants() { 7629 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7630 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7631 10 * DateUtils.SECOND_IN_MILLIS); 7632 } 7633 } 7634 7635 private void writeGrantedUriPermissions() { 7636 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7637 7638 // Snapshot permissions so we can persist without lock 7639 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7640 synchronized (this) { 7641 final int size = mGrantedUriPermissions.size(); 7642 for (int i = 0; i < size; i++) { 7643 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7644 for (UriPermission perm : perms.values()) { 7645 if (perm.persistedModeFlags != 0) { 7646 persist.add(perm.snapshot()); 7647 } 7648 } 7649 } 7650 } 7651 7652 FileOutputStream fos = null; 7653 try { 7654 fos = mGrantFile.startWrite(); 7655 7656 XmlSerializer out = new FastXmlSerializer(); 7657 out.setOutput(fos, "utf-8"); 7658 out.startDocument(null, true); 7659 out.startTag(null, TAG_URI_GRANTS); 7660 for (UriPermission.Snapshot perm : persist) { 7661 out.startTag(null, TAG_URI_GRANT); 7662 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7663 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7664 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7665 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7666 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7667 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7668 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7669 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7670 out.endTag(null, TAG_URI_GRANT); 7671 } 7672 out.endTag(null, TAG_URI_GRANTS); 7673 out.endDocument(); 7674 7675 mGrantFile.finishWrite(fos); 7676 } catch (IOException e) { 7677 if (fos != null) { 7678 mGrantFile.failWrite(fos); 7679 } 7680 } 7681 } 7682 7683 private void readGrantedUriPermissionsLocked() { 7684 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7685 7686 final long now = System.currentTimeMillis(); 7687 7688 FileInputStream fis = null; 7689 try { 7690 fis = mGrantFile.openRead(); 7691 final XmlPullParser in = Xml.newPullParser(); 7692 in.setInput(fis, null); 7693 7694 int type; 7695 while ((type = in.next()) != END_DOCUMENT) { 7696 final String tag = in.getName(); 7697 if (type == START_TAG) { 7698 if (TAG_URI_GRANT.equals(tag)) { 7699 final int sourceUserId; 7700 final int targetUserId; 7701 final int userHandle = readIntAttribute(in, 7702 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7703 if (userHandle != UserHandle.USER_NULL) { 7704 // For backwards compatibility. 7705 sourceUserId = userHandle; 7706 targetUserId = userHandle; 7707 } else { 7708 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7709 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7710 } 7711 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7712 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7713 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7714 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7715 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7716 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7717 7718 // Sanity check that provider still belongs to source package 7719 final ProviderInfo pi = getProviderInfoLocked( 7720 uri.getAuthority(), sourceUserId); 7721 if (pi != null && sourcePkg.equals(pi.packageName)) { 7722 int targetUid = -1; 7723 try { 7724 targetUid = AppGlobals.getPackageManager() 7725 .getPackageUid(targetPkg, targetUserId); 7726 } catch (RemoteException e) { 7727 } 7728 if (targetUid != -1) { 7729 final UriPermission perm = findOrCreateUriPermissionLocked( 7730 sourcePkg, targetPkg, targetUid, 7731 new GrantUri(sourceUserId, uri, prefix)); 7732 perm.initPersistedModes(modeFlags, createdTime); 7733 } 7734 } else { 7735 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7736 + " but instead found " + pi); 7737 } 7738 } 7739 } 7740 } 7741 } catch (FileNotFoundException e) { 7742 // Missing grants is okay 7743 } catch (IOException e) { 7744 Slog.wtf(TAG, "Failed reading Uri grants", e); 7745 } catch (XmlPullParserException e) { 7746 Slog.wtf(TAG, "Failed reading Uri grants", e); 7747 } finally { 7748 IoUtils.closeQuietly(fis); 7749 } 7750 } 7751 7752 /** 7753 * @param uri This uri must NOT contain an embedded userId. 7754 * @param userId The userId in which the uri is to be resolved. 7755 */ 7756 @Override 7757 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7758 enforceNotIsolatedCaller("takePersistableUriPermission"); 7759 7760 Preconditions.checkFlagsArgument(modeFlags, 7761 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7762 7763 synchronized (this) { 7764 final int callingUid = Binder.getCallingUid(); 7765 boolean persistChanged = false; 7766 GrantUri grantUri = new GrantUri(userId, uri, false); 7767 7768 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7769 new GrantUri(userId, uri, false)); 7770 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7771 new GrantUri(userId, uri, true)); 7772 7773 final boolean exactValid = (exactPerm != null) 7774 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7775 final boolean prefixValid = (prefixPerm != null) 7776 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7777 7778 if (!(exactValid || prefixValid)) { 7779 throw new SecurityException("No persistable permission grants found for UID " 7780 + callingUid + " and Uri " + grantUri.toSafeString()); 7781 } 7782 7783 if (exactValid) { 7784 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7785 } 7786 if (prefixValid) { 7787 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7788 } 7789 7790 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7791 7792 if (persistChanged) { 7793 schedulePersistUriGrants(); 7794 } 7795 } 7796 } 7797 7798 /** 7799 * @param uri This uri must NOT contain an embedded userId. 7800 * @param userId The userId in which the uri is to be resolved. 7801 */ 7802 @Override 7803 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7804 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7805 7806 Preconditions.checkFlagsArgument(modeFlags, 7807 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7808 7809 synchronized (this) { 7810 final int callingUid = Binder.getCallingUid(); 7811 boolean persistChanged = false; 7812 7813 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7814 new GrantUri(userId, uri, false)); 7815 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7816 new GrantUri(userId, uri, true)); 7817 if (exactPerm == null && prefixPerm == null) { 7818 throw new SecurityException("No permission grants found for UID " + callingUid 7819 + " and Uri " + uri.toSafeString()); 7820 } 7821 7822 if (exactPerm != null) { 7823 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7824 removeUriPermissionIfNeededLocked(exactPerm); 7825 } 7826 if (prefixPerm != null) { 7827 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7828 removeUriPermissionIfNeededLocked(prefixPerm); 7829 } 7830 7831 if (persistChanged) { 7832 schedulePersistUriGrants(); 7833 } 7834 } 7835 } 7836 7837 /** 7838 * Prune any older {@link UriPermission} for the given UID until outstanding 7839 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7840 * 7841 * @return if any mutations occured that require persisting. 7842 */ 7843 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7844 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7845 if (perms == null) return false; 7846 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7847 7848 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7849 for (UriPermission perm : perms.values()) { 7850 if (perm.persistedModeFlags != 0) { 7851 persisted.add(perm); 7852 } 7853 } 7854 7855 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7856 if (trimCount <= 0) return false; 7857 7858 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7859 for (int i = 0; i < trimCount; i++) { 7860 final UriPermission perm = persisted.get(i); 7861 7862 if (DEBUG_URI_PERMISSION) { 7863 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7864 } 7865 7866 perm.releasePersistableModes(~0); 7867 removeUriPermissionIfNeededLocked(perm); 7868 } 7869 7870 return true; 7871 } 7872 7873 @Override 7874 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7875 String packageName, boolean incoming) { 7876 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7877 Preconditions.checkNotNull(packageName, "packageName"); 7878 7879 final int callingUid = Binder.getCallingUid(); 7880 final IPackageManager pm = AppGlobals.getPackageManager(); 7881 try { 7882 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7883 if (packageUid != callingUid) { 7884 throw new SecurityException( 7885 "Package " + packageName + " does not belong to calling UID " + callingUid); 7886 } 7887 } catch (RemoteException e) { 7888 throw new SecurityException("Failed to verify package name ownership"); 7889 } 7890 7891 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7892 synchronized (this) { 7893 if (incoming) { 7894 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7895 callingUid); 7896 if (perms == null) { 7897 Slog.w(TAG, "No permission grants found for " + packageName); 7898 } else { 7899 for (UriPermission perm : perms.values()) { 7900 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7901 result.add(perm.buildPersistedPublicApiObject()); 7902 } 7903 } 7904 } 7905 } else { 7906 final int size = mGrantedUriPermissions.size(); 7907 for (int i = 0; i < size; i++) { 7908 final ArrayMap<GrantUri, UriPermission> perms = 7909 mGrantedUriPermissions.valueAt(i); 7910 for (UriPermission perm : perms.values()) { 7911 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7912 result.add(perm.buildPersistedPublicApiObject()); 7913 } 7914 } 7915 } 7916 } 7917 } 7918 return new ParceledListSlice<android.content.UriPermission>(result); 7919 } 7920 7921 @Override 7922 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7923 synchronized (this) { 7924 ProcessRecord app = 7925 who != null ? getRecordForAppLocked(who) : null; 7926 if (app == null) return; 7927 7928 Message msg = Message.obtain(); 7929 msg.what = WAIT_FOR_DEBUGGER_MSG; 7930 msg.obj = app; 7931 msg.arg1 = waiting ? 1 : 0; 7932 mHandler.sendMessage(msg); 7933 } 7934 } 7935 7936 @Override 7937 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7938 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7939 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7940 outInfo.availMem = Process.getFreeMemory(); 7941 outInfo.totalMem = Process.getTotalMemory(); 7942 outInfo.threshold = homeAppMem; 7943 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7944 outInfo.hiddenAppThreshold = cachedAppMem; 7945 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7946 ProcessList.SERVICE_ADJ); 7947 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7948 ProcessList.VISIBLE_APP_ADJ); 7949 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7950 ProcessList.FOREGROUND_APP_ADJ); 7951 } 7952 7953 // ========================================================= 7954 // TASK MANAGEMENT 7955 // ========================================================= 7956 7957 @Override 7958 public List<IAppTask> getAppTasks(String callingPackage) { 7959 int callingUid = Binder.getCallingUid(); 7960 long ident = Binder.clearCallingIdentity(); 7961 7962 synchronized(this) { 7963 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7964 try { 7965 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7966 7967 final int N = mRecentTasks.size(); 7968 for (int i = 0; i < N; i++) { 7969 TaskRecord tr = mRecentTasks.get(i); 7970 // Skip tasks that do not match the caller. We don't need to verify 7971 // callingPackage, because we are also limiting to callingUid and know 7972 // that will limit to the correct security sandbox. 7973 if (tr.effectiveUid != callingUid) { 7974 continue; 7975 } 7976 Intent intent = tr.getBaseIntent(); 7977 if (intent == null || 7978 !callingPackage.equals(intent.getComponent().getPackageName())) { 7979 continue; 7980 } 7981 ActivityManager.RecentTaskInfo taskInfo = 7982 createRecentTaskInfoFromTaskRecord(tr); 7983 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7984 list.add(taskImpl); 7985 } 7986 } finally { 7987 Binder.restoreCallingIdentity(ident); 7988 } 7989 return list; 7990 } 7991 } 7992 7993 @Override 7994 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7995 final int callingUid = Binder.getCallingUid(); 7996 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7997 7998 synchronized(this) { 7999 if (localLOGV) Slog.v( 8000 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8001 8002 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8003 callingUid); 8004 8005 // TODO: Improve with MRU list from all ActivityStacks. 8006 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8007 } 8008 8009 return list; 8010 } 8011 8012 TaskRecord getMostRecentTask() { 8013 return mRecentTasks.get(0); 8014 } 8015 8016 /** 8017 * Creates a new RecentTaskInfo from a TaskRecord. 8018 */ 8019 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8020 // Update the task description to reflect any changes in the task stack 8021 tr.updateTaskDescription(); 8022 8023 // Compose the recent task info 8024 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8025 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8026 rti.persistentId = tr.taskId; 8027 rti.baseIntent = new Intent(tr.getBaseIntent()); 8028 rti.origActivity = tr.origActivity; 8029 rti.description = tr.lastDescription; 8030 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8031 rti.userId = tr.userId; 8032 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8033 rti.firstActiveTime = tr.firstActiveTime; 8034 rti.lastActiveTime = tr.lastActiveTime; 8035 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8036 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8037 return rti; 8038 } 8039 8040 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8041 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8042 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8043 if (!allowed) { 8044 if (checkPermission(android.Manifest.permission.GET_TASKS, 8045 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8046 // Temporary compatibility: some existing apps on the system image may 8047 // still be requesting the old permission and not switched to the new 8048 // one; if so, we'll still allow them full access. This means we need 8049 // to see if they are holding the old permission and are a system app. 8050 try { 8051 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8052 allowed = true; 8053 Slog.w(TAG, caller + ": caller " + callingUid 8054 + " is using old GET_TASKS but privileged; allowing"); 8055 } 8056 } catch (RemoteException e) { 8057 } 8058 } 8059 } 8060 if (!allowed) { 8061 Slog.w(TAG, caller + ": caller " + callingUid 8062 + " does not hold GET_TASKS; limiting output"); 8063 } 8064 return allowed; 8065 } 8066 8067 @Override 8068 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8069 final int callingUid = Binder.getCallingUid(); 8070 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8071 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8072 8073 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8074 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8075 synchronized (this) { 8076 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8077 callingUid); 8078 final boolean detailed = checkCallingPermission( 8079 android.Manifest.permission.GET_DETAILED_TASKS) 8080 == PackageManager.PERMISSION_GRANTED; 8081 8082 final int N = mRecentTasks.size(); 8083 ArrayList<ActivityManager.RecentTaskInfo> res 8084 = new ArrayList<ActivityManager.RecentTaskInfo>( 8085 maxNum < N ? maxNum : N); 8086 8087 final Set<Integer> includedUsers; 8088 if (includeProfiles) { 8089 includedUsers = getProfileIdsLocked(userId); 8090 } else { 8091 includedUsers = new HashSet<Integer>(); 8092 } 8093 includedUsers.add(Integer.valueOf(userId)); 8094 8095 for (int i=0; i<N && maxNum > 0; i++) { 8096 TaskRecord tr = mRecentTasks.get(i); 8097 // Only add calling user or related users recent tasks 8098 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8099 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8100 continue; 8101 } 8102 8103 // Return the entry if desired by the caller. We always return 8104 // the first entry, because callers always expect this to be the 8105 // foreground app. We may filter others if the caller has 8106 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8107 // we should exclude the entry. 8108 8109 if (i == 0 8110 || withExcluded 8111 || (tr.intent == null) 8112 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8113 == 0)) { 8114 if (!allowed) { 8115 // If the caller doesn't have the GET_TASKS permission, then only 8116 // allow them to see a small subset of tasks -- their own and home. 8117 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8118 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8119 continue; 8120 } 8121 } 8122 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8123 if (tr.stack != null && tr.stack.isHomeStack()) { 8124 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8125 continue; 8126 } 8127 } 8128 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8129 // Don't include auto remove tasks that are finished or finishing. 8130 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8131 + tr); 8132 continue; 8133 } 8134 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8135 && !tr.isAvailable) { 8136 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8137 continue; 8138 } 8139 8140 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8141 if (!detailed) { 8142 rti.baseIntent.replaceExtras((Bundle)null); 8143 } 8144 8145 res.add(rti); 8146 maxNum--; 8147 } 8148 } 8149 return res; 8150 } 8151 } 8152 8153 private TaskRecord recentTaskForIdLocked(int id) { 8154 final int N = mRecentTasks.size(); 8155 for (int i=0; i<N; i++) { 8156 TaskRecord tr = mRecentTasks.get(i); 8157 if (tr.taskId == id) { 8158 return tr; 8159 } 8160 } 8161 return null; 8162 } 8163 8164 @Override 8165 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8166 synchronized (this) { 8167 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8168 "getTaskThumbnail()"); 8169 TaskRecord tr = recentTaskForIdLocked(id); 8170 if (tr != null) { 8171 return tr.getTaskThumbnailLocked(); 8172 } 8173 } 8174 return null; 8175 } 8176 8177 @Override 8178 public int addAppTask(IBinder activityToken, Intent intent, 8179 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8180 final int callingUid = Binder.getCallingUid(); 8181 final long callingIdent = Binder.clearCallingIdentity(); 8182 8183 try { 8184 synchronized (this) { 8185 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8186 if (r == null) { 8187 throw new IllegalArgumentException("Activity does not exist; token=" 8188 + activityToken); 8189 } 8190 ComponentName comp = intent.getComponent(); 8191 if (comp == null) { 8192 throw new IllegalArgumentException("Intent " + intent 8193 + " must specify explicit component"); 8194 } 8195 if (thumbnail.getWidth() != mThumbnailWidth 8196 || thumbnail.getHeight() != mThumbnailHeight) { 8197 throw new IllegalArgumentException("Bad thumbnail size: got " 8198 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8199 + mThumbnailWidth + "x" + mThumbnailHeight); 8200 } 8201 if (intent.getSelector() != null) { 8202 intent.setSelector(null); 8203 } 8204 if (intent.getSourceBounds() != null) { 8205 intent.setSourceBounds(null); 8206 } 8207 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8208 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8209 // The caller has added this as an auto-remove task... that makes no 8210 // sense, so turn off auto-remove. 8211 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8212 } 8213 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8214 // Must be a new task. 8215 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8216 } 8217 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8218 mLastAddedTaskActivity = null; 8219 } 8220 ActivityInfo ainfo = mLastAddedTaskActivity; 8221 if (ainfo == null) { 8222 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8223 comp, 0, UserHandle.getUserId(callingUid)); 8224 if (ainfo.applicationInfo.uid != callingUid) { 8225 throw new SecurityException( 8226 "Can't add task for another application: target uid=" 8227 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8228 } 8229 } 8230 8231 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8232 intent, description); 8233 8234 int trimIdx = trimRecentsForTask(task, false); 8235 if (trimIdx >= 0) { 8236 // If this would have caused a trim, then we'll abort because that 8237 // means it would be added at the end of the list but then just removed. 8238 return -1; 8239 } 8240 8241 final int N = mRecentTasks.size(); 8242 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8243 final TaskRecord tr = mRecentTasks.remove(N - 1); 8244 tr.removedFromRecents(mTaskPersister); 8245 } 8246 8247 task.inRecents = true; 8248 mRecentTasks.add(task); 8249 r.task.stack.addTask(task, false, false); 8250 8251 task.setLastThumbnail(thumbnail); 8252 task.freeLastThumbnail(); 8253 8254 return task.taskId; 8255 } 8256 } finally { 8257 Binder.restoreCallingIdentity(callingIdent); 8258 } 8259 } 8260 8261 @Override 8262 public Point getAppTaskThumbnailSize() { 8263 synchronized (this) { 8264 return new Point(mThumbnailWidth, mThumbnailHeight); 8265 } 8266 } 8267 8268 @Override 8269 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8270 synchronized (this) { 8271 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8272 if (r != null) { 8273 r.setTaskDescription(td); 8274 r.task.updateTaskDescription(); 8275 } 8276 } 8277 } 8278 8279 @Override 8280 public Bitmap getTaskDescriptionIcon(String filename) { 8281 if (!FileUtils.isValidExtFilename(filename) 8282 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8283 throw new IllegalArgumentException("Bad filename: " + filename); 8284 } 8285 return mTaskPersister.getTaskDescriptionIcon(filename); 8286 } 8287 8288 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8289 mRecentTasks.remove(tr); 8290 tr.removedFromRecents(mTaskPersister); 8291 ComponentName component = tr.getBaseIntent().getComponent(); 8292 if (component == null) { 8293 Slog.w(TAG, "No component for base intent of task: " + tr); 8294 return; 8295 } 8296 8297 if (!killProcess) { 8298 return; 8299 } 8300 8301 // Determine if the process(es) for this task should be killed. 8302 final String pkg = component.getPackageName(); 8303 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8304 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8305 for (int i = 0; i < pmap.size(); i++) { 8306 8307 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8308 for (int j = 0; j < uids.size(); j++) { 8309 ProcessRecord proc = uids.valueAt(j); 8310 if (proc.userId != tr.userId) { 8311 // Don't kill process for a different user. 8312 continue; 8313 } 8314 if (proc == mHomeProcess) { 8315 // Don't kill the home process along with tasks from the same package. 8316 continue; 8317 } 8318 if (!proc.pkgList.containsKey(pkg)) { 8319 // Don't kill process that is not associated with this task. 8320 continue; 8321 } 8322 8323 for (int k = 0; k < proc.activities.size(); k++) { 8324 TaskRecord otherTask = proc.activities.get(k).task; 8325 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8326 // Don't kill process(es) that has an activity in a different task that is 8327 // also in recents. 8328 return; 8329 } 8330 } 8331 8332 // Add process to kill list. 8333 procsToKill.add(proc); 8334 } 8335 } 8336 8337 // Find any running services associated with this app and stop if needed. 8338 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8339 8340 // Kill the running processes. 8341 for (int i = 0; i < procsToKill.size(); i++) { 8342 ProcessRecord pr = procsToKill.get(i); 8343 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8344 pr.kill("remove task", true); 8345 } else { 8346 pr.waitingToKill = "remove task"; 8347 } 8348 } 8349 } 8350 8351 /** 8352 * Removes the task with the specified task id. 8353 * 8354 * @param taskId Identifier of the task to be removed. 8355 * @param killProcess Kill any process associated with the task if possible. 8356 * @return Returns true if the given task was found and removed. 8357 */ 8358 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8359 TaskRecord tr = recentTaskForIdLocked(taskId); 8360 if (tr != null) { 8361 tr.removeTaskActivitiesLocked(); 8362 cleanUpRemovedTaskLocked(tr, killProcess); 8363 if (tr.isPersistable) { 8364 notifyTaskPersisterLocked(null, true); 8365 } 8366 return true; 8367 } 8368 return false; 8369 } 8370 8371 @Override 8372 public boolean removeTask(int taskId) { 8373 synchronized (this) { 8374 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8375 "removeTask()"); 8376 long ident = Binder.clearCallingIdentity(); 8377 try { 8378 return removeTaskByIdLocked(taskId, true); 8379 } finally { 8380 Binder.restoreCallingIdentity(ident); 8381 } 8382 } 8383 } 8384 8385 /** 8386 * TODO: Add mController hook 8387 */ 8388 @Override 8389 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8390 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8391 "moveTaskToFront()"); 8392 8393 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8394 synchronized(this) { 8395 moveTaskToFrontLocked(taskId, flags, options); 8396 } 8397 } 8398 8399 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8400 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8401 Binder.getCallingUid(), -1, -1, "Task to front")) { 8402 ActivityOptions.abort(options); 8403 return; 8404 } 8405 final long origId = Binder.clearCallingIdentity(); 8406 try { 8407 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8408 if (task == null) { 8409 return; 8410 } 8411 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8412 mStackSupervisor.showLockTaskToast(); 8413 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8414 return; 8415 } 8416 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8417 if (prev != null && prev.isRecentsActivity()) { 8418 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8419 } 8420 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8421 } finally { 8422 Binder.restoreCallingIdentity(origId); 8423 } 8424 ActivityOptions.abort(options); 8425 } 8426 8427 @Override 8428 public void moveTaskToBack(int taskId) { 8429 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8430 "moveTaskToBack()"); 8431 8432 synchronized(this) { 8433 TaskRecord tr = recentTaskForIdLocked(taskId); 8434 if (tr != null) { 8435 if (tr == mStackSupervisor.mLockTaskModeTask) { 8436 mStackSupervisor.showLockTaskToast(); 8437 return; 8438 } 8439 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8440 ActivityStack stack = tr.stack; 8441 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8442 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8443 Binder.getCallingUid(), -1, -1, "Task to back")) { 8444 return; 8445 } 8446 } 8447 final long origId = Binder.clearCallingIdentity(); 8448 try { 8449 stack.moveTaskToBackLocked(taskId, null); 8450 } finally { 8451 Binder.restoreCallingIdentity(origId); 8452 } 8453 } 8454 } 8455 } 8456 8457 /** 8458 * Moves an activity, and all of the other activities within the same task, to the bottom 8459 * of the history stack. The activity's order within the task is unchanged. 8460 * 8461 * @param token A reference to the activity we wish to move 8462 * @param nonRoot If false then this only works if the activity is the root 8463 * of a task; if true it will work for any activity in a task. 8464 * @return Returns true if the move completed, false if not. 8465 */ 8466 @Override 8467 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8468 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8469 synchronized(this) { 8470 final long origId = Binder.clearCallingIdentity(); 8471 try { 8472 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8473 if (taskId >= 0) { 8474 if ((mStackSupervisor.mLockTaskModeTask != null) 8475 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8476 mStackSupervisor.showLockTaskToast(); 8477 return false; 8478 } 8479 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8480 } 8481 } finally { 8482 Binder.restoreCallingIdentity(origId); 8483 } 8484 } 8485 return false; 8486 } 8487 8488 @Override 8489 public void moveTaskBackwards(int task) { 8490 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8491 "moveTaskBackwards()"); 8492 8493 synchronized(this) { 8494 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8495 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8496 return; 8497 } 8498 final long origId = Binder.clearCallingIdentity(); 8499 moveTaskBackwardsLocked(task); 8500 Binder.restoreCallingIdentity(origId); 8501 } 8502 } 8503 8504 private final void moveTaskBackwardsLocked(int task) { 8505 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8506 } 8507 8508 @Override 8509 public IBinder getHomeActivityToken() throws RemoteException { 8510 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8511 "getHomeActivityToken()"); 8512 synchronized (this) { 8513 return mStackSupervisor.getHomeActivityToken(); 8514 } 8515 } 8516 8517 @Override 8518 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8519 IActivityContainerCallback callback) throws RemoteException { 8520 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8521 "createActivityContainer()"); 8522 synchronized (this) { 8523 if (parentActivityToken == null) { 8524 throw new IllegalArgumentException("parent token must not be null"); 8525 } 8526 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8527 if (r == null) { 8528 return null; 8529 } 8530 if (callback == null) { 8531 throw new IllegalArgumentException("callback must not be null"); 8532 } 8533 return mStackSupervisor.createActivityContainer(r, callback); 8534 } 8535 } 8536 8537 @Override 8538 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8539 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8540 "deleteActivityContainer()"); 8541 synchronized (this) { 8542 mStackSupervisor.deleteActivityContainer(container); 8543 } 8544 } 8545 8546 @Override 8547 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8548 throws RemoteException { 8549 synchronized (this) { 8550 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8551 if (stack != null) { 8552 return stack.mActivityContainer; 8553 } 8554 return null; 8555 } 8556 } 8557 8558 @Override 8559 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8560 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8561 "moveTaskToStack()"); 8562 if (stackId == HOME_STACK_ID) { 8563 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8564 new RuntimeException("here").fillInStackTrace()); 8565 } 8566 synchronized (this) { 8567 long ident = Binder.clearCallingIdentity(); 8568 try { 8569 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8570 + stackId + " toTop=" + toTop); 8571 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8572 } finally { 8573 Binder.restoreCallingIdentity(ident); 8574 } 8575 } 8576 } 8577 8578 @Override 8579 public void resizeStack(int stackBoxId, Rect bounds) { 8580 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8581 "resizeStackBox()"); 8582 long ident = Binder.clearCallingIdentity(); 8583 try { 8584 mWindowManager.resizeStack(stackBoxId, bounds); 8585 } finally { 8586 Binder.restoreCallingIdentity(ident); 8587 } 8588 } 8589 8590 @Override 8591 public List<StackInfo> getAllStackInfos() { 8592 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8593 "getAllStackInfos()"); 8594 long ident = Binder.clearCallingIdentity(); 8595 try { 8596 synchronized (this) { 8597 return mStackSupervisor.getAllStackInfosLocked(); 8598 } 8599 } finally { 8600 Binder.restoreCallingIdentity(ident); 8601 } 8602 } 8603 8604 @Override 8605 public StackInfo getStackInfo(int stackId) { 8606 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8607 "getStackInfo()"); 8608 long ident = Binder.clearCallingIdentity(); 8609 try { 8610 synchronized (this) { 8611 return mStackSupervisor.getStackInfoLocked(stackId); 8612 } 8613 } finally { 8614 Binder.restoreCallingIdentity(ident); 8615 } 8616 } 8617 8618 @Override 8619 public boolean isInHomeStack(int taskId) { 8620 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8621 "getStackInfo()"); 8622 long ident = Binder.clearCallingIdentity(); 8623 try { 8624 synchronized (this) { 8625 TaskRecord tr = recentTaskForIdLocked(taskId); 8626 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8627 } 8628 } finally { 8629 Binder.restoreCallingIdentity(ident); 8630 } 8631 } 8632 8633 @Override 8634 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8635 synchronized(this) { 8636 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8637 } 8638 } 8639 8640 private boolean isLockTaskAuthorized(String pkg) { 8641 final DevicePolicyManager dpm = (DevicePolicyManager) 8642 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8643 try { 8644 int uid = mContext.getPackageManager().getPackageUid(pkg, 8645 Binder.getCallingUserHandle().getIdentifier()); 8646 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8647 } catch (NameNotFoundException e) { 8648 return false; 8649 } 8650 } 8651 8652 void startLockTaskMode(TaskRecord task) { 8653 final String pkg; 8654 synchronized (this) { 8655 pkg = task.intent.getComponent().getPackageName(); 8656 } 8657 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8658 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8659 final TaskRecord taskRecord = task; 8660 mHandler.post(new Runnable() { 8661 @Override 8662 public void run() { 8663 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8664 } 8665 }); 8666 return; 8667 } 8668 long ident = Binder.clearCallingIdentity(); 8669 try { 8670 synchronized (this) { 8671 // Since we lost lock on task, make sure it is still there. 8672 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8673 if (task != null) { 8674 if (!isSystemInitiated 8675 && ((mStackSupervisor.getFocusedStack() == null) 8676 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8677 throw new IllegalArgumentException("Invalid task, not in foreground"); 8678 } 8679 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8680 } 8681 } 8682 } finally { 8683 Binder.restoreCallingIdentity(ident); 8684 } 8685 } 8686 8687 @Override 8688 public void startLockTaskMode(int taskId) { 8689 final TaskRecord task; 8690 long ident = Binder.clearCallingIdentity(); 8691 try { 8692 synchronized (this) { 8693 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8694 } 8695 } finally { 8696 Binder.restoreCallingIdentity(ident); 8697 } 8698 if (task != null) { 8699 startLockTaskMode(task); 8700 } 8701 } 8702 8703 @Override 8704 public void startLockTaskMode(IBinder token) { 8705 final TaskRecord task; 8706 long ident = Binder.clearCallingIdentity(); 8707 try { 8708 synchronized (this) { 8709 final ActivityRecord r = ActivityRecord.forToken(token); 8710 if (r == null) { 8711 return; 8712 } 8713 task = r.task; 8714 } 8715 } finally { 8716 Binder.restoreCallingIdentity(ident); 8717 } 8718 if (task != null) { 8719 startLockTaskMode(task); 8720 } 8721 } 8722 8723 @Override 8724 public void startLockTaskModeOnCurrent() throws RemoteException { 8725 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8726 "startLockTaskModeOnCurrent"); 8727 ActivityRecord r = null; 8728 synchronized (this) { 8729 r = mStackSupervisor.topRunningActivityLocked(); 8730 } 8731 startLockTaskMode(r.task); 8732 } 8733 8734 @Override 8735 public void stopLockTaskMode() { 8736 // Verify that the user matches the package of the intent for the TaskRecord 8737 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8738 // and stopLockTaskMode. 8739 final int callingUid = Binder.getCallingUid(); 8740 if (callingUid != Process.SYSTEM_UID) { 8741 try { 8742 String pkg = 8743 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8744 int uid = mContext.getPackageManager().getPackageUid(pkg, 8745 Binder.getCallingUserHandle().getIdentifier()); 8746 if (uid != callingUid) { 8747 throw new SecurityException("Invalid uid, expected " + uid); 8748 } 8749 } catch (NameNotFoundException e) { 8750 Log.d(TAG, "stopLockTaskMode " + e); 8751 return; 8752 } 8753 } 8754 long ident = Binder.clearCallingIdentity(); 8755 try { 8756 Log.d(TAG, "stopLockTaskMode"); 8757 // Stop lock task 8758 synchronized (this) { 8759 mStackSupervisor.setLockTaskModeLocked(null, false); 8760 } 8761 } finally { 8762 Binder.restoreCallingIdentity(ident); 8763 } 8764 } 8765 8766 @Override 8767 public void stopLockTaskModeOnCurrent() throws RemoteException { 8768 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8769 "stopLockTaskModeOnCurrent"); 8770 long ident = Binder.clearCallingIdentity(); 8771 try { 8772 stopLockTaskMode(); 8773 } finally { 8774 Binder.restoreCallingIdentity(ident); 8775 } 8776 } 8777 8778 @Override 8779 public boolean isInLockTaskMode() { 8780 synchronized (this) { 8781 return mStackSupervisor.isInLockTaskMode(); 8782 } 8783 } 8784 8785 // ========================================================= 8786 // CONTENT PROVIDERS 8787 // ========================================================= 8788 8789 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8790 List<ProviderInfo> providers = null; 8791 try { 8792 providers = AppGlobals.getPackageManager(). 8793 queryContentProviders(app.processName, app.uid, 8794 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8795 } catch (RemoteException ex) { 8796 } 8797 if (DEBUG_MU) 8798 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8799 int userId = app.userId; 8800 if (providers != null) { 8801 int N = providers.size(); 8802 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8803 for (int i=0; i<N; i++) { 8804 ProviderInfo cpi = 8805 (ProviderInfo)providers.get(i); 8806 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8807 cpi.name, cpi.flags); 8808 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8809 // This is a singleton provider, but a user besides the 8810 // default user is asking to initialize a process it runs 8811 // in... well, no, it doesn't actually run in this process, 8812 // it runs in the process of the default user. Get rid of it. 8813 providers.remove(i); 8814 N--; 8815 i--; 8816 continue; 8817 } 8818 8819 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8820 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8821 if (cpr == null) { 8822 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8823 mProviderMap.putProviderByClass(comp, cpr); 8824 } 8825 if (DEBUG_MU) 8826 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8827 app.pubProviders.put(cpi.name, cpr); 8828 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8829 // Don't add this if it is a platform component that is marked 8830 // to run in multiple processes, because this is actually 8831 // part of the framework so doesn't make sense to track as a 8832 // separate apk in the process. 8833 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8834 mProcessStats); 8835 } 8836 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8837 } 8838 } 8839 return providers; 8840 } 8841 8842 /** 8843 * Check if {@link ProcessRecord} has a possible chance at accessing the 8844 * given {@link ProviderInfo}. Final permission checking is always done 8845 * in {@link ContentProvider}. 8846 */ 8847 private final String checkContentProviderPermissionLocked( 8848 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8849 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8850 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8851 boolean checkedGrants = false; 8852 if (checkUser) { 8853 // Looking for cross-user grants before enforcing the typical cross-users permissions 8854 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8855 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8856 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8857 return null; 8858 } 8859 checkedGrants = true; 8860 } 8861 userId = handleIncomingUser(callingPid, callingUid, userId, 8862 false, ALLOW_NON_FULL, 8863 "checkContentProviderPermissionLocked " + cpi.authority, null); 8864 if (userId != tmpTargetUserId) { 8865 // When we actually went to determine the final targer user ID, this ended 8866 // up different than our initial check for the authority. This is because 8867 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8868 // SELF. So we need to re-check the grants again. 8869 checkedGrants = false; 8870 } 8871 } 8872 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8873 cpi.applicationInfo.uid, cpi.exported) 8874 == PackageManager.PERMISSION_GRANTED) { 8875 return null; 8876 } 8877 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8878 cpi.applicationInfo.uid, cpi.exported) 8879 == PackageManager.PERMISSION_GRANTED) { 8880 return null; 8881 } 8882 8883 PathPermission[] pps = cpi.pathPermissions; 8884 if (pps != null) { 8885 int i = pps.length; 8886 while (i > 0) { 8887 i--; 8888 PathPermission pp = pps[i]; 8889 String pprperm = pp.getReadPermission(); 8890 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8891 cpi.applicationInfo.uid, cpi.exported) 8892 == PackageManager.PERMISSION_GRANTED) { 8893 return null; 8894 } 8895 String ppwperm = pp.getWritePermission(); 8896 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8897 cpi.applicationInfo.uid, cpi.exported) 8898 == PackageManager.PERMISSION_GRANTED) { 8899 return null; 8900 } 8901 } 8902 } 8903 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8904 return null; 8905 } 8906 8907 String msg; 8908 if (!cpi.exported) { 8909 msg = "Permission Denial: opening provider " + cpi.name 8910 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8911 + ", uid=" + callingUid + ") that is not exported from uid " 8912 + cpi.applicationInfo.uid; 8913 } else { 8914 msg = "Permission Denial: opening provider " + cpi.name 8915 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8916 + ", uid=" + callingUid + ") requires " 8917 + cpi.readPermission + " or " + cpi.writePermission; 8918 } 8919 Slog.w(TAG, msg); 8920 return msg; 8921 } 8922 8923 /** 8924 * Returns if the ContentProvider has granted a uri to callingUid 8925 */ 8926 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8927 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8928 if (perms != null) { 8929 for (int i=perms.size()-1; i>=0; i--) { 8930 GrantUri grantUri = perms.keyAt(i); 8931 if (grantUri.sourceUserId == userId || !checkUser) { 8932 if (matchesProvider(grantUri.uri, cpi)) { 8933 return true; 8934 } 8935 } 8936 } 8937 } 8938 return false; 8939 } 8940 8941 /** 8942 * Returns true if the uri authority is one of the authorities specified in the provider. 8943 */ 8944 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8945 String uriAuth = uri.getAuthority(); 8946 String cpiAuth = cpi.authority; 8947 if (cpiAuth.indexOf(';') == -1) { 8948 return cpiAuth.equals(uriAuth); 8949 } 8950 String[] cpiAuths = cpiAuth.split(";"); 8951 int length = cpiAuths.length; 8952 for (int i = 0; i < length; i++) { 8953 if (cpiAuths[i].equals(uriAuth)) return true; 8954 } 8955 return false; 8956 } 8957 8958 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8959 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8960 if (r != null) { 8961 for (int i=0; i<r.conProviders.size(); i++) { 8962 ContentProviderConnection conn = r.conProviders.get(i); 8963 if (conn.provider == cpr) { 8964 if (DEBUG_PROVIDER) Slog.v(TAG, 8965 "Adding provider requested by " 8966 + r.processName + " from process " 8967 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8968 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8969 if (stable) { 8970 conn.stableCount++; 8971 conn.numStableIncs++; 8972 } else { 8973 conn.unstableCount++; 8974 conn.numUnstableIncs++; 8975 } 8976 return conn; 8977 } 8978 } 8979 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8980 if (stable) { 8981 conn.stableCount = 1; 8982 conn.numStableIncs = 1; 8983 } else { 8984 conn.unstableCount = 1; 8985 conn.numUnstableIncs = 1; 8986 } 8987 cpr.connections.add(conn); 8988 r.conProviders.add(conn); 8989 return conn; 8990 } 8991 cpr.addExternalProcessHandleLocked(externalProcessToken); 8992 return null; 8993 } 8994 8995 boolean decProviderCountLocked(ContentProviderConnection conn, 8996 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8997 if (conn != null) { 8998 cpr = conn.provider; 8999 if (DEBUG_PROVIDER) Slog.v(TAG, 9000 "Removing provider requested by " 9001 + conn.client.processName + " from process " 9002 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9003 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9004 if (stable) { 9005 conn.stableCount--; 9006 } else { 9007 conn.unstableCount--; 9008 } 9009 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9010 cpr.connections.remove(conn); 9011 conn.client.conProviders.remove(conn); 9012 return true; 9013 } 9014 return false; 9015 } 9016 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9017 return false; 9018 } 9019 9020 private void checkTime(long startTime, String where) { 9021 long now = SystemClock.elapsedRealtime(); 9022 if ((now-startTime) > 1000) { 9023 // If we are taking more than a second, log about it. 9024 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9025 } 9026 } 9027 9028 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9029 String name, IBinder token, boolean stable, int userId) { 9030 ContentProviderRecord cpr; 9031 ContentProviderConnection conn = null; 9032 ProviderInfo cpi = null; 9033 9034 synchronized(this) { 9035 long startTime = SystemClock.elapsedRealtime(); 9036 9037 ProcessRecord r = null; 9038 if (caller != null) { 9039 r = getRecordForAppLocked(caller); 9040 if (r == null) { 9041 throw new SecurityException( 9042 "Unable to find app for caller " + caller 9043 + " (pid=" + Binder.getCallingPid() 9044 + ") when getting content provider " + name); 9045 } 9046 } 9047 9048 boolean checkCrossUser = true; 9049 9050 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9051 9052 // First check if this content provider has been published... 9053 cpr = mProviderMap.getProviderByName(name, userId); 9054 // If that didn't work, check if it exists for user 0 and then 9055 // verify that it's a singleton provider before using it. 9056 if (cpr == null && userId != UserHandle.USER_OWNER) { 9057 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9058 if (cpr != null) { 9059 cpi = cpr.info; 9060 if (isSingleton(cpi.processName, cpi.applicationInfo, 9061 cpi.name, cpi.flags) 9062 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9063 userId = UserHandle.USER_OWNER; 9064 checkCrossUser = false; 9065 } else { 9066 cpr = null; 9067 cpi = null; 9068 } 9069 } 9070 } 9071 9072 boolean providerRunning = cpr != null; 9073 if (providerRunning) { 9074 cpi = cpr.info; 9075 String msg; 9076 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9077 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9078 != null) { 9079 throw new SecurityException(msg); 9080 } 9081 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9082 9083 if (r != null && cpr.canRunHere(r)) { 9084 // This provider has been published or is in the process 9085 // of being published... but it is also allowed to run 9086 // in the caller's process, so don't make a connection 9087 // and just let the caller instantiate its own instance. 9088 ContentProviderHolder holder = cpr.newHolder(null); 9089 // don't give caller the provider object, it needs 9090 // to make its own. 9091 holder.provider = null; 9092 return holder; 9093 } 9094 9095 final long origId = Binder.clearCallingIdentity(); 9096 9097 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9098 9099 // In this case the provider instance already exists, so we can 9100 // return it right away. 9101 conn = incProviderCountLocked(r, cpr, token, stable); 9102 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9103 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9104 // If this is a perceptible app accessing the provider, 9105 // make sure to count it as being accessed and thus 9106 // back up on the LRU list. This is good because 9107 // content providers are often expensive to start. 9108 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9109 updateLruProcessLocked(cpr.proc, false, null); 9110 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9111 } 9112 } 9113 9114 if (cpr.proc != null) { 9115 if (false) { 9116 if (cpr.name.flattenToShortString().equals( 9117 "com.android.providers.calendar/.CalendarProvider2")) { 9118 Slog.v(TAG, "****************** KILLING " 9119 + cpr.name.flattenToShortString()); 9120 Process.killProcess(cpr.proc.pid); 9121 } 9122 } 9123 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9124 boolean success = updateOomAdjLocked(cpr.proc); 9125 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9126 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9127 // NOTE: there is still a race here where a signal could be 9128 // pending on the process even though we managed to update its 9129 // adj level. Not sure what to do about this, but at least 9130 // the race is now smaller. 9131 if (!success) { 9132 // Uh oh... it looks like the provider's process 9133 // has been killed on us. We need to wait for a new 9134 // process to be started, and make sure its death 9135 // doesn't kill our process. 9136 Slog.i(TAG, 9137 "Existing provider " + cpr.name.flattenToShortString() 9138 + " is crashing; detaching " + r); 9139 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9140 checkTime(startTime, "getContentProviderImpl: before appDied"); 9141 appDiedLocked(cpr.proc); 9142 checkTime(startTime, "getContentProviderImpl: after appDied"); 9143 if (!lastRef) { 9144 // This wasn't the last ref our process had on 9145 // the provider... we have now been killed, bail. 9146 return null; 9147 } 9148 providerRunning = false; 9149 conn = null; 9150 } 9151 } 9152 9153 Binder.restoreCallingIdentity(origId); 9154 } 9155 9156 boolean singleton; 9157 if (!providerRunning) { 9158 try { 9159 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9160 cpi = AppGlobals.getPackageManager(). 9161 resolveContentProvider(name, 9162 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9163 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9164 } catch (RemoteException ex) { 9165 } 9166 if (cpi == null) { 9167 return null; 9168 } 9169 // If the provider is a singleton AND 9170 // (it's a call within the same user || the provider is a 9171 // privileged app) 9172 // Then allow connecting to the singleton provider 9173 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9174 cpi.name, cpi.flags) 9175 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9176 if (singleton) { 9177 userId = UserHandle.USER_OWNER; 9178 } 9179 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9180 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9181 9182 String msg; 9183 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9184 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9185 != null) { 9186 throw new SecurityException(msg); 9187 } 9188 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9189 9190 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9191 && !cpi.processName.equals("system")) { 9192 // If this content provider does not run in the system 9193 // process, and the system is not yet ready to run other 9194 // processes, then fail fast instead of hanging. 9195 throw new IllegalArgumentException( 9196 "Attempt to launch content provider before system ready"); 9197 } 9198 9199 // Make sure that the user who owns this provider is started. If not, 9200 // we don't want to allow it to run. 9201 if (mStartedUsers.get(userId) == null) { 9202 Slog.w(TAG, "Unable to launch app " 9203 + cpi.applicationInfo.packageName + "/" 9204 + cpi.applicationInfo.uid + " for provider " 9205 + name + ": user " + userId + " is stopped"); 9206 return null; 9207 } 9208 9209 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9210 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9211 cpr = mProviderMap.getProviderByClass(comp, userId); 9212 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9213 final boolean firstClass = cpr == null; 9214 if (firstClass) { 9215 final long ident = Binder.clearCallingIdentity(); 9216 try { 9217 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9218 ApplicationInfo ai = 9219 AppGlobals.getPackageManager(). 9220 getApplicationInfo( 9221 cpi.applicationInfo.packageName, 9222 STOCK_PM_FLAGS, userId); 9223 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9224 if (ai == null) { 9225 Slog.w(TAG, "No package info for content provider " 9226 + cpi.name); 9227 return null; 9228 } 9229 ai = getAppInfoForUser(ai, userId); 9230 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9231 } catch (RemoteException ex) { 9232 // pm is in same process, this will never happen. 9233 } finally { 9234 Binder.restoreCallingIdentity(ident); 9235 } 9236 } 9237 9238 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9239 9240 if (r != null && cpr.canRunHere(r)) { 9241 // If this is a multiprocess provider, then just return its 9242 // info and allow the caller to instantiate it. Only do 9243 // this if the provider is the same user as the caller's 9244 // process, or can run as root (so can be in any process). 9245 return cpr.newHolder(null); 9246 } 9247 9248 if (DEBUG_PROVIDER) { 9249 RuntimeException e = new RuntimeException("here"); 9250 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9251 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9252 } 9253 9254 // This is single process, and our app is now connecting to it. 9255 // See if we are already in the process of launching this 9256 // provider. 9257 final int N = mLaunchingProviders.size(); 9258 int i; 9259 for (i=0; i<N; i++) { 9260 if (mLaunchingProviders.get(i) == cpr) { 9261 break; 9262 } 9263 } 9264 9265 // If the provider is not already being launched, then get it 9266 // started. 9267 if (i >= N) { 9268 final long origId = Binder.clearCallingIdentity(); 9269 9270 try { 9271 // Content provider is now in use, its package can't be stopped. 9272 try { 9273 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9274 AppGlobals.getPackageManager().setPackageStoppedState( 9275 cpr.appInfo.packageName, false, userId); 9276 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9277 } catch (RemoteException e) { 9278 } catch (IllegalArgumentException e) { 9279 Slog.w(TAG, "Failed trying to unstop package " 9280 + cpr.appInfo.packageName + ": " + e); 9281 } 9282 9283 // Use existing process if already started 9284 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9285 ProcessRecord proc = getProcessRecordLocked( 9286 cpi.processName, cpr.appInfo.uid, false); 9287 if (proc != null && proc.thread != null) { 9288 if (DEBUG_PROVIDER) { 9289 Slog.d(TAG, "Installing in existing process " + proc); 9290 } 9291 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9292 proc.pubProviders.put(cpi.name, cpr); 9293 try { 9294 proc.thread.scheduleInstallProvider(cpi); 9295 } catch (RemoteException e) { 9296 } 9297 } else { 9298 checkTime(startTime, "getContentProviderImpl: before start process"); 9299 proc = startProcessLocked(cpi.processName, 9300 cpr.appInfo, false, 0, "content provider", 9301 new ComponentName(cpi.applicationInfo.packageName, 9302 cpi.name), false, false, false); 9303 checkTime(startTime, "getContentProviderImpl: after start process"); 9304 if (proc == null) { 9305 Slog.w(TAG, "Unable to launch app " 9306 + cpi.applicationInfo.packageName + "/" 9307 + cpi.applicationInfo.uid + " for provider " 9308 + name + ": process is bad"); 9309 return null; 9310 } 9311 } 9312 cpr.launchingApp = proc; 9313 mLaunchingProviders.add(cpr); 9314 } finally { 9315 Binder.restoreCallingIdentity(origId); 9316 } 9317 } 9318 9319 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9320 9321 // Make sure the provider is published (the same provider class 9322 // may be published under multiple names). 9323 if (firstClass) { 9324 mProviderMap.putProviderByClass(comp, cpr); 9325 } 9326 9327 mProviderMap.putProviderByName(name, cpr); 9328 conn = incProviderCountLocked(r, cpr, token, stable); 9329 if (conn != null) { 9330 conn.waiting = true; 9331 } 9332 } 9333 checkTime(startTime, "getContentProviderImpl: done!"); 9334 } 9335 9336 // Wait for the provider to be published... 9337 synchronized (cpr) { 9338 while (cpr.provider == null) { 9339 if (cpr.launchingApp == null) { 9340 Slog.w(TAG, "Unable to launch app " 9341 + cpi.applicationInfo.packageName + "/" 9342 + cpi.applicationInfo.uid + " for provider " 9343 + name + ": launching app became null"); 9344 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9345 UserHandle.getUserId(cpi.applicationInfo.uid), 9346 cpi.applicationInfo.packageName, 9347 cpi.applicationInfo.uid, name); 9348 return null; 9349 } 9350 try { 9351 if (DEBUG_MU) { 9352 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9353 + cpr.launchingApp); 9354 } 9355 if (conn != null) { 9356 conn.waiting = true; 9357 } 9358 cpr.wait(); 9359 } catch (InterruptedException ex) { 9360 } finally { 9361 if (conn != null) { 9362 conn.waiting = false; 9363 } 9364 } 9365 } 9366 } 9367 return cpr != null ? cpr.newHolder(conn) : null; 9368 } 9369 9370 @Override 9371 public final ContentProviderHolder getContentProvider( 9372 IApplicationThread caller, String name, int userId, boolean stable) { 9373 enforceNotIsolatedCaller("getContentProvider"); 9374 if (caller == null) { 9375 String msg = "null IApplicationThread when getting content provider " 9376 + name; 9377 Slog.w(TAG, msg); 9378 throw new SecurityException(msg); 9379 } 9380 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9381 // with cross-user grant. 9382 return getContentProviderImpl(caller, name, null, stable, userId); 9383 } 9384 9385 public ContentProviderHolder getContentProviderExternal( 9386 String name, int userId, IBinder token) { 9387 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9388 "Do not have permission in call getContentProviderExternal()"); 9389 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9390 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9391 return getContentProviderExternalUnchecked(name, token, userId); 9392 } 9393 9394 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9395 IBinder token, int userId) { 9396 return getContentProviderImpl(null, name, token, true, userId); 9397 } 9398 9399 /** 9400 * Drop a content provider from a ProcessRecord's bookkeeping 9401 */ 9402 public void removeContentProvider(IBinder connection, boolean stable) { 9403 enforceNotIsolatedCaller("removeContentProvider"); 9404 long ident = Binder.clearCallingIdentity(); 9405 try { 9406 synchronized (this) { 9407 ContentProviderConnection conn; 9408 try { 9409 conn = (ContentProviderConnection)connection; 9410 } catch (ClassCastException e) { 9411 String msg ="removeContentProvider: " + connection 9412 + " not a ContentProviderConnection"; 9413 Slog.w(TAG, msg); 9414 throw new IllegalArgumentException(msg); 9415 } 9416 if (conn == null) { 9417 throw new NullPointerException("connection is null"); 9418 } 9419 if (decProviderCountLocked(conn, null, null, stable)) { 9420 updateOomAdjLocked(); 9421 } 9422 } 9423 } finally { 9424 Binder.restoreCallingIdentity(ident); 9425 } 9426 } 9427 9428 public void removeContentProviderExternal(String name, IBinder token) { 9429 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9430 "Do not have permission in call removeContentProviderExternal()"); 9431 int userId = UserHandle.getCallingUserId(); 9432 long ident = Binder.clearCallingIdentity(); 9433 try { 9434 removeContentProviderExternalUnchecked(name, token, userId); 9435 } finally { 9436 Binder.restoreCallingIdentity(ident); 9437 } 9438 } 9439 9440 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9441 synchronized (this) { 9442 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9443 if(cpr == null) { 9444 //remove from mProvidersByClass 9445 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9446 return; 9447 } 9448 9449 //update content provider record entry info 9450 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9451 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9452 if (localCpr.hasExternalProcessHandles()) { 9453 if (localCpr.removeExternalProcessHandleLocked(token)) { 9454 updateOomAdjLocked(); 9455 } else { 9456 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9457 + " with no external reference for token: " 9458 + token + "."); 9459 } 9460 } else { 9461 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9462 + " with no external references."); 9463 } 9464 } 9465 } 9466 9467 public final void publishContentProviders(IApplicationThread caller, 9468 List<ContentProviderHolder> providers) { 9469 if (providers == null) { 9470 return; 9471 } 9472 9473 enforceNotIsolatedCaller("publishContentProviders"); 9474 synchronized (this) { 9475 final ProcessRecord r = getRecordForAppLocked(caller); 9476 if (DEBUG_MU) 9477 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9478 if (r == null) { 9479 throw new SecurityException( 9480 "Unable to find app for caller " + caller 9481 + " (pid=" + Binder.getCallingPid() 9482 + ") when publishing content providers"); 9483 } 9484 9485 final long origId = Binder.clearCallingIdentity(); 9486 9487 final int N = providers.size(); 9488 for (int i=0; i<N; i++) { 9489 ContentProviderHolder src = providers.get(i); 9490 if (src == null || src.info == null || src.provider == null) { 9491 continue; 9492 } 9493 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9494 if (DEBUG_MU) 9495 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9496 if (dst != null) { 9497 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9498 mProviderMap.putProviderByClass(comp, dst); 9499 String names[] = dst.info.authority.split(";"); 9500 for (int j = 0; j < names.length; j++) { 9501 mProviderMap.putProviderByName(names[j], dst); 9502 } 9503 9504 int NL = mLaunchingProviders.size(); 9505 int j; 9506 for (j=0; j<NL; j++) { 9507 if (mLaunchingProviders.get(j) == dst) { 9508 mLaunchingProviders.remove(j); 9509 j--; 9510 NL--; 9511 } 9512 } 9513 synchronized (dst) { 9514 dst.provider = src.provider; 9515 dst.proc = r; 9516 dst.notifyAll(); 9517 } 9518 updateOomAdjLocked(r); 9519 } 9520 } 9521 9522 Binder.restoreCallingIdentity(origId); 9523 } 9524 } 9525 9526 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9527 ContentProviderConnection conn; 9528 try { 9529 conn = (ContentProviderConnection)connection; 9530 } catch (ClassCastException e) { 9531 String msg ="refContentProvider: " + connection 9532 + " not a ContentProviderConnection"; 9533 Slog.w(TAG, msg); 9534 throw new IllegalArgumentException(msg); 9535 } 9536 if (conn == null) { 9537 throw new NullPointerException("connection is null"); 9538 } 9539 9540 synchronized (this) { 9541 if (stable > 0) { 9542 conn.numStableIncs += stable; 9543 } 9544 stable = conn.stableCount + stable; 9545 if (stable < 0) { 9546 throw new IllegalStateException("stableCount < 0: " + stable); 9547 } 9548 9549 if (unstable > 0) { 9550 conn.numUnstableIncs += unstable; 9551 } 9552 unstable = conn.unstableCount + unstable; 9553 if (unstable < 0) { 9554 throw new IllegalStateException("unstableCount < 0: " + unstable); 9555 } 9556 9557 if ((stable+unstable) <= 0) { 9558 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9559 + stable + " unstable=" + unstable); 9560 } 9561 conn.stableCount = stable; 9562 conn.unstableCount = unstable; 9563 return !conn.dead; 9564 } 9565 } 9566 9567 public void unstableProviderDied(IBinder connection) { 9568 ContentProviderConnection conn; 9569 try { 9570 conn = (ContentProviderConnection)connection; 9571 } catch (ClassCastException e) { 9572 String msg ="refContentProvider: " + connection 9573 + " not a ContentProviderConnection"; 9574 Slog.w(TAG, msg); 9575 throw new IllegalArgumentException(msg); 9576 } 9577 if (conn == null) { 9578 throw new NullPointerException("connection is null"); 9579 } 9580 9581 // Safely retrieve the content provider associated with the connection. 9582 IContentProvider provider; 9583 synchronized (this) { 9584 provider = conn.provider.provider; 9585 } 9586 9587 if (provider == null) { 9588 // Um, yeah, we're way ahead of you. 9589 return; 9590 } 9591 9592 // Make sure the caller is being honest with us. 9593 if (provider.asBinder().pingBinder()) { 9594 // Er, no, still looks good to us. 9595 synchronized (this) { 9596 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9597 + " says " + conn + " died, but we don't agree"); 9598 return; 9599 } 9600 } 9601 9602 // Well look at that! It's dead! 9603 synchronized (this) { 9604 if (conn.provider.provider != provider) { 9605 // But something changed... good enough. 9606 return; 9607 } 9608 9609 ProcessRecord proc = conn.provider.proc; 9610 if (proc == null || proc.thread == null) { 9611 // Seems like the process is already cleaned up. 9612 return; 9613 } 9614 9615 // As far as we're concerned, this is just like receiving a 9616 // death notification... just a bit prematurely. 9617 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9618 + ") early provider death"); 9619 final long ident = Binder.clearCallingIdentity(); 9620 try { 9621 appDiedLocked(proc); 9622 } finally { 9623 Binder.restoreCallingIdentity(ident); 9624 } 9625 } 9626 } 9627 9628 @Override 9629 public void appNotRespondingViaProvider(IBinder connection) { 9630 enforceCallingPermission( 9631 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9632 9633 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9634 if (conn == null) { 9635 Slog.w(TAG, "ContentProviderConnection is null"); 9636 return; 9637 } 9638 9639 final ProcessRecord host = conn.provider.proc; 9640 if (host == null) { 9641 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9642 return; 9643 } 9644 9645 final long token = Binder.clearCallingIdentity(); 9646 try { 9647 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9648 } finally { 9649 Binder.restoreCallingIdentity(token); 9650 } 9651 } 9652 9653 public final void installSystemProviders() { 9654 List<ProviderInfo> providers; 9655 synchronized (this) { 9656 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9657 providers = generateApplicationProvidersLocked(app); 9658 if (providers != null) { 9659 for (int i=providers.size()-1; i>=0; i--) { 9660 ProviderInfo pi = (ProviderInfo)providers.get(i); 9661 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9662 Slog.w(TAG, "Not installing system proc provider " + pi.name 9663 + ": not system .apk"); 9664 providers.remove(i); 9665 } 9666 } 9667 } 9668 } 9669 if (providers != null) { 9670 mSystemThread.installSystemProviders(providers); 9671 } 9672 9673 mCoreSettingsObserver = new CoreSettingsObserver(this); 9674 9675 //mUsageStatsService.monitorPackages(); 9676 } 9677 9678 /** 9679 * Allows apps to retrieve the MIME type of a URI. 9680 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9681 * users, then it does not need permission to access the ContentProvider. 9682 * Either, it needs cross-user uri grants. 9683 * 9684 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9685 * 9686 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9687 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9688 */ 9689 public String getProviderMimeType(Uri uri, int userId) { 9690 enforceNotIsolatedCaller("getProviderMimeType"); 9691 final String name = uri.getAuthority(); 9692 int callingUid = Binder.getCallingUid(); 9693 int callingPid = Binder.getCallingPid(); 9694 long ident = 0; 9695 boolean clearedIdentity = false; 9696 userId = unsafeConvertIncomingUser(userId); 9697 if (canClearIdentity(callingPid, callingUid, userId)) { 9698 clearedIdentity = true; 9699 ident = Binder.clearCallingIdentity(); 9700 } 9701 ContentProviderHolder holder = null; 9702 try { 9703 holder = getContentProviderExternalUnchecked(name, null, userId); 9704 if (holder != null) { 9705 return holder.provider.getType(uri); 9706 } 9707 } catch (RemoteException e) { 9708 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9709 return null; 9710 } finally { 9711 // We need to clear the identity to call removeContentProviderExternalUnchecked 9712 if (!clearedIdentity) { 9713 ident = Binder.clearCallingIdentity(); 9714 } 9715 try { 9716 if (holder != null) { 9717 removeContentProviderExternalUnchecked(name, null, userId); 9718 } 9719 } finally { 9720 Binder.restoreCallingIdentity(ident); 9721 } 9722 } 9723 9724 return null; 9725 } 9726 9727 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9728 if (UserHandle.getUserId(callingUid) == userId) { 9729 return true; 9730 } 9731 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9732 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9733 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9734 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9735 return true; 9736 } 9737 return false; 9738 } 9739 9740 // ========================================================= 9741 // GLOBAL MANAGEMENT 9742 // ========================================================= 9743 9744 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9745 boolean isolated, int isolatedUid) { 9746 String proc = customProcess != null ? customProcess : info.processName; 9747 BatteryStatsImpl.Uid.Proc ps = null; 9748 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9749 int uid = info.uid; 9750 if (isolated) { 9751 if (isolatedUid == 0) { 9752 int userId = UserHandle.getUserId(uid); 9753 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9754 while (true) { 9755 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9756 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9757 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9758 } 9759 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9760 mNextIsolatedProcessUid++; 9761 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9762 // No process for this uid, use it. 9763 break; 9764 } 9765 stepsLeft--; 9766 if (stepsLeft <= 0) { 9767 return null; 9768 } 9769 } 9770 } else { 9771 // Special case for startIsolatedProcess (internal only), where 9772 // the uid of the isolated process is specified by the caller. 9773 uid = isolatedUid; 9774 } 9775 } 9776 return new ProcessRecord(stats, info, proc, uid); 9777 } 9778 9779 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9780 String abiOverride) { 9781 ProcessRecord app; 9782 if (!isolated) { 9783 app = getProcessRecordLocked(info.processName, info.uid, true); 9784 } else { 9785 app = null; 9786 } 9787 9788 if (app == null) { 9789 app = newProcessRecordLocked(info, null, isolated, 0); 9790 mProcessNames.put(info.processName, app.uid, app); 9791 if (isolated) { 9792 mIsolatedProcesses.put(app.uid, app); 9793 } 9794 updateLruProcessLocked(app, false, null); 9795 updateOomAdjLocked(); 9796 } 9797 9798 // This package really, really can not be stopped. 9799 try { 9800 AppGlobals.getPackageManager().setPackageStoppedState( 9801 info.packageName, false, UserHandle.getUserId(app.uid)); 9802 } catch (RemoteException e) { 9803 } catch (IllegalArgumentException e) { 9804 Slog.w(TAG, "Failed trying to unstop package " 9805 + info.packageName + ": " + e); 9806 } 9807 9808 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9809 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9810 app.persistent = true; 9811 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9812 } 9813 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9814 mPersistentStartingProcesses.add(app); 9815 startProcessLocked(app, "added application", app.processName, abiOverride, 9816 null /* entryPoint */, null /* entryPointArgs */); 9817 } 9818 9819 return app; 9820 } 9821 9822 public void unhandledBack() { 9823 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9824 "unhandledBack()"); 9825 9826 synchronized(this) { 9827 final long origId = Binder.clearCallingIdentity(); 9828 try { 9829 getFocusedStack().unhandledBackLocked(); 9830 } finally { 9831 Binder.restoreCallingIdentity(origId); 9832 } 9833 } 9834 } 9835 9836 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9837 enforceNotIsolatedCaller("openContentUri"); 9838 final int userId = UserHandle.getCallingUserId(); 9839 String name = uri.getAuthority(); 9840 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9841 ParcelFileDescriptor pfd = null; 9842 if (cph != null) { 9843 // We record the binder invoker's uid in thread-local storage before 9844 // going to the content provider to open the file. Later, in the code 9845 // that handles all permissions checks, we look for this uid and use 9846 // that rather than the Activity Manager's own uid. The effect is that 9847 // we do the check against the caller's permissions even though it looks 9848 // to the content provider like the Activity Manager itself is making 9849 // the request. 9850 sCallerIdentity.set(new Identity( 9851 Binder.getCallingPid(), Binder.getCallingUid())); 9852 try { 9853 pfd = cph.provider.openFile(null, uri, "r", null); 9854 } catch (FileNotFoundException e) { 9855 // do nothing; pfd will be returned null 9856 } finally { 9857 // Ensure that whatever happens, we clean up the identity state 9858 sCallerIdentity.remove(); 9859 } 9860 9861 // We've got the fd now, so we're done with the provider. 9862 removeContentProviderExternalUnchecked(name, null, userId); 9863 } else { 9864 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9865 } 9866 return pfd; 9867 } 9868 9869 // Actually is sleeping or shutting down or whatever else in the future 9870 // is an inactive state. 9871 public boolean isSleepingOrShuttingDown() { 9872 return isSleeping() || mShuttingDown; 9873 } 9874 9875 public boolean isSleeping() { 9876 return mSleeping; 9877 } 9878 9879 void goingToSleep() { 9880 synchronized(this) { 9881 mWentToSleep = true; 9882 goToSleepIfNeededLocked(); 9883 } 9884 } 9885 9886 void finishRunningVoiceLocked() { 9887 if (mRunningVoice) { 9888 mRunningVoice = false; 9889 goToSleepIfNeededLocked(); 9890 } 9891 } 9892 9893 void goToSleepIfNeededLocked() { 9894 if (mWentToSleep && !mRunningVoice) { 9895 if (!mSleeping) { 9896 mSleeping = true; 9897 mStackSupervisor.goingToSleepLocked(); 9898 9899 // Initialize the wake times of all processes. 9900 checkExcessivePowerUsageLocked(false); 9901 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9902 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9903 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9904 } 9905 } 9906 } 9907 9908 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9909 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9910 // Never persist the home stack. 9911 return; 9912 } 9913 mTaskPersister.wakeup(task, flush); 9914 } 9915 9916 @Override 9917 public boolean shutdown(int timeout) { 9918 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9919 != PackageManager.PERMISSION_GRANTED) { 9920 throw new SecurityException("Requires permission " 9921 + android.Manifest.permission.SHUTDOWN); 9922 } 9923 9924 boolean timedout = false; 9925 9926 synchronized(this) { 9927 mShuttingDown = true; 9928 updateEventDispatchingLocked(); 9929 timedout = mStackSupervisor.shutdownLocked(timeout); 9930 } 9931 9932 mAppOpsService.shutdown(); 9933 if (mUsageStatsService != null) { 9934 mUsageStatsService.prepareShutdown(); 9935 } 9936 mBatteryStatsService.shutdown(); 9937 synchronized (this) { 9938 mProcessStats.shutdownLocked(); 9939 } 9940 notifyTaskPersisterLocked(null, true); 9941 9942 return timedout; 9943 } 9944 9945 public final void activitySlept(IBinder token) { 9946 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9947 9948 final long origId = Binder.clearCallingIdentity(); 9949 9950 synchronized (this) { 9951 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9952 if (r != null) { 9953 mStackSupervisor.activitySleptLocked(r); 9954 } 9955 } 9956 9957 Binder.restoreCallingIdentity(origId); 9958 } 9959 9960 void logLockScreen(String msg) { 9961 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9962 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9963 mWentToSleep + " mSleeping=" + mSleeping); 9964 } 9965 9966 private void comeOutOfSleepIfNeededLocked() { 9967 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9968 if (mSleeping) { 9969 mSleeping = false; 9970 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9971 } 9972 } 9973 } 9974 9975 void wakingUp() { 9976 synchronized(this) { 9977 mWentToSleep = false; 9978 comeOutOfSleepIfNeededLocked(); 9979 } 9980 } 9981 9982 void startRunningVoiceLocked() { 9983 if (!mRunningVoice) { 9984 mRunningVoice = true; 9985 comeOutOfSleepIfNeededLocked(); 9986 } 9987 } 9988 9989 private void updateEventDispatchingLocked() { 9990 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 9991 } 9992 9993 public void setLockScreenShown(boolean shown) { 9994 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9995 != PackageManager.PERMISSION_GRANTED) { 9996 throw new SecurityException("Requires permission " 9997 + android.Manifest.permission.DEVICE_POWER); 9998 } 9999 10000 synchronized(this) { 10001 long ident = Binder.clearCallingIdentity(); 10002 try { 10003 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10004 mLockScreenShown = shown; 10005 comeOutOfSleepIfNeededLocked(); 10006 } finally { 10007 Binder.restoreCallingIdentity(ident); 10008 } 10009 } 10010 } 10011 10012 @Override 10013 public void stopAppSwitches() { 10014 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10015 != PackageManager.PERMISSION_GRANTED) { 10016 throw new SecurityException("Requires permission " 10017 + android.Manifest.permission.STOP_APP_SWITCHES); 10018 } 10019 10020 synchronized(this) { 10021 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10022 + APP_SWITCH_DELAY_TIME; 10023 mDidAppSwitch = false; 10024 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10025 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10026 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10027 } 10028 } 10029 10030 public void resumeAppSwitches() { 10031 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10032 != PackageManager.PERMISSION_GRANTED) { 10033 throw new SecurityException("Requires permission " 10034 + android.Manifest.permission.STOP_APP_SWITCHES); 10035 } 10036 10037 synchronized(this) { 10038 // Note that we don't execute any pending app switches... we will 10039 // let those wait until either the timeout, or the next start 10040 // activity request. 10041 mAppSwitchesAllowedTime = 0; 10042 } 10043 } 10044 10045 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10046 int callingPid, int callingUid, String name) { 10047 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10048 return true; 10049 } 10050 10051 int perm = checkComponentPermission( 10052 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10053 sourceUid, -1, true); 10054 if (perm == PackageManager.PERMISSION_GRANTED) { 10055 return true; 10056 } 10057 10058 // If the actual IPC caller is different from the logical source, then 10059 // also see if they are allowed to control app switches. 10060 if (callingUid != -1 && callingUid != sourceUid) { 10061 perm = checkComponentPermission( 10062 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10063 callingUid, -1, true); 10064 if (perm == PackageManager.PERMISSION_GRANTED) { 10065 return true; 10066 } 10067 } 10068 10069 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10070 return false; 10071 } 10072 10073 public void setDebugApp(String packageName, boolean waitForDebugger, 10074 boolean persistent) { 10075 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10076 "setDebugApp()"); 10077 10078 long ident = Binder.clearCallingIdentity(); 10079 try { 10080 // Note that this is not really thread safe if there are multiple 10081 // callers into it at the same time, but that's not a situation we 10082 // care about. 10083 if (persistent) { 10084 final ContentResolver resolver = mContext.getContentResolver(); 10085 Settings.Global.putString( 10086 resolver, Settings.Global.DEBUG_APP, 10087 packageName); 10088 Settings.Global.putInt( 10089 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10090 waitForDebugger ? 1 : 0); 10091 } 10092 10093 synchronized (this) { 10094 if (!persistent) { 10095 mOrigDebugApp = mDebugApp; 10096 mOrigWaitForDebugger = mWaitForDebugger; 10097 } 10098 mDebugApp = packageName; 10099 mWaitForDebugger = waitForDebugger; 10100 mDebugTransient = !persistent; 10101 if (packageName != null) { 10102 forceStopPackageLocked(packageName, -1, false, false, true, true, 10103 false, UserHandle.USER_ALL, "set debug app"); 10104 } 10105 } 10106 } finally { 10107 Binder.restoreCallingIdentity(ident); 10108 } 10109 } 10110 10111 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10112 synchronized (this) { 10113 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10114 if (!isDebuggable) { 10115 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10116 throw new SecurityException("Process not debuggable: " + app.packageName); 10117 } 10118 } 10119 10120 mOpenGlTraceApp = processName; 10121 } 10122 } 10123 10124 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10125 synchronized (this) { 10126 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10127 if (!isDebuggable) { 10128 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10129 throw new SecurityException("Process not debuggable: " + app.packageName); 10130 } 10131 } 10132 mProfileApp = processName; 10133 mProfileFile = profilerInfo.profileFile; 10134 if (mProfileFd != null) { 10135 try { 10136 mProfileFd.close(); 10137 } catch (IOException e) { 10138 } 10139 mProfileFd = null; 10140 } 10141 mProfileFd = profilerInfo.profileFd; 10142 mSamplingInterval = profilerInfo.samplingInterval; 10143 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10144 mProfileType = 0; 10145 } 10146 } 10147 10148 @Override 10149 public void setAlwaysFinish(boolean enabled) { 10150 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10151 "setAlwaysFinish()"); 10152 10153 Settings.Global.putInt( 10154 mContext.getContentResolver(), 10155 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10156 10157 synchronized (this) { 10158 mAlwaysFinishActivities = enabled; 10159 } 10160 } 10161 10162 @Override 10163 public void setActivityController(IActivityController controller) { 10164 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10165 "setActivityController()"); 10166 synchronized (this) { 10167 mController = controller; 10168 Watchdog.getInstance().setActivityController(controller); 10169 } 10170 } 10171 10172 @Override 10173 public void setUserIsMonkey(boolean userIsMonkey) { 10174 synchronized (this) { 10175 synchronized (mPidsSelfLocked) { 10176 final int callingPid = Binder.getCallingPid(); 10177 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10178 if (precessRecord == null) { 10179 throw new SecurityException("Unknown process: " + callingPid); 10180 } 10181 if (precessRecord.instrumentationUiAutomationConnection == null) { 10182 throw new SecurityException("Only an instrumentation process " 10183 + "with a UiAutomation can call setUserIsMonkey"); 10184 } 10185 } 10186 mUserIsMonkey = userIsMonkey; 10187 } 10188 } 10189 10190 @Override 10191 public boolean isUserAMonkey() { 10192 synchronized (this) { 10193 // If there is a controller also implies the user is a monkey. 10194 return (mUserIsMonkey || mController != null); 10195 } 10196 } 10197 10198 public void requestBugReport() { 10199 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10200 SystemProperties.set("ctl.start", "bugreport"); 10201 } 10202 10203 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10204 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10205 } 10206 10207 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10208 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10209 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10210 } 10211 return KEY_DISPATCHING_TIMEOUT; 10212 } 10213 10214 @Override 10215 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10216 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10217 != PackageManager.PERMISSION_GRANTED) { 10218 throw new SecurityException("Requires permission " 10219 + android.Manifest.permission.FILTER_EVENTS); 10220 } 10221 ProcessRecord proc; 10222 long timeout; 10223 synchronized (this) { 10224 synchronized (mPidsSelfLocked) { 10225 proc = mPidsSelfLocked.get(pid); 10226 } 10227 timeout = getInputDispatchingTimeoutLocked(proc); 10228 } 10229 10230 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10231 return -1; 10232 } 10233 10234 return timeout; 10235 } 10236 10237 /** 10238 * Handle input dispatching timeouts. 10239 * Returns whether input dispatching should be aborted or not. 10240 */ 10241 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10242 final ActivityRecord activity, final ActivityRecord parent, 10243 final boolean aboveSystem, String reason) { 10244 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10245 != PackageManager.PERMISSION_GRANTED) { 10246 throw new SecurityException("Requires permission " 10247 + android.Manifest.permission.FILTER_EVENTS); 10248 } 10249 10250 final String annotation; 10251 if (reason == null) { 10252 annotation = "Input dispatching timed out"; 10253 } else { 10254 annotation = "Input dispatching timed out (" + reason + ")"; 10255 } 10256 10257 if (proc != null) { 10258 synchronized (this) { 10259 if (proc.debugging) { 10260 return false; 10261 } 10262 10263 if (mDidDexOpt) { 10264 // Give more time since we were dexopting. 10265 mDidDexOpt = false; 10266 return false; 10267 } 10268 10269 if (proc.instrumentationClass != null) { 10270 Bundle info = new Bundle(); 10271 info.putString("shortMsg", "keyDispatchingTimedOut"); 10272 info.putString("longMsg", annotation); 10273 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10274 return true; 10275 } 10276 } 10277 mHandler.post(new Runnable() { 10278 @Override 10279 public void run() { 10280 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10281 } 10282 }); 10283 } 10284 10285 return true; 10286 } 10287 10288 public Bundle getAssistContextExtras(int requestType) { 10289 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10290 UserHandle.getCallingUserId()); 10291 if (pae == null) { 10292 return null; 10293 } 10294 synchronized (pae) { 10295 while (!pae.haveResult) { 10296 try { 10297 pae.wait(); 10298 } catch (InterruptedException e) { 10299 } 10300 } 10301 if (pae.result != null) { 10302 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10303 } 10304 } 10305 synchronized (this) { 10306 mPendingAssistExtras.remove(pae); 10307 mHandler.removeCallbacks(pae); 10308 } 10309 return pae.extras; 10310 } 10311 10312 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10313 int userHandle) { 10314 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10315 "getAssistContextExtras()"); 10316 PendingAssistExtras pae; 10317 Bundle extras = new Bundle(); 10318 synchronized (this) { 10319 ActivityRecord activity = getFocusedStack().mResumedActivity; 10320 if (activity == null) { 10321 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10322 return null; 10323 } 10324 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10325 if (activity.app == null || activity.app.thread == null) { 10326 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10327 return null; 10328 } 10329 if (activity.app.pid == Binder.getCallingPid()) { 10330 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10331 return null; 10332 } 10333 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10334 try { 10335 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10336 requestType); 10337 mPendingAssistExtras.add(pae); 10338 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10339 } catch (RemoteException e) { 10340 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10341 return null; 10342 } 10343 return pae; 10344 } 10345 } 10346 10347 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10348 PendingAssistExtras pae = (PendingAssistExtras)token; 10349 synchronized (pae) { 10350 pae.result = extras; 10351 pae.haveResult = true; 10352 pae.notifyAll(); 10353 if (pae.intent == null) { 10354 // Caller is just waiting for the result. 10355 return; 10356 } 10357 } 10358 10359 // We are now ready to launch the assist activity. 10360 synchronized (this) { 10361 boolean exists = mPendingAssistExtras.remove(pae); 10362 mHandler.removeCallbacks(pae); 10363 if (!exists) { 10364 // Timed out. 10365 return; 10366 } 10367 } 10368 pae.intent.replaceExtras(extras); 10369 if (pae.hint != null) { 10370 pae.intent.putExtra(pae.hint, true); 10371 } 10372 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10373 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10374 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10375 closeSystemDialogs("assist"); 10376 try { 10377 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10378 } catch (ActivityNotFoundException e) { 10379 Slog.w(TAG, "No activity to handle assist action.", e); 10380 } 10381 } 10382 10383 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10384 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10385 } 10386 10387 public void registerProcessObserver(IProcessObserver observer) { 10388 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10389 "registerProcessObserver()"); 10390 synchronized (this) { 10391 mProcessObservers.register(observer); 10392 } 10393 } 10394 10395 @Override 10396 public void unregisterProcessObserver(IProcessObserver observer) { 10397 synchronized (this) { 10398 mProcessObservers.unregister(observer); 10399 } 10400 } 10401 10402 @Override 10403 public boolean convertFromTranslucent(IBinder token) { 10404 final long origId = Binder.clearCallingIdentity(); 10405 try { 10406 synchronized (this) { 10407 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10408 if (r == null) { 10409 return false; 10410 } 10411 final boolean translucentChanged = r.changeWindowTranslucency(true); 10412 if (translucentChanged) { 10413 r.task.stack.releaseBackgroundResources(); 10414 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10415 } 10416 mWindowManager.setAppFullscreen(token, true); 10417 return translucentChanged; 10418 } 10419 } finally { 10420 Binder.restoreCallingIdentity(origId); 10421 } 10422 } 10423 10424 @Override 10425 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10426 final long origId = Binder.clearCallingIdentity(); 10427 try { 10428 synchronized (this) { 10429 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10430 if (r == null) { 10431 return false; 10432 } 10433 int index = r.task.mActivities.lastIndexOf(r); 10434 if (index > 0) { 10435 ActivityRecord under = r.task.mActivities.get(index - 1); 10436 under.returningOptions = options; 10437 } 10438 final boolean translucentChanged = r.changeWindowTranslucency(false); 10439 if (translucentChanged) { 10440 r.task.stack.convertToTranslucent(r); 10441 } 10442 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10443 mWindowManager.setAppFullscreen(token, false); 10444 return translucentChanged; 10445 } 10446 } finally { 10447 Binder.restoreCallingIdentity(origId); 10448 } 10449 } 10450 10451 @Override 10452 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10453 final long origId = Binder.clearCallingIdentity(); 10454 try { 10455 synchronized (this) { 10456 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10457 if (r != null) { 10458 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10459 } 10460 } 10461 return false; 10462 } finally { 10463 Binder.restoreCallingIdentity(origId); 10464 } 10465 } 10466 10467 @Override 10468 public boolean isBackgroundVisibleBehind(IBinder token) { 10469 final long origId = Binder.clearCallingIdentity(); 10470 try { 10471 synchronized (this) { 10472 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10473 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10474 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10475 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10476 return visible; 10477 } 10478 } finally { 10479 Binder.restoreCallingIdentity(origId); 10480 } 10481 } 10482 10483 @Override 10484 public ActivityOptions getActivityOptions(IBinder token) { 10485 final long origId = Binder.clearCallingIdentity(); 10486 try { 10487 synchronized (this) { 10488 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10489 if (r != null) { 10490 final ActivityOptions activityOptions = r.pendingOptions; 10491 r.pendingOptions = null; 10492 return activityOptions; 10493 } 10494 return null; 10495 } 10496 } finally { 10497 Binder.restoreCallingIdentity(origId); 10498 } 10499 } 10500 10501 @Override 10502 public void setImmersive(IBinder token, boolean immersive) { 10503 synchronized(this) { 10504 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10505 if (r == null) { 10506 throw new IllegalArgumentException(); 10507 } 10508 r.immersive = immersive; 10509 10510 // update associated state if we're frontmost 10511 if (r == mFocusedActivity) { 10512 if (DEBUG_IMMERSIVE) { 10513 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10514 } 10515 applyUpdateLockStateLocked(r); 10516 } 10517 } 10518 } 10519 10520 @Override 10521 public boolean isImmersive(IBinder token) { 10522 synchronized (this) { 10523 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10524 if (r == null) { 10525 throw new IllegalArgumentException(); 10526 } 10527 return r.immersive; 10528 } 10529 } 10530 10531 public boolean isTopActivityImmersive() { 10532 enforceNotIsolatedCaller("startActivity"); 10533 synchronized (this) { 10534 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10535 return (r != null) ? r.immersive : false; 10536 } 10537 } 10538 10539 @Override 10540 public boolean isTopOfTask(IBinder token) { 10541 synchronized (this) { 10542 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10543 if (r == null) { 10544 throw new IllegalArgumentException(); 10545 } 10546 return r.task.getTopActivity() == r; 10547 } 10548 } 10549 10550 public final void enterSafeMode() { 10551 synchronized(this) { 10552 // It only makes sense to do this before the system is ready 10553 // and started launching other packages. 10554 if (!mSystemReady) { 10555 try { 10556 AppGlobals.getPackageManager().enterSafeMode(); 10557 } catch (RemoteException e) { 10558 } 10559 } 10560 10561 mSafeMode = true; 10562 } 10563 } 10564 10565 public final void showSafeModeOverlay() { 10566 View v = LayoutInflater.from(mContext).inflate( 10567 com.android.internal.R.layout.safe_mode, null); 10568 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10569 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10570 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10571 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10572 lp.gravity = Gravity.BOTTOM | Gravity.START; 10573 lp.format = v.getBackground().getOpacity(); 10574 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10575 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10576 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10577 ((WindowManager)mContext.getSystemService( 10578 Context.WINDOW_SERVICE)).addView(v, lp); 10579 } 10580 10581 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10582 if (!(sender instanceof PendingIntentRecord)) { 10583 return; 10584 } 10585 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10586 synchronized (stats) { 10587 if (mBatteryStatsService.isOnBattery()) { 10588 mBatteryStatsService.enforceCallingPermission(); 10589 PendingIntentRecord rec = (PendingIntentRecord)sender; 10590 int MY_UID = Binder.getCallingUid(); 10591 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10592 BatteryStatsImpl.Uid.Pkg pkg = 10593 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10594 sourcePkg != null ? sourcePkg : rec.key.packageName); 10595 pkg.incWakeupsLocked(); 10596 } 10597 } 10598 } 10599 10600 public boolean killPids(int[] pids, String pReason, boolean secure) { 10601 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10602 throw new SecurityException("killPids only available to the system"); 10603 } 10604 String reason = (pReason == null) ? "Unknown" : pReason; 10605 // XXX Note: don't acquire main activity lock here, because the window 10606 // manager calls in with its locks held. 10607 10608 boolean killed = false; 10609 synchronized (mPidsSelfLocked) { 10610 int[] types = new int[pids.length]; 10611 int worstType = 0; 10612 for (int i=0; i<pids.length; i++) { 10613 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10614 if (proc != null) { 10615 int type = proc.setAdj; 10616 types[i] = type; 10617 if (type > worstType) { 10618 worstType = type; 10619 } 10620 } 10621 } 10622 10623 // If the worst oom_adj is somewhere in the cached proc LRU range, 10624 // then constrain it so we will kill all cached procs. 10625 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10626 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10627 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10628 } 10629 10630 // If this is not a secure call, don't let it kill processes that 10631 // are important. 10632 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10633 worstType = ProcessList.SERVICE_ADJ; 10634 } 10635 10636 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10637 for (int i=0; i<pids.length; i++) { 10638 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10639 if (proc == null) { 10640 continue; 10641 } 10642 int adj = proc.setAdj; 10643 if (adj >= worstType && !proc.killedByAm) { 10644 proc.kill(reason, true); 10645 killed = true; 10646 } 10647 } 10648 } 10649 return killed; 10650 } 10651 10652 @Override 10653 public void killUid(int uid, String reason) { 10654 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10655 throw new SecurityException("killUid only available to the system"); 10656 } 10657 synchronized (this) { 10658 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10659 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10660 reason != null ? reason : "kill uid"); 10661 } 10662 } 10663 10664 @Override 10665 public boolean killProcessesBelowForeground(String reason) { 10666 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10667 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10668 } 10669 10670 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10671 } 10672 10673 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10674 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10675 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10676 } 10677 10678 boolean killed = false; 10679 synchronized (mPidsSelfLocked) { 10680 final int size = mPidsSelfLocked.size(); 10681 for (int i = 0; i < size; i++) { 10682 final int pid = mPidsSelfLocked.keyAt(i); 10683 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10684 if (proc == null) continue; 10685 10686 final int adj = proc.setAdj; 10687 if (adj > belowAdj && !proc.killedByAm) { 10688 proc.kill(reason, true); 10689 killed = true; 10690 } 10691 } 10692 } 10693 return killed; 10694 } 10695 10696 @Override 10697 public void hang(final IBinder who, boolean allowRestart) { 10698 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10699 != PackageManager.PERMISSION_GRANTED) { 10700 throw new SecurityException("Requires permission " 10701 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10702 } 10703 10704 final IBinder.DeathRecipient death = new DeathRecipient() { 10705 @Override 10706 public void binderDied() { 10707 synchronized (this) { 10708 notifyAll(); 10709 } 10710 } 10711 }; 10712 10713 try { 10714 who.linkToDeath(death, 0); 10715 } catch (RemoteException e) { 10716 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10717 return; 10718 } 10719 10720 synchronized (this) { 10721 Watchdog.getInstance().setAllowRestart(allowRestart); 10722 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10723 synchronized (death) { 10724 while (who.isBinderAlive()) { 10725 try { 10726 death.wait(); 10727 } catch (InterruptedException e) { 10728 } 10729 } 10730 } 10731 Watchdog.getInstance().setAllowRestart(true); 10732 } 10733 } 10734 10735 @Override 10736 public void restart() { 10737 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10738 != PackageManager.PERMISSION_GRANTED) { 10739 throw new SecurityException("Requires permission " 10740 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10741 } 10742 10743 Log.i(TAG, "Sending shutdown broadcast..."); 10744 10745 BroadcastReceiver br = new BroadcastReceiver() { 10746 @Override public void onReceive(Context context, Intent intent) { 10747 // Now the broadcast is done, finish up the low-level shutdown. 10748 Log.i(TAG, "Shutting down activity manager..."); 10749 shutdown(10000); 10750 Log.i(TAG, "Shutdown complete, restarting!"); 10751 Process.killProcess(Process.myPid()); 10752 System.exit(10); 10753 } 10754 }; 10755 10756 // First send the high-level shut down broadcast. 10757 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10758 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10759 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10760 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10761 mContext.sendOrderedBroadcastAsUser(intent, 10762 UserHandle.ALL, null, br, mHandler, 0, null, null); 10763 */ 10764 br.onReceive(mContext, intent); 10765 } 10766 10767 private long getLowRamTimeSinceIdle(long now) { 10768 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10769 } 10770 10771 @Override 10772 public void performIdleMaintenance() { 10773 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10774 != PackageManager.PERMISSION_GRANTED) { 10775 throw new SecurityException("Requires permission " 10776 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10777 } 10778 10779 synchronized (this) { 10780 final long now = SystemClock.uptimeMillis(); 10781 final long timeSinceLastIdle = now - mLastIdleTime; 10782 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10783 mLastIdleTime = now; 10784 mLowRamTimeSinceLastIdle = 0; 10785 if (mLowRamStartTime != 0) { 10786 mLowRamStartTime = now; 10787 } 10788 10789 StringBuilder sb = new StringBuilder(128); 10790 sb.append("Idle maintenance over "); 10791 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10792 sb.append(" low RAM for "); 10793 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10794 Slog.i(TAG, sb.toString()); 10795 10796 // If at least 1/3 of our time since the last idle period has been spent 10797 // with RAM low, then we want to kill processes. 10798 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10799 10800 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10801 ProcessRecord proc = mLruProcesses.get(i); 10802 if (proc.notCachedSinceIdle) { 10803 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10804 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10805 if (doKilling && proc.initialIdlePss != 0 10806 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10807 proc.kill("idle maint (pss " + proc.lastPss 10808 + " from " + proc.initialIdlePss + ")", true); 10809 } 10810 } 10811 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10812 proc.notCachedSinceIdle = true; 10813 proc.initialIdlePss = 0; 10814 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10815 isSleeping(), now); 10816 } 10817 } 10818 10819 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10820 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10821 } 10822 } 10823 10824 private void retrieveSettings() { 10825 final ContentResolver resolver = mContext.getContentResolver(); 10826 String debugApp = Settings.Global.getString( 10827 resolver, Settings.Global.DEBUG_APP); 10828 boolean waitForDebugger = Settings.Global.getInt( 10829 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10830 boolean alwaysFinishActivities = Settings.Global.getInt( 10831 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10832 boolean forceRtl = Settings.Global.getInt( 10833 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10834 // Transfer any global setting for forcing RTL layout, into a System Property 10835 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10836 10837 Configuration configuration = new Configuration(); 10838 Settings.System.getConfiguration(resolver, configuration); 10839 if (forceRtl) { 10840 // This will take care of setting the correct layout direction flags 10841 configuration.setLayoutDirection(configuration.locale); 10842 } 10843 10844 synchronized (this) { 10845 mDebugApp = mOrigDebugApp = debugApp; 10846 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10847 mAlwaysFinishActivities = alwaysFinishActivities; 10848 // This happens before any activities are started, so we can 10849 // change mConfiguration in-place. 10850 updateConfigurationLocked(configuration, null, false, true); 10851 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10852 } 10853 } 10854 10855 /** Loads resources after the current configuration has been set. */ 10856 private void loadResourcesOnSystemReady() { 10857 final Resources res = mContext.getResources(); 10858 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10859 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10860 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10861 } 10862 10863 public boolean testIsSystemReady() { 10864 // no need to synchronize(this) just to read & return the value 10865 return mSystemReady; 10866 } 10867 10868 private static File getCalledPreBootReceiversFile() { 10869 File dataDir = Environment.getDataDirectory(); 10870 File systemDir = new File(dataDir, "system"); 10871 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10872 return fname; 10873 } 10874 10875 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10876 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10877 File file = getCalledPreBootReceiversFile(); 10878 FileInputStream fis = null; 10879 try { 10880 fis = new FileInputStream(file); 10881 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10882 int fvers = dis.readInt(); 10883 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10884 String vers = dis.readUTF(); 10885 String codename = dis.readUTF(); 10886 String build = dis.readUTF(); 10887 if (android.os.Build.VERSION.RELEASE.equals(vers) 10888 && android.os.Build.VERSION.CODENAME.equals(codename) 10889 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10890 int num = dis.readInt(); 10891 while (num > 0) { 10892 num--; 10893 String pkg = dis.readUTF(); 10894 String cls = dis.readUTF(); 10895 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10896 } 10897 } 10898 } 10899 } catch (FileNotFoundException e) { 10900 } catch (IOException e) { 10901 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10902 } finally { 10903 if (fis != null) { 10904 try { 10905 fis.close(); 10906 } catch (IOException e) { 10907 } 10908 } 10909 } 10910 return lastDoneReceivers; 10911 } 10912 10913 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10914 File file = getCalledPreBootReceiversFile(); 10915 FileOutputStream fos = null; 10916 DataOutputStream dos = null; 10917 try { 10918 fos = new FileOutputStream(file); 10919 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10920 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10921 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10922 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10923 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10924 dos.writeInt(list.size()); 10925 for (int i=0; i<list.size(); i++) { 10926 dos.writeUTF(list.get(i).getPackageName()); 10927 dos.writeUTF(list.get(i).getClassName()); 10928 } 10929 } catch (IOException e) { 10930 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10931 file.delete(); 10932 } finally { 10933 FileUtils.sync(fos); 10934 if (dos != null) { 10935 try { 10936 dos.close(); 10937 } catch (IOException e) { 10938 // TODO Auto-generated catch block 10939 e.printStackTrace(); 10940 } 10941 } 10942 } 10943 } 10944 10945 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10946 ArrayList<ComponentName> doneReceivers, int userId) { 10947 boolean waitingUpdate = false; 10948 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10949 List<ResolveInfo> ris = null; 10950 try { 10951 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10952 intent, null, 0, userId); 10953 } catch (RemoteException e) { 10954 } 10955 if (ris != null) { 10956 for (int i=ris.size()-1; i>=0; i--) { 10957 if ((ris.get(i).activityInfo.applicationInfo.flags 10958 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10959 ris.remove(i); 10960 } 10961 } 10962 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10963 10964 // For User 0, load the version number. When delivering to a new user, deliver 10965 // to all receivers. 10966 if (userId == UserHandle.USER_OWNER) { 10967 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10968 for (int i=0; i<ris.size(); i++) { 10969 ActivityInfo ai = ris.get(i).activityInfo; 10970 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10971 if (lastDoneReceivers.contains(comp)) { 10972 // We already did the pre boot receiver for this app with the current 10973 // platform version, so don't do it again... 10974 ris.remove(i); 10975 i--; 10976 // ...however, do keep it as one that has been done, so we don't 10977 // forget about it when rewriting the file of last done receivers. 10978 doneReceivers.add(comp); 10979 } 10980 } 10981 } 10982 10983 // If primary user, send broadcast to all available users, else just to userId 10984 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 10985 : new int[] { userId }; 10986 for (int i = 0; i < ris.size(); i++) { 10987 ActivityInfo ai = ris.get(i).activityInfo; 10988 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10989 doneReceivers.add(comp); 10990 intent.setComponent(comp); 10991 for (int j=0; j<users.length; j++) { 10992 IIntentReceiver finisher = null; 10993 // On last receiver and user, set up a completion callback 10994 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 10995 finisher = new IIntentReceiver.Stub() { 10996 public void performReceive(Intent intent, int resultCode, 10997 String data, Bundle extras, boolean ordered, 10998 boolean sticky, int sendingUser) { 10999 // The raw IIntentReceiver interface is called 11000 // with the AM lock held, so redispatch to 11001 // execute our code without the lock. 11002 mHandler.post(onFinishCallback); 11003 } 11004 }; 11005 } 11006 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11007 + " for user " + users[j]); 11008 broadcastIntentLocked(null, null, intent, null, finisher, 11009 0, null, null, null, AppOpsManager.OP_NONE, 11010 true, false, MY_PID, Process.SYSTEM_UID, 11011 users[j]); 11012 if (finisher != null) { 11013 waitingUpdate = true; 11014 } 11015 } 11016 } 11017 } 11018 11019 return waitingUpdate; 11020 } 11021 11022 public void systemReady(final Runnable goingCallback) { 11023 synchronized(this) { 11024 if (mSystemReady) { 11025 // If we're done calling all the receivers, run the next "boot phase" passed in 11026 // by the SystemServer 11027 if (goingCallback != null) { 11028 goingCallback.run(); 11029 } 11030 return; 11031 } 11032 11033 // Make sure we have the current profile info, since it is needed for 11034 // security checks. 11035 updateCurrentProfileIdsLocked(); 11036 11037 if (mRecentTasks == null) { 11038 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11039 if (!mRecentTasks.isEmpty()) { 11040 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11041 } 11042 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11043 mTaskPersister.startPersisting(); 11044 } 11045 11046 // Check to see if there are any update receivers to run. 11047 if (!mDidUpdate) { 11048 if (mWaitingUpdate) { 11049 return; 11050 } 11051 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11052 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11053 public void run() { 11054 synchronized (ActivityManagerService.this) { 11055 mDidUpdate = true; 11056 } 11057 writeLastDonePreBootReceivers(doneReceivers); 11058 showBootMessage(mContext.getText( 11059 R.string.android_upgrading_complete), 11060 false); 11061 systemReady(goingCallback); 11062 } 11063 }, doneReceivers, UserHandle.USER_OWNER); 11064 11065 if (mWaitingUpdate) { 11066 return; 11067 } 11068 mDidUpdate = true; 11069 } 11070 11071 mAppOpsService.systemReady(); 11072 mSystemReady = true; 11073 } 11074 11075 ArrayList<ProcessRecord> procsToKill = null; 11076 synchronized(mPidsSelfLocked) { 11077 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11078 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11079 if (!isAllowedWhileBooting(proc.info)){ 11080 if (procsToKill == null) { 11081 procsToKill = new ArrayList<ProcessRecord>(); 11082 } 11083 procsToKill.add(proc); 11084 } 11085 } 11086 } 11087 11088 synchronized(this) { 11089 if (procsToKill != null) { 11090 for (int i=procsToKill.size()-1; i>=0; i--) { 11091 ProcessRecord proc = procsToKill.get(i); 11092 Slog.i(TAG, "Removing system update proc: " + proc); 11093 removeProcessLocked(proc, true, false, "system update done"); 11094 } 11095 } 11096 11097 // Now that we have cleaned up any update processes, we 11098 // are ready to start launching real processes and know that 11099 // we won't trample on them any more. 11100 mProcessesReady = true; 11101 } 11102 11103 Slog.i(TAG, "System now ready"); 11104 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11105 SystemClock.uptimeMillis()); 11106 11107 synchronized(this) { 11108 // Make sure we have no pre-ready processes sitting around. 11109 11110 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11111 ResolveInfo ri = mContext.getPackageManager() 11112 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11113 STOCK_PM_FLAGS); 11114 CharSequence errorMsg = null; 11115 if (ri != null) { 11116 ActivityInfo ai = ri.activityInfo; 11117 ApplicationInfo app = ai.applicationInfo; 11118 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11119 mTopAction = Intent.ACTION_FACTORY_TEST; 11120 mTopData = null; 11121 mTopComponent = new ComponentName(app.packageName, 11122 ai.name); 11123 } else { 11124 errorMsg = mContext.getResources().getText( 11125 com.android.internal.R.string.factorytest_not_system); 11126 } 11127 } else { 11128 errorMsg = mContext.getResources().getText( 11129 com.android.internal.R.string.factorytest_no_action); 11130 } 11131 if (errorMsg != null) { 11132 mTopAction = null; 11133 mTopData = null; 11134 mTopComponent = null; 11135 Message msg = Message.obtain(); 11136 msg.what = SHOW_FACTORY_ERROR_MSG; 11137 msg.getData().putCharSequence("msg", errorMsg); 11138 mHandler.sendMessage(msg); 11139 } 11140 } 11141 } 11142 11143 retrieveSettings(); 11144 loadResourcesOnSystemReady(); 11145 11146 synchronized (this) { 11147 readGrantedUriPermissionsLocked(); 11148 } 11149 11150 if (goingCallback != null) goingCallback.run(); 11151 11152 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11153 Integer.toString(mCurrentUserId), mCurrentUserId); 11154 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11155 Integer.toString(mCurrentUserId), mCurrentUserId); 11156 mSystemServiceManager.startUser(mCurrentUserId); 11157 11158 synchronized (this) { 11159 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11160 try { 11161 List apps = AppGlobals.getPackageManager(). 11162 getPersistentApplications(STOCK_PM_FLAGS); 11163 if (apps != null) { 11164 int N = apps.size(); 11165 int i; 11166 for (i=0; i<N; i++) { 11167 ApplicationInfo info 11168 = (ApplicationInfo)apps.get(i); 11169 if (info != null && 11170 !info.packageName.equals("android")) { 11171 addAppLocked(info, false, null /* ABI override */); 11172 } 11173 } 11174 } 11175 } catch (RemoteException ex) { 11176 // pm is in same process, this will never happen. 11177 } 11178 } 11179 11180 // Start up initial activity. 11181 mBooting = true; 11182 startHomeActivityLocked(mCurrentUserId); 11183 11184 try { 11185 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11186 Message msg = Message.obtain(); 11187 msg.what = SHOW_UID_ERROR_MSG; 11188 mHandler.sendMessage(msg); 11189 } 11190 } catch (RemoteException e) { 11191 } 11192 11193 long ident = Binder.clearCallingIdentity(); 11194 try { 11195 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11196 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11197 | Intent.FLAG_RECEIVER_FOREGROUND); 11198 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11199 broadcastIntentLocked(null, null, intent, 11200 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11201 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11202 intent = new Intent(Intent.ACTION_USER_STARTING); 11203 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11204 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11205 broadcastIntentLocked(null, null, intent, 11206 null, new IIntentReceiver.Stub() { 11207 @Override 11208 public void performReceive(Intent intent, int resultCode, String data, 11209 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11210 throws RemoteException { 11211 } 11212 }, 0, null, null, 11213 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11214 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11215 } catch (Throwable t) { 11216 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11217 } finally { 11218 Binder.restoreCallingIdentity(ident); 11219 } 11220 mStackSupervisor.resumeTopActivitiesLocked(); 11221 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11222 } 11223 } 11224 11225 private boolean makeAppCrashingLocked(ProcessRecord app, 11226 String shortMsg, String longMsg, String stackTrace) { 11227 app.crashing = true; 11228 app.crashingReport = generateProcessError(app, 11229 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11230 startAppProblemLocked(app); 11231 app.stopFreezingAllLocked(); 11232 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11233 } 11234 11235 private void makeAppNotRespondingLocked(ProcessRecord app, 11236 String activity, String shortMsg, String longMsg) { 11237 app.notResponding = true; 11238 app.notRespondingReport = generateProcessError(app, 11239 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11240 activity, shortMsg, longMsg, null); 11241 startAppProblemLocked(app); 11242 app.stopFreezingAllLocked(); 11243 } 11244 11245 /** 11246 * Generate a process error record, suitable for attachment to a ProcessRecord. 11247 * 11248 * @param app The ProcessRecord in which the error occurred. 11249 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11250 * ActivityManager.AppErrorStateInfo 11251 * @param activity The activity associated with the crash, if known. 11252 * @param shortMsg Short message describing the crash. 11253 * @param longMsg Long message describing the crash. 11254 * @param stackTrace Full crash stack trace, may be null. 11255 * 11256 * @return Returns a fully-formed AppErrorStateInfo record. 11257 */ 11258 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11259 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11260 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11261 11262 report.condition = condition; 11263 report.processName = app.processName; 11264 report.pid = app.pid; 11265 report.uid = app.info.uid; 11266 report.tag = activity; 11267 report.shortMsg = shortMsg; 11268 report.longMsg = longMsg; 11269 report.stackTrace = stackTrace; 11270 11271 return report; 11272 } 11273 11274 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11275 synchronized (this) { 11276 app.crashing = false; 11277 app.crashingReport = null; 11278 app.notResponding = false; 11279 app.notRespondingReport = null; 11280 if (app.anrDialog == fromDialog) { 11281 app.anrDialog = null; 11282 } 11283 if (app.waitDialog == fromDialog) { 11284 app.waitDialog = null; 11285 } 11286 if (app.pid > 0 && app.pid != MY_PID) { 11287 handleAppCrashLocked(app, null, null, null); 11288 app.kill("user request after error", true); 11289 } 11290 } 11291 } 11292 11293 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11294 String stackTrace) { 11295 long now = SystemClock.uptimeMillis(); 11296 11297 Long crashTime; 11298 if (!app.isolated) { 11299 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11300 } else { 11301 crashTime = null; 11302 } 11303 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11304 // This process loses! 11305 Slog.w(TAG, "Process " + app.info.processName 11306 + " has crashed too many times: killing!"); 11307 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11308 app.userId, app.info.processName, app.uid); 11309 mStackSupervisor.handleAppCrashLocked(app); 11310 if (!app.persistent) { 11311 // We don't want to start this process again until the user 11312 // explicitly does so... but for persistent process, we really 11313 // need to keep it running. If a persistent process is actually 11314 // repeatedly crashing, then badness for everyone. 11315 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11316 app.info.processName); 11317 if (!app.isolated) { 11318 // XXX We don't have a way to mark isolated processes 11319 // as bad, since they don't have a peristent identity. 11320 mBadProcesses.put(app.info.processName, app.uid, 11321 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11322 mProcessCrashTimes.remove(app.info.processName, app.uid); 11323 } 11324 app.bad = true; 11325 app.removed = true; 11326 // Don't let services in this process be restarted and potentially 11327 // annoy the user repeatedly. Unless it is persistent, since those 11328 // processes run critical code. 11329 removeProcessLocked(app, false, false, "crash"); 11330 mStackSupervisor.resumeTopActivitiesLocked(); 11331 return false; 11332 } 11333 mStackSupervisor.resumeTopActivitiesLocked(); 11334 } else { 11335 mStackSupervisor.finishTopRunningActivityLocked(app); 11336 } 11337 11338 // Bump up the crash count of any services currently running in the proc. 11339 for (int i=app.services.size()-1; i>=0; i--) { 11340 // Any services running in the application need to be placed 11341 // back in the pending list. 11342 ServiceRecord sr = app.services.valueAt(i); 11343 sr.crashCount++; 11344 } 11345 11346 // If the crashing process is what we consider to be the "home process" and it has been 11347 // replaced by a third-party app, clear the package preferred activities from packages 11348 // with a home activity running in the process to prevent a repeatedly crashing app 11349 // from blocking the user to manually clear the list. 11350 final ArrayList<ActivityRecord> activities = app.activities; 11351 if (app == mHomeProcess && activities.size() > 0 11352 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11353 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11354 final ActivityRecord r = activities.get(activityNdx); 11355 if (r.isHomeActivity()) { 11356 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11357 try { 11358 ActivityThread.getPackageManager() 11359 .clearPackagePreferredActivities(r.packageName); 11360 } catch (RemoteException c) { 11361 // pm is in same process, this will never happen. 11362 } 11363 } 11364 } 11365 } 11366 11367 if (!app.isolated) { 11368 // XXX Can't keep track of crash times for isolated processes, 11369 // because they don't have a perisistent identity. 11370 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11371 } 11372 11373 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11374 return true; 11375 } 11376 11377 void startAppProblemLocked(ProcessRecord app) { 11378 // If this app is not running under the current user, then we 11379 // can't give it a report button because that would require 11380 // launching the report UI under a different user. 11381 app.errorReportReceiver = null; 11382 11383 for (int userId : mCurrentProfileIds) { 11384 if (app.userId == userId) { 11385 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11386 mContext, app.info.packageName, app.info.flags); 11387 } 11388 } 11389 skipCurrentReceiverLocked(app); 11390 } 11391 11392 void skipCurrentReceiverLocked(ProcessRecord app) { 11393 for (BroadcastQueue queue : mBroadcastQueues) { 11394 queue.skipCurrentReceiverLocked(app); 11395 } 11396 } 11397 11398 /** 11399 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11400 * The application process will exit immediately after this call returns. 11401 * @param app object of the crashing app, null for the system server 11402 * @param crashInfo describing the exception 11403 */ 11404 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11405 ProcessRecord r = findAppProcess(app, "Crash"); 11406 final String processName = app == null ? "system_server" 11407 : (r == null ? "unknown" : r.processName); 11408 11409 handleApplicationCrashInner("crash", r, processName, crashInfo); 11410 } 11411 11412 /* Native crash reporting uses this inner version because it needs to be somewhat 11413 * decoupled from the AM-managed cleanup lifecycle 11414 */ 11415 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11416 ApplicationErrorReport.CrashInfo crashInfo) { 11417 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11418 UserHandle.getUserId(Binder.getCallingUid()), processName, 11419 r == null ? -1 : r.info.flags, 11420 crashInfo.exceptionClassName, 11421 crashInfo.exceptionMessage, 11422 crashInfo.throwFileName, 11423 crashInfo.throwLineNumber); 11424 11425 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11426 11427 crashApplication(r, crashInfo); 11428 } 11429 11430 public void handleApplicationStrictModeViolation( 11431 IBinder app, 11432 int violationMask, 11433 StrictMode.ViolationInfo info) { 11434 ProcessRecord r = findAppProcess(app, "StrictMode"); 11435 if (r == null) { 11436 return; 11437 } 11438 11439 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11440 Integer stackFingerprint = info.hashCode(); 11441 boolean logIt = true; 11442 synchronized (mAlreadyLoggedViolatedStacks) { 11443 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11444 logIt = false; 11445 // TODO: sub-sample into EventLog for these, with 11446 // the info.durationMillis? Then we'd get 11447 // the relative pain numbers, without logging all 11448 // the stack traces repeatedly. We'd want to do 11449 // likewise in the client code, which also does 11450 // dup suppression, before the Binder call. 11451 } else { 11452 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11453 mAlreadyLoggedViolatedStacks.clear(); 11454 } 11455 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11456 } 11457 } 11458 if (logIt) { 11459 logStrictModeViolationToDropBox(r, info); 11460 } 11461 } 11462 11463 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11464 AppErrorResult result = new AppErrorResult(); 11465 synchronized (this) { 11466 final long origId = Binder.clearCallingIdentity(); 11467 11468 Message msg = Message.obtain(); 11469 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11470 HashMap<String, Object> data = new HashMap<String, Object>(); 11471 data.put("result", result); 11472 data.put("app", r); 11473 data.put("violationMask", violationMask); 11474 data.put("info", info); 11475 msg.obj = data; 11476 mHandler.sendMessage(msg); 11477 11478 Binder.restoreCallingIdentity(origId); 11479 } 11480 int res = result.get(); 11481 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11482 } 11483 } 11484 11485 // Depending on the policy in effect, there could be a bunch of 11486 // these in quick succession so we try to batch these together to 11487 // minimize disk writes, number of dropbox entries, and maximize 11488 // compression, by having more fewer, larger records. 11489 private void logStrictModeViolationToDropBox( 11490 ProcessRecord process, 11491 StrictMode.ViolationInfo info) { 11492 if (info == null) { 11493 return; 11494 } 11495 final boolean isSystemApp = process == null || 11496 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11497 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11498 final String processName = process == null ? "unknown" : process.processName; 11499 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11500 final DropBoxManager dbox = (DropBoxManager) 11501 mContext.getSystemService(Context.DROPBOX_SERVICE); 11502 11503 // Exit early if the dropbox isn't configured to accept this report type. 11504 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11505 11506 boolean bufferWasEmpty; 11507 boolean needsFlush; 11508 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11509 synchronized (sb) { 11510 bufferWasEmpty = sb.length() == 0; 11511 appendDropBoxProcessHeaders(process, processName, sb); 11512 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11513 sb.append("System-App: ").append(isSystemApp).append("\n"); 11514 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11515 if (info.violationNumThisLoop != 0) { 11516 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11517 } 11518 if (info.numAnimationsRunning != 0) { 11519 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11520 } 11521 if (info.broadcastIntentAction != null) { 11522 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11523 } 11524 if (info.durationMillis != -1) { 11525 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11526 } 11527 if (info.numInstances != -1) { 11528 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11529 } 11530 if (info.tags != null) { 11531 for (String tag : info.tags) { 11532 sb.append("Span-Tag: ").append(tag).append("\n"); 11533 } 11534 } 11535 sb.append("\n"); 11536 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11537 sb.append(info.crashInfo.stackTrace); 11538 } 11539 sb.append("\n"); 11540 11541 // Only buffer up to ~64k. Various logging bits truncate 11542 // things at 128k. 11543 needsFlush = (sb.length() > 64 * 1024); 11544 } 11545 11546 // Flush immediately if the buffer's grown too large, or this 11547 // is a non-system app. Non-system apps are isolated with a 11548 // different tag & policy and not batched. 11549 // 11550 // Batching is useful during internal testing with 11551 // StrictMode settings turned up high. Without batching, 11552 // thousands of separate files could be created on boot. 11553 if (!isSystemApp || needsFlush) { 11554 new Thread("Error dump: " + dropboxTag) { 11555 @Override 11556 public void run() { 11557 String report; 11558 synchronized (sb) { 11559 report = sb.toString(); 11560 sb.delete(0, sb.length()); 11561 sb.trimToSize(); 11562 } 11563 if (report.length() != 0) { 11564 dbox.addText(dropboxTag, report); 11565 } 11566 } 11567 }.start(); 11568 return; 11569 } 11570 11571 // System app batching: 11572 if (!bufferWasEmpty) { 11573 // An existing dropbox-writing thread is outstanding, so 11574 // we don't need to start it up. The existing thread will 11575 // catch the buffer appends we just did. 11576 return; 11577 } 11578 11579 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11580 // (After this point, we shouldn't access AMS internal data structures.) 11581 new Thread("Error dump: " + dropboxTag) { 11582 @Override 11583 public void run() { 11584 // 5 second sleep to let stacks arrive and be batched together 11585 try { 11586 Thread.sleep(5000); // 5 seconds 11587 } catch (InterruptedException e) {} 11588 11589 String errorReport; 11590 synchronized (mStrictModeBuffer) { 11591 errorReport = mStrictModeBuffer.toString(); 11592 if (errorReport.length() == 0) { 11593 return; 11594 } 11595 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11596 mStrictModeBuffer.trimToSize(); 11597 } 11598 dbox.addText(dropboxTag, errorReport); 11599 } 11600 }.start(); 11601 } 11602 11603 /** 11604 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11605 * @param app object of the crashing app, null for the system server 11606 * @param tag reported by the caller 11607 * @param system whether this wtf is coming from the system 11608 * @param crashInfo describing the context of the error 11609 * @return true if the process should exit immediately (WTF is fatal) 11610 */ 11611 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11612 final ApplicationErrorReport.CrashInfo crashInfo) { 11613 final int callingUid = Binder.getCallingUid(); 11614 final int callingPid = Binder.getCallingPid(); 11615 11616 if (system) { 11617 // If this is coming from the system, we could very well have low-level 11618 // system locks held, so we want to do this all asynchronously. And we 11619 // never want this to become fatal, so there is that too. 11620 mHandler.post(new Runnable() { 11621 @Override public void run() { 11622 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11623 } 11624 }); 11625 return false; 11626 } 11627 11628 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11629 crashInfo); 11630 11631 if (r != null && r.pid != Process.myPid() && 11632 Settings.Global.getInt(mContext.getContentResolver(), 11633 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11634 crashApplication(r, crashInfo); 11635 return true; 11636 } else { 11637 return false; 11638 } 11639 } 11640 11641 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11642 final ApplicationErrorReport.CrashInfo crashInfo) { 11643 final ProcessRecord r = findAppProcess(app, "WTF"); 11644 final String processName = app == null ? "system_server" 11645 : (r == null ? "unknown" : r.processName); 11646 11647 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11648 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11649 11650 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11651 11652 return r; 11653 } 11654 11655 /** 11656 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11657 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11658 */ 11659 private ProcessRecord findAppProcess(IBinder app, String reason) { 11660 if (app == null) { 11661 return null; 11662 } 11663 11664 synchronized (this) { 11665 final int NP = mProcessNames.getMap().size(); 11666 for (int ip=0; ip<NP; ip++) { 11667 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11668 final int NA = apps.size(); 11669 for (int ia=0; ia<NA; ia++) { 11670 ProcessRecord p = apps.valueAt(ia); 11671 if (p.thread != null && p.thread.asBinder() == app) { 11672 return p; 11673 } 11674 } 11675 } 11676 11677 Slog.w(TAG, "Can't find mystery application for " + reason 11678 + " from pid=" + Binder.getCallingPid() 11679 + " uid=" + Binder.getCallingUid() + ": " + app); 11680 return null; 11681 } 11682 } 11683 11684 /** 11685 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11686 * to append various headers to the dropbox log text. 11687 */ 11688 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11689 StringBuilder sb) { 11690 // Watchdog thread ends up invoking this function (with 11691 // a null ProcessRecord) to add the stack file to dropbox. 11692 // Do not acquire a lock on this (am) in such cases, as it 11693 // could cause a potential deadlock, if and when watchdog 11694 // is invoked due to unavailability of lock on am and it 11695 // would prevent watchdog from killing system_server. 11696 if (process == null) { 11697 sb.append("Process: ").append(processName).append("\n"); 11698 return; 11699 } 11700 // Note: ProcessRecord 'process' is guarded by the service 11701 // instance. (notably process.pkgList, which could otherwise change 11702 // concurrently during execution of this method) 11703 synchronized (this) { 11704 sb.append("Process: ").append(processName).append("\n"); 11705 int flags = process.info.flags; 11706 IPackageManager pm = AppGlobals.getPackageManager(); 11707 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11708 for (int ip=0; ip<process.pkgList.size(); ip++) { 11709 String pkg = process.pkgList.keyAt(ip); 11710 sb.append("Package: ").append(pkg); 11711 try { 11712 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11713 if (pi != null) { 11714 sb.append(" v").append(pi.versionCode); 11715 if (pi.versionName != null) { 11716 sb.append(" (").append(pi.versionName).append(")"); 11717 } 11718 } 11719 } catch (RemoteException e) { 11720 Slog.e(TAG, "Error getting package info: " + pkg, e); 11721 } 11722 sb.append("\n"); 11723 } 11724 } 11725 } 11726 11727 private static String processClass(ProcessRecord process) { 11728 if (process == null || process.pid == MY_PID) { 11729 return "system_server"; 11730 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11731 return "system_app"; 11732 } else { 11733 return "data_app"; 11734 } 11735 } 11736 11737 /** 11738 * Write a description of an error (crash, WTF, ANR) to the drop box. 11739 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11740 * @param process which caused the error, null means the system server 11741 * @param activity which triggered the error, null if unknown 11742 * @param parent activity related to the error, null if unknown 11743 * @param subject line related to the error, null if absent 11744 * @param report in long form describing the error, null if absent 11745 * @param logFile to include in the report, null if none 11746 * @param crashInfo giving an application stack trace, null if absent 11747 */ 11748 public void addErrorToDropBox(String eventType, 11749 ProcessRecord process, String processName, ActivityRecord activity, 11750 ActivityRecord parent, String subject, 11751 final String report, final File logFile, 11752 final ApplicationErrorReport.CrashInfo crashInfo) { 11753 // NOTE -- this must never acquire the ActivityManagerService lock, 11754 // otherwise the watchdog may be prevented from resetting the system. 11755 11756 final String dropboxTag = processClass(process) + "_" + eventType; 11757 final DropBoxManager dbox = (DropBoxManager) 11758 mContext.getSystemService(Context.DROPBOX_SERVICE); 11759 11760 // Exit early if the dropbox isn't configured to accept this report type. 11761 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11762 11763 final StringBuilder sb = new StringBuilder(1024); 11764 appendDropBoxProcessHeaders(process, processName, sb); 11765 if (activity != null) { 11766 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11767 } 11768 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11769 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11770 } 11771 if (parent != null && parent != activity) { 11772 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11773 } 11774 if (subject != null) { 11775 sb.append("Subject: ").append(subject).append("\n"); 11776 } 11777 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11778 if (Debug.isDebuggerConnected()) { 11779 sb.append("Debugger: Connected\n"); 11780 } 11781 sb.append("\n"); 11782 11783 // Do the rest in a worker thread to avoid blocking the caller on I/O 11784 // (After this point, we shouldn't access AMS internal data structures.) 11785 Thread worker = new Thread("Error dump: " + dropboxTag) { 11786 @Override 11787 public void run() { 11788 if (report != null) { 11789 sb.append(report); 11790 } 11791 if (logFile != null) { 11792 try { 11793 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11794 "\n\n[[TRUNCATED]]")); 11795 } catch (IOException e) { 11796 Slog.e(TAG, "Error reading " + logFile, e); 11797 } 11798 } 11799 if (crashInfo != null && crashInfo.stackTrace != null) { 11800 sb.append(crashInfo.stackTrace); 11801 } 11802 11803 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11804 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11805 if (lines > 0) { 11806 sb.append("\n"); 11807 11808 // Merge several logcat streams, and take the last N lines 11809 InputStreamReader input = null; 11810 try { 11811 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11812 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11813 "-b", "crash", 11814 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11815 11816 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11817 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11818 input = new InputStreamReader(logcat.getInputStream()); 11819 11820 int num; 11821 char[] buf = new char[8192]; 11822 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11823 } catch (IOException e) { 11824 Slog.e(TAG, "Error running logcat", e); 11825 } finally { 11826 if (input != null) try { input.close(); } catch (IOException e) {} 11827 } 11828 } 11829 11830 dbox.addText(dropboxTag, sb.toString()); 11831 } 11832 }; 11833 11834 if (process == null) { 11835 // If process is null, we are being called from some internal code 11836 // and may be about to die -- run this synchronously. 11837 worker.run(); 11838 } else { 11839 worker.start(); 11840 } 11841 } 11842 11843 /** 11844 * Bring up the "unexpected error" dialog box for a crashing app. 11845 * Deal with edge cases (intercepts from instrumented applications, 11846 * ActivityController, error intent receivers, that sort of thing). 11847 * @param r the application crashing 11848 * @param crashInfo describing the failure 11849 */ 11850 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11851 long timeMillis = System.currentTimeMillis(); 11852 String shortMsg = crashInfo.exceptionClassName; 11853 String longMsg = crashInfo.exceptionMessage; 11854 String stackTrace = crashInfo.stackTrace; 11855 if (shortMsg != null && longMsg != null) { 11856 longMsg = shortMsg + ": " + longMsg; 11857 } else if (shortMsg != null) { 11858 longMsg = shortMsg; 11859 } 11860 11861 AppErrorResult result = new AppErrorResult(); 11862 synchronized (this) { 11863 if (mController != null) { 11864 try { 11865 String name = r != null ? r.processName : null; 11866 int pid = r != null ? r.pid : Binder.getCallingPid(); 11867 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11868 if (!mController.appCrashed(name, pid, 11869 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11870 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11871 && "Native crash".equals(crashInfo.exceptionClassName)) { 11872 Slog.w(TAG, "Skip killing native crashed app " + name 11873 + "(" + pid + ") during testing"); 11874 } else { 11875 Slog.w(TAG, "Force-killing crashed app " + name 11876 + " at watcher's request"); 11877 if (r != null) { 11878 r.kill("crash", true); 11879 } else { 11880 // Huh. 11881 Process.killProcess(pid); 11882 Process.killProcessGroup(uid, pid); 11883 } 11884 } 11885 return; 11886 } 11887 } catch (RemoteException e) { 11888 mController = null; 11889 Watchdog.getInstance().setActivityController(null); 11890 } 11891 } 11892 11893 final long origId = Binder.clearCallingIdentity(); 11894 11895 // If this process is running instrumentation, finish it. 11896 if (r != null && r.instrumentationClass != null) { 11897 Slog.w(TAG, "Error in app " + r.processName 11898 + " running instrumentation " + r.instrumentationClass + ":"); 11899 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11900 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11901 Bundle info = new Bundle(); 11902 info.putString("shortMsg", shortMsg); 11903 info.putString("longMsg", longMsg); 11904 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11905 Binder.restoreCallingIdentity(origId); 11906 return; 11907 } 11908 11909 // If we can't identify the process or it's already exceeded its crash quota, 11910 // quit right away without showing a crash dialog. 11911 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11912 Binder.restoreCallingIdentity(origId); 11913 return; 11914 } 11915 11916 Message msg = Message.obtain(); 11917 msg.what = SHOW_ERROR_MSG; 11918 HashMap data = new HashMap(); 11919 data.put("result", result); 11920 data.put("app", r); 11921 msg.obj = data; 11922 mHandler.sendMessage(msg); 11923 11924 Binder.restoreCallingIdentity(origId); 11925 } 11926 11927 int res = result.get(); 11928 11929 Intent appErrorIntent = null; 11930 synchronized (this) { 11931 if (r != null && !r.isolated) { 11932 // XXX Can't keep track of crash time for isolated processes, 11933 // since they don't have a persistent identity. 11934 mProcessCrashTimes.put(r.info.processName, r.uid, 11935 SystemClock.uptimeMillis()); 11936 } 11937 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11938 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11939 } 11940 } 11941 11942 if (appErrorIntent != null) { 11943 try { 11944 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11945 } catch (ActivityNotFoundException e) { 11946 Slog.w(TAG, "bug report receiver dissappeared", e); 11947 } 11948 } 11949 } 11950 11951 Intent createAppErrorIntentLocked(ProcessRecord r, 11952 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11953 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11954 if (report == null) { 11955 return null; 11956 } 11957 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11958 result.setComponent(r.errorReportReceiver); 11959 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11960 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11961 return result; 11962 } 11963 11964 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11965 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11966 if (r.errorReportReceiver == null) { 11967 return null; 11968 } 11969 11970 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11971 return null; 11972 } 11973 11974 ApplicationErrorReport report = new ApplicationErrorReport(); 11975 report.packageName = r.info.packageName; 11976 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11977 report.processName = r.processName; 11978 report.time = timeMillis; 11979 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11980 11981 if (r.crashing || r.forceCrashReport) { 11982 report.type = ApplicationErrorReport.TYPE_CRASH; 11983 report.crashInfo = crashInfo; 11984 } else if (r.notResponding) { 11985 report.type = ApplicationErrorReport.TYPE_ANR; 11986 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 11987 11988 report.anrInfo.activity = r.notRespondingReport.tag; 11989 report.anrInfo.cause = r.notRespondingReport.shortMsg; 11990 report.anrInfo.info = r.notRespondingReport.longMsg; 11991 } 11992 11993 return report; 11994 } 11995 11996 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 11997 enforceNotIsolatedCaller("getProcessesInErrorState"); 11998 // assume our apps are happy - lazy create the list 11999 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12000 12001 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12002 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12003 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12004 12005 synchronized (this) { 12006 12007 // iterate across all processes 12008 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12009 ProcessRecord app = mLruProcesses.get(i); 12010 if (!allUsers && app.userId != userId) { 12011 continue; 12012 } 12013 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12014 // This one's in trouble, so we'll generate a report for it 12015 // crashes are higher priority (in case there's a crash *and* an anr) 12016 ActivityManager.ProcessErrorStateInfo report = null; 12017 if (app.crashing) { 12018 report = app.crashingReport; 12019 } else if (app.notResponding) { 12020 report = app.notRespondingReport; 12021 } 12022 12023 if (report != null) { 12024 if (errList == null) { 12025 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12026 } 12027 errList.add(report); 12028 } else { 12029 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12030 " crashing = " + app.crashing + 12031 " notResponding = " + app.notResponding); 12032 } 12033 } 12034 } 12035 } 12036 12037 return errList; 12038 } 12039 12040 static int procStateToImportance(int procState, int memAdj, 12041 ActivityManager.RunningAppProcessInfo currApp) { 12042 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12043 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12044 currApp.lru = memAdj; 12045 } else { 12046 currApp.lru = 0; 12047 } 12048 return imp; 12049 } 12050 12051 private void fillInProcMemInfo(ProcessRecord app, 12052 ActivityManager.RunningAppProcessInfo outInfo) { 12053 outInfo.pid = app.pid; 12054 outInfo.uid = app.info.uid; 12055 if (mHeavyWeightProcess == app) { 12056 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12057 } 12058 if (app.persistent) { 12059 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12060 } 12061 if (app.activities.size() > 0) { 12062 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12063 } 12064 outInfo.lastTrimLevel = app.trimMemoryLevel; 12065 int adj = app.curAdj; 12066 int procState = app.curProcState; 12067 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12068 outInfo.importanceReasonCode = app.adjTypeCode; 12069 outInfo.processState = app.curProcState; 12070 } 12071 12072 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12073 enforceNotIsolatedCaller("getRunningAppProcesses"); 12074 // Lazy instantiation of list 12075 List<ActivityManager.RunningAppProcessInfo> runList = null; 12076 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12077 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12078 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12079 synchronized (this) { 12080 // Iterate across all processes 12081 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12082 ProcessRecord app = mLruProcesses.get(i); 12083 if (!allUsers && app.userId != userId) { 12084 continue; 12085 } 12086 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12087 // Generate process state info for running application 12088 ActivityManager.RunningAppProcessInfo currApp = 12089 new ActivityManager.RunningAppProcessInfo(app.processName, 12090 app.pid, app.getPackageList()); 12091 fillInProcMemInfo(app, currApp); 12092 if (app.adjSource instanceof ProcessRecord) { 12093 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12094 currApp.importanceReasonImportance = 12095 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12096 app.adjSourceProcState); 12097 } else if (app.adjSource instanceof ActivityRecord) { 12098 ActivityRecord r = (ActivityRecord)app.adjSource; 12099 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12100 } 12101 if (app.adjTarget instanceof ComponentName) { 12102 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12103 } 12104 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12105 // + " lru=" + currApp.lru); 12106 if (runList == null) { 12107 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12108 } 12109 runList.add(currApp); 12110 } 12111 } 12112 } 12113 return runList; 12114 } 12115 12116 public List<ApplicationInfo> getRunningExternalApplications() { 12117 enforceNotIsolatedCaller("getRunningExternalApplications"); 12118 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12119 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12120 if (runningApps != null && runningApps.size() > 0) { 12121 Set<String> extList = new HashSet<String>(); 12122 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12123 if (app.pkgList != null) { 12124 for (String pkg : app.pkgList) { 12125 extList.add(pkg); 12126 } 12127 } 12128 } 12129 IPackageManager pm = AppGlobals.getPackageManager(); 12130 for (String pkg : extList) { 12131 try { 12132 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12133 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12134 retList.add(info); 12135 } 12136 } catch (RemoteException e) { 12137 } 12138 } 12139 } 12140 return retList; 12141 } 12142 12143 @Override 12144 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12145 enforceNotIsolatedCaller("getMyMemoryState"); 12146 synchronized (this) { 12147 ProcessRecord proc; 12148 synchronized (mPidsSelfLocked) { 12149 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12150 } 12151 fillInProcMemInfo(proc, outInfo); 12152 } 12153 } 12154 12155 @Override 12156 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12157 if (checkCallingPermission(android.Manifest.permission.DUMP) 12158 != PackageManager.PERMISSION_GRANTED) { 12159 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12160 + Binder.getCallingPid() 12161 + ", uid=" + Binder.getCallingUid() 12162 + " without permission " 12163 + android.Manifest.permission.DUMP); 12164 return; 12165 } 12166 12167 boolean dumpAll = false; 12168 boolean dumpClient = false; 12169 String dumpPackage = null; 12170 12171 int opti = 0; 12172 while (opti < args.length) { 12173 String opt = args[opti]; 12174 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12175 break; 12176 } 12177 opti++; 12178 if ("-a".equals(opt)) { 12179 dumpAll = true; 12180 } else if ("-c".equals(opt)) { 12181 dumpClient = true; 12182 } else if ("-h".equals(opt)) { 12183 pw.println("Activity manager dump options:"); 12184 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12185 pw.println(" cmd may be one of:"); 12186 pw.println(" a[ctivities]: activity stack state"); 12187 pw.println(" r[recents]: recent activities state"); 12188 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12189 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12190 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12191 pw.println(" o[om]: out of memory management"); 12192 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12193 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12194 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12195 pw.println(" service [COMP_SPEC]: service client-side state"); 12196 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12197 pw.println(" all: dump all activities"); 12198 pw.println(" top: dump the top activity"); 12199 pw.println(" write: write all pending state to storage"); 12200 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12201 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12202 pw.println(" a partial substring in a component name, a"); 12203 pw.println(" hex object identifier."); 12204 pw.println(" -a: include all available server state."); 12205 pw.println(" -c: include client state."); 12206 return; 12207 } else { 12208 pw.println("Unknown argument: " + opt + "; use -h for help"); 12209 } 12210 } 12211 12212 long origId = Binder.clearCallingIdentity(); 12213 boolean more = false; 12214 // Is the caller requesting to dump a particular piece of data? 12215 if (opti < args.length) { 12216 String cmd = args[opti]; 12217 opti++; 12218 if ("activities".equals(cmd) || "a".equals(cmd)) { 12219 synchronized (this) { 12220 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12221 } 12222 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12223 synchronized (this) { 12224 dumpRecentsLocked(fd, pw, args, opti, true, null); 12225 } 12226 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12227 String[] newArgs; 12228 String name; 12229 if (opti >= args.length) { 12230 name = null; 12231 newArgs = EMPTY_STRING_ARRAY; 12232 } else { 12233 name = args[opti]; 12234 opti++; 12235 newArgs = new String[args.length - opti]; 12236 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12237 args.length - opti); 12238 } 12239 synchronized (this) { 12240 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12241 } 12242 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12243 String[] newArgs; 12244 String name; 12245 if (opti >= args.length) { 12246 name = null; 12247 newArgs = EMPTY_STRING_ARRAY; 12248 } else { 12249 name = args[opti]; 12250 opti++; 12251 newArgs = new String[args.length - opti]; 12252 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12253 args.length - opti); 12254 } 12255 synchronized (this) { 12256 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12257 } 12258 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12259 String[] newArgs; 12260 String name; 12261 if (opti >= args.length) { 12262 name = null; 12263 newArgs = EMPTY_STRING_ARRAY; 12264 } else { 12265 name = args[opti]; 12266 opti++; 12267 newArgs = new String[args.length - opti]; 12268 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12269 args.length - opti); 12270 } 12271 synchronized (this) { 12272 dumpProcessesLocked(fd, pw, args, opti, true, name); 12273 } 12274 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12275 synchronized (this) { 12276 dumpOomLocked(fd, pw, args, opti, true); 12277 } 12278 } else if ("provider".equals(cmd)) { 12279 String[] newArgs; 12280 String name; 12281 if (opti >= args.length) { 12282 name = null; 12283 newArgs = EMPTY_STRING_ARRAY; 12284 } else { 12285 name = args[opti]; 12286 opti++; 12287 newArgs = new String[args.length - opti]; 12288 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12289 } 12290 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12291 pw.println("No providers match: " + name); 12292 pw.println("Use -h for help."); 12293 } 12294 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12295 synchronized (this) { 12296 dumpProvidersLocked(fd, pw, args, opti, true, null); 12297 } 12298 } else if ("service".equals(cmd)) { 12299 String[] newArgs; 12300 String name; 12301 if (opti >= args.length) { 12302 name = null; 12303 newArgs = EMPTY_STRING_ARRAY; 12304 } else { 12305 name = args[opti]; 12306 opti++; 12307 newArgs = new String[args.length - opti]; 12308 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12309 args.length - opti); 12310 } 12311 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12312 pw.println("No services match: " + name); 12313 pw.println("Use -h for help."); 12314 } 12315 } else if ("package".equals(cmd)) { 12316 String[] newArgs; 12317 if (opti >= args.length) { 12318 pw.println("package: no package name specified"); 12319 pw.println("Use -h for help."); 12320 } else { 12321 dumpPackage = args[opti]; 12322 opti++; 12323 newArgs = new String[args.length - opti]; 12324 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12325 args.length - opti); 12326 args = newArgs; 12327 opti = 0; 12328 more = true; 12329 } 12330 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12331 synchronized (this) { 12332 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12333 } 12334 } else if ("write".equals(cmd)) { 12335 mTaskPersister.flush(); 12336 pw.println("All tasks persisted."); 12337 return; 12338 } else { 12339 // Dumping a single activity? 12340 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12341 pw.println("Bad activity command, or no activities match: " + cmd); 12342 pw.println("Use -h for help."); 12343 } 12344 } 12345 if (!more) { 12346 Binder.restoreCallingIdentity(origId); 12347 return; 12348 } 12349 } 12350 12351 // No piece of data specified, dump everything. 12352 synchronized (this) { 12353 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12354 pw.println(); 12355 if (dumpAll) { 12356 pw.println("-------------------------------------------------------------------------------"); 12357 } 12358 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12359 pw.println(); 12360 if (dumpAll) { 12361 pw.println("-------------------------------------------------------------------------------"); 12362 } 12363 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12364 pw.println(); 12365 if (dumpAll) { 12366 pw.println("-------------------------------------------------------------------------------"); 12367 } 12368 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12369 pw.println(); 12370 if (dumpAll) { 12371 pw.println("-------------------------------------------------------------------------------"); 12372 } 12373 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12374 pw.println(); 12375 if (dumpAll) { 12376 pw.println("-------------------------------------------------------------------------------"); 12377 } 12378 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12379 pw.println(); 12380 if (dumpAll) { 12381 pw.println("-------------------------------------------------------------------------------"); 12382 } 12383 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12384 } 12385 Binder.restoreCallingIdentity(origId); 12386 } 12387 12388 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12389 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12390 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12391 12392 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12393 dumpPackage); 12394 boolean needSep = printedAnything; 12395 12396 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12397 dumpPackage, needSep, " mFocusedActivity: "); 12398 if (printed) { 12399 printedAnything = true; 12400 needSep = false; 12401 } 12402 12403 if (dumpPackage == null) { 12404 if (needSep) { 12405 pw.println(); 12406 } 12407 needSep = true; 12408 printedAnything = true; 12409 mStackSupervisor.dump(pw, " "); 12410 } 12411 12412 if (!printedAnything) { 12413 pw.println(" (nothing)"); 12414 } 12415 } 12416 12417 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12418 int opti, boolean dumpAll, String dumpPackage) { 12419 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12420 12421 boolean printedAnything = false; 12422 12423 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12424 boolean printedHeader = false; 12425 12426 final int N = mRecentTasks.size(); 12427 for (int i=0; i<N; i++) { 12428 TaskRecord tr = mRecentTasks.get(i); 12429 if (dumpPackage != null) { 12430 if (tr.realActivity == null || 12431 !dumpPackage.equals(tr.realActivity)) { 12432 continue; 12433 } 12434 } 12435 if (!printedHeader) { 12436 pw.println(" Recent tasks:"); 12437 printedHeader = true; 12438 printedAnything = true; 12439 } 12440 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12441 pw.println(tr); 12442 if (dumpAll) { 12443 mRecentTasks.get(i).dump(pw, " "); 12444 } 12445 } 12446 } 12447 12448 if (!printedAnything) { 12449 pw.println(" (nothing)"); 12450 } 12451 } 12452 12453 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12454 int opti, boolean dumpAll, String dumpPackage) { 12455 boolean needSep = false; 12456 boolean printedAnything = false; 12457 int numPers = 0; 12458 12459 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12460 12461 if (dumpAll) { 12462 final int NP = mProcessNames.getMap().size(); 12463 for (int ip=0; ip<NP; ip++) { 12464 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12465 final int NA = procs.size(); 12466 for (int ia=0; ia<NA; ia++) { 12467 ProcessRecord r = procs.valueAt(ia); 12468 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12469 continue; 12470 } 12471 if (!needSep) { 12472 pw.println(" All known processes:"); 12473 needSep = true; 12474 printedAnything = true; 12475 } 12476 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12477 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12478 pw.print(" "); pw.println(r); 12479 r.dump(pw, " "); 12480 if (r.persistent) { 12481 numPers++; 12482 } 12483 } 12484 } 12485 } 12486 12487 if (mIsolatedProcesses.size() > 0) { 12488 boolean printed = false; 12489 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12490 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12491 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12492 continue; 12493 } 12494 if (!printed) { 12495 if (needSep) { 12496 pw.println(); 12497 } 12498 pw.println(" Isolated process list (sorted by uid):"); 12499 printedAnything = true; 12500 printed = true; 12501 needSep = true; 12502 } 12503 pw.println(String.format("%sIsolated #%2d: %s", 12504 " ", i, r.toString())); 12505 } 12506 } 12507 12508 if (mLruProcesses.size() > 0) { 12509 if (needSep) { 12510 pw.println(); 12511 } 12512 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12513 pw.print(" total, non-act at "); 12514 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12515 pw.print(", non-svc at "); 12516 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12517 pw.println("):"); 12518 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12519 needSep = true; 12520 printedAnything = true; 12521 } 12522 12523 if (dumpAll || dumpPackage != null) { 12524 synchronized (mPidsSelfLocked) { 12525 boolean printed = false; 12526 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12527 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12528 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12529 continue; 12530 } 12531 if (!printed) { 12532 if (needSep) pw.println(); 12533 needSep = true; 12534 pw.println(" PID mappings:"); 12535 printed = true; 12536 printedAnything = true; 12537 } 12538 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12539 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12540 } 12541 } 12542 } 12543 12544 if (mForegroundProcesses.size() > 0) { 12545 synchronized (mPidsSelfLocked) { 12546 boolean printed = false; 12547 for (int i=0; i<mForegroundProcesses.size(); i++) { 12548 ProcessRecord r = mPidsSelfLocked.get( 12549 mForegroundProcesses.valueAt(i).pid); 12550 if (dumpPackage != null && (r == null 12551 || !r.pkgList.containsKey(dumpPackage))) { 12552 continue; 12553 } 12554 if (!printed) { 12555 if (needSep) pw.println(); 12556 needSep = true; 12557 pw.println(" Foreground Processes:"); 12558 printed = true; 12559 printedAnything = true; 12560 } 12561 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12562 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12563 } 12564 } 12565 } 12566 12567 if (mPersistentStartingProcesses.size() > 0) { 12568 if (needSep) pw.println(); 12569 needSep = true; 12570 printedAnything = true; 12571 pw.println(" Persisent processes that are starting:"); 12572 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12573 "Starting Norm", "Restarting PERS", dumpPackage); 12574 } 12575 12576 if (mRemovedProcesses.size() > 0) { 12577 if (needSep) pw.println(); 12578 needSep = true; 12579 printedAnything = true; 12580 pw.println(" Processes that are being removed:"); 12581 dumpProcessList(pw, this, mRemovedProcesses, " ", 12582 "Removed Norm", "Removed PERS", dumpPackage); 12583 } 12584 12585 if (mProcessesOnHold.size() > 0) { 12586 if (needSep) pw.println(); 12587 needSep = true; 12588 printedAnything = true; 12589 pw.println(" Processes that are on old until the system is ready:"); 12590 dumpProcessList(pw, this, mProcessesOnHold, " ", 12591 "OnHold Norm", "OnHold PERS", dumpPackage); 12592 } 12593 12594 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12595 12596 if (mProcessCrashTimes.getMap().size() > 0) { 12597 boolean printed = false; 12598 long now = SystemClock.uptimeMillis(); 12599 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12600 final int NP = pmap.size(); 12601 for (int ip=0; ip<NP; ip++) { 12602 String pname = pmap.keyAt(ip); 12603 SparseArray<Long> uids = pmap.valueAt(ip); 12604 final int N = uids.size(); 12605 for (int i=0; i<N; i++) { 12606 int puid = uids.keyAt(i); 12607 ProcessRecord r = mProcessNames.get(pname, puid); 12608 if (dumpPackage != null && (r == null 12609 || !r.pkgList.containsKey(dumpPackage))) { 12610 continue; 12611 } 12612 if (!printed) { 12613 if (needSep) pw.println(); 12614 needSep = true; 12615 pw.println(" Time since processes crashed:"); 12616 printed = true; 12617 printedAnything = true; 12618 } 12619 pw.print(" Process "); pw.print(pname); 12620 pw.print(" uid "); pw.print(puid); 12621 pw.print(": last crashed "); 12622 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12623 pw.println(" ago"); 12624 } 12625 } 12626 } 12627 12628 if (mBadProcesses.getMap().size() > 0) { 12629 boolean printed = false; 12630 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12631 final int NP = pmap.size(); 12632 for (int ip=0; ip<NP; ip++) { 12633 String pname = pmap.keyAt(ip); 12634 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12635 final int N = uids.size(); 12636 for (int i=0; i<N; i++) { 12637 int puid = uids.keyAt(i); 12638 ProcessRecord r = mProcessNames.get(pname, puid); 12639 if (dumpPackage != null && (r == null 12640 || !r.pkgList.containsKey(dumpPackage))) { 12641 continue; 12642 } 12643 if (!printed) { 12644 if (needSep) pw.println(); 12645 needSep = true; 12646 pw.println(" Bad processes:"); 12647 printedAnything = true; 12648 } 12649 BadProcessInfo info = uids.valueAt(i); 12650 pw.print(" Bad process "); pw.print(pname); 12651 pw.print(" uid "); pw.print(puid); 12652 pw.print(": crashed at time "); pw.println(info.time); 12653 if (info.shortMsg != null) { 12654 pw.print(" Short msg: "); pw.println(info.shortMsg); 12655 } 12656 if (info.longMsg != null) { 12657 pw.print(" Long msg: "); pw.println(info.longMsg); 12658 } 12659 if (info.stack != null) { 12660 pw.println(" Stack:"); 12661 int lastPos = 0; 12662 for (int pos=0; pos<info.stack.length(); pos++) { 12663 if (info.stack.charAt(pos) == '\n') { 12664 pw.print(" "); 12665 pw.write(info.stack, lastPos, pos-lastPos); 12666 pw.println(); 12667 lastPos = pos+1; 12668 } 12669 } 12670 if (lastPos < info.stack.length()) { 12671 pw.print(" "); 12672 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12673 pw.println(); 12674 } 12675 } 12676 } 12677 } 12678 } 12679 12680 if (dumpPackage == null) { 12681 pw.println(); 12682 needSep = false; 12683 pw.println(" mStartedUsers:"); 12684 for (int i=0; i<mStartedUsers.size(); i++) { 12685 UserStartedState uss = mStartedUsers.valueAt(i); 12686 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12687 pw.print(": "); uss.dump("", pw); 12688 } 12689 pw.print(" mStartedUserArray: ["); 12690 for (int i=0; i<mStartedUserArray.length; i++) { 12691 if (i > 0) pw.print(", "); 12692 pw.print(mStartedUserArray[i]); 12693 } 12694 pw.println("]"); 12695 pw.print(" mUserLru: ["); 12696 for (int i=0; i<mUserLru.size(); i++) { 12697 if (i > 0) pw.print(", "); 12698 pw.print(mUserLru.get(i)); 12699 } 12700 pw.println("]"); 12701 if (dumpAll) { 12702 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12703 } 12704 synchronized (mUserProfileGroupIdsSelfLocked) { 12705 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12706 pw.println(" mUserProfileGroupIds:"); 12707 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12708 pw.print(" User #"); 12709 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12710 pw.print(" -> profile #"); 12711 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12712 } 12713 } 12714 } 12715 } 12716 if (mHomeProcess != null && (dumpPackage == null 12717 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12718 if (needSep) { 12719 pw.println(); 12720 needSep = false; 12721 } 12722 pw.println(" mHomeProcess: " + mHomeProcess); 12723 } 12724 if (mPreviousProcess != null && (dumpPackage == null 12725 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12726 if (needSep) { 12727 pw.println(); 12728 needSep = false; 12729 } 12730 pw.println(" mPreviousProcess: " + mPreviousProcess); 12731 } 12732 if (dumpAll) { 12733 StringBuilder sb = new StringBuilder(128); 12734 sb.append(" mPreviousProcessVisibleTime: "); 12735 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12736 pw.println(sb); 12737 } 12738 if (mHeavyWeightProcess != null && (dumpPackage == null 12739 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12740 if (needSep) { 12741 pw.println(); 12742 needSep = false; 12743 } 12744 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12745 } 12746 if (dumpPackage == null) { 12747 pw.println(" mConfiguration: " + mConfiguration); 12748 } 12749 if (dumpAll) { 12750 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12751 if (mCompatModePackages.getPackages().size() > 0) { 12752 boolean printed = false; 12753 for (Map.Entry<String, Integer> entry 12754 : mCompatModePackages.getPackages().entrySet()) { 12755 String pkg = entry.getKey(); 12756 int mode = entry.getValue(); 12757 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12758 continue; 12759 } 12760 if (!printed) { 12761 pw.println(" mScreenCompatPackages:"); 12762 printed = true; 12763 } 12764 pw.print(" "); pw.print(pkg); pw.print(": "); 12765 pw.print(mode); pw.println(); 12766 } 12767 } 12768 } 12769 if (dumpPackage == null) { 12770 if (mSleeping || mWentToSleep || mLockScreenShown) { 12771 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12772 + " mLockScreenShown " + mLockScreenShown); 12773 } 12774 if (mShuttingDown || mRunningVoice) { 12775 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12776 } 12777 } 12778 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12779 || mOrigWaitForDebugger) { 12780 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12781 || dumpPackage.equals(mOrigDebugApp)) { 12782 if (needSep) { 12783 pw.println(); 12784 needSep = false; 12785 } 12786 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12787 + " mDebugTransient=" + mDebugTransient 12788 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12789 } 12790 } 12791 if (mOpenGlTraceApp != null) { 12792 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12793 if (needSep) { 12794 pw.println(); 12795 needSep = false; 12796 } 12797 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12798 } 12799 } 12800 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12801 || mProfileFd != null) { 12802 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12803 if (needSep) { 12804 pw.println(); 12805 needSep = false; 12806 } 12807 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12808 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12809 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12810 + mAutoStopProfiler); 12811 pw.println(" mProfileType=" + mProfileType); 12812 } 12813 } 12814 if (dumpPackage == null) { 12815 if (mAlwaysFinishActivities || mController != null) { 12816 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12817 + " mController=" + mController); 12818 } 12819 if (dumpAll) { 12820 pw.println(" Total persistent processes: " + numPers); 12821 pw.println(" mProcessesReady=" + mProcessesReady 12822 + " mSystemReady=" + mSystemReady 12823 + " mBooted=" + mBooted 12824 + " mFactoryTest=" + mFactoryTest); 12825 pw.println(" mBooting=" + mBooting 12826 + " mCallFinishBooting=" + mCallFinishBooting 12827 + " mBootAnimationComplete=" + mBootAnimationComplete); 12828 pw.print(" mLastPowerCheckRealtime="); 12829 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12830 pw.println(""); 12831 pw.print(" mLastPowerCheckUptime="); 12832 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12833 pw.println(""); 12834 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12835 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12836 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12837 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12838 + " (" + mLruProcesses.size() + " total)" 12839 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12840 + " mNumServiceProcs=" + mNumServiceProcs 12841 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12842 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12843 + " mLastMemoryLevel" + mLastMemoryLevel 12844 + " mLastNumProcesses" + mLastNumProcesses); 12845 long now = SystemClock.uptimeMillis(); 12846 pw.print(" mLastIdleTime="); 12847 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12848 pw.print(" mLowRamSinceLastIdle="); 12849 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12850 pw.println(); 12851 } 12852 } 12853 12854 if (!printedAnything) { 12855 pw.println(" (nothing)"); 12856 } 12857 } 12858 12859 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12860 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12861 if (mProcessesToGc.size() > 0) { 12862 boolean printed = false; 12863 long now = SystemClock.uptimeMillis(); 12864 for (int i=0; i<mProcessesToGc.size(); i++) { 12865 ProcessRecord proc = mProcessesToGc.get(i); 12866 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12867 continue; 12868 } 12869 if (!printed) { 12870 if (needSep) pw.println(); 12871 needSep = true; 12872 pw.println(" Processes that are waiting to GC:"); 12873 printed = true; 12874 } 12875 pw.print(" Process "); pw.println(proc); 12876 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12877 pw.print(", last gced="); 12878 pw.print(now-proc.lastRequestedGc); 12879 pw.print(" ms ago, last lowMem="); 12880 pw.print(now-proc.lastLowMemory); 12881 pw.println(" ms ago"); 12882 12883 } 12884 } 12885 return needSep; 12886 } 12887 12888 void printOomLevel(PrintWriter pw, String name, int adj) { 12889 pw.print(" "); 12890 if (adj >= 0) { 12891 pw.print(' '); 12892 if (adj < 10) pw.print(' '); 12893 } else { 12894 if (adj > -10) pw.print(' '); 12895 } 12896 pw.print(adj); 12897 pw.print(": "); 12898 pw.print(name); 12899 pw.print(" ("); 12900 pw.print(mProcessList.getMemLevel(adj)/1024); 12901 pw.println(" kB)"); 12902 } 12903 12904 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12905 int opti, boolean dumpAll) { 12906 boolean needSep = false; 12907 12908 if (mLruProcesses.size() > 0) { 12909 if (needSep) pw.println(); 12910 needSep = true; 12911 pw.println(" OOM levels:"); 12912 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12913 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12914 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 12915 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12916 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12917 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12918 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12919 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12920 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12921 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12922 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12923 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12924 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12925 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12926 12927 if (needSep) pw.println(); 12928 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12929 pw.print(" total, non-act at "); 12930 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12931 pw.print(", non-svc at "); 12932 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12933 pw.println("):"); 12934 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12935 needSep = true; 12936 } 12937 12938 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12939 12940 pw.println(); 12941 pw.println(" mHomeProcess: " + mHomeProcess); 12942 pw.println(" mPreviousProcess: " + mPreviousProcess); 12943 if (mHeavyWeightProcess != null) { 12944 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12945 } 12946 12947 return true; 12948 } 12949 12950 /** 12951 * There are three ways to call this: 12952 * - no provider specified: dump all the providers 12953 * - a flattened component name that matched an existing provider was specified as the 12954 * first arg: dump that one provider 12955 * - the first arg isn't the flattened component name of an existing provider: 12956 * dump all providers whose component contains the first arg as a substring 12957 */ 12958 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12959 int opti, boolean dumpAll) { 12960 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12961 } 12962 12963 static class ItemMatcher { 12964 ArrayList<ComponentName> components; 12965 ArrayList<String> strings; 12966 ArrayList<Integer> objects; 12967 boolean all; 12968 12969 ItemMatcher() { 12970 all = true; 12971 } 12972 12973 void build(String name) { 12974 ComponentName componentName = ComponentName.unflattenFromString(name); 12975 if (componentName != null) { 12976 if (components == null) { 12977 components = new ArrayList<ComponentName>(); 12978 } 12979 components.add(componentName); 12980 all = false; 12981 } else { 12982 int objectId = 0; 12983 // Not a '/' separated full component name; maybe an object ID? 12984 try { 12985 objectId = Integer.parseInt(name, 16); 12986 if (objects == null) { 12987 objects = new ArrayList<Integer>(); 12988 } 12989 objects.add(objectId); 12990 all = false; 12991 } catch (RuntimeException e) { 12992 // Not an integer; just do string match. 12993 if (strings == null) { 12994 strings = new ArrayList<String>(); 12995 } 12996 strings.add(name); 12997 all = false; 12998 } 12999 } 13000 } 13001 13002 int build(String[] args, int opti) { 13003 for (; opti<args.length; opti++) { 13004 String name = args[opti]; 13005 if ("--".equals(name)) { 13006 return opti+1; 13007 } 13008 build(name); 13009 } 13010 return opti; 13011 } 13012 13013 boolean match(Object object, ComponentName comp) { 13014 if (all) { 13015 return true; 13016 } 13017 if (components != null) { 13018 for (int i=0; i<components.size(); i++) { 13019 if (components.get(i).equals(comp)) { 13020 return true; 13021 } 13022 } 13023 } 13024 if (objects != null) { 13025 for (int i=0; i<objects.size(); i++) { 13026 if (System.identityHashCode(object) == objects.get(i)) { 13027 return true; 13028 } 13029 } 13030 } 13031 if (strings != null) { 13032 String flat = comp.flattenToString(); 13033 for (int i=0; i<strings.size(); i++) { 13034 if (flat.contains(strings.get(i))) { 13035 return true; 13036 } 13037 } 13038 } 13039 return false; 13040 } 13041 } 13042 13043 /** 13044 * There are three things that cmd can be: 13045 * - a flattened component name that matches an existing activity 13046 * - the cmd arg isn't the flattened component name of an existing activity: 13047 * dump all activity whose component contains the cmd as a substring 13048 * - A hex number of the ActivityRecord object instance. 13049 */ 13050 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13051 int opti, boolean dumpAll) { 13052 ArrayList<ActivityRecord> activities; 13053 13054 synchronized (this) { 13055 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13056 } 13057 13058 if (activities.size() <= 0) { 13059 return false; 13060 } 13061 13062 String[] newArgs = new String[args.length - opti]; 13063 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13064 13065 TaskRecord lastTask = null; 13066 boolean needSep = false; 13067 for (int i=activities.size()-1; i>=0; i--) { 13068 ActivityRecord r = activities.get(i); 13069 if (needSep) { 13070 pw.println(); 13071 } 13072 needSep = true; 13073 synchronized (this) { 13074 if (lastTask != r.task) { 13075 lastTask = r.task; 13076 pw.print("TASK "); pw.print(lastTask.affinity); 13077 pw.print(" id="); pw.println(lastTask.taskId); 13078 if (dumpAll) { 13079 lastTask.dump(pw, " "); 13080 } 13081 } 13082 } 13083 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13084 } 13085 return true; 13086 } 13087 13088 /** 13089 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13090 * there is a thread associated with the activity. 13091 */ 13092 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13093 final ActivityRecord r, String[] args, boolean dumpAll) { 13094 String innerPrefix = prefix + " "; 13095 synchronized (this) { 13096 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13097 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13098 pw.print(" pid="); 13099 if (r.app != null) pw.println(r.app.pid); 13100 else pw.println("(not running)"); 13101 if (dumpAll) { 13102 r.dump(pw, innerPrefix); 13103 } 13104 } 13105 if (r.app != null && r.app.thread != null) { 13106 // flush anything that is already in the PrintWriter since the thread is going 13107 // to write to the file descriptor directly 13108 pw.flush(); 13109 try { 13110 TransferPipe tp = new TransferPipe(); 13111 try { 13112 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13113 r.appToken, innerPrefix, args); 13114 tp.go(fd); 13115 } finally { 13116 tp.kill(); 13117 } 13118 } catch (IOException e) { 13119 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13120 } catch (RemoteException e) { 13121 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13122 } 13123 } 13124 } 13125 13126 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13127 int opti, boolean dumpAll, String dumpPackage) { 13128 boolean needSep = false; 13129 boolean onlyHistory = false; 13130 boolean printedAnything = false; 13131 13132 if ("history".equals(dumpPackage)) { 13133 if (opti < args.length && "-s".equals(args[opti])) { 13134 dumpAll = false; 13135 } 13136 onlyHistory = true; 13137 dumpPackage = null; 13138 } 13139 13140 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13141 if (!onlyHistory && dumpAll) { 13142 if (mRegisteredReceivers.size() > 0) { 13143 boolean printed = false; 13144 Iterator it = mRegisteredReceivers.values().iterator(); 13145 while (it.hasNext()) { 13146 ReceiverList r = (ReceiverList)it.next(); 13147 if (dumpPackage != null && (r.app == null || 13148 !dumpPackage.equals(r.app.info.packageName))) { 13149 continue; 13150 } 13151 if (!printed) { 13152 pw.println(" Registered Receivers:"); 13153 needSep = true; 13154 printed = true; 13155 printedAnything = true; 13156 } 13157 pw.print(" * "); pw.println(r); 13158 r.dump(pw, " "); 13159 } 13160 } 13161 13162 if (mReceiverResolver.dump(pw, needSep ? 13163 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13164 " ", dumpPackage, false)) { 13165 needSep = true; 13166 printedAnything = true; 13167 } 13168 } 13169 13170 for (BroadcastQueue q : mBroadcastQueues) { 13171 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13172 printedAnything |= needSep; 13173 } 13174 13175 needSep = true; 13176 13177 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13178 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13179 if (needSep) { 13180 pw.println(); 13181 } 13182 needSep = true; 13183 printedAnything = true; 13184 pw.print(" Sticky broadcasts for user "); 13185 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13186 StringBuilder sb = new StringBuilder(128); 13187 for (Map.Entry<String, ArrayList<Intent>> ent 13188 : mStickyBroadcasts.valueAt(user).entrySet()) { 13189 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13190 if (dumpAll) { 13191 pw.println(":"); 13192 ArrayList<Intent> intents = ent.getValue(); 13193 final int N = intents.size(); 13194 for (int i=0; i<N; i++) { 13195 sb.setLength(0); 13196 sb.append(" Intent: "); 13197 intents.get(i).toShortString(sb, false, true, false, false); 13198 pw.println(sb.toString()); 13199 Bundle bundle = intents.get(i).getExtras(); 13200 if (bundle != null) { 13201 pw.print(" "); 13202 pw.println(bundle.toString()); 13203 } 13204 } 13205 } else { 13206 pw.println(""); 13207 } 13208 } 13209 } 13210 } 13211 13212 if (!onlyHistory && dumpAll) { 13213 pw.println(); 13214 for (BroadcastQueue queue : mBroadcastQueues) { 13215 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13216 + queue.mBroadcastsScheduled); 13217 } 13218 pw.println(" mHandler:"); 13219 mHandler.dump(new PrintWriterPrinter(pw), " "); 13220 needSep = true; 13221 printedAnything = true; 13222 } 13223 13224 if (!printedAnything) { 13225 pw.println(" (nothing)"); 13226 } 13227 } 13228 13229 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13230 int opti, boolean dumpAll, String dumpPackage) { 13231 boolean needSep; 13232 boolean printedAnything = false; 13233 13234 ItemMatcher matcher = new ItemMatcher(); 13235 matcher.build(args, opti); 13236 13237 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13238 13239 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13240 printedAnything |= needSep; 13241 13242 if (mLaunchingProviders.size() > 0) { 13243 boolean printed = false; 13244 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13245 ContentProviderRecord r = mLaunchingProviders.get(i); 13246 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13247 continue; 13248 } 13249 if (!printed) { 13250 if (needSep) pw.println(); 13251 needSep = true; 13252 pw.println(" Launching content providers:"); 13253 printed = true; 13254 printedAnything = true; 13255 } 13256 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13257 pw.println(r); 13258 } 13259 } 13260 13261 if (mGrantedUriPermissions.size() > 0) { 13262 boolean printed = false; 13263 int dumpUid = -2; 13264 if (dumpPackage != null) { 13265 try { 13266 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13267 } catch (NameNotFoundException e) { 13268 dumpUid = -1; 13269 } 13270 } 13271 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13272 int uid = mGrantedUriPermissions.keyAt(i); 13273 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13274 continue; 13275 } 13276 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13277 if (!printed) { 13278 if (needSep) pw.println(); 13279 needSep = true; 13280 pw.println(" Granted Uri Permissions:"); 13281 printed = true; 13282 printedAnything = true; 13283 } 13284 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13285 for (UriPermission perm : perms.values()) { 13286 pw.print(" "); pw.println(perm); 13287 if (dumpAll) { 13288 perm.dump(pw, " "); 13289 } 13290 } 13291 } 13292 } 13293 13294 if (!printedAnything) { 13295 pw.println(" (nothing)"); 13296 } 13297 } 13298 13299 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13300 int opti, boolean dumpAll, String dumpPackage) { 13301 boolean printed = false; 13302 13303 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13304 13305 if (mIntentSenderRecords.size() > 0) { 13306 Iterator<WeakReference<PendingIntentRecord>> it 13307 = mIntentSenderRecords.values().iterator(); 13308 while (it.hasNext()) { 13309 WeakReference<PendingIntentRecord> ref = it.next(); 13310 PendingIntentRecord rec = ref != null ? ref.get(): null; 13311 if (dumpPackage != null && (rec == null 13312 || !dumpPackage.equals(rec.key.packageName))) { 13313 continue; 13314 } 13315 printed = true; 13316 if (rec != null) { 13317 pw.print(" * "); pw.println(rec); 13318 if (dumpAll) { 13319 rec.dump(pw, " "); 13320 } 13321 } else { 13322 pw.print(" * "); pw.println(ref); 13323 } 13324 } 13325 } 13326 13327 if (!printed) { 13328 pw.println(" (nothing)"); 13329 } 13330 } 13331 13332 private static final int dumpProcessList(PrintWriter pw, 13333 ActivityManagerService service, List list, 13334 String prefix, String normalLabel, String persistentLabel, 13335 String dumpPackage) { 13336 int numPers = 0; 13337 final int N = list.size()-1; 13338 for (int i=N; i>=0; i--) { 13339 ProcessRecord r = (ProcessRecord)list.get(i); 13340 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13341 continue; 13342 } 13343 pw.println(String.format("%s%s #%2d: %s", 13344 prefix, (r.persistent ? persistentLabel : normalLabel), 13345 i, r.toString())); 13346 if (r.persistent) { 13347 numPers++; 13348 } 13349 } 13350 return numPers; 13351 } 13352 13353 private static final boolean dumpProcessOomList(PrintWriter pw, 13354 ActivityManagerService service, List<ProcessRecord> origList, 13355 String prefix, String normalLabel, String persistentLabel, 13356 boolean inclDetails, String dumpPackage) { 13357 13358 ArrayList<Pair<ProcessRecord, Integer>> list 13359 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13360 for (int i=0; i<origList.size(); i++) { 13361 ProcessRecord r = origList.get(i); 13362 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13363 continue; 13364 } 13365 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13366 } 13367 13368 if (list.size() <= 0) { 13369 return false; 13370 } 13371 13372 Comparator<Pair<ProcessRecord, Integer>> comparator 13373 = new Comparator<Pair<ProcessRecord, Integer>>() { 13374 @Override 13375 public int compare(Pair<ProcessRecord, Integer> object1, 13376 Pair<ProcessRecord, Integer> object2) { 13377 if (object1.first.setAdj != object2.first.setAdj) { 13378 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13379 } 13380 if (object1.second.intValue() != object2.second.intValue()) { 13381 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13382 } 13383 return 0; 13384 } 13385 }; 13386 13387 Collections.sort(list, comparator); 13388 13389 final long curRealtime = SystemClock.elapsedRealtime(); 13390 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13391 final long curUptime = SystemClock.uptimeMillis(); 13392 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13393 13394 for (int i=list.size()-1; i>=0; i--) { 13395 ProcessRecord r = list.get(i).first; 13396 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13397 char schedGroup; 13398 switch (r.setSchedGroup) { 13399 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13400 schedGroup = 'B'; 13401 break; 13402 case Process.THREAD_GROUP_DEFAULT: 13403 schedGroup = 'F'; 13404 break; 13405 default: 13406 schedGroup = '?'; 13407 break; 13408 } 13409 char foreground; 13410 if (r.foregroundActivities) { 13411 foreground = 'A'; 13412 } else if (r.foregroundServices) { 13413 foreground = 'S'; 13414 } else { 13415 foreground = ' '; 13416 } 13417 String procState = ProcessList.makeProcStateString(r.curProcState); 13418 pw.print(prefix); 13419 pw.print(r.persistent ? persistentLabel : normalLabel); 13420 pw.print(" #"); 13421 int num = (origList.size()-1)-list.get(i).second; 13422 if (num < 10) pw.print(' '); 13423 pw.print(num); 13424 pw.print(": "); 13425 pw.print(oomAdj); 13426 pw.print(' '); 13427 pw.print(schedGroup); 13428 pw.print('/'); 13429 pw.print(foreground); 13430 pw.print('/'); 13431 pw.print(procState); 13432 pw.print(" trm:"); 13433 if (r.trimMemoryLevel < 10) pw.print(' '); 13434 pw.print(r.trimMemoryLevel); 13435 pw.print(' '); 13436 pw.print(r.toShortString()); 13437 pw.print(" ("); 13438 pw.print(r.adjType); 13439 pw.println(')'); 13440 if (r.adjSource != null || r.adjTarget != null) { 13441 pw.print(prefix); 13442 pw.print(" "); 13443 if (r.adjTarget instanceof ComponentName) { 13444 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13445 } else if (r.adjTarget != null) { 13446 pw.print(r.adjTarget.toString()); 13447 } else { 13448 pw.print("{null}"); 13449 } 13450 pw.print("<="); 13451 if (r.adjSource instanceof ProcessRecord) { 13452 pw.print("Proc{"); 13453 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13454 pw.println("}"); 13455 } else if (r.adjSource != null) { 13456 pw.println(r.adjSource.toString()); 13457 } else { 13458 pw.println("{null}"); 13459 } 13460 } 13461 if (inclDetails) { 13462 pw.print(prefix); 13463 pw.print(" "); 13464 pw.print("oom: max="); pw.print(r.maxAdj); 13465 pw.print(" curRaw="); pw.print(r.curRawAdj); 13466 pw.print(" setRaw="); pw.print(r.setRawAdj); 13467 pw.print(" cur="); pw.print(r.curAdj); 13468 pw.print(" set="); pw.println(r.setAdj); 13469 pw.print(prefix); 13470 pw.print(" "); 13471 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13472 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13473 pw.print(" lastPss="); pw.print(r.lastPss); 13474 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13475 pw.print(prefix); 13476 pw.print(" "); 13477 pw.print("cached="); pw.print(r.cached); 13478 pw.print(" empty="); pw.print(r.empty); 13479 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13480 13481 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13482 if (r.lastWakeTime != 0) { 13483 long wtime; 13484 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13485 synchronized (stats) { 13486 wtime = stats.getProcessWakeTime(r.info.uid, 13487 r.pid, curRealtime); 13488 } 13489 long timeUsed = wtime - r.lastWakeTime; 13490 pw.print(prefix); 13491 pw.print(" "); 13492 pw.print("keep awake over "); 13493 TimeUtils.formatDuration(realtimeSince, pw); 13494 pw.print(" used "); 13495 TimeUtils.formatDuration(timeUsed, pw); 13496 pw.print(" ("); 13497 pw.print((timeUsed*100)/realtimeSince); 13498 pw.println("%)"); 13499 } 13500 if (r.lastCpuTime != 0) { 13501 long timeUsed = r.curCpuTime - r.lastCpuTime; 13502 pw.print(prefix); 13503 pw.print(" "); 13504 pw.print("run cpu over "); 13505 TimeUtils.formatDuration(uptimeSince, pw); 13506 pw.print(" used "); 13507 TimeUtils.formatDuration(timeUsed, pw); 13508 pw.print(" ("); 13509 pw.print((timeUsed*100)/uptimeSince); 13510 pw.println("%)"); 13511 } 13512 } 13513 } 13514 } 13515 return true; 13516 } 13517 13518 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13519 String[] args) { 13520 ArrayList<ProcessRecord> procs; 13521 synchronized (this) { 13522 if (args != null && args.length > start 13523 && args[start].charAt(0) != '-') { 13524 procs = new ArrayList<ProcessRecord>(); 13525 int pid = -1; 13526 try { 13527 pid = Integer.parseInt(args[start]); 13528 } catch (NumberFormatException e) { 13529 } 13530 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13531 ProcessRecord proc = mLruProcesses.get(i); 13532 if (proc.pid == pid) { 13533 procs.add(proc); 13534 } else if (allPkgs && proc.pkgList != null 13535 && proc.pkgList.containsKey(args[start])) { 13536 procs.add(proc); 13537 } else if (proc.processName.equals(args[start])) { 13538 procs.add(proc); 13539 } 13540 } 13541 if (procs.size() <= 0) { 13542 return null; 13543 } 13544 } else { 13545 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13546 } 13547 } 13548 return procs; 13549 } 13550 13551 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13552 PrintWriter pw, String[] args) { 13553 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13554 if (procs == null) { 13555 pw.println("No process found for: " + args[0]); 13556 return; 13557 } 13558 13559 long uptime = SystemClock.uptimeMillis(); 13560 long realtime = SystemClock.elapsedRealtime(); 13561 pw.println("Applications Graphics Acceleration Info:"); 13562 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13563 13564 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13565 ProcessRecord r = procs.get(i); 13566 if (r.thread != null) { 13567 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13568 pw.flush(); 13569 try { 13570 TransferPipe tp = new TransferPipe(); 13571 try { 13572 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13573 tp.go(fd); 13574 } finally { 13575 tp.kill(); 13576 } 13577 } catch (IOException e) { 13578 pw.println("Failure while dumping the app: " + r); 13579 pw.flush(); 13580 } catch (RemoteException e) { 13581 pw.println("Got a RemoteException while dumping the app " + r); 13582 pw.flush(); 13583 } 13584 } 13585 } 13586 } 13587 13588 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13589 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13590 if (procs == null) { 13591 pw.println("No process found for: " + args[0]); 13592 return; 13593 } 13594 13595 pw.println("Applications Database Info:"); 13596 13597 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13598 ProcessRecord r = procs.get(i); 13599 if (r.thread != null) { 13600 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13601 pw.flush(); 13602 try { 13603 TransferPipe tp = new TransferPipe(); 13604 try { 13605 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13606 tp.go(fd); 13607 } finally { 13608 tp.kill(); 13609 } 13610 } catch (IOException e) { 13611 pw.println("Failure while dumping the app: " + r); 13612 pw.flush(); 13613 } catch (RemoteException e) { 13614 pw.println("Got a RemoteException while dumping the app " + r); 13615 pw.flush(); 13616 } 13617 } 13618 } 13619 } 13620 13621 final static class MemItem { 13622 final boolean isProc; 13623 final String label; 13624 final String shortLabel; 13625 final long pss; 13626 final int id; 13627 final boolean hasActivities; 13628 ArrayList<MemItem> subitems; 13629 13630 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13631 boolean _hasActivities) { 13632 isProc = true; 13633 label = _label; 13634 shortLabel = _shortLabel; 13635 pss = _pss; 13636 id = _id; 13637 hasActivities = _hasActivities; 13638 } 13639 13640 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13641 isProc = false; 13642 label = _label; 13643 shortLabel = _shortLabel; 13644 pss = _pss; 13645 id = _id; 13646 hasActivities = false; 13647 } 13648 } 13649 13650 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13651 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13652 if (sort && !isCompact) { 13653 Collections.sort(items, new Comparator<MemItem>() { 13654 @Override 13655 public int compare(MemItem lhs, MemItem rhs) { 13656 if (lhs.pss < rhs.pss) { 13657 return 1; 13658 } else if (lhs.pss > rhs.pss) { 13659 return -1; 13660 } 13661 return 0; 13662 } 13663 }); 13664 } 13665 13666 for (int i=0; i<items.size(); i++) { 13667 MemItem mi = items.get(i); 13668 if (!isCompact) { 13669 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13670 } else if (mi.isProc) { 13671 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13672 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13673 pw.println(mi.hasActivities ? ",a" : ",e"); 13674 } else { 13675 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13676 pw.println(mi.pss); 13677 } 13678 if (mi.subitems != null) { 13679 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13680 true, isCompact); 13681 } 13682 } 13683 } 13684 13685 // These are in KB. 13686 static final long[] DUMP_MEM_BUCKETS = new long[] { 13687 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13688 120*1024, 160*1024, 200*1024, 13689 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13690 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13691 }; 13692 13693 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13694 boolean stackLike) { 13695 int start = label.lastIndexOf('.'); 13696 if (start >= 0) start++; 13697 else start = 0; 13698 int end = label.length(); 13699 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13700 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13701 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13702 out.append(bucket); 13703 out.append(stackLike ? "MB." : "MB "); 13704 out.append(label, start, end); 13705 return; 13706 } 13707 } 13708 out.append(memKB/1024); 13709 out.append(stackLike ? "MB." : "MB "); 13710 out.append(label, start, end); 13711 } 13712 13713 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13714 ProcessList.NATIVE_ADJ, 13715 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13716 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13717 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13718 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13719 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13720 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13721 }; 13722 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13723 "Native", 13724 "System", "Persistent", "Persistent Service", "Foreground", 13725 "Visible", "Perceptible", 13726 "Heavy Weight", "Backup", 13727 "A Services", "Home", 13728 "Previous", "B Services", "Cached" 13729 }; 13730 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13731 "native", 13732 "sys", "pers", "persvc", "fore", 13733 "vis", "percept", 13734 "heavy", "backup", 13735 "servicea", "home", 13736 "prev", "serviceb", "cached" 13737 }; 13738 13739 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13740 long realtime, boolean isCheckinRequest, boolean isCompact) { 13741 if (isCheckinRequest || isCompact) { 13742 // short checkin version 13743 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13744 } else { 13745 pw.println("Applications Memory Usage (kB):"); 13746 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13747 } 13748 } 13749 13750 private static final int KSM_SHARED = 0; 13751 private static final int KSM_SHARING = 1; 13752 private static final int KSM_UNSHARED = 2; 13753 private static final int KSM_VOLATILE = 3; 13754 13755 private final long[] getKsmInfo() { 13756 long[] longOut = new long[4]; 13757 final int[] SINGLE_LONG_FORMAT = new int[] { 13758 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13759 }; 13760 long[] longTmp = new long[1]; 13761 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13762 SINGLE_LONG_FORMAT, null, longTmp, null); 13763 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13764 longTmp[0] = 0; 13765 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13766 SINGLE_LONG_FORMAT, null, longTmp, null); 13767 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13768 longTmp[0] = 0; 13769 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13770 SINGLE_LONG_FORMAT, null, longTmp, null); 13771 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13772 longTmp[0] = 0; 13773 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13774 SINGLE_LONG_FORMAT, null, longTmp, null); 13775 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13776 return longOut; 13777 } 13778 13779 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13780 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13781 boolean dumpDetails = false; 13782 boolean dumpFullDetails = false; 13783 boolean dumpDalvik = false; 13784 boolean oomOnly = false; 13785 boolean isCompact = false; 13786 boolean localOnly = false; 13787 boolean packages = false; 13788 13789 int opti = 0; 13790 while (opti < args.length) { 13791 String opt = args[opti]; 13792 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13793 break; 13794 } 13795 opti++; 13796 if ("-a".equals(opt)) { 13797 dumpDetails = true; 13798 dumpFullDetails = true; 13799 dumpDalvik = true; 13800 } else if ("-d".equals(opt)) { 13801 dumpDalvik = true; 13802 } else if ("-c".equals(opt)) { 13803 isCompact = true; 13804 } else if ("--oom".equals(opt)) { 13805 oomOnly = true; 13806 } else if ("--local".equals(opt)) { 13807 localOnly = true; 13808 } else if ("--package".equals(opt)) { 13809 packages = true; 13810 } else if ("-h".equals(opt)) { 13811 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13812 pw.println(" -a: include all available information for each process."); 13813 pw.println(" -d: include dalvik details when dumping process details."); 13814 pw.println(" -c: dump in a compact machine-parseable representation."); 13815 pw.println(" --oom: only show processes organized by oom adj."); 13816 pw.println(" --local: only collect details locally, don't call process."); 13817 pw.println(" --package: interpret process arg as package, dumping all"); 13818 pw.println(" processes that have loaded that package."); 13819 pw.println("If [process] is specified it can be the name or "); 13820 pw.println("pid of a specific process to dump."); 13821 return; 13822 } else { 13823 pw.println("Unknown argument: " + opt + "; use -h for help"); 13824 } 13825 } 13826 13827 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13828 long uptime = SystemClock.uptimeMillis(); 13829 long realtime = SystemClock.elapsedRealtime(); 13830 final long[] tmpLong = new long[1]; 13831 13832 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13833 if (procs == null) { 13834 // No Java processes. Maybe they want to print a native process. 13835 if (args != null && args.length > opti 13836 && args[opti].charAt(0) != '-') { 13837 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13838 = new ArrayList<ProcessCpuTracker.Stats>(); 13839 updateCpuStatsNow(); 13840 int findPid = -1; 13841 try { 13842 findPid = Integer.parseInt(args[opti]); 13843 } catch (NumberFormatException e) { 13844 } 13845 synchronized (mProcessCpuTracker) { 13846 final int N = mProcessCpuTracker.countStats(); 13847 for (int i=0; i<N; i++) { 13848 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13849 if (st.pid == findPid || (st.baseName != null 13850 && st.baseName.equals(args[opti]))) { 13851 nativeProcs.add(st); 13852 } 13853 } 13854 } 13855 if (nativeProcs.size() > 0) { 13856 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13857 isCompact); 13858 Debug.MemoryInfo mi = null; 13859 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13860 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13861 final int pid = r.pid; 13862 if (!isCheckinRequest && dumpDetails) { 13863 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13864 } 13865 if (mi == null) { 13866 mi = new Debug.MemoryInfo(); 13867 } 13868 if (dumpDetails || (!brief && !oomOnly)) { 13869 Debug.getMemoryInfo(pid, mi); 13870 } else { 13871 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13872 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13873 } 13874 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13875 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13876 if (isCheckinRequest) { 13877 pw.println(); 13878 } 13879 } 13880 return; 13881 } 13882 } 13883 pw.println("No process found for: " + args[opti]); 13884 return; 13885 } 13886 13887 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 13888 dumpDetails = true; 13889 } 13890 13891 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13892 13893 String[] innerArgs = new String[args.length-opti]; 13894 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13895 13896 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13897 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13898 long nativePss=0, dalvikPss=0, otherPss=0; 13899 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13900 13901 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13902 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13903 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13904 13905 long totalPss = 0; 13906 long cachedPss = 0; 13907 13908 Debug.MemoryInfo mi = null; 13909 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13910 final ProcessRecord r = procs.get(i); 13911 final IApplicationThread thread; 13912 final int pid; 13913 final int oomAdj; 13914 final boolean hasActivities; 13915 synchronized (this) { 13916 thread = r.thread; 13917 pid = r.pid; 13918 oomAdj = r.getSetAdjWithServices(); 13919 hasActivities = r.activities.size() > 0; 13920 } 13921 if (thread != null) { 13922 if (!isCheckinRequest && dumpDetails) { 13923 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13924 } 13925 if (mi == null) { 13926 mi = new Debug.MemoryInfo(); 13927 } 13928 if (dumpDetails || (!brief && !oomOnly)) { 13929 Debug.getMemoryInfo(pid, mi); 13930 } else { 13931 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13932 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13933 } 13934 if (dumpDetails) { 13935 if (localOnly) { 13936 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13937 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13938 if (isCheckinRequest) { 13939 pw.println(); 13940 } 13941 } else { 13942 try { 13943 pw.flush(); 13944 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13945 dumpDalvik, innerArgs); 13946 } catch (RemoteException e) { 13947 if (!isCheckinRequest) { 13948 pw.println("Got RemoteException!"); 13949 pw.flush(); 13950 } 13951 } 13952 } 13953 } 13954 13955 final long myTotalPss = mi.getTotalPss(); 13956 final long myTotalUss = mi.getTotalUss(); 13957 13958 synchronized (this) { 13959 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13960 // Record this for posterity if the process has been stable. 13961 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13962 } 13963 } 13964 13965 if (!isCheckinRequest && mi != null) { 13966 totalPss += myTotalPss; 13967 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13968 (hasActivities ? " / activities)" : ")"), 13969 r.processName, myTotalPss, pid, hasActivities); 13970 procMems.add(pssItem); 13971 procMemsMap.put(pid, pssItem); 13972 13973 nativePss += mi.nativePss; 13974 dalvikPss += mi.dalvikPss; 13975 otherPss += mi.otherPss; 13976 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13977 long mem = mi.getOtherPss(j); 13978 miscPss[j] += mem; 13979 otherPss -= mem; 13980 } 13981 13982 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13983 cachedPss += myTotalPss; 13984 } 13985 13986 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13987 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13988 || oomIndex == (oomPss.length-1)) { 13989 oomPss[oomIndex] += myTotalPss; 13990 if (oomProcs[oomIndex] == null) { 13991 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13992 } 13993 oomProcs[oomIndex].add(pssItem); 13994 break; 13995 } 13996 } 13997 } 13998 } 13999 } 14000 14001 long nativeProcTotalPss = 0; 14002 14003 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14004 // If we are showing aggregations, also look for native processes to 14005 // include so that our aggregations are more accurate. 14006 updateCpuStatsNow(); 14007 synchronized (mProcessCpuTracker) { 14008 final int N = mProcessCpuTracker.countStats(); 14009 for (int i=0; i<N; i++) { 14010 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14011 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14012 if (mi == null) { 14013 mi = new Debug.MemoryInfo(); 14014 } 14015 if (!brief && !oomOnly) { 14016 Debug.getMemoryInfo(st.pid, mi); 14017 } else { 14018 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14019 mi.nativePrivateDirty = (int)tmpLong[0]; 14020 } 14021 14022 final long myTotalPss = mi.getTotalPss(); 14023 totalPss += myTotalPss; 14024 nativeProcTotalPss += myTotalPss; 14025 14026 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14027 st.name, myTotalPss, st.pid, false); 14028 procMems.add(pssItem); 14029 14030 nativePss += mi.nativePss; 14031 dalvikPss += mi.dalvikPss; 14032 otherPss += mi.otherPss; 14033 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14034 long mem = mi.getOtherPss(j); 14035 miscPss[j] += mem; 14036 otherPss -= mem; 14037 } 14038 oomPss[0] += myTotalPss; 14039 if (oomProcs[0] == null) { 14040 oomProcs[0] = new ArrayList<MemItem>(); 14041 } 14042 oomProcs[0].add(pssItem); 14043 } 14044 } 14045 } 14046 14047 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14048 14049 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14050 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14051 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14052 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14053 String label = Debug.MemoryInfo.getOtherLabel(j); 14054 catMems.add(new MemItem(label, label, miscPss[j], j)); 14055 } 14056 14057 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14058 for (int j=0; j<oomPss.length; j++) { 14059 if (oomPss[j] != 0) { 14060 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14061 : DUMP_MEM_OOM_LABEL[j]; 14062 MemItem item = new MemItem(label, label, oomPss[j], 14063 DUMP_MEM_OOM_ADJ[j]); 14064 item.subitems = oomProcs[j]; 14065 oomMems.add(item); 14066 } 14067 } 14068 14069 if (!brief && !oomOnly && !isCompact) { 14070 pw.println(); 14071 pw.println("Total PSS by process:"); 14072 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14073 pw.println(); 14074 } 14075 if (!isCompact) { 14076 pw.println("Total PSS by OOM adjustment:"); 14077 } 14078 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14079 if (!brief && !oomOnly) { 14080 PrintWriter out = categoryPw != null ? categoryPw : pw; 14081 if (!isCompact) { 14082 out.println(); 14083 out.println("Total PSS by category:"); 14084 } 14085 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14086 } 14087 if (!isCompact) { 14088 pw.println(); 14089 } 14090 MemInfoReader memInfo = new MemInfoReader(); 14091 memInfo.readMemInfo(); 14092 if (nativeProcTotalPss > 0) { 14093 synchronized (this) { 14094 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14095 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14096 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14097 } 14098 } 14099 if (!brief) { 14100 if (!isCompact) { 14101 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14102 pw.print(" kB (status "); 14103 switch (mLastMemoryLevel) { 14104 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14105 pw.println("normal)"); 14106 break; 14107 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14108 pw.println("moderate)"); 14109 break; 14110 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14111 pw.println("low)"); 14112 break; 14113 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14114 pw.println("critical)"); 14115 break; 14116 default: 14117 pw.print(mLastMemoryLevel); 14118 pw.println(")"); 14119 break; 14120 } 14121 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14122 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14123 pw.print(cachedPss); pw.print(" cached pss + "); 14124 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14125 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14126 } else { 14127 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14128 pw.print(cachedPss + memInfo.getCachedSizeKb() 14129 + memInfo.getFreeSizeKb()); pw.print(","); 14130 pw.println(totalPss - cachedPss); 14131 } 14132 } 14133 if (!isCompact) { 14134 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14135 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14136 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14137 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14138 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14139 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14140 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14141 } 14142 if (!brief) { 14143 if (memInfo.getZramTotalSizeKb() != 0) { 14144 if (!isCompact) { 14145 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14146 pw.print(" kB physical used for "); 14147 pw.print(memInfo.getSwapTotalSizeKb() 14148 - memInfo.getSwapFreeSizeKb()); 14149 pw.print(" kB in swap ("); 14150 pw.print(memInfo.getSwapTotalSizeKb()); 14151 pw.println(" kB total swap)"); 14152 } else { 14153 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14154 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14155 pw.println(memInfo.getSwapFreeSizeKb()); 14156 } 14157 } 14158 final long[] ksm = getKsmInfo(); 14159 if (!isCompact) { 14160 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14161 || ksm[KSM_VOLATILE] != 0) { 14162 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14163 pw.print(" kB saved from shared "); 14164 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14165 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14166 pw.print(" kB unshared; "); 14167 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14168 } 14169 pw.print(" Tuning: "); 14170 pw.print(ActivityManager.staticGetMemoryClass()); 14171 pw.print(" (large "); 14172 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14173 pw.print("), oom "); 14174 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14175 pw.print(" kB"); 14176 pw.print(", restore limit "); 14177 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14178 pw.print(" kB"); 14179 if (ActivityManager.isLowRamDeviceStatic()) { 14180 pw.print(" (low-ram)"); 14181 } 14182 if (ActivityManager.isHighEndGfx()) { 14183 pw.print(" (high-end-gfx)"); 14184 } 14185 pw.println(); 14186 } else { 14187 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14188 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14189 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14190 pw.print("tuning,"); 14191 pw.print(ActivityManager.staticGetMemoryClass()); 14192 pw.print(','); 14193 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14194 pw.print(','); 14195 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14196 if (ActivityManager.isLowRamDeviceStatic()) { 14197 pw.print(",low-ram"); 14198 } 14199 if (ActivityManager.isHighEndGfx()) { 14200 pw.print(",high-end-gfx"); 14201 } 14202 pw.println(); 14203 } 14204 } 14205 } 14206 } 14207 14208 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14209 String name) { 14210 sb.append(" "); 14211 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14212 sb.append(' '); 14213 sb.append(ProcessList.makeProcStateString(procState)); 14214 sb.append(' '); 14215 ProcessList.appendRamKb(sb, pss); 14216 sb.append(" kB: "); 14217 sb.append(name); 14218 } 14219 14220 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14221 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name); 14222 sb.append(" ("); 14223 sb.append(mi.pid); 14224 sb.append(") "); 14225 sb.append(mi.adjType); 14226 sb.append('\n'); 14227 if (mi.adjReason != null) { 14228 sb.append(" "); 14229 sb.append(mi.adjReason); 14230 sb.append('\n'); 14231 } 14232 } 14233 14234 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14235 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14236 for (int i=0, N=memInfos.size(); i<N; i++) { 14237 ProcessMemInfo mi = memInfos.get(i); 14238 infoMap.put(mi.pid, mi); 14239 } 14240 updateCpuStatsNow(); 14241 synchronized (mProcessCpuTracker) { 14242 final int N = mProcessCpuTracker.countStats(); 14243 for (int i=0; i<N; i++) { 14244 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14245 if (st.vsize > 0) { 14246 long pss = Debug.getPss(st.pid, null); 14247 if (pss > 0) { 14248 if (infoMap.indexOfKey(st.pid) < 0) { 14249 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14250 ProcessList.NATIVE_ADJ, -1, "native", null); 14251 mi.pss = pss; 14252 memInfos.add(mi); 14253 } 14254 } 14255 } 14256 } 14257 } 14258 14259 long totalPss = 0; 14260 for (int i=0, N=memInfos.size(); i<N; i++) { 14261 ProcessMemInfo mi = memInfos.get(i); 14262 if (mi.pss == 0) { 14263 mi.pss = Debug.getPss(mi.pid, null); 14264 } 14265 totalPss += mi.pss; 14266 } 14267 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14268 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14269 if (lhs.oomAdj != rhs.oomAdj) { 14270 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14271 } 14272 if (lhs.pss != rhs.pss) { 14273 return lhs.pss < rhs.pss ? 1 : -1; 14274 } 14275 return 0; 14276 } 14277 }); 14278 14279 StringBuilder tag = new StringBuilder(128); 14280 StringBuilder stack = new StringBuilder(128); 14281 tag.append("Low on memory -- "); 14282 appendMemBucket(tag, totalPss, "total", false); 14283 appendMemBucket(stack, totalPss, "total", true); 14284 14285 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14286 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14287 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14288 14289 boolean firstLine = true; 14290 int lastOomAdj = Integer.MIN_VALUE; 14291 long extraNativeRam = 0; 14292 long cachedPss = 0; 14293 for (int i=0, N=memInfos.size(); i<N; i++) { 14294 ProcessMemInfo mi = memInfos.get(i); 14295 14296 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14297 cachedPss += mi.pss; 14298 } 14299 14300 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14301 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14302 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14303 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14304 if (lastOomAdj != mi.oomAdj) { 14305 lastOomAdj = mi.oomAdj; 14306 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14307 tag.append(" / "); 14308 } 14309 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14310 if (firstLine) { 14311 stack.append(":"); 14312 firstLine = false; 14313 } 14314 stack.append("\n\t at "); 14315 } else { 14316 stack.append("$"); 14317 } 14318 } else { 14319 tag.append(" "); 14320 stack.append("$"); 14321 } 14322 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14323 appendMemBucket(tag, mi.pss, mi.name, false); 14324 } 14325 appendMemBucket(stack, mi.pss, mi.name, true); 14326 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14327 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14328 stack.append("("); 14329 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14330 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14331 stack.append(DUMP_MEM_OOM_LABEL[k]); 14332 stack.append(":"); 14333 stack.append(DUMP_MEM_OOM_ADJ[k]); 14334 } 14335 } 14336 stack.append(")"); 14337 } 14338 } 14339 14340 appendMemInfo(fullNativeBuilder, mi); 14341 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14342 // The short form only has native processes that are >= 1MB. 14343 if (mi.pss >= 1000) { 14344 appendMemInfo(shortNativeBuilder, mi); 14345 } else { 14346 extraNativeRam += mi.pss; 14347 } 14348 } else { 14349 // Short form has all other details, but if we have collected RAM 14350 // from smaller native processes let's dump a summary of that. 14351 if (extraNativeRam > 0) { 14352 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14353 -1, extraNativeRam, "(Other native)"); 14354 shortNativeBuilder.append('\n'); 14355 extraNativeRam = 0; 14356 } 14357 appendMemInfo(fullJavaBuilder, mi); 14358 } 14359 } 14360 14361 fullJavaBuilder.append(" "); 14362 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14363 fullJavaBuilder.append(" kB: TOTAL\n"); 14364 14365 MemInfoReader memInfo = new MemInfoReader(); 14366 memInfo.readMemInfo(); 14367 final long[] infos = memInfo.getRawInfo(); 14368 14369 StringBuilder memInfoBuilder = new StringBuilder(1024); 14370 Debug.getMemInfo(infos); 14371 memInfoBuilder.append(" MemInfo: "); 14372 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14373 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14374 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14375 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14376 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14377 memInfoBuilder.append(" "); 14378 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14379 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14380 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14381 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14382 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14383 memInfoBuilder.append(" ZRAM: "); 14384 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14385 memInfoBuilder.append(" kB RAM, "); 14386 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14387 memInfoBuilder.append(" kB swap total, "); 14388 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14389 memInfoBuilder.append(" kB swap free\n"); 14390 } 14391 final long[] ksm = getKsmInfo(); 14392 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14393 || ksm[KSM_VOLATILE] != 0) { 14394 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14395 memInfoBuilder.append(" kB saved from shared "); 14396 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14397 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14398 memInfoBuilder.append(" kB unshared; "); 14399 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14400 } 14401 memInfoBuilder.append(" Free RAM: "); 14402 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14403 + memInfo.getFreeSizeKb()); 14404 memInfoBuilder.append(" kB\n"); 14405 memInfoBuilder.append(" Used RAM: "); 14406 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14407 memInfoBuilder.append(" kB\n"); 14408 memInfoBuilder.append(" Lost RAM: "); 14409 memInfoBuilder.append(memInfo.getTotalSizeKb() 14410 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14411 - memInfo.getKernelUsedSizeKb()); 14412 memInfoBuilder.append(" kB\n"); 14413 Slog.i(TAG, "Low on memory:"); 14414 Slog.i(TAG, shortNativeBuilder.toString()); 14415 Slog.i(TAG, fullJavaBuilder.toString()); 14416 Slog.i(TAG, memInfoBuilder.toString()); 14417 14418 StringBuilder dropBuilder = new StringBuilder(1024); 14419 /* 14420 StringWriter oomSw = new StringWriter(); 14421 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14422 StringWriter catSw = new StringWriter(); 14423 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14424 String[] emptyArgs = new String[] { }; 14425 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14426 oomPw.flush(); 14427 String oomString = oomSw.toString(); 14428 */ 14429 dropBuilder.append("Low on memory:"); 14430 dropBuilder.append(stack); 14431 dropBuilder.append('\n'); 14432 dropBuilder.append(fullNativeBuilder); 14433 dropBuilder.append(fullJavaBuilder); 14434 dropBuilder.append('\n'); 14435 dropBuilder.append(memInfoBuilder); 14436 dropBuilder.append('\n'); 14437 /* 14438 dropBuilder.append(oomString); 14439 dropBuilder.append('\n'); 14440 */ 14441 StringWriter catSw = new StringWriter(); 14442 synchronized (ActivityManagerService.this) { 14443 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14444 String[] emptyArgs = new String[] { }; 14445 catPw.println(); 14446 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14447 catPw.println(); 14448 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14449 false, false, null); 14450 catPw.println(); 14451 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14452 catPw.flush(); 14453 } 14454 dropBuilder.append(catSw.toString()); 14455 addErrorToDropBox("lowmem", null, "system_server", null, 14456 null, tag.toString(), dropBuilder.toString(), null, null); 14457 //Slog.i(TAG, "Sent to dropbox:"); 14458 //Slog.i(TAG, dropBuilder.toString()); 14459 synchronized (ActivityManagerService.this) { 14460 long now = SystemClock.uptimeMillis(); 14461 if (mLastMemUsageReportTime < now) { 14462 mLastMemUsageReportTime = now; 14463 } 14464 } 14465 } 14466 14467 /** 14468 * Searches array of arguments for the specified string 14469 * @param args array of argument strings 14470 * @param value value to search for 14471 * @return true if the value is contained in the array 14472 */ 14473 private static boolean scanArgs(String[] args, String value) { 14474 if (args != null) { 14475 for (String arg : args) { 14476 if (value.equals(arg)) { 14477 return true; 14478 } 14479 } 14480 } 14481 return false; 14482 } 14483 14484 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14485 ContentProviderRecord cpr, boolean always) { 14486 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14487 14488 if (!inLaunching || always) { 14489 synchronized (cpr) { 14490 cpr.launchingApp = null; 14491 cpr.notifyAll(); 14492 } 14493 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14494 String names[] = cpr.info.authority.split(";"); 14495 for (int j = 0; j < names.length; j++) { 14496 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14497 } 14498 } 14499 14500 for (int i=0; i<cpr.connections.size(); i++) { 14501 ContentProviderConnection conn = cpr.connections.get(i); 14502 if (conn.waiting) { 14503 // If this connection is waiting for the provider, then we don't 14504 // need to mess with its process unless we are always removing 14505 // or for some reason the provider is not currently launching. 14506 if (inLaunching && !always) { 14507 continue; 14508 } 14509 } 14510 ProcessRecord capp = conn.client; 14511 conn.dead = true; 14512 if (conn.stableCount > 0) { 14513 if (!capp.persistent && capp.thread != null 14514 && capp.pid != 0 14515 && capp.pid != MY_PID) { 14516 capp.kill("depends on provider " 14517 + cpr.name.flattenToShortString() 14518 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14519 } 14520 } else if (capp.thread != null && conn.provider.provider != null) { 14521 try { 14522 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14523 } catch (RemoteException e) { 14524 } 14525 // In the protocol here, we don't expect the client to correctly 14526 // clean up this connection, we'll just remove it. 14527 cpr.connections.remove(i); 14528 conn.client.conProviders.remove(conn); 14529 } 14530 } 14531 14532 if (inLaunching && always) { 14533 mLaunchingProviders.remove(cpr); 14534 } 14535 return inLaunching; 14536 } 14537 14538 /** 14539 * Main code for cleaning up a process when it has gone away. This is 14540 * called both as a result of the process dying, or directly when stopping 14541 * a process when running in single process mode. 14542 * 14543 * @return Returns true if the given process has been restarted, so the 14544 * app that was passed in must remain on the process lists. 14545 */ 14546 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14547 boolean restarting, boolean allowRestart, int index) { 14548 if (index >= 0) { 14549 removeLruProcessLocked(app); 14550 ProcessList.remove(app.pid); 14551 } 14552 14553 mProcessesToGc.remove(app); 14554 mPendingPssProcesses.remove(app); 14555 14556 // Dismiss any open dialogs. 14557 if (app.crashDialog != null && !app.forceCrashReport) { 14558 app.crashDialog.dismiss(); 14559 app.crashDialog = null; 14560 } 14561 if (app.anrDialog != null) { 14562 app.anrDialog.dismiss(); 14563 app.anrDialog = null; 14564 } 14565 if (app.waitDialog != null) { 14566 app.waitDialog.dismiss(); 14567 app.waitDialog = null; 14568 } 14569 14570 app.crashing = false; 14571 app.notResponding = false; 14572 14573 app.resetPackageList(mProcessStats); 14574 app.unlinkDeathRecipient(); 14575 app.makeInactive(mProcessStats); 14576 app.waitingToKill = null; 14577 app.forcingToForeground = null; 14578 updateProcessForegroundLocked(app, false, false); 14579 app.foregroundActivities = false; 14580 app.hasShownUi = false; 14581 app.treatLikeActivity = false; 14582 app.hasAboveClient = false; 14583 app.hasClientActivities = false; 14584 14585 mServices.killServicesLocked(app, allowRestart); 14586 14587 boolean restart = false; 14588 14589 // Remove published content providers. 14590 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14591 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14592 final boolean always = app.bad || !allowRestart; 14593 if (removeDyingProviderLocked(app, cpr, always) || always) { 14594 // We left the provider in the launching list, need to 14595 // restart it. 14596 restart = true; 14597 } 14598 14599 cpr.provider = null; 14600 cpr.proc = null; 14601 } 14602 app.pubProviders.clear(); 14603 14604 // Take care of any launching providers waiting for this process. 14605 if (checkAppInLaunchingProvidersLocked(app, false)) { 14606 restart = true; 14607 } 14608 14609 // Unregister from connected content providers. 14610 if (!app.conProviders.isEmpty()) { 14611 for (int i=0; i<app.conProviders.size(); i++) { 14612 ContentProviderConnection conn = app.conProviders.get(i); 14613 conn.provider.connections.remove(conn); 14614 } 14615 app.conProviders.clear(); 14616 } 14617 14618 // At this point there may be remaining entries in mLaunchingProviders 14619 // where we were the only one waiting, so they are no longer of use. 14620 // Look for these and clean up if found. 14621 // XXX Commented out for now. Trying to figure out a way to reproduce 14622 // the actual situation to identify what is actually going on. 14623 if (false) { 14624 for (int i=0; i<mLaunchingProviders.size(); i++) { 14625 ContentProviderRecord cpr = (ContentProviderRecord) 14626 mLaunchingProviders.get(i); 14627 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14628 synchronized (cpr) { 14629 cpr.launchingApp = null; 14630 cpr.notifyAll(); 14631 } 14632 } 14633 } 14634 } 14635 14636 skipCurrentReceiverLocked(app); 14637 14638 // Unregister any receivers. 14639 for (int i=app.receivers.size()-1; i>=0; i--) { 14640 removeReceiverLocked(app.receivers.valueAt(i)); 14641 } 14642 app.receivers.clear(); 14643 14644 // If the app is undergoing backup, tell the backup manager about it 14645 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14646 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14647 + mBackupTarget.appInfo + " died during backup"); 14648 try { 14649 IBackupManager bm = IBackupManager.Stub.asInterface( 14650 ServiceManager.getService(Context.BACKUP_SERVICE)); 14651 bm.agentDisconnected(app.info.packageName); 14652 } catch (RemoteException e) { 14653 // can't happen; backup manager is local 14654 } 14655 } 14656 14657 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14658 ProcessChangeItem item = mPendingProcessChanges.get(i); 14659 if (item.pid == app.pid) { 14660 mPendingProcessChanges.remove(i); 14661 mAvailProcessChanges.add(item); 14662 } 14663 } 14664 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14665 14666 // If the caller is restarting this app, then leave it in its 14667 // current lists and let the caller take care of it. 14668 if (restarting) { 14669 return false; 14670 } 14671 14672 if (!app.persistent || app.isolated) { 14673 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14674 "Removing non-persistent process during cleanup: " + app); 14675 mProcessNames.remove(app.processName, app.uid); 14676 mIsolatedProcesses.remove(app.uid); 14677 if (mHeavyWeightProcess == app) { 14678 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14679 mHeavyWeightProcess.userId, 0)); 14680 mHeavyWeightProcess = null; 14681 } 14682 } else if (!app.removed) { 14683 // This app is persistent, so we need to keep its record around. 14684 // If it is not already on the pending app list, add it there 14685 // and start a new process for it. 14686 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14687 mPersistentStartingProcesses.add(app); 14688 restart = true; 14689 } 14690 } 14691 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14692 "Clean-up removing on hold: " + app); 14693 mProcessesOnHold.remove(app); 14694 14695 if (app == mHomeProcess) { 14696 mHomeProcess = null; 14697 } 14698 if (app == mPreviousProcess) { 14699 mPreviousProcess = null; 14700 } 14701 14702 if (restart && !app.isolated) { 14703 // We have components that still need to be running in the 14704 // process, so re-launch it. 14705 if (index < 0) { 14706 ProcessList.remove(app.pid); 14707 } 14708 mProcessNames.put(app.processName, app.uid, app); 14709 startProcessLocked(app, "restart", app.processName); 14710 return true; 14711 } else if (app.pid > 0 && app.pid != MY_PID) { 14712 // Goodbye! 14713 boolean removed; 14714 synchronized (mPidsSelfLocked) { 14715 mPidsSelfLocked.remove(app.pid); 14716 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14717 } 14718 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14719 if (app.isolated) { 14720 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14721 } 14722 app.setPid(0); 14723 } 14724 return false; 14725 } 14726 14727 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14728 // Look through the content providers we are waiting to have launched, 14729 // and if any run in this process then either schedule a restart of 14730 // the process or kill the client waiting for it if this process has 14731 // gone bad. 14732 int NL = mLaunchingProviders.size(); 14733 boolean restart = false; 14734 for (int i=0; i<NL; i++) { 14735 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14736 if (cpr.launchingApp == app) { 14737 if (!alwaysBad && !app.bad) { 14738 restart = true; 14739 } else { 14740 removeDyingProviderLocked(app, cpr, true); 14741 // cpr should have been removed from mLaunchingProviders 14742 NL = mLaunchingProviders.size(); 14743 i--; 14744 } 14745 } 14746 } 14747 return restart; 14748 } 14749 14750 // ========================================================= 14751 // SERVICES 14752 // ========================================================= 14753 14754 @Override 14755 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14756 int flags) { 14757 enforceNotIsolatedCaller("getServices"); 14758 synchronized (this) { 14759 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14760 } 14761 } 14762 14763 @Override 14764 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14765 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14766 synchronized (this) { 14767 return mServices.getRunningServiceControlPanelLocked(name); 14768 } 14769 } 14770 14771 @Override 14772 public ComponentName startService(IApplicationThread caller, Intent service, 14773 String resolvedType, int userId) { 14774 enforceNotIsolatedCaller("startService"); 14775 // Refuse possible leaked file descriptors 14776 if (service != null && service.hasFileDescriptors() == true) { 14777 throw new IllegalArgumentException("File descriptors passed in Intent"); 14778 } 14779 14780 if (DEBUG_SERVICE) 14781 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14782 synchronized(this) { 14783 final int callingPid = Binder.getCallingPid(); 14784 final int callingUid = Binder.getCallingUid(); 14785 final long origId = Binder.clearCallingIdentity(); 14786 ComponentName res = mServices.startServiceLocked(caller, service, 14787 resolvedType, callingPid, callingUid, userId); 14788 Binder.restoreCallingIdentity(origId); 14789 return res; 14790 } 14791 } 14792 14793 ComponentName startServiceInPackage(int uid, 14794 Intent service, String resolvedType, int userId) { 14795 synchronized(this) { 14796 if (DEBUG_SERVICE) 14797 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14798 final long origId = Binder.clearCallingIdentity(); 14799 ComponentName res = mServices.startServiceLocked(null, service, 14800 resolvedType, -1, uid, userId); 14801 Binder.restoreCallingIdentity(origId); 14802 return res; 14803 } 14804 } 14805 14806 @Override 14807 public int stopService(IApplicationThread caller, Intent service, 14808 String resolvedType, int userId) { 14809 enforceNotIsolatedCaller("stopService"); 14810 // Refuse possible leaked file descriptors 14811 if (service != null && service.hasFileDescriptors() == true) { 14812 throw new IllegalArgumentException("File descriptors passed in Intent"); 14813 } 14814 14815 synchronized(this) { 14816 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14817 } 14818 } 14819 14820 @Override 14821 public IBinder peekService(Intent service, String resolvedType) { 14822 enforceNotIsolatedCaller("peekService"); 14823 // Refuse possible leaked file descriptors 14824 if (service != null && service.hasFileDescriptors() == true) { 14825 throw new IllegalArgumentException("File descriptors passed in Intent"); 14826 } 14827 synchronized(this) { 14828 return mServices.peekServiceLocked(service, resolvedType); 14829 } 14830 } 14831 14832 @Override 14833 public boolean stopServiceToken(ComponentName className, IBinder token, 14834 int startId) { 14835 synchronized(this) { 14836 return mServices.stopServiceTokenLocked(className, token, startId); 14837 } 14838 } 14839 14840 @Override 14841 public void setServiceForeground(ComponentName className, IBinder token, 14842 int id, Notification notification, boolean removeNotification) { 14843 synchronized(this) { 14844 mServices.setServiceForegroundLocked(className, token, id, notification, 14845 removeNotification); 14846 } 14847 } 14848 14849 @Override 14850 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14851 boolean requireFull, String name, String callerPackage) { 14852 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14853 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14854 } 14855 14856 int unsafeConvertIncomingUser(int userId) { 14857 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14858 ? mCurrentUserId : userId; 14859 } 14860 14861 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14862 int allowMode, String name, String callerPackage) { 14863 final int callingUserId = UserHandle.getUserId(callingUid); 14864 if (callingUserId == userId) { 14865 return userId; 14866 } 14867 14868 // Note that we may be accessing mCurrentUserId outside of a lock... 14869 // shouldn't be a big deal, if this is being called outside 14870 // of a locked context there is intrinsically a race with 14871 // the value the caller will receive and someone else changing it. 14872 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14873 // we will switch to the calling user if access to the current user fails. 14874 int targetUserId = unsafeConvertIncomingUser(userId); 14875 14876 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14877 final boolean allow; 14878 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14879 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14880 // If the caller has this permission, they always pass go. And collect $200. 14881 allow = true; 14882 } else if (allowMode == ALLOW_FULL_ONLY) { 14883 // We require full access, sucks to be you. 14884 allow = false; 14885 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14886 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14887 // If the caller does not have either permission, they are always doomed. 14888 allow = false; 14889 } else if (allowMode == ALLOW_NON_FULL) { 14890 // We are blanket allowing non-full access, you lucky caller! 14891 allow = true; 14892 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14893 // We may or may not allow this depending on whether the two users are 14894 // in the same profile. 14895 synchronized (mUserProfileGroupIdsSelfLocked) { 14896 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14897 UserInfo.NO_PROFILE_GROUP_ID); 14898 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14899 UserInfo.NO_PROFILE_GROUP_ID); 14900 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14901 && callingProfile == targetProfile; 14902 } 14903 } else { 14904 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14905 } 14906 if (!allow) { 14907 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14908 // In this case, they would like to just execute as their 14909 // owner user instead of failing. 14910 targetUserId = callingUserId; 14911 } else { 14912 StringBuilder builder = new StringBuilder(128); 14913 builder.append("Permission Denial: "); 14914 builder.append(name); 14915 if (callerPackage != null) { 14916 builder.append(" from "); 14917 builder.append(callerPackage); 14918 } 14919 builder.append(" asks to run as user "); 14920 builder.append(userId); 14921 builder.append(" but is calling from user "); 14922 builder.append(UserHandle.getUserId(callingUid)); 14923 builder.append("; this requires "); 14924 builder.append(INTERACT_ACROSS_USERS_FULL); 14925 if (allowMode != ALLOW_FULL_ONLY) { 14926 builder.append(" or "); 14927 builder.append(INTERACT_ACROSS_USERS); 14928 } 14929 String msg = builder.toString(); 14930 Slog.w(TAG, msg); 14931 throw new SecurityException(msg); 14932 } 14933 } 14934 } 14935 if (!allowAll && targetUserId < 0) { 14936 throw new IllegalArgumentException( 14937 "Call does not support special user #" + targetUserId); 14938 } 14939 // Check shell permission 14940 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14941 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14942 targetUserId)) { 14943 throw new SecurityException("Shell does not have permission to access user " 14944 + targetUserId + "\n " + Debug.getCallers(3)); 14945 } 14946 } 14947 return targetUserId; 14948 } 14949 14950 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14951 String className, int flags) { 14952 boolean result = false; 14953 // For apps that don't have pre-defined UIDs, check for permission 14954 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14955 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14956 if (ActivityManager.checkUidPermission( 14957 INTERACT_ACROSS_USERS, 14958 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14959 ComponentName comp = new ComponentName(aInfo.packageName, className); 14960 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14961 + " requests FLAG_SINGLE_USER, but app does not hold " 14962 + INTERACT_ACROSS_USERS; 14963 Slog.w(TAG, msg); 14964 throw new SecurityException(msg); 14965 } 14966 // Permission passed 14967 result = true; 14968 } 14969 } else if ("system".equals(componentProcessName)) { 14970 result = true; 14971 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14972 // Phone app and persistent apps are allowed to export singleuser providers. 14973 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14974 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14975 } 14976 if (DEBUG_MU) { 14977 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14978 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14979 } 14980 return result; 14981 } 14982 14983 /** 14984 * Checks to see if the caller is in the same app as the singleton 14985 * component, or the component is in a special app. It allows special apps 14986 * to export singleton components but prevents exporting singleton 14987 * components for regular apps. 14988 */ 14989 boolean isValidSingletonCall(int callingUid, int componentUid) { 14990 int componentAppId = UserHandle.getAppId(componentUid); 14991 return UserHandle.isSameApp(callingUid, componentUid) 14992 || componentAppId == Process.SYSTEM_UID 14993 || componentAppId == Process.PHONE_UID 14994 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14995 == PackageManager.PERMISSION_GRANTED; 14996 } 14997 14998 public int bindService(IApplicationThread caller, IBinder token, 14999 Intent service, String resolvedType, 15000 IServiceConnection connection, int flags, int userId) { 15001 enforceNotIsolatedCaller("bindService"); 15002 15003 // Refuse possible leaked file descriptors 15004 if (service != null && service.hasFileDescriptors() == true) { 15005 throw new IllegalArgumentException("File descriptors passed in Intent"); 15006 } 15007 15008 synchronized(this) { 15009 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15010 connection, flags, userId); 15011 } 15012 } 15013 15014 public boolean unbindService(IServiceConnection connection) { 15015 synchronized (this) { 15016 return mServices.unbindServiceLocked(connection); 15017 } 15018 } 15019 15020 public void publishService(IBinder token, Intent intent, IBinder service) { 15021 // Refuse possible leaked file descriptors 15022 if (intent != null && intent.hasFileDescriptors() == true) { 15023 throw new IllegalArgumentException("File descriptors passed in Intent"); 15024 } 15025 15026 synchronized(this) { 15027 if (!(token instanceof ServiceRecord)) { 15028 throw new IllegalArgumentException("Invalid service token"); 15029 } 15030 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15031 } 15032 } 15033 15034 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15035 // Refuse possible leaked file descriptors 15036 if (intent != null && intent.hasFileDescriptors() == true) { 15037 throw new IllegalArgumentException("File descriptors passed in Intent"); 15038 } 15039 15040 synchronized(this) { 15041 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15042 } 15043 } 15044 15045 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15046 synchronized(this) { 15047 if (!(token instanceof ServiceRecord)) { 15048 throw new IllegalArgumentException("Invalid service token"); 15049 } 15050 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15051 } 15052 } 15053 15054 // ========================================================= 15055 // BACKUP AND RESTORE 15056 // ========================================================= 15057 15058 // Cause the target app to be launched if necessary and its backup agent 15059 // instantiated. The backup agent will invoke backupAgentCreated() on the 15060 // activity manager to announce its creation. 15061 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15062 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15063 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15064 15065 synchronized(this) { 15066 // !!! TODO: currently no check here that we're already bound 15067 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15068 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15069 synchronized (stats) { 15070 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15071 } 15072 15073 // Backup agent is now in use, its package can't be stopped. 15074 try { 15075 AppGlobals.getPackageManager().setPackageStoppedState( 15076 app.packageName, false, UserHandle.getUserId(app.uid)); 15077 } catch (RemoteException e) { 15078 } catch (IllegalArgumentException e) { 15079 Slog.w(TAG, "Failed trying to unstop package " 15080 + app.packageName + ": " + e); 15081 } 15082 15083 BackupRecord r = new BackupRecord(ss, app, backupMode); 15084 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15085 ? new ComponentName(app.packageName, app.backupAgentName) 15086 : new ComponentName("android", "FullBackupAgent"); 15087 // startProcessLocked() returns existing proc's record if it's already running 15088 ProcessRecord proc = startProcessLocked(app.processName, app, 15089 false, 0, "backup", hostingName, false, false, false); 15090 if (proc == null) { 15091 Slog.e(TAG, "Unable to start backup agent process " + r); 15092 return false; 15093 } 15094 15095 r.app = proc; 15096 mBackupTarget = r; 15097 mBackupAppName = app.packageName; 15098 15099 // Try not to kill the process during backup 15100 updateOomAdjLocked(proc); 15101 15102 // If the process is already attached, schedule the creation of the backup agent now. 15103 // If it is not yet live, this will be done when it attaches to the framework. 15104 if (proc.thread != null) { 15105 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15106 try { 15107 proc.thread.scheduleCreateBackupAgent(app, 15108 compatibilityInfoForPackageLocked(app), backupMode); 15109 } catch (RemoteException e) { 15110 // Will time out on the backup manager side 15111 } 15112 } else { 15113 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15114 } 15115 // Invariants: at this point, the target app process exists and the application 15116 // is either already running or in the process of coming up. mBackupTarget and 15117 // mBackupAppName describe the app, so that when it binds back to the AM we 15118 // know that it's scheduled for a backup-agent operation. 15119 } 15120 15121 return true; 15122 } 15123 15124 @Override 15125 public void clearPendingBackup() { 15126 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15127 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15128 15129 synchronized (this) { 15130 mBackupTarget = null; 15131 mBackupAppName = null; 15132 } 15133 } 15134 15135 // A backup agent has just come up 15136 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15137 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15138 + " = " + agent); 15139 15140 synchronized(this) { 15141 if (!agentPackageName.equals(mBackupAppName)) { 15142 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15143 return; 15144 } 15145 } 15146 15147 long oldIdent = Binder.clearCallingIdentity(); 15148 try { 15149 IBackupManager bm = IBackupManager.Stub.asInterface( 15150 ServiceManager.getService(Context.BACKUP_SERVICE)); 15151 bm.agentConnected(agentPackageName, agent); 15152 } catch (RemoteException e) { 15153 // can't happen; the backup manager service is local 15154 } catch (Exception e) { 15155 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15156 e.printStackTrace(); 15157 } finally { 15158 Binder.restoreCallingIdentity(oldIdent); 15159 } 15160 } 15161 15162 // done with this agent 15163 public void unbindBackupAgent(ApplicationInfo appInfo) { 15164 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15165 if (appInfo == null) { 15166 Slog.w(TAG, "unbind backup agent for null app"); 15167 return; 15168 } 15169 15170 synchronized(this) { 15171 try { 15172 if (mBackupAppName == null) { 15173 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15174 return; 15175 } 15176 15177 if (!mBackupAppName.equals(appInfo.packageName)) { 15178 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15179 return; 15180 } 15181 15182 // Not backing this app up any more; reset its OOM adjustment 15183 final ProcessRecord proc = mBackupTarget.app; 15184 updateOomAdjLocked(proc); 15185 15186 // If the app crashed during backup, 'thread' will be null here 15187 if (proc.thread != null) { 15188 try { 15189 proc.thread.scheduleDestroyBackupAgent(appInfo, 15190 compatibilityInfoForPackageLocked(appInfo)); 15191 } catch (Exception e) { 15192 Slog.e(TAG, "Exception when unbinding backup agent:"); 15193 e.printStackTrace(); 15194 } 15195 } 15196 } finally { 15197 mBackupTarget = null; 15198 mBackupAppName = null; 15199 } 15200 } 15201 } 15202 // ========================================================= 15203 // BROADCASTS 15204 // ========================================================= 15205 15206 private final List getStickiesLocked(String action, IntentFilter filter, 15207 List cur, int userId) { 15208 final ContentResolver resolver = mContext.getContentResolver(); 15209 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15210 if (stickies == null) { 15211 return cur; 15212 } 15213 final ArrayList<Intent> list = stickies.get(action); 15214 if (list == null) { 15215 return cur; 15216 } 15217 int N = list.size(); 15218 for (int i=0; i<N; i++) { 15219 Intent intent = list.get(i); 15220 if (filter.match(resolver, intent, true, TAG) >= 0) { 15221 if (cur == null) { 15222 cur = new ArrayList<Intent>(); 15223 } 15224 cur.add(intent); 15225 } 15226 } 15227 return cur; 15228 } 15229 15230 boolean isPendingBroadcastProcessLocked(int pid) { 15231 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15232 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15233 } 15234 15235 void skipPendingBroadcastLocked(int pid) { 15236 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15237 for (BroadcastQueue queue : mBroadcastQueues) { 15238 queue.skipPendingBroadcastLocked(pid); 15239 } 15240 } 15241 15242 // The app just attached; send any pending broadcasts that it should receive 15243 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15244 boolean didSomething = false; 15245 for (BroadcastQueue queue : mBroadcastQueues) { 15246 didSomething |= queue.sendPendingBroadcastsLocked(app); 15247 } 15248 return didSomething; 15249 } 15250 15251 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15252 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15253 enforceNotIsolatedCaller("registerReceiver"); 15254 int callingUid; 15255 int callingPid; 15256 synchronized(this) { 15257 ProcessRecord callerApp = null; 15258 if (caller != null) { 15259 callerApp = getRecordForAppLocked(caller); 15260 if (callerApp == null) { 15261 throw new SecurityException( 15262 "Unable to find app for caller " + caller 15263 + " (pid=" + Binder.getCallingPid() 15264 + ") when registering receiver " + receiver); 15265 } 15266 if (callerApp.info.uid != Process.SYSTEM_UID && 15267 !callerApp.pkgList.containsKey(callerPackage) && 15268 !"android".equals(callerPackage)) { 15269 throw new SecurityException("Given caller package " + callerPackage 15270 + " is not running in process " + callerApp); 15271 } 15272 callingUid = callerApp.info.uid; 15273 callingPid = callerApp.pid; 15274 } else { 15275 callerPackage = null; 15276 callingUid = Binder.getCallingUid(); 15277 callingPid = Binder.getCallingPid(); 15278 } 15279 15280 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15281 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15282 15283 List allSticky = null; 15284 15285 // Look for any matching sticky broadcasts... 15286 Iterator actions = filter.actionsIterator(); 15287 if (actions != null) { 15288 while (actions.hasNext()) { 15289 String action = (String)actions.next(); 15290 allSticky = getStickiesLocked(action, filter, allSticky, 15291 UserHandle.USER_ALL); 15292 allSticky = getStickiesLocked(action, filter, allSticky, 15293 UserHandle.getUserId(callingUid)); 15294 } 15295 } else { 15296 allSticky = getStickiesLocked(null, filter, allSticky, 15297 UserHandle.USER_ALL); 15298 allSticky = getStickiesLocked(null, filter, allSticky, 15299 UserHandle.getUserId(callingUid)); 15300 } 15301 15302 // The first sticky in the list is returned directly back to 15303 // the client. 15304 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15305 15306 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15307 + ": " + sticky); 15308 15309 if (receiver == null) { 15310 return sticky; 15311 } 15312 15313 ReceiverList rl 15314 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15315 if (rl == null) { 15316 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15317 userId, receiver); 15318 if (rl.app != null) { 15319 rl.app.receivers.add(rl); 15320 } else { 15321 try { 15322 receiver.asBinder().linkToDeath(rl, 0); 15323 } catch (RemoteException e) { 15324 return sticky; 15325 } 15326 rl.linkedToDeath = true; 15327 } 15328 mRegisteredReceivers.put(receiver.asBinder(), rl); 15329 } else if (rl.uid != callingUid) { 15330 throw new IllegalArgumentException( 15331 "Receiver requested to register for uid " + callingUid 15332 + " was previously registered for uid " + rl.uid); 15333 } else if (rl.pid != callingPid) { 15334 throw new IllegalArgumentException( 15335 "Receiver requested to register for pid " + callingPid 15336 + " was previously registered for pid " + rl.pid); 15337 } else if (rl.userId != userId) { 15338 throw new IllegalArgumentException( 15339 "Receiver requested to register for user " + userId 15340 + " was previously registered for user " + rl.userId); 15341 } 15342 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15343 permission, callingUid, userId); 15344 rl.add(bf); 15345 if (!bf.debugCheck()) { 15346 Slog.w(TAG, "==> For Dynamic broadast"); 15347 } 15348 mReceiverResolver.addFilter(bf); 15349 15350 // Enqueue broadcasts for all existing stickies that match 15351 // this filter. 15352 if (allSticky != null) { 15353 ArrayList receivers = new ArrayList(); 15354 receivers.add(bf); 15355 15356 int N = allSticky.size(); 15357 for (int i=0; i<N; i++) { 15358 Intent intent = (Intent)allSticky.get(i); 15359 BroadcastQueue queue = broadcastQueueForIntent(intent); 15360 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15361 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15362 null, null, false, true, true, -1); 15363 queue.enqueueParallelBroadcastLocked(r); 15364 queue.scheduleBroadcastsLocked(); 15365 } 15366 } 15367 15368 return sticky; 15369 } 15370 } 15371 15372 public void unregisterReceiver(IIntentReceiver receiver) { 15373 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15374 15375 final long origId = Binder.clearCallingIdentity(); 15376 try { 15377 boolean doTrim = false; 15378 15379 synchronized(this) { 15380 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15381 if (rl != null) { 15382 if (rl.curBroadcast != null) { 15383 BroadcastRecord r = rl.curBroadcast; 15384 final boolean doNext = finishReceiverLocked( 15385 receiver.asBinder(), r.resultCode, r.resultData, 15386 r.resultExtras, r.resultAbort); 15387 if (doNext) { 15388 doTrim = true; 15389 r.queue.processNextBroadcast(false); 15390 } 15391 } 15392 15393 if (rl.app != null) { 15394 rl.app.receivers.remove(rl); 15395 } 15396 removeReceiverLocked(rl); 15397 if (rl.linkedToDeath) { 15398 rl.linkedToDeath = false; 15399 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15400 } 15401 } 15402 } 15403 15404 // If we actually concluded any broadcasts, we might now be able 15405 // to trim the recipients' apps from our working set 15406 if (doTrim) { 15407 trimApplications(); 15408 return; 15409 } 15410 15411 } finally { 15412 Binder.restoreCallingIdentity(origId); 15413 } 15414 } 15415 15416 void removeReceiverLocked(ReceiverList rl) { 15417 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15418 int N = rl.size(); 15419 for (int i=0; i<N; i++) { 15420 mReceiverResolver.removeFilter(rl.get(i)); 15421 } 15422 } 15423 15424 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15425 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15426 ProcessRecord r = mLruProcesses.get(i); 15427 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15428 try { 15429 r.thread.dispatchPackageBroadcast(cmd, packages); 15430 } catch (RemoteException ex) { 15431 } 15432 } 15433 } 15434 } 15435 15436 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15437 int callingUid, int[] users) { 15438 List<ResolveInfo> receivers = null; 15439 try { 15440 HashSet<ComponentName> singleUserReceivers = null; 15441 boolean scannedFirstReceivers = false; 15442 for (int user : users) { 15443 // Skip users that have Shell restrictions 15444 if (callingUid == Process.SHELL_UID 15445 && getUserManagerLocked().hasUserRestriction( 15446 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15447 continue; 15448 } 15449 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15450 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15451 if (user != 0 && newReceivers != null) { 15452 // If this is not the primary user, we need to check for 15453 // any receivers that should be filtered out. 15454 for (int i=0; i<newReceivers.size(); i++) { 15455 ResolveInfo ri = newReceivers.get(i); 15456 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15457 newReceivers.remove(i); 15458 i--; 15459 } 15460 } 15461 } 15462 if (newReceivers != null && newReceivers.size() == 0) { 15463 newReceivers = null; 15464 } 15465 if (receivers == null) { 15466 receivers = newReceivers; 15467 } else if (newReceivers != null) { 15468 // We need to concatenate the additional receivers 15469 // found with what we have do far. This would be easy, 15470 // but we also need to de-dup any receivers that are 15471 // singleUser. 15472 if (!scannedFirstReceivers) { 15473 // Collect any single user receivers we had already retrieved. 15474 scannedFirstReceivers = true; 15475 for (int i=0; i<receivers.size(); i++) { 15476 ResolveInfo ri = receivers.get(i); 15477 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15478 ComponentName cn = new ComponentName( 15479 ri.activityInfo.packageName, ri.activityInfo.name); 15480 if (singleUserReceivers == null) { 15481 singleUserReceivers = new HashSet<ComponentName>(); 15482 } 15483 singleUserReceivers.add(cn); 15484 } 15485 } 15486 } 15487 // Add the new results to the existing results, tracking 15488 // and de-dupping single user receivers. 15489 for (int i=0; i<newReceivers.size(); i++) { 15490 ResolveInfo ri = newReceivers.get(i); 15491 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15492 ComponentName cn = new ComponentName( 15493 ri.activityInfo.packageName, ri.activityInfo.name); 15494 if (singleUserReceivers == null) { 15495 singleUserReceivers = new HashSet<ComponentName>(); 15496 } 15497 if (!singleUserReceivers.contains(cn)) { 15498 singleUserReceivers.add(cn); 15499 receivers.add(ri); 15500 } 15501 } else { 15502 receivers.add(ri); 15503 } 15504 } 15505 } 15506 } 15507 } catch (RemoteException ex) { 15508 // pm is in same process, this will never happen. 15509 } 15510 return receivers; 15511 } 15512 15513 private final int broadcastIntentLocked(ProcessRecord callerApp, 15514 String callerPackage, Intent intent, String resolvedType, 15515 IIntentReceiver resultTo, int resultCode, String resultData, 15516 Bundle map, String requiredPermission, int appOp, 15517 boolean ordered, boolean sticky, int callingPid, int callingUid, 15518 int userId) { 15519 intent = new Intent(intent); 15520 15521 // By default broadcasts do not go to stopped apps. 15522 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15523 15524 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15525 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15526 + " ordered=" + ordered + " userid=" + userId); 15527 if ((resultTo != null) && !ordered) { 15528 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15529 } 15530 15531 userId = handleIncomingUser(callingPid, callingUid, userId, 15532 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15533 15534 // Make sure that the user who is receiving this broadcast is started. 15535 // If not, we will just skip it. 15536 15537 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15538 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15539 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15540 Slog.w(TAG, "Skipping broadcast of " + intent 15541 + ": user " + userId + " is stopped"); 15542 return ActivityManager.BROADCAST_SUCCESS; 15543 } 15544 } 15545 15546 /* 15547 * Prevent non-system code (defined here to be non-persistent 15548 * processes) from sending protected broadcasts. 15549 */ 15550 int callingAppId = UserHandle.getAppId(callingUid); 15551 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15552 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15553 || callingAppId == Process.NFC_UID || callingUid == 0) { 15554 // Always okay. 15555 } else if (callerApp == null || !callerApp.persistent) { 15556 try { 15557 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15558 intent.getAction())) { 15559 String msg = "Permission Denial: not allowed to send broadcast " 15560 + intent.getAction() + " from pid=" 15561 + callingPid + ", uid=" + callingUid; 15562 Slog.w(TAG, msg); 15563 throw new SecurityException(msg); 15564 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15565 // Special case for compatibility: we don't want apps to send this, 15566 // but historically it has not been protected and apps may be using it 15567 // to poke their own app widget. So, instead of making it protected, 15568 // just limit it to the caller. 15569 if (callerApp == null) { 15570 String msg = "Permission Denial: not allowed to send broadcast " 15571 + intent.getAction() + " from unknown caller."; 15572 Slog.w(TAG, msg); 15573 throw new SecurityException(msg); 15574 } else if (intent.getComponent() != null) { 15575 // They are good enough to send to an explicit component... verify 15576 // it is being sent to the calling app. 15577 if (!intent.getComponent().getPackageName().equals( 15578 callerApp.info.packageName)) { 15579 String msg = "Permission Denial: not allowed to send broadcast " 15580 + intent.getAction() + " to " 15581 + intent.getComponent().getPackageName() + " from " 15582 + callerApp.info.packageName; 15583 Slog.w(TAG, msg); 15584 throw new SecurityException(msg); 15585 } 15586 } else { 15587 // Limit broadcast to their own package. 15588 intent.setPackage(callerApp.info.packageName); 15589 } 15590 } 15591 } catch (RemoteException e) { 15592 Slog.w(TAG, "Remote exception", e); 15593 return ActivityManager.BROADCAST_SUCCESS; 15594 } 15595 } 15596 15597 // Handle special intents: if this broadcast is from the package 15598 // manager about a package being removed, we need to remove all of 15599 // its activities from the history stack. 15600 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15601 intent.getAction()); 15602 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15603 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15604 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15605 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15606 || uidRemoved) { 15607 if (checkComponentPermission( 15608 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15609 callingPid, callingUid, -1, true) 15610 == PackageManager.PERMISSION_GRANTED) { 15611 if (uidRemoved) { 15612 final Bundle intentExtras = intent.getExtras(); 15613 final int uid = intentExtras != null 15614 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15615 if (uid >= 0) { 15616 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15617 synchronized (bs) { 15618 bs.removeUidStatsLocked(uid); 15619 } 15620 mAppOpsService.uidRemoved(uid); 15621 } 15622 } else { 15623 // If resources are unavailable just force stop all 15624 // those packages and flush the attribute cache as well. 15625 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15626 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15627 if (list != null && (list.length > 0)) { 15628 for (String pkg : list) { 15629 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15630 "storage unmount"); 15631 } 15632 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15633 sendPackageBroadcastLocked( 15634 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15635 } 15636 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15637 intent.getAction())) { 15638 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15639 } else { 15640 Uri data = intent.getData(); 15641 String ssp; 15642 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15643 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15644 intent.getAction()); 15645 boolean fullUninstall = removed && 15646 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15647 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15648 forceStopPackageLocked(ssp, UserHandle.getAppId( 15649 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15650 false, fullUninstall, userId, 15651 removed ? "pkg removed" : "pkg changed"); 15652 } 15653 if (removed) { 15654 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15655 new String[] {ssp}, userId); 15656 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15657 mAppOpsService.packageRemoved( 15658 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15659 15660 // Remove all permissions granted from/to this package 15661 removeUriPermissionsForPackageLocked(ssp, userId, true); 15662 } 15663 } 15664 } 15665 } 15666 } 15667 } else { 15668 String msg = "Permission Denial: " + intent.getAction() 15669 + " broadcast from " + callerPackage + " (pid=" + callingPid 15670 + ", uid=" + callingUid + ")" 15671 + " requires " 15672 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15673 Slog.w(TAG, msg); 15674 throw new SecurityException(msg); 15675 } 15676 15677 // Special case for adding a package: by default turn on compatibility 15678 // mode. 15679 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15680 Uri data = intent.getData(); 15681 String ssp; 15682 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15683 mCompatModePackages.handlePackageAddedLocked(ssp, 15684 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15685 } 15686 } 15687 15688 /* 15689 * If this is the time zone changed action, queue up a message that will reset the timezone 15690 * of all currently running processes. This message will get queued up before the broadcast 15691 * happens. 15692 */ 15693 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15694 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15695 } 15696 15697 /* 15698 * If the user set the time, let all running processes know. 15699 */ 15700 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15701 final int is24Hour = intent.getBooleanExtra( 15702 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15703 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15704 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15705 synchronized (stats) { 15706 stats.noteCurrentTimeChangedLocked(); 15707 } 15708 } 15709 15710 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15711 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15712 } 15713 15714 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15715 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15716 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15717 } 15718 15719 // Add to the sticky list if requested. 15720 if (sticky) { 15721 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15722 callingPid, callingUid) 15723 != PackageManager.PERMISSION_GRANTED) { 15724 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15725 + callingPid + ", uid=" + callingUid 15726 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15727 Slog.w(TAG, msg); 15728 throw new SecurityException(msg); 15729 } 15730 if (requiredPermission != null) { 15731 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15732 + " and enforce permission " + requiredPermission); 15733 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15734 } 15735 if (intent.getComponent() != null) { 15736 throw new SecurityException( 15737 "Sticky broadcasts can't target a specific component"); 15738 } 15739 // We use userId directly here, since the "all" target is maintained 15740 // as a separate set of sticky broadcasts. 15741 if (userId != UserHandle.USER_ALL) { 15742 // But first, if this is not a broadcast to all users, then 15743 // make sure it doesn't conflict with an existing broadcast to 15744 // all users. 15745 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15746 UserHandle.USER_ALL); 15747 if (stickies != null) { 15748 ArrayList<Intent> list = stickies.get(intent.getAction()); 15749 if (list != null) { 15750 int N = list.size(); 15751 int i; 15752 for (i=0; i<N; i++) { 15753 if (intent.filterEquals(list.get(i))) { 15754 throw new IllegalArgumentException( 15755 "Sticky broadcast " + intent + " for user " 15756 + userId + " conflicts with existing global broadcast"); 15757 } 15758 } 15759 } 15760 } 15761 } 15762 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15763 if (stickies == null) { 15764 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15765 mStickyBroadcasts.put(userId, stickies); 15766 } 15767 ArrayList<Intent> list = stickies.get(intent.getAction()); 15768 if (list == null) { 15769 list = new ArrayList<Intent>(); 15770 stickies.put(intent.getAction(), list); 15771 } 15772 int N = list.size(); 15773 int i; 15774 for (i=0; i<N; i++) { 15775 if (intent.filterEquals(list.get(i))) { 15776 // This sticky already exists, replace it. 15777 list.set(i, new Intent(intent)); 15778 break; 15779 } 15780 } 15781 if (i >= N) { 15782 list.add(new Intent(intent)); 15783 } 15784 } 15785 15786 int[] users; 15787 if (userId == UserHandle.USER_ALL) { 15788 // Caller wants broadcast to go to all started users. 15789 users = mStartedUserArray; 15790 } else { 15791 // Caller wants broadcast to go to one specific user. 15792 users = new int[] {userId}; 15793 } 15794 15795 // Figure out who all will receive this broadcast. 15796 List receivers = null; 15797 List<BroadcastFilter> registeredReceivers = null; 15798 // Need to resolve the intent to interested receivers... 15799 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15800 == 0) { 15801 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15802 } 15803 if (intent.getComponent() == null) { 15804 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15805 // Query one target user at a time, excluding shell-restricted users 15806 UserManagerService ums = getUserManagerLocked(); 15807 for (int i = 0; i < users.length; i++) { 15808 if (ums.hasUserRestriction( 15809 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15810 continue; 15811 } 15812 List<BroadcastFilter> registeredReceiversForUser = 15813 mReceiverResolver.queryIntent(intent, 15814 resolvedType, false, users[i]); 15815 if (registeredReceivers == null) { 15816 registeredReceivers = registeredReceiversForUser; 15817 } else if (registeredReceiversForUser != null) { 15818 registeredReceivers.addAll(registeredReceiversForUser); 15819 } 15820 } 15821 } else { 15822 registeredReceivers = mReceiverResolver.queryIntent(intent, 15823 resolvedType, false, userId); 15824 } 15825 } 15826 15827 final boolean replacePending = 15828 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15829 15830 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15831 + " replacePending=" + replacePending); 15832 15833 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15834 if (!ordered && NR > 0) { 15835 // If we are not serializing this broadcast, then send the 15836 // registered receivers separately so they don't wait for the 15837 // components to be launched. 15838 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15839 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15840 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15841 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15842 ordered, sticky, false, userId); 15843 if (DEBUG_BROADCAST) Slog.v( 15844 TAG, "Enqueueing parallel broadcast " + r); 15845 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15846 if (!replaced) { 15847 queue.enqueueParallelBroadcastLocked(r); 15848 queue.scheduleBroadcastsLocked(); 15849 } 15850 registeredReceivers = null; 15851 NR = 0; 15852 } 15853 15854 // Merge into one list. 15855 int ir = 0; 15856 if (receivers != null) { 15857 // A special case for PACKAGE_ADDED: do not allow the package 15858 // being added to see this broadcast. This prevents them from 15859 // using this as a back door to get run as soon as they are 15860 // installed. Maybe in the future we want to have a special install 15861 // broadcast or such for apps, but we'd like to deliberately make 15862 // this decision. 15863 String skipPackages[] = null; 15864 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15865 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15866 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15867 Uri data = intent.getData(); 15868 if (data != null) { 15869 String pkgName = data.getSchemeSpecificPart(); 15870 if (pkgName != null) { 15871 skipPackages = new String[] { pkgName }; 15872 } 15873 } 15874 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15875 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15876 } 15877 if (skipPackages != null && (skipPackages.length > 0)) { 15878 for (String skipPackage : skipPackages) { 15879 if (skipPackage != null) { 15880 int NT = receivers.size(); 15881 for (int it=0; it<NT; it++) { 15882 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15883 if (curt.activityInfo.packageName.equals(skipPackage)) { 15884 receivers.remove(it); 15885 it--; 15886 NT--; 15887 } 15888 } 15889 } 15890 } 15891 } 15892 15893 int NT = receivers != null ? receivers.size() : 0; 15894 int it = 0; 15895 ResolveInfo curt = null; 15896 BroadcastFilter curr = null; 15897 while (it < NT && ir < NR) { 15898 if (curt == null) { 15899 curt = (ResolveInfo)receivers.get(it); 15900 } 15901 if (curr == null) { 15902 curr = registeredReceivers.get(ir); 15903 } 15904 if (curr.getPriority() >= curt.priority) { 15905 // Insert this broadcast record into the final list. 15906 receivers.add(it, curr); 15907 ir++; 15908 curr = null; 15909 it++; 15910 NT++; 15911 } else { 15912 // Skip to the next ResolveInfo in the final list. 15913 it++; 15914 curt = null; 15915 } 15916 } 15917 } 15918 while (ir < NR) { 15919 if (receivers == null) { 15920 receivers = new ArrayList(); 15921 } 15922 receivers.add(registeredReceivers.get(ir)); 15923 ir++; 15924 } 15925 15926 if ((receivers != null && receivers.size() > 0) 15927 || resultTo != null) { 15928 BroadcastQueue queue = broadcastQueueForIntent(intent); 15929 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15930 callerPackage, callingPid, callingUid, resolvedType, 15931 requiredPermission, appOp, receivers, resultTo, resultCode, 15932 resultData, map, ordered, sticky, false, userId); 15933 if (DEBUG_BROADCAST) Slog.v( 15934 TAG, "Enqueueing ordered broadcast " + r 15935 + ": prev had " + queue.mOrderedBroadcasts.size()); 15936 if (DEBUG_BROADCAST) { 15937 int seq = r.intent.getIntExtra("seq", -1); 15938 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15939 } 15940 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15941 if (!replaced) { 15942 queue.enqueueOrderedBroadcastLocked(r); 15943 queue.scheduleBroadcastsLocked(); 15944 } 15945 } 15946 15947 return ActivityManager.BROADCAST_SUCCESS; 15948 } 15949 15950 final Intent verifyBroadcastLocked(Intent intent) { 15951 // Refuse possible leaked file descriptors 15952 if (intent != null && intent.hasFileDescriptors() == true) { 15953 throw new IllegalArgumentException("File descriptors passed in Intent"); 15954 } 15955 15956 int flags = intent.getFlags(); 15957 15958 if (!mProcessesReady) { 15959 // if the caller really truly claims to know what they're doing, go 15960 // ahead and allow the broadcast without launching any receivers 15961 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15962 intent = new Intent(intent); 15963 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15964 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15965 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15966 + " before boot completion"); 15967 throw new IllegalStateException("Cannot broadcast before boot completed"); 15968 } 15969 } 15970 15971 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15972 throw new IllegalArgumentException( 15973 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15974 } 15975 15976 return intent; 15977 } 15978 15979 public final int broadcastIntent(IApplicationThread caller, 15980 Intent intent, String resolvedType, IIntentReceiver resultTo, 15981 int resultCode, String resultData, Bundle map, 15982 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15983 enforceNotIsolatedCaller("broadcastIntent"); 15984 synchronized(this) { 15985 intent = verifyBroadcastLocked(intent); 15986 15987 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15988 final int callingPid = Binder.getCallingPid(); 15989 final int callingUid = Binder.getCallingUid(); 15990 final long origId = Binder.clearCallingIdentity(); 15991 int res = broadcastIntentLocked(callerApp, 15992 callerApp != null ? callerApp.info.packageName : null, 15993 intent, resolvedType, resultTo, 15994 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15995 callingPid, callingUid, userId); 15996 Binder.restoreCallingIdentity(origId); 15997 return res; 15998 } 15999 } 16000 16001 int broadcastIntentInPackage(String packageName, int uid, 16002 Intent intent, String resolvedType, IIntentReceiver resultTo, 16003 int resultCode, String resultData, Bundle map, 16004 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16005 synchronized(this) { 16006 intent = verifyBroadcastLocked(intent); 16007 16008 final long origId = Binder.clearCallingIdentity(); 16009 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16010 resultTo, resultCode, resultData, map, requiredPermission, 16011 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16012 Binder.restoreCallingIdentity(origId); 16013 return res; 16014 } 16015 } 16016 16017 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16018 // Refuse possible leaked file descriptors 16019 if (intent != null && intent.hasFileDescriptors() == true) { 16020 throw new IllegalArgumentException("File descriptors passed in Intent"); 16021 } 16022 16023 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16024 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16025 16026 synchronized(this) { 16027 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16028 != PackageManager.PERMISSION_GRANTED) { 16029 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16030 + Binder.getCallingPid() 16031 + ", uid=" + Binder.getCallingUid() 16032 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16033 Slog.w(TAG, msg); 16034 throw new SecurityException(msg); 16035 } 16036 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16037 if (stickies != null) { 16038 ArrayList<Intent> list = stickies.get(intent.getAction()); 16039 if (list != null) { 16040 int N = list.size(); 16041 int i; 16042 for (i=0; i<N; i++) { 16043 if (intent.filterEquals(list.get(i))) { 16044 list.remove(i); 16045 break; 16046 } 16047 } 16048 if (list.size() <= 0) { 16049 stickies.remove(intent.getAction()); 16050 } 16051 } 16052 if (stickies.size() <= 0) { 16053 mStickyBroadcasts.remove(userId); 16054 } 16055 } 16056 } 16057 } 16058 16059 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16060 String resultData, Bundle resultExtras, boolean resultAbort) { 16061 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16062 if (r == null) { 16063 Slog.w(TAG, "finishReceiver called but not found on queue"); 16064 return false; 16065 } 16066 16067 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16068 } 16069 16070 void backgroundServicesFinishedLocked(int userId) { 16071 for (BroadcastQueue queue : mBroadcastQueues) { 16072 queue.backgroundServicesFinishedLocked(userId); 16073 } 16074 } 16075 16076 public void finishReceiver(IBinder who, int resultCode, String resultData, 16077 Bundle resultExtras, boolean resultAbort) { 16078 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16079 16080 // Refuse possible leaked file descriptors 16081 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16082 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16083 } 16084 16085 final long origId = Binder.clearCallingIdentity(); 16086 try { 16087 boolean doNext = false; 16088 BroadcastRecord r; 16089 16090 synchronized(this) { 16091 r = broadcastRecordForReceiverLocked(who); 16092 if (r != null) { 16093 doNext = r.queue.finishReceiverLocked(r, resultCode, 16094 resultData, resultExtras, resultAbort, true); 16095 } 16096 } 16097 16098 if (doNext) { 16099 r.queue.processNextBroadcast(false); 16100 } 16101 trimApplications(); 16102 } finally { 16103 Binder.restoreCallingIdentity(origId); 16104 } 16105 } 16106 16107 // ========================================================= 16108 // INSTRUMENTATION 16109 // ========================================================= 16110 16111 public boolean startInstrumentation(ComponentName className, 16112 String profileFile, int flags, Bundle arguments, 16113 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16114 int userId, String abiOverride) { 16115 enforceNotIsolatedCaller("startInstrumentation"); 16116 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16117 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16118 // Refuse possible leaked file descriptors 16119 if (arguments != null && arguments.hasFileDescriptors()) { 16120 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16121 } 16122 16123 synchronized(this) { 16124 InstrumentationInfo ii = null; 16125 ApplicationInfo ai = null; 16126 try { 16127 ii = mContext.getPackageManager().getInstrumentationInfo( 16128 className, STOCK_PM_FLAGS); 16129 ai = AppGlobals.getPackageManager().getApplicationInfo( 16130 ii.targetPackage, STOCK_PM_FLAGS, userId); 16131 } catch (PackageManager.NameNotFoundException e) { 16132 } catch (RemoteException e) { 16133 } 16134 if (ii == null) { 16135 reportStartInstrumentationFailure(watcher, className, 16136 "Unable to find instrumentation info for: " + className); 16137 return false; 16138 } 16139 if (ai == null) { 16140 reportStartInstrumentationFailure(watcher, className, 16141 "Unable to find instrumentation target package: " + ii.targetPackage); 16142 return false; 16143 } 16144 16145 int match = mContext.getPackageManager().checkSignatures( 16146 ii.targetPackage, ii.packageName); 16147 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16148 String msg = "Permission Denial: starting instrumentation " 16149 + className + " from pid=" 16150 + Binder.getCallingPid() 16151 + ", uid=" + Binder.getCallingPid() 16152 + " not allowed because package " + ii.packageName 16153 + " does not have a signature matching the target " 16154 + ii.targetPackage; 16155 reportStartInstrumentationFailure(watcher, className, msg); 16156 throw new SecurityException(msg); 16157 } 16158 16159 final long origId = Binder.clearCallingIdentity(); 16160 // Instrumentation can kill and relaunch even persistent processes 16161 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16162 "start instr"); 16163 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16164 app.instrumentationClass = className; 16165 app.instrumentationInfo = ai; 16166 app.instrumentationProfileFile = profileFile; 16167 app.instrumentationArguments = arguments; 16168 app.instrumentationWatcher = watcher; 16169 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16170 app.instrumentationResultClass = className; 16171 Binder.restoreCallingIdentity(origId); 16172 } 16173 16174 return true; 16175 } 16176 16177 /** 16178 * Report errors that occur while attempting to start Instrumentation. Always writes the 16179 * error to the logs, but if somebody is watching, send the report there too. This enables 16180 * the "am" command to report errors with more information. 16181 * 16182 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16183 * @param cn The component name of the instrumentation. 16184 * @param report The error report. 16185 */ 16186 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16187 ComponentName cn, String report) { 16188 Slog.w(TAG, report); 16189 try { 16190 if (watcher != null) { 16191 Bundle results = new Bundle(); 16192 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16193 results.putString("Error", report); 16194 watcher.instrumentationStatus(cn, -1, results); 16195 } 16196 } catch (RemoteException e) { 16197 Slog.w(TAG, e); 16198 } 16199 } 16200 16201 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16202 if (app.instrumentationWatcher != null) { 16203 try { 16204 // NOTE: IInstrumentationWatcher *must* be oneway here 16205 app.instrumentationWatcher.instrumentationFinished( 16206 app.instrumentationClass, 16207 resultCode, 16208 results); 16209 } catch (RemoteException e) { 16210 } 16211 } 16212 if (app.instrumentationUiAutomationConnection != null) { 16213 try { 16214 app.instrumentationUiAutomationConnection.shutdown(); 16215 } catch (RemoteException re) { 16216 /* ignore */ 16217 } 16218 // Only a UiAutomation can set this flag and now that 16219 // it is finished we make sure it is reset to its default. 16220 mUserIsMonkey = false; 16221 } 16222 app.instrumentationWatcher = null; 16223 app.instrumentationUiAutomationConnection = null; 16224 app.instrumentationClass = null; 16225 app.instrumentationInfo = null; 16226 app.instrumentationProfileFile = null; 16227 app.instrumentationArguments = null; 16228 16229 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16230 "finished inst"); 16231 } 16232 16233 public void finishInstrumentation(IApplicationThread target, 16234 int resultCode, Bundle results) { 16235 int userId = UserHandle.getCallingUserId(); 16236 // Refuse possible leaked file descriptors 16237 if (results != null && results.hasFileDescriptors()) { 16238 throw new IllegalArgumentException("File descriptors passed in Intent"); 16239 } 16240 16241 synchronized(this) { 16242 ProcessRecord app = getRecordForAppLocked(target); 16243 if (app == null) { 16244 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16245 return; 16246 } 16247 final long origId = Binder.clearCallingIdentity(); 16248 finishInstrumentationLocked(app, resultCode, results); 16249 Binder.restoreCallingIdentity(origId); 16250 } 16251 } 16252 16253 // ========================================================= 16254 // CONFIGURATION 16255 // ========================================================= 16256 16257 public ConfigurationInfo getDeviceConfigurationInfo() { 16258 ConfigurationInfo config = new ConfigurationInfo(); 16259 synchronized (this) { 16260 config.reqTouchScreen = mConfiguration.touchscreen; 16261 config.reqKeyboardType = mConfiguration.keyboard; 16262 config.reqNavigation = mConfiguration.navigation; 16263 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16264 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16265 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16266 } 16267 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16268 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16269 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16270 } 16271 config.reqGlEsVersion = GL_ES_VERSION; 16272 } 16273 return config; 16274 } 16275 16276 ActivityStack getFocusedStack() { 16277 return mStackSupervisor.getFocusedStack(); 16278 } 16279 16280 public Configuration getConfiguration() { 16281 Configuration ci; 16282 synchronized(this) { 16283 ci = new Configuration(mConfiguration); 16284 } 16285 return ci; 16286 } 16287 16288 public void updatePersistentConfiguration(Configuration values) { 16289 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16290 "updateConfiguration()"); 16291 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16292 "updateConfiguration()"); 16293 if (values == null) { 16294 throw new NullPointerException("Configuration must not be null"); 16295 } 16296 16297 synchronized(this) { 16298 final long origId = Binder.clearCallingIdentity(); 16299 updateConfigurationLocked(values, null, true, false); 16300 Binder.restoreCallingIdentity(origId); 16301 } 16302 } 16303 16304 public void updateConfiguration(Configuration values) { 16305 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16306 "updateConfiguration()"); 16307 16308 synchronized(this) { 16309 if (values == null && mWindowManager != null) { 16310 // sentinel: fetch the current configuration from the window manager 16311 values = mWindowManager.computeNewConfiguration(); 16312 } 16313 16314 if (mWindowManager != null) { 16315 mProcessList.applyDisplaySize(mWindowManager); 16316 } 16317 16318 final long origId = Binder.clearCallingIdentity(); 16319 if (values != null) { 16320 Settings.System.clearConfiguration(values); 16321 } 16322 updateConfigurationLocked(values, null, false, false); 16323 Binder.restoreCallingIdentity(origId); 16324 } 16325 } 16326 16327 /** 16328 * Do either or both things: (1) change the current configuration, and (2) 16329 * make sure the given activity is running with the (now) current 16330 * configuration. Returns true if the activity has been left running, or 16331 * false if <var>starting</var> is being destroyed to match the new 16332 * configuration. 16333 * @param persistent TODO 16334 */ 16335 boolean updateConfigurationLocked(Configuration values, 16336 ActivityRecord starting, boolean persistent, boolean initLocale) { 16337 int changes = 0; 16338 16339 if (values != null) { 16340 Configuration newConfig = new Configuration(mConfiguration); 16341 changes = newConfig.updateFrom(values); 16342 if (changes != 0) { 16343 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16344 Slog.i(TAG, "Updating configuration to: " + values); 16345 } 16346 16347 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16348 16349 if (values.locale != null && !initLocale) { 16350 saveLocaleLocked(values.locale, 16351 !values.locale.equals(mConfiguration.locale), 16352 values.userSetLocale); 16353 } 16354 16355 mConfigurationSeq++; 16356 if (mConfigurationSeq <= 0) { 16357 mConfigurationSeq = 1; 16358 } 16359 newConfig.seq = mConfigurationSeq; 16360 mConfiguration = newConfig; 16361 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16362 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16363 //mUsageStatsService.noteStartConfig(newConfig); 16364 16365 final Configuration configCopy = new Configuration(mConfiguration); 16366 16367 // TODO: If our config changes, should we auto dismiss any currently 16368 // showing dialogs? 16369 mShowDialogs = shouldShowDialogs(newConfig); 16370 16371 AttributeCache ac = AttributeCache.instance(); 16372 if (ac != null) { 16373 ac.updateConfiguration(configCopy); 16374 } 16375 16376 // Make sure all resources in our process are updated 16377 // right now, so that anyone who is going to retrieve 16378 // resource values after we return will be sure to get 16379 // the new ones. This is especially important during 16380 // boot, where the first config change needs to guarantee 16381 // all resources have that config before following boot 16382 // code is executed. 16383 mSystemThread.applyConfigurationToResources(configCopy); 16384 16385 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16386 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16387 msg.obj = new Configuration(configCopy); 16388 mHandler.sendMessage(msg); 16389 } 16390 16391 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16392 ProcessRecord app = mLruProcesses.get(i); 16393 try { 16394 if (app.thread != null) { 16395 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16396 + app.processName + " new config " + mConfiguration); 16397 app.thread.scheduleConfigurationChanged(configCopy); 16398 } 16399 } catch (Exception e) { 16400 } 16401 } 16402 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16403 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16404 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16405 | Intent.FLAG_RECEIVER_FOREGROUND); 16406 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16407 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16408 Process.SYSTEM_UID, UserHandle.USER_ALL); 16409 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16410 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16411 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16412 broadcastIntentLocked(null, null, intent, 16413 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16414 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16415 } 16416 } 16417 } 16418 16419 boolean kept = true; 16420 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16421 // mainStack is null during startup. 16422 if (mainStack != null) { 16423 if (changes != 0 && starting == null) { 16424 // If the configuration changed, and the caller is not already 16425 // in the process of starting an activity, then find the top 16426 // activity to check if its configuration needs to change. 16427 starting = mainStack.topRunningActivityLocked(null); 16428 } 16429 16430 if (starting != null) { 16431 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16432 // And we need to make sure at this point that all other activities 16433 // are made visible with the correct configuration. 16434 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16435 } 16436 } 16437 16438 if (values != null && mWindowManager != null) { 16439 mWindowManager.setNewConfiguration(mConfiguration); 16440 } 16441 16442 return kept; 16443 } 16444 16445 /** 16446 * Decide based on the configuration whether we should shouw the ANR, 16447 * crash, etc dialogs. The idea is that if there is no affordnace to 16448 * press the on-screen buttons, we shouldn't show the dialog. 16449 * 16450 * A thought: SystemUI might also want to get told about this, the Power 16451 * dialog / global actions also might want different behaviors. 16452 */ 16453 private static final boolean shouldShowDialogs(Configuration config) { 16454 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16455 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16456 } 16457 16458 /** 16459 * Save the locale. You must be inside a synchronized (this) block. 16460 */ 16461 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16462 if(isDiff) { 16463 SystemProperties.set("user.language", l.getLanguage()); 16464 SystemProperties.set("user.region", l.getCountry()); 16465 } 16466 16467 if(isPersist) { 16468 SystemProperties.set("persist.sys.language", l.getLanguage()); 16469 SystemProperties.set("persist.sys.country", l.getCountry()); 16470 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16471 16472 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16473 } 16474 } 16475 16476 @Override 16477 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16478 synchronized (this) { 16479 ActivityRecord srec = ActivityRecord.forToken(token); 16480 if (srec.task != null && srec.task.stack != null) { 16481 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16482 } 16483 } 16484 return false; 16485 } 16486 16487 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16488 Intent resultData) { 16489 16490 synchronized (this) { 16491 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16492 if (stack != null) { 16493 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16494 } 16495 return false; 16496 } 16497 } 16498 16499 public int getLaunchedFromUid(IBinder activityToken) { 16500 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16501 if (srec == null) { 16502 return -1; 16503 } 16504 return srec.launchedFromUid; 16505 } 16506 16507 public String getLaunchedFromPackage(IBinder activityToken) { 16508 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16509 if (srec == null) { 16510 return null; 16511 } 16512 return srec.launchedFromPackage; 16513 } 16514 16515 // ========================================================= 16516 // LIFETIME MANAGEMENT 16517 // ========================================================= 16518 16519 // Returns which broadcast queue the app is the current [or imminent] receiver 16520 // on, or 'null' if the app is not an active broadcast recipient. 16521 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16522 BroadcastRecord r = app.curReceiver; 16523 if (r != null) { 16524 return r.queue; 16525 } 16526 16527 // It's not the current receiver, but it might be starting up to become one 16528 synchronized (this) { 16529 for (BroadcastQueue queue : mBroadcastQueues) { 16530 r = queue.mPendingBroadcast; 16531 if (r != null && r.curApp == app) { 16532 // found it; report which queue it's in 16533 return queue; 16534 } 16535 } 16536 } 16537 16538 return null; 16539 } 16540 16541 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16542 boolean doingAll, long now) { 16543 if (mAdjSeq == app.adjSeq) { 16544 // This adjustment has already been computed. 16545 return app.curRawAdj; 16546 } 16547 16548 if (app.thread == null) { 16549 app.adjSeq = mAdjSeq; 16550 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16551 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16552 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16553 } 16554 16555 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16556 app.adjSource = null; 16557 app.adjTarget = null; 16558 app.empty = false; 16559 app.cached = false; 16560 16561 final int activitiesSize = app.activities.size(); 16562 16563 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16564 // The max adjustment doesn't allow this app to be anything 16565 // below foreground, so it is not worth doing work for it. 16566 app.adjType = "fixed"; 16567 app.adjSeq = mAdjSeq; 16568 app.curRawAdj = app.maxAdj; 16569 app.foregroundActivities = false; 16570 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16571 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16572 // System processes can do UI, and when they do we want to have 16573 // them trim their memory after the user leaves the UI. To 16574 // facilitate this, here we need to determine whether or not it 16575 // is currently showing UI. 16576 app.systemNoUi = true; 16577 if (app == TOP_APP) { 16578 app.systemNoUi = false; 16579 } else if (activitiesSize > 0) { 16580 for (int j = 0; j < activitiesSize; j++) { 16581 final ActivityRecord r = app.activities.get(j); 16582 if (r.visible) { 16583 app.systemNoUi = false; 16584 } 16585 } 16586 } 16587 if (!app.systemNoUi) { 16588 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16589 } 16590 return (app.curAdj=app.maxAdj); 16591 } 16592 16593 app.systemNoUi = false; 16594 16595 // Determine the importance of the process, starting with most 16596 // important to least, and assign an appropriate OOM adjustment. 16597 int adj; 16598 int schedGroup; 16599 int procState; 16600 boolean foregroundActivities = false; 16601 BroadcastQueue queue; 16602 if (app == TOP_APP) { 16603 // The last app on the list is the foreground app. 16604 adj = ProcessList.FOREGROUND_APP_ADJ; 16605 schedGroup = Process.THREAD_GROUP_DEFAULT; 16606 app.adjType = "top-activity"; 16607 foregroundActivities = true; 16608 procState = ActivityManager.PROCESS_STATE_TOP; 16609 } else if (app.instrumentationClass != null) { 16610 // Don't want to kill running instrumentation. 16611 adj = ProcessList.FOREGROUND_APP_ADJ; 16612 schedGroup = Process.THREAD_GROUP_DEFAULT; 16613 app.adjType = "instrumentation"; 16614 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16615 } else if ((queue = isReceivingBroadcast(app)) != null) { 16616 // An app that is currently receiving a broadcast also 16617 // counts as being in the foreground for OOM killer purposes. 16618 // It's placed in a sched group based on the nature of the 16619 // broadcast as reflected by which queue it's active in. 16620 adj = ProcessList.FOREGROUND_APP_ADJ; 16621 schedGroup = (queue == mFgBroadcastQueue) 16622 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16623 app.adjType = "broadcast"; 16624 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16625 } else if (app.executingServices.size() > 0) { 16626 // An app that is currently executing a service callback also 16627 // counts as being in the foreground. 16628 adj = ProcessList.FOREGROUND_APP_ADJ; 16629 schedGroup = app.execServicesFg ? 16630 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16631 app.adjType = "exec-service"; 16632 procState = ActivityManager.PROCESS_STATE_SERVICE; 16633 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16634 } else { 16635 // As far as we know the process is empty. We may change our mind later. 16636 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16637 // At this point we don't actually know the adjustment. Use the cached adj 16638 // value that the caller wants us to. 16639 adj = cachedAdj; 16640 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16641 app.cached = true; 16642 app.empty = true; 16643 app.adjType = "cch-empty"; 16644 } 16645 16646 // Examine all activities if not already foreground. 16647 if (!foregroundActivities && activitiesSize > 0) { 16648 for (int j = 0; j < activitiesSize; j++) { 16649 final ActivityRecord r = app.activities.get(j); 16650 if (r.app != app) { 16651 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16652 + app + "?!?"); 16653 continue; 16654 } 16655 if (r.visible) { 16656 // App has a visible activity; only upgrade adjustment. 16657 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16658 adj = ProcessList.VISIBLE_APP_ADJ; 16659 app.adjType = "visible"; 16660 } 16661 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16662 procState = ActivityManager.PROCESS_STATE_TOP; 16663 } 16664 schedGroup = Process.THREAD_GROUP_DEFAULT; 16665 app.cached = false; 16666 app.empty = false; 16667 foregroundActivities = true; 16668 break; 16669 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16670 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16671 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16672 app.adjType = "pausing"; 16673 } 16674 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16675 procState = ActivityManager.PROCESS_STATE_TOP; 16676 } 16677 schedGroup = Process.THREAD_GROUP_DEFAULT; 16678 app.cached = false; 16679 app.empty = false; 16680 foregroundActivities = true; 16681 } else if (r.state == ActivityState.STOPPING) { 16682 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16683 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16684 app.adjType = "stopping"; 16685 } 16686 // For the process state, we will at this point consider the 16687 // process to be cached. It will be cached either as an activity 16688 // or empty depending on whether the activity is finishing. We do 16689 // this so that we can treat the process as cached for purposes of 16690 // memory trimming (determing current memory level, trim command to 16691 // send to process) since there can be an arbitrary number of stopping 16692 // processes and they should soon all go into the cached state. 16693 if (!r.finishing) { 16694 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16695 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16696 } 16697 } 16698 app.cached = false; 16699 app.empty = false; 16700 foregroundActivities = true; 16701 } else { 16702 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16703 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16704 app.adjType = "cch-act"; 16705 } 16706 } 16707 } 16708 } 16709 16710 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16711 if (app.foregroundServices) { 16712 // The user is aware of this app, so make it visible. 16713 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16714 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16715 app.cached = false; 16716 app.adjType = "fg-service"; 16717 schedGroup = Process.THREAD_GROUP_DEFAULT; 16718 } else if (app.forcingToForeground != null) { 16719 // The user is aware of this app, so make it visible. 16720 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16721 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16722 app.cached = false; 16723 app.adjType = "force-fg"; 16724 app.adjSource = app.forcingToForeground; 16725 schedGroup = Process.THREAD_GROUP_DEFAULT; 16726 } 16727 } 16728 16729 if (app == mHeavyWeightProcess) { 16730 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16731 // We don't want to kill the current heavy-weight process. 16732 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16733 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16734 app.cached = false; 16735 app.adjType = "heavy"; 16736 } 16737 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16738 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16739 } 16740 } 16741 16742 if (app == mHomeProcess) { 16743 if (adj > ProcessList.HOME_APP_ADJ) { 16744 // This process is hosting what we currently consider to be the 16745 // home app, so we don't want to let it go into the background. 16746 adj = ProcessList.HOME_APP_ADJ; 16747 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16748 app.cached = false; 16749 app.adjType = "home"; 16750 } 16751 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16752 procState = ActivityManager.PROCESS_STATE_HOME; 16753 } 16754 } 16755 16756 if (app == mPreviousProcess && app.activities.size() > 0) { 16757 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16758 // This was the previous process that showed UI to the user. 16759 // We want to try to keep it around more aggressively, to give 16760 // a good experience around switching between two apps. 16761 adj = ProcessList.PREVIOUS_APP_ADJ; 16762 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16763 app.cached = false; 16764 app.adjType = "previous"; 16765 } 16766 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16767 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16768 } 16769 } 16770 16771 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16772 + " reason=" + app.adjType); 16773 16774 // By default, we use the computed adjustment. It may be changed if 16775 // there are applications dependent on our services or providers, but 16776 // this gives us a baseline and makes sure we don't get into an 16777 // infinite recursion. 16778 app.adjSeq = mAdjSeq; 16779 app.curRawAdj = adj; 16780 app.hasStartedServices = false; 16781 16782 if (mBackupTarget != null && app == mBackupTarget.app) { 16783 // If possible we want to avoid killing apps while they're being backed up 16784 if (adj > ProcessList.BACKUP_APP_ADJ) { 16785 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16786 adj = ProcessList.BACKUP_APP_ADJ; 16787 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16788 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16789 } 16790 app.adjType = "backup"; 16791 app.cached = false; 16792 } 16793 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16794 procState = ActivityManager.PROCESS_STATE_BACKUP; 16795 } 16796 } 16797 16798 boolean mayBeTop = false; 16799 16800 for (int is = app.services.size()-1; 16801 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16802 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16803 || procState > ActivityManager.PROCESS_STATE_TOP); 16804 is--) { 16805 ServiceRecord s = app.services.valueAt(is); 16806 if (s.startRequested) { 16807 app.hasStartedServices = true; 16808 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16809 procState = ActivityManager.PROCESS_STATE_SERVICE; 16810 } 16811 if (app.hasShownUi && app != mHomeProcess) { 16812 // If this process has shown some UI, let it immediately 16813 // go to the LRU list because it may be pretty heavy with 16814 // UI stuff. We'll tag it with a label just to help 16815 // debug and understand what is going on. 16816 if (adj > ProcessList.SERVICE_ADJ) { 16817 app.adjType = "cch-started-ui-services"; 16818 } 16819 } else { 16820 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16821 // This service has seen some activity within 16822 // recent memory, so we will keep its process ahead 16823 // of the background processes. 16824 if (adj > ProcessList.SERVICE_ADJ) { 16825 adj = ProcessList.SERVICE_ADJ; 16826 app.adjType = "started-services"; 16827 app.cached = false; 16828 } 16829 } 16830 // If we have let the service slide into the background 16831 // state, still have some text describing what it is doing 16832 // even though the service no longer has an impact. 16833 if (adj > ProcessList.SERVICE_ADJ) { 16834 app.adjType = "cch-started-services"; 16835 } 16836 } 16837 } 16838 for (int conni = s.connections.size()-1; 16839 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16840 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16841 || procState > ActivityManager.PROCESS_STATE_TOP); 16842 conni--) { 16843 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16844 for (int i = 0; 16845 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16846 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16847 || procState > ActivityManager.PROCESS_STATE_TOP); 16848 i++) { 16849 // XXX should compute this based on the max of 16850 // all connected clients. 16851 ConnectionRecord cr = clist.get(i); 16852 if (cr.binding.client == app) { 16853 // Binding to ourself is not interesting. 16854 continue; 16855 } 16856 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16857 ProcessRecord client = cr.binding.client; 16858 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16859 TOP_APP, doingAll, now); 16860 int clientProcState = client.curProcState; 16861 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16862 // If the other app is cached for any reason, for purposes here 16863 // we are going to consider it empty. The specific cached state 16864 // doesn't propagate except under certain conditions. 16865 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16866 } 16867 String adjType = null; 16868 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16869 // Not doing bind OOM management, so treat 16870 // this guy more like a started service. 16871 if (app.hasShownUi && app != mHomeProcess) { 16872 // If this process has shown some UI, let it immediately 16873 // go to the LRU list because it may be pretty heavy with 16874 // UI stuff. We'll tag it with a label just to help 16875 // debug and understand what is going on. 16876 if (adj > clientAdj) { 16877 adjType = "cch-bound-ui-services"; 16878 } 16879 app.cached = false; 16880 clientAdj = adj; 16881 clientProcState = procState; 16882 } else { 16883 if (now >= (s.lastActivity 16884 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16885 // This service has not seen activity within 16886 // recent memory, so allow it to drop to the 16887 // LRU list if there is no other reason to keep 16888 // it around. We'll also tag it with a label just 16889 // to help debug and undertand what is going on. 16890 if (adj > clientAdj) { 16891 adjType = "cch-bound-services"; 16892 } 16893 clientAdj = adj; 16894 } 16895 } 16896 } 16897 if (adj > clientAdj) { 16898 // If this process has recently shown UI, and 16899 // the process that is binding to it is less 16900 // important than being visible, then we don't 16901 // care about the binding as much as we care 16902 // about letting this process get into the LRU 16903 // list to be killed and restarted if needed for 16904 // memory. 16905 if (app.hasShownUi && app != mHomeProcess 16906 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16907 adjType = "cch-bound-ui-services"; 16908 } else { 16909 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16910 |Context.BIND_IMPORTANT)) != 0) { 16911 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 16912 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 16913 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16914 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16915 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16916 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16917 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16918 adj = clientAdj; 16919 } else { 16920 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16921 adj = ProcessList.VISIBLE_APP_ADJ; 16922 } 16923 } 16924 if (!client.cached) { 16925 app.cached = false; 16926 } 16927 adjType = "service"; 16928 } 16929 } 16930 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16931 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16932 schedGroup = Process.THREAD_GROUP_DEFAULT; 16933 } 16934 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16935 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16936 // Special handling of clients who are in the top state. 16937 // We *may* want to consider this process to be in the 16938 // top state as well, but only if there is not another 16939 // reason for it to be running. Being on the top is a 16940 // special state, meaning you are specifically running 16941 // for the current top app. If the process is already 16942 // running in the background for some other reason, it 16943 // is more important to continue considering it to be 16944 // in the background state. 16945 mayBeTop = true; 16946 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16947 } else { 16948 // Special handling for above-top states (persistent 16949 // processes). These should not bring the current process 16950 // into the top state, since they are not on top. Instead 16951 // give them the best state after that. 16952 clientProcState = 16953 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16954 } 16955 } 16956 } else { 16957 if (clientProcState < 16958 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16959 clientProcState = 16960 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16961 } 16962 } 16963 if (procState > clientProcState) { 16964 procState = clientProcState; 16965 } 16966 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16967 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16968 app.pendingUiClean = true; 16969 } 16970 if (adjType != null) { 16971 app.adjType = adjType; 16972 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16973 .REASON_SERVICE_IN_USE; 16974 app.adjSource = cr.binding.client; 16975 app.adjSourceProcState = clientProcState; 16976 app.adjTarget = s.name; 16977 } 16978 } 16979 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16980 app.treatLikeActivity = true; 16981 } 16982 final ActivityRecord a = cr.activity; 16983 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16984 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16985 (a.visible || a.state == ActivityState.RESUMED 16986 || a.state == ActivityState.PAUSING)) { 16987 adj = ProcessList.FOREGROUND_APP_ADJ; 16988 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16989 schedGroup = Process.THREAD_GROUP_DEFAULT; 16990 } 16991 app.cached = false; 16992 app.adjType = "service"; 16993 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16994 .REASON_SERVICE_IN_USE; 16995 app.adjSource = a; 16996 app.adjSourceProcState = procState; 16997 app.adjTarget = s.name; 16998 } 16999 } 17000 } 17001 } 17002 } 17003 17004 for (int provi = app.pubProviders.size()-1; 17005 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17006 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17007 || procState > ActivityManager.PROCESS_STATE_TOP); 17008 provi--) { 17009 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17010 for (int i = cpr.connections.size()-1; 17011 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17012 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17013 || procState > ActivityManager.PROCESS_STATE_TOP); 17014 i--) { 17015 ContentProviderConnection conn = cpr.connections.get(i); 17016 ProcessRecord client = conn.client; 17017 if (client == app) { 17018 // Being our own client is not interesting. 17019 continue; 17020 } 17021 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17022 int clientProcState = client.curProcState; 17023 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17024 // If the other app is cached for any reason, for purposes here 17025 // we are going to consider it empty. 17026 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17027 } 17028 if (adj > clientAdj) { 17029 if (app.hasShownUi && app != mHomeProcess 17030 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17031 app.adjType = "cch-ui-provider"; 17032 } else { 17033 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17034 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17035 app.adjType = "provider"; 17036 } 17037 app.cached &= client.cached; 17038 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17039 .REASON_PROVIDER_IN_USE; 17040 app.adjSource = client; 17041 app.adjSourceProcState = clientProcState; 17042 app.adjTarget = cpr.name; 17043 } 17044 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17045 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17046 // Special handling of clients who are in the top state. 17047 // We *may* want to consider this process to be in the 17048 // top state as well, but only if there is not another 17049 // reason for it to be running. Being on the top is a 17050 // special state, meaning you are specifically running 17051 // for the current top app. If the process is already 17052 // running in the background for some other reason, it 17053 // is more important to continue considering it to be 17054 // in the background state. 17055 mayBeTop = true; 17056 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17057 } else { 17058 // Special handling for above-top states (persistent 17059 // processes). These should not bring the current process 17060 // into the top state, since they are not on top. Instead 17061 // give them the best state after that. 17062 clientProcState = 17063 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17064 } 17065 } 17066 if (procState > clientProcState) { 17067 procState = clientProcState; 17068 } 17069 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17070 schedGroup = Process.THREAD_GROUP_DEFAULT; 17071 } 17072 } 17073 // If the provider has external (non-framework) process 17074 // dependencies, ensure that its adjustment is at least 17075 // FOREGROUND_APP_ADJ. 17076 if (cpr.hasExternalProcessHandles()) { 17077 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17078 adj = ProcessList.FOREGROUND_APP_ADJ; 17079 schedGroup = Process.THREAD_GROUP_DEFAULT; 17080 app.cached = false; 17081 app.adjType = "provider"; 17082 app.adjTarget = cpr.name; 17083 } 17084 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17085 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17086 } 17087 } 17088 } 17089 17090 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17091 // A client of one of our services or providers is in the top state. We 17092 // *may* want to be in the top state, but not if we are already running in 17093 // the background for some other reason. For the decision here, we are going 17094 // to pick out a few specific states that we want to remain in when a client 17095 // is top (states that tend to be longer-term) and otherwise allow it to go 17096 // to the top state. 17097 switch (procState) { 17098 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17099 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17100 case ActivityManager.PROCESS_STATE_SERVICE: 17101 // These all are longer-term states, so pull them up to the top 17102 // of the background states, but not all the way to the top state. 17103 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17104 break; 17105 default: 17106 // Otherwise, top is a better choice, so take it. 17107 procState = ActivityManager.PROCESS_STATE_TOP; 17108 break; 17109 } 17110 } 17111 17112 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17113 if (app.hasClientActivities) { 17114 // This is a cached process, but with client activities. Mark it so. 17115 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17116 app.adjType = "cch-client-act"; 17117 } else if (app.treatLikeActivity) { 17118 // This is a cached process, but somebody wants us to treat it like it has 17119 // an activity, okay! 17120 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17121 app.adjType = "cch-as-act"; 17122 } 17123 } 17124 17125 if (adj == ProcessList.SERVICE_ADJ) { 17126 if (doingAll) { 17127 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17128 mNewNumServiceProcs++; 17129 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17130 if (!app.serviceb) { 17131 // This service isn't far enough down on the LRU list to 17132 // normally be a B service, but if we are low on RAM and it 17133 // is large we want to force it down since we would prefer to 17134 // keep launcher over it. 17135 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17136 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17137 app.serviceHighRam = true; 17138 app.serviceb = true; 17139 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17140 } else { 17141 mNewNumAServiceProcs++; 17142 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17143 } 17144 } else { 17145 app.serviceHighRam = false; 17146 } 17147 } 17148 if (app.serviceb) { 17149 adj = ProcessList.SERVICE_B_ADJ; 17150 } 17151 } 17152 17153 app.curRawAdj = adj; 17154 17155 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17156 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17157 if (adj > app.maxAdj) { 17158 adj = app.maxAdj; 17159 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17160 schedGroup = Process.THREAD_GROUP_DEFAULT; 17161 } 17162 } 17163 17164 // Do final modification to adj. Everything we do between here and applying 17165 // the final setAdj must be done in this function, because we will also use 17166 // it when computing the final cached adj later. Note that we don't need to 17167 // worry about this for max adj above, since max adj will always be used to 17168 // keep it out of the cached vaues. 17169 app.curAdj = app.modifyRawOomAdj(adj); 17170 app.curSchedGroup = schedGroup; 17171 app.curProcState = procState; 17172 app.foregroundActivities = foregroundActivities; 17173 17174 return app.curRawAdj; 17175 } 17176 17177 /** 17178 * Schedule PSS collection of a process. 17179 */ 17180 void requestPssLocked(ProcessRecord proc, int procState) { 17181 if (mPendingPssProcesses.contains(proc)) { 17182 return; 17183 } 17184 if (mPendingPssProcesses.size() == 0) { 17185 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17186 } 17187 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17188 proc.pssProcState = procState; 17189 mPendingPssProcesses.add(proc); 17190 } 17191 17192 /** 17193 * Schedule PSS collection of all processes. 17194 */ 17195 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17196 if (!always) { 17197 if (now < (mLastFullPssTime + 17198 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17199 return; 17200 } 17201 } 17202 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17203 mLastFullPssTime = now; 17204 mFullPssPending = true; 17205 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17206 mPendingPssProcesses.clear(); 17207 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17208 ProcessRecord app = mLruProcesses.get(i); 17209 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17210 app.pssProcState = app.setProcState; 17211 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17212 isSleeping(), now); 17213 mPendingPssProcesses.add(app); 17214 } 17215 } 17216 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17217 } 17218 17219 /** 17220 * Ask a given process to GC right now. 17221 */ 17222 final void performAppGcLocked(ProcessRecord app) { 17223 try { 17224 app.lastRequestedGc = SystemClock.uptimeMillis(); 17225 if (app.thread != null) { 17226 if (app.reportLowMemory) { 17227 app.reportLowMemory = false; 17228 app.thread.scheduleLowMemory(); 17229 } else { 17230 app.thread.processInBackground(); 17231 } 17232 } 17233 } catch (Exception e) { 17234 // whatever. 17235 } 17236 } 17237 17238 /** 17239 * Returns true if things are idle enough to perform GCs. 17240 */ 17241 private final boolean canGcNowLocked() { 17242 boolean processingBroadcasts = false; 17243 for (BroadcastQueue q : mBroadcastQueues) { 17244 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17245 processingBroadcasts = true; 17246 } 17247 } 17248 return !processingBroadcasts 17249 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17250 } 17251 17252 /** 17253 * Perform GCs on all processes that are waiting for it, but only 17254 * if things are idle. 17255 */ 17256 final void performAppGcsLocked() { 17257 final int N = mProcessesToGc.size(); 17258 if (N <= 0) { 17259 return; 17260 } 17261 if (canGcNowLocked()) { 17262 while (mProcessesToGc.size() > 0) { 17263 ProcessRecord proc = mProcessesToGc.remove(0); 17264 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17265 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17266 <= SystemClock.uptimeMillis()) { 17267 // To avoid spamming the system, we will GC processes one 17268 // at a time, waiting a few seconds between each. 17269 performAppGcLocked(proc); 17270 scheduleAppGcsLocked(); 17271 return; 17272 } else { 17273 // It hasn't been long enough since we last GCed this 17274 // process... put it in the list to wait for its time. 17275 addProcessToGcListLocked(proc); 17276 break; 17277 } 17278 } 17279 } 17280 17281 scheduleAppGcsLocked(); 17282 } 17283 } 17284 17285 /** 17286 * If all looks good, perform GCs on all processes waiting for them. 17287 */ 17288 final void performAppGcsIfAppropriateLocked() { 17289 if (canGcNowLocked()) { 17290 performAppGcsLocked(); 17291 return; 17292 } 17293 // Still not idle, wait some more. 17294 scheduleAppGcsLocked(); 17295 } 17296 17297 /** 17298 * Schedule the execution of all pending app GCs. 17299 */ 17300 final void scheduleAppGcsLocked() { 17301 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17302 17303 if (mProcessesToGc.size() > 0) { 17304 // Schedule a GC for the time to the next process. 17305 ProcessRecord proc = mProcessesToGc.get(0); 17306 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17307 17308 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17309 long now = SystemClock.uptimeMillis(); 17310 if (when < (now+GC_TIMEOUT)) { 17311 when = now + GC_TIMEOUT; 17312 } 17313 mHandler.sendMessageAtTime(msg, when); 17314 } 17315 } 17316 17317 /** 17318 * Add a process to the array of processes waiting to be GCed. Keeps the 17319 * list in sorted order by the last GC time. The process can't already be 17320 * on the list. 17321 */ 17322 final void addProcessToGcListLocked(ProcessRecord proc) { 17323 boolean added = false; 17324 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17325 if (mProcessesToGc.get(i).lastRequestedGc < 17326 proc.lastRequestedGc) { 17327 added = true; 17328 mProcessesToGc.add(i+1, proc); 17329 break; 17330 } 17331 } 17332 if (!added) { 17333 mProcessesToGc.add(0, proc); 17334 } 17335 } 17336 17337 /** 17338 * Set up to ask a process to GC itself. This will either do it 17339 * immediately, or put it on the list of processes to gc the next 17340 * time things are idle. 17341 */ 17342 final void scheduleAppGcLocked(ProcessRecord app) { 17343 long now = SystemClock.uptimeMillis(); 17344 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17345 return; 17346 } 17347 if (!mProcessesToGc.contains(app)) { 17348 addProcessToGcListLocked(app); 17349 scheduleAppGcsLocked(); 17350 } 17351 } 17352 17353 final void checkExcessivePowerUsageLocked(boolean doKills) { 17354 updateCpuStatsNow(); 17355 17356 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17357 boolean doWakeKills = doKills; 17358 boolean doCpuKills = doKills; 17359 if (mLastPowerCheckRealtime == 0) { 17360 doWakeKills = false; 17361 } 17362 if (mLastPowerCheckUptime == 0) { 17363 doCpuKills = false; 17364 } 17365 if (stats.isScreenOn()) { 17366 doWakeKills = false; 17367 } 17368 final long curRealtime = SystemClock.elapsedRealtime(); 17369 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17370 final long curUptime = SystemClock.uptimeMillis(); 17371 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17372 mLastPowerCheckRealtime = curRealtime; 17373 mLastPowerCheckUptime = curUptime; 17374 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17375 doWakeKills = false; 17376 } 17377 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17378 doCpuKills = false; 17379 } 17380 int i = mLruProcesses.size(); 17381 while (i > 0) { 17382 i--; 17383 ProcessRecord app = mLruProcesses.get(i); 17384 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17385 long wtime; 17386 synchronized (stats) { 17387 wtime = stats.getProcessWakeTime(app.info.uid, 17388 app.pid, curRealtime); 17389 } 17390 long wtimeUsed = wtime - app.lastWakeTime; 17391 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17392 if (DEBUG_POWER) { 17393 StringBuilder sb = new StringBuilder(128); 17394 sb.append("Wake for "); 17395 app.toShortString(sb); 17396 sb.append(": over "); 17397 TimeUtils.formatDuration(realtimeSince, sb); 17398 sb.append(" used "); 17399 TimeUtils.formatDuration(wtimeUsed, sb); 17400 sb.append(" ("); 17401 sb.append((wtimeUsed*100)/realtimeSince); 17402 sb.append("%)"); 17403 Slog.i(TAG, sb.toString()); 17404 sb.setLength(0); 17405 sb.append("CPU for "); 17406 app.toShortString(sb); 17407 sb.append(": over "); 17408 TimeUtils.formatDuration(uptimeSince, sb); 17409 sb.append(" used "); 17410 TimeUtils.formatDuration(cputimeUsed, sb); 17411 sb.append(" ("); 17412 sb.append((cputimeUsed*100)/uptimeSince); 17413 sb.append("%)"); 17414 Slog.i(TAG, sb.toString()); 17415 } 17416 // If a process has held a wake lock for more 17417 // than 50% of the time during this period, 17418 // that sounds bad. Kill! 17419 if (doWakeKills && realtimeSince > 0 17420 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17421 synchronized (stats) { 17422 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17423 realtimeSince, wtimeUsed); 17424 } 17425 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17426 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17427 } else if (doCpuKills && uptimeSince > 0 17428 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17429 synchronized (stats) { 17430 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17431 uptimeSince, cputimeUsed); 17432 } 17433 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17434 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17435 } else { 17436 app.lastWakeTime = wtime; 17437 app.lastCpuTime = app.curCpuTime; 17438 } 17439 } 17440 } 17441 } 17442 17443 private final boolean applyOomAdjLocked(ProcessRecord app, 17444 ProcessRecord TOP_APP, boolean doingAll, long now) { 17445 boolean success = true; 17446 17447 if (app.curRawAdj != app.setRawAdj) { 17448 app.setRawAdj = app.curRawAdj; 17449 } 17450 17451 int changes = 0; 17452 17453 if (app.curAdj != app.setAdj) { 17454 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17455 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17456 TAG, "Set " + app.pid + " " + app.processName + 17457 " adj " + app.curAdj + ": " + app.adjType); 17458 app.setAdj = app.curAdj; 17459 } 17460 17461 if (app.setSchedGroup != app.curSchedGroup) { 17462 app.setSchedGroup = app.curSchedGroup; 17463 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17464 "Setting process group of " + app.processName 17465 + " to " + app.curSchedGroup); 17466 if (app.waitingToKill != null && 17467 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17468 app.kill(app.waitingToKill, true); 17469 success = false; 17470 } else { 17471 if (true) { 17472 long oldId = Binder.clearCallingIdentity(); 17473 try { 17474 Process.setProcessGroup(app.pid, app.curSchedGroup); 17475 } catch (Exception e) { 17476 Slog.w(TAG, "Failed setting process group of " + app.pid 17477 + " to " + app.curSchedGroup); 17478 e.printStackTrace(); 17479 } finally { 17480 Binder.restoreCallingIdentity(oldId); 17481 } 17482 } else { 17483 if (app.thread != null) { 17484 try { 17485 app.thread.setSchedulingGroup(app.curSchedGroup); 17486 } catch (RemoteException e) { 17487 } 17488 } 17489 } 17490 Process.setSwappiness(app.pid, 17491 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17492 } 17493 } 17494 if (app.repForegroundActivities != app.foregroundActivities) { 17495 app.repForegroundActivities = app.foregroundActivities; 17496 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17497 } 17498 if (app.repProcState != app.curProcState) { 17499 app.repProcState = app.curProcState; 17500 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17501 if (app.thread != null) { 17502 try { 17503 if (false) { 17504 //RuntimeException h = new RuntimeException("here"); 17505 Slog.i(TAG, "Sending new process state " + app.repProcState 17506 + " to " + app /*, h*/); 17507 } 17508 app.thread.setProcessState(app.repProcState); 17509 } catch (RemoteException e) { 17510 } 17511 } 17512 } 17513 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17514 app.setProcState)) { 17515 app.lastStateTime = now; 17516 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17517 isSleeping(), now); 17518 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17519 + ProcessList.makeProcStateString(app.setProcState) + " to " 17520 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17521 + (app.nextPssTime-now) + ": " + app); 17522 } else { 17523 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17524 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17525 requestPssLocked(app, app.setProcState); 17526 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17527 isSleeping(), now); 17528 } else if (false && DEBUG_PSS) { 17529 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17530 } 17531 } 17532 if (app.setProcState != app.curProcState) { 17533 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17534 "Proc state change of " + app.processName 17535 + " to " + app.curProcState); 17536 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17537 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17538 if (setImportant && !curImportant) { 17539 // This app is no longer something we consider important enough to allow to 17540 // use arbitrary amounts of battery power. Note 17541 // its current wake lock time to later know to kill it if 17542 // it is not behaving well. 17543 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17544 synchronized (stats) { 17545 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17546 app.pid, SystemClock.elapsedRealtime()); 17547 } 17548 app.lastCpuTime = app.curCpuTime; 17549 17550 } 17551 app.setProcState = app.curProcState; 17552 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17553 app.notCachedSinceIdle = false; 17554 } 17555 if (!doingAll) { 17556 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17557 } else { 17558 app.procStateChanged = true; 17559 } 17560 } 17561 17562 if (changes != 0) { 17563 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17564 int i = mPendingProcessChanges.size()-1; 17565 ProcessChangeItem item = null; 17566 while (i >= 0) { 17567 item = mPendingProcessChanges.get(i); 17568 if (item.pid == app.pid) { 17569 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17570 break; 17571 } 17572 i--; 17573 } 17574 if (i < 0) { 17575 // No existing item in pending changes; need a new one. 17576 final int NA = mAvailProcessChanges.size(); 17577 if (NA > 0) { 17578 item = mAvailProcessChanges.remove(NA-1); 17579 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17580 } else { 17581 item = new ProcessChangeItem(); 17582 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17583 } 17584 item.changes = 0; 17585 item.pid = app.pid; 17586 item.uid = app.info.uid; 17587 if (mPendingProcessChanges.size() == 0) { 17588 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17589 "*** Enqueueing dispatch processes changed!"); 17590 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17591 } 17592 mPendingProcessChanges.add(item); 17593 } 17594 item.changes |= changes; 17595 item.processState = app.repProcState; 17596 item.foregroundActivities = app.repForegroundActivities; 17597 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17598 + Integer.toHexString(System.identityHashCode(item)) 17599 + " " + app.toShortString() + ": changes=" + item.changes 17600 + " procState=" + item.processState 17601 + " foreground=" + item.foregroundActivities 17602 + " type=" + app.adjType + " source=" + app.adjSource 17603 + " target=" + app.adjTarget); 17604 } 17605 17606 return success; 17607 } 17608 17609 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17610 if (proc.thread != null) { 17611 if (proc.baseProcessTracker != null) { 17612 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17613 } 17614 if (proc.repProcState >= 0) { 17615 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17616 proc.repProcState); 17617 } 17618 } 17619 } 17620 17621 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17622 ProcessRecord TOP_APP, boolean doingAll, long now) { 17623 if (app.thread == null) { 17624 return false; 17625 } 17626 17627 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17628 17629 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17630 } 17631 17632 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17633 boolean oomAdj) { 17634 if (isForeground != proc.foregroundServices) { 17635 proc.foregroundServices = isForeground; 17636 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17637 proc.info.uid); 17638 if (isForeground) { 17639 if (curProcs == null) { 17640 curProcs = new ArrayList<ProcessRecord>(); 17641 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17642 } 17643 if (!curProcs.contains(proc)) { 17644 curProcs.add(proc); 17645 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17646 proc.info.packageName, proc.info.uid); 17647 } 17648 } else { 17649 if (curProcs != null) { 17650 if (curProcs.remove(proc)) { 17651 mBatteryStatsService.noteEvent( 17652 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17653 proc.info.packageName, proc.info.uid); 17654 if (curProcs.size() <= 0) { 17655 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17656 } 17657 } 17658 } 17659 } 17660 if (oomAdj) { 17661 updateOomAdjLocked(); 17662 } 17663 } 17664 } 17665 17666 private final ActivityRecord resumedAppLocked() { 17667 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17668 String pkg; 17669 int uid; 17670 if (act != null) { 17671 pkg = act.packageName; 17672 uid = act.info.applicationInfo.uid; 17673 } else { 17674 pkg = null; 17675 uid = -1; 17676 } 17677 // Has the UID or resumed package name changed? 17678 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17679 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17680 if (mCurResumedPackage != null) { 17681 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17682 mCurResumedPackage, mCurResumedUid); 17683 } 17684 mCurResumedPackage = pkg; 17685 mCurResumedUid = uid; 17686 if (mCurResumedPackage != null) { 17687 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17688 mCurResumedPackage, mCurResumedUid); 17689 } 17690 } 17691 return act; 17692 } 17693 17694 final boolean updateOomAdjLocked(ProcessRecord app) { 17695 final ActivityRecord TOP_ACT = resumedAppLocked(); 17696 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17697 final boolean wasCached = app.cached; 17698 17699 mAdjSeq++; 17700 17701 // This is the desired cached adjusment we want to tell it to use. 17702 // If our app is currently cached, we know it, and that is it. Otherwise, 17703 // we don't know it yet, and it needs to now be cached we will then 17704 // need to do a complete oom adj. 17705 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17706 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17707 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17708 SystemClock.uptimeMillis()); 17709 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17710 // Changed to/from cached state, so apps after it in the LRU 17711 // list may also be changed. 17712 updateOomAdjLocked(); 17713 } 17714 return success; 17715 } 17716 17717 final void updateOomAdjLocked() { 17718 final ActivityRecord TOP_ACT = resumedAppLocked(); 17719 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17720 final long now = SystemClock.uptimeMillis(); 17721 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17722 final int N = mLruProcesses.size(); 17723 17724 if (false) { 17725 RuntimeException e = new RuntimeException(); 17726 e.fillInStackTrace(); 17727 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17728 } 17729 17730 mAdjSeq++; 17731 mNewNumServiceProcs = 0; 17732 mNewNumAServiceProcs = 0; 17733 17734 final int emptyProcessLimit; 17735 final int cachedProcessLimit; 17736 if (mProcessLimit <= 0) { 17737 emptyProcessLimit = cachedProcessLimit = 0; 17738 } else if (mProcessLimit == 1) { 17739 emptyProcessLimit = 1; 17740 cachedProcessLimit = 0; 17741 } else { 17742 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17743 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17744 } 17745 17746 // Let's determine how many processes we have running vs. 17747 // how many slots we have for background processes; we may want 17748 // to put multiple processes in a slot of there are enough of 17749 // them. 17750 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17751 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17752 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17753 if (numEmptyProcs > cachedProcessLimit) { 17754 // If there are more empty processes than our limit on cached 17755 // processes, then use the cached process limit for the factor. 17756 // This ensures that the really old empty processes get pushed 17757 // down to the bottom, so if we are running low on memory we will 17758 // have a better chance at keeping around more cached processes 17759 // instead of a gazillion empty processes. 17760 numEmptyProcs = cachedProcessLimit; 17761 } 17762 int emptyFactor = numEmptyProcs/numSlots; 17763 if (emptyFactor < 1) emptyFactor = 1; 17764 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17765 if (cachedFactor < 1) cachedFactor = 1; 17766 int stepCached = 0; 17767 int stepEmpty = 0; 17768 int numCached = 0; 17769 int numEmpty = 0; 17770 int numTrimming = 0; 17771 17772 mNumNonCachedProcs = 0; 17773 mNumCachedHiddenProcs = 0; 17774 17775 // First update the OOM adjustment for each of the 17776 // application processes based on their current state. 17777 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17778 int nextCachedAdj = curCachedAdj+1; 17779 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17780 int nextEmptyAdj = curEmptyAdj+2; 17781 for (int i=N-1; i>=0; i--) { 17782 ProcessRecord app = mLruProcesses.get(i); 17783 if (!app.killedByAm && app.thread != null) { 17784 app.procStateChanged = false; 17785 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17786 17787 // If we haven't yet assigned the final cached adj 17788 // to the process, do that now. 17789 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17790 switch (app.curProcState) { 17791 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17792 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17793 // This process is a cached process holding activities... 17794 // assign it the next cached value for that type, and then 17795 // step that cached level. 17796 app.curRawAdj = curCachedAdj; 17797 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17798 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17799 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17800 + ")"); 17801 if (curCachedAdj != nextCachedAdj) { 17802 stepCached++; 17803 if (stepCached >= cachedFactor) { 17804 stepCached = 0; 17805 curCachedAdj = nextCachedAdj; 17806 nextCachedAdj += 2; 17807 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17808 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17809 } 17810 } 17811 } 17812 break; 17813 default: 17814 // For everything else, assign next empty cached process 17815 // level and bump that up. Note that this means that 17816 // long-running services that have dropped down to the 17817 // cached level will be treated as empty (since their process 17818 // state is still as a service), which is what we want. 17819 app.curRawAdj = curEmptyAdj; 17820 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17821 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17822 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17823 + ")"); 17824 if (curEmptyAdj != nextEmptyAdj) { 17825 stepEmpty++; 17826 if (stepEmpty >= emptyFactor) { 17827 stepEmpty = 0; 17828 curEmptyAdj = nextEmptyAdj; 17829 nextEmptyAdj += 2; 17830 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17831 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17832 } 17833 } 17834 } 17835 break; 17836 } 17837 } 17838 17839 applyOomAdjLocked(app, TOP_APP, true, now); 17840 17841 // Count the number of process types. 17842 switch (app.curProcState) { 17843 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17844 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17845 mNumCachedHiddenProcs++; 17846 numCached++; 17847 if (numCached > cachedProcessLimit) { 17848 app.kill("cached #" + numCached, true); 17849 } 17850 break; 17851 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17852 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17853 && app.lastActivityTime < oldTime) { 17854 app.kill("empty for " 17855 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17856 / 1000) + "s", true); 17857 } else { 17858 numEmpty++; 17859 if (numEmpty > emptyProcessLimit) { 17860 app.kill("empty #" + numEmpty, true); 17861 } 17862 } 17863 break; 17864 default: 17865 mNumNonCachedProcs++; 17866 break; 17867 } 17868 17869 if (app.isolated && app.services.size() <= 0) { 17870 // If this is an isolated process, and there are no 17871 // services running in it, then the process is no longer 17872 // needed. We agressively kill these because we can by 17873 // definition not re-use the same process again, and it is 17874 // good to avoid having whatever code was running in them 17875 // left sitting around after no longer needed. 17876 app.kill("isolated not needed", true); 17877 } 17878 17879 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17880 && !app.killedByAm) { 17881 numTrimming++; 17882 } 17883 } 17884 } 17885 17886 mNumServiceProcs = mNewNumServiceProcs; 17887 17888 // Now determine the memory trimming level of background processes. 17889 // Unfortunately we need to start at the back of the list to do this 17890 // properly. We only do this if the number of background apps we 17891 // are managing to keep around is less than half the maximum we desire; 17892 // if we are keeping a good number around, we'll let them use whatever 17893 // memory they want. 17894 final int numCachedAndEmpty = numCached + numEmpty; 17895 int memFactor; 17896 if (numCached <= ProcessList.TRIM_CACHED_APPS 17897 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17898 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17899 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17900 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17901 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17902 } else { 17903 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17904 } 17905 } else { 17906 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17907 } 17908 // We always allow the memory level to go up (better). We only allow it to go 17909 // down if we are in a state where that is allowed, *and* the total number of processes 17910 // has gone down since last time. 17911 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17912 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17913 + " last=" + mLastNumProcesses); 17914 if (memFactor > mLastMemoryLevel) { 17915 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17916 memFactor = mLastMemoryLevel; 17917 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17918 } 17919 } 17920 mLastMemoryLevel = memFactor; 17921 mLastNumProcesses = mLruProcesses.size(); 17922 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17923 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17924 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17925 if (mLowRamStartTime == 0) { 17926 mLowRamStartTime = now; 17927 } 17928 int step = 0; 17929 int fgTrimLevel; 17930 switch (memFactor) { 17931 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17932 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17933 break; 17934 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17935 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17936 break; 17937 default: 17938 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17939 break; 17940 } 17941 int factor = numTrimming/3; 17942 int minFactor = 2; 17943 if (mHomeProcess != null) minFactor++; 17944 if (mPreviousProcess != null) minFactor++; 17945 if (factor < minFactor) factor = minFactor; 17946 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17947 for (int i=N-1; i>=0; i--) { 17948 ProcessRecord app = mLruProcesses.get(i); 17949 if (allChanged || app.procStateChanged) { 17950 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17951 app.procStateChanged = false; 17952 } 17953 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17954 && !app.killedByAm) { 17955 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17956 try { 17957 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17958 "Trimming memory of " + app.processName 17959 + " to " + curLevel); 17960 app.thread.scheduleTrimMemory(curLevel); 17961 } catch (RemoteException e) { 17962 } 17963 if (false) { 17964 // For now we won't do this; our memory trimming seems 17965 // to be good enough at this point that destroying 17966 // activities causes more harm than good. 17967 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17968 && app != mHomeProcess && app != mPreviousProcess) { 17969 // Need to do this on its own message because the stack may not 17970 // be in a consistent state at this point. 17971 // For these apps we will also finish their activities 17972 // to help them free memory. 17973 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17974 } 17975 } 17976 } 17977 app.trimMemoryLevel = curLevel; 17978 step++; 17979 if (step >= factor) { 17980 step = 0; 17981 switch (curLevel) { 17982 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17983 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17984 break; 17985 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17986 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17987 break; 17988 } 17989 } 17990 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17991 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17992 && app.thread != null) { 17993 try { 17994 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17995 "Trimming memory of heavy-weight " + app.processName 17996 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17997 app.thread.scheduleTrimMemory( 17998 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17999 } catch (RemoteException e) { 18000 } 18001 } 18002 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18003 } else { 18004 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18005 || app.systemNoUi) && app.pendingUiClean) { 18006 // If this application is now in the background and it 18007 // had done UI, then give it the special trim level to 18008 // have it free UI resources. 18009 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18010 if (app.trimMemoryLevel < level && app.thread != null) { 18011 try { 18012 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18013 "Trimming memory of bg-ui " + app.processName 18014 + " to " + level); 18015 app.thread.scheduleTrimMemory(level); 18016 } catch (RemoteException e) { 18017 } 18018 } 18019 app.pendingUiClean = false; 18020 } 18021 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18022 try { 18023 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18024 "Trimming memory of fg " + app.processName 18025 + " to " + fgTrimLevel); 18026 app.thread.scheduleTrimMemory(fgTrimLevel); 18027 } catch (RemoteException e) { 18028 } 18029 } 18030 app.trimMemoryLevel = fgTrimLevel; 18031 } 18032 } 18033 } else { 18034 if (mLowRamStartTime != 0) { 18035 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18036 mLowRamStartTime = 0; 18037 } 18038 for (int i=N-1; i>=0; i--) { 18039 ProcessRecord app = mLruProcesses.get(i); 18040 if (allChanged || app.procStateChanged) { 18041 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18042 app.procStateChanged = false; 18043 } 18044 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18045 || app.systemNoUi) && app.pendingUiClean) { 18046 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18047 && app.thread != null) { 18048 try { 18049 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18050 "Trimming memory of ui hidden " + app.processName 18051 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18052 app.thread.scheduleTrimMemory( 18053 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18054 } catch (RemoteException e) { 18055 } 18056 } 18057 app.pendingUiClean = false; 18058 } 18059 app.trimMemoryLevel = 0; 18060 } 18061 } 18062 18063 if (mAlwaysFinishActivities) { 18064 // Need to do this on its own message because the stack may not 18065 // be in a consistent state at this point. 18066 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18067 } 18068 18069 if (allChanged) { 18070 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18071 } 18072 18073 if (mProcessStats.shouldWriteNowLocked(now)) { 18074 mHandler.post(new Runnable() { 18075 @Override public void run() { 18076 synchronized (ActivityManagerService.this) { 18077 mProcessStats.writeStateAsyncLocked(); 18078 } 18079 } 18080 }); 18081 } 18082 18083 if (DEBUG_OOM_ADJ) { 18084 if (false) { 18085 RuntimeException here = new RuntimeException("here"); 18086 here.fillInStackTrace(); 18087 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18088 } else { 18089 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18090 } 18091 } 18092 } 18093 18094 final void trimApplications() { 18095 synchronized (this) { 18096 int i; 18097 18098 // First remove any unused application processes whose package 18099 // has been removed. 18100 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18101 final ProcessRecord app = mRemovedProcesses.get(i); 18102 if (app.activities.size() == 0 18103 && app.curReceiver == null && app.services.size() == 0) { 18104 Slog.i( 18105 TAG, "Exiting empty application process " 18106 + app.processName + " (" 18107 + (app.thread != null ? app.thread.asBinder() : null) 18108 + ")\n"); 18109 if (app.pid > 0 && app.pid != MY_PID) { 18110 app.kill("empty", false); 18111 } else { 18112 try { 18113 app.thread.scheduleExit(); 18114 } catch (Exception e) { 18115 // Ignore exceptions. 18116 } 18117 } 18118 cleanUpApplicationRecordLocked(app, false, true, -1); 18119 mRemovedProcesses.remove(i); 18120 18121 if (app.persistent) { 18122 addAppLocked(app.info, false, null /* ABI override */); 18123 } 18124 } 18125 } 18126 18127 // Now update the oom adj for all processes. 18128 updateOomAdjLocked(); 18129 } 18130 } 18131 18132 /** This method sends the specified signal to each of the persistent apps */ 18133 public void signalPersistentProcesses(int sig) throws RemoteException { 18134 if (sig != Process.SIGNAL_USR1) { 18135 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18136 } 18137 18138 synchronized (this) { 18139 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18140 != PackageManager.PERMISSION_GRANTED) { 18141 throw new SecurityException("Requires permission " 18142 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18143 } 18144 18145 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18146 ProcessRecord r = mLruProcesses.get(i); 18147 if (r.thread != null && r.persistent) { 18148 Process.sendSignal(r.pid, sig); 18149 } 18150 } 18151 } 18152 } 18153 18154 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18155 if (proc == null || proc == mProfileProc) { 18156 proc = mProfileProc; 18157 profileType = mProfileType; 18158 clearProfilerLocked(); 18159 } 18160 if (proc == null) { 18161 return; 18162 } 18163 try { 18164 proc.thread.profilerControl(false, null, profileType); 18165 } catch (RemoteException e) { 18166 throw new IllegalStateException("Process disappeared"); 18167 } 18168 } 18169 18170 private void clearProfilerLocked() { 18171 if (mProfileFd != null) { 18172 try { 18173 mProfileFd.close(); 18174 } catch (IOException e) { 18175 } 18176 } 18177 mProfileApp = null; 18178 mProfileProc = null; 18179 mProfileFile = null; 18180 mProfileType = 0; 18181 mAutoStopProfiler = false; 18182 mSamplingInterval = 0; 18183 } 18184 18185 public boolean profileControl(String process, int userId, boolean start, 18186 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18187 18188 try { 18189 synchronized (this) { 18190 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18191 // its own permission. 18192 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18193 != PackageManager.PERMISSION_GRANTED) { 18194 throw new SecurityException("Requires permission " 18195 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18196 } 18197 18198 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18199 throw new IllegalArgumentException("null profile info or fd"); 18200 } 18201 18202 ProcessRecord proc = null; 18203 if (process != null) { 18204 proc = findProcessLocked(process, userId, "profileControl"); 18205 } 18206 18207 if (start && (proc == null || proc.thread == null)) { 18208 throw new IllegalArgumentException("Unknown process: " + process); 18209 } 18210 18211 if (start) { 18212 stopProfilerLocked(null, 0); 18213 setProfileApp(proc.info, proc.processName, profilerInfo); 18214 mProfileProc = proc; 18215 mProfileType = profileType; 18216 ParcelFileDescriptor fd = profilerInfo.profileFd; 18217 try { 18218 fd = fd.dup(); 18219 } catch (IOException e) { 18220 fd = null; 18221 } 18222 profilerInfo.profileFd = fd; 18223 proc.thread.profilerControl(start, profilerInfo, profileType); 18224 fd = null; 18225 mProfileFd = null; 18226 } else { 18227 stopProfilerLocked(proc, profileType); 18228 if (profilerInfo != null && profilerInfo.profileFd != null) { 18229 try { 18230 profilerInfo.profileFd.close(); 18231 } catch (IOException e) { 18232 } 18233 } 18234 } 18235 18236 return true; 18237 } 18238 } catch (RemoteException e) { 18239 throw new IllegalStateException("Process disappeared"); 18240 } finally { 18241 if (profilerInfo != null && profilerInfo.profileFd != null) { 18242 try { 18243 profilerInfo.profileFd.close(); 18244 } catch (IOException e) { 18245 } 18246 } 18247 } 18248 } 18249 18250 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18251 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18252 userId, true, ALLOW_FULL_ONLY, callName, null); 18253 ProcessRecord proc = null; 18254 try { 18255 int pid = Integer.parseInt(process); 18256 synchronized (mPidsSelfLocked) { 18257 proc = mPidsSelfLocked.get(pid); 18258 } 18259 } catch (NumberFormatException e) { 18260 } 18261 18262 if (proc == null) { 18263 ArrayMap<String, SparseArray<ProcessRecord>> all 18264 = mProcessNames.getMap(); 18265 SparseArray<ProcessRecord> procs = all.get(process); 18266 if (procs != null && procs.size() > 0) { 18267 proc = procs.valueAt(0); 18268 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18269 for (int i=1; i<procs.size(); i++) { 18270 ProcessRecord thisProc = procs.valueAt(i); 18271 if (thisProc.userId == userId) { 18272 proc = thisProc; 18273 break; 18274 } 18275 } 18276 } 18277 } 18278 } 18279 18280 return proc; 18281 } 18282 18283 public boolean dumpHeap(String process, int userId, boolean managed, 18284 String path, ParcelFileDescriptor fd) throws RemoteException { 18285 18286 try { 18287 synchronized (this) { 18288 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18289 // its own permission (same as profileControl). 18290 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18291 != PackageManager.PERMISSION_GRANTED) { 18292 throw new SecurityException("Requires permission " 18293 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18294 } 18295 18296 if (fd == null) { 18297 throw new IllegalArgumentException("null fd"); 18298 } 18299 18300 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18301 if (proc == null || proc.thread == null) { 18302 throw new IllegalArgumentException("Unknown process: " + process); 18303 } 18304 18305 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18306 if (!isDebuggable) { 18307 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18308 throw new SecurityException("Process not debuggable: " + proc); 18309 } 18310 } 18311 18312 proc.thread.dumpHeap(managed, path, fd); 18313 fd = null; 18314 return true; 18315 } 18316 } catch (RemoteException e) { 18317 throw new IllegalStateException("Process disappeared"); 18318 } finally { 18319 if (fd != null) { 18320 try { 18321 fd.close(); 18322 } catch (IOException e) { 18323 } 18324 } 18325 } 18326 } 18327 18328 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18329 public void monitor() { 18330 synchronized (this) { } 18331 } 18332 18333 void onCoreSettingsChange(Bundle settings) { 18334 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18335 ProcessRecord processRecord = mLruProcesses.get(i); 18336 try { 18337 if (processRecord.thread != null) { 18338 processRecord.thread.setCoreSettings(settings); 18339 } 18340 } catch (RemoteException re) { 18341 /* ignore */ 18342 } 18343 } 18344 } 18345 18346 // Multi-user methods 18347 18348 /** 18349 * Start user, if its not already running, but don't bring it to foreground. 18350 */ 18351 @Override 18352 public boolean startUserInBackground(final int userId) { 18353 return startUser(userId, /* foreground */ false); 18354 } 18355 18356 /** 18357 * Start user, if its not already running, and bring it to foreground. 18358 */ 18359 boolean startUserInForeground(final int userId, Dialog dlg) { 18360 boolean result = startUser(userId, /* foreground */ true); 18361 dlg.dismiss(); 18362 return result; 18363 } 18364 18365 /** 18366 * Refreshes the list of users related to the current user when either a 18367 * user switch happens or when a new related user is started in the 18368 * background. 18369 */ 18370 private void updateCurrentProfileIdsLocked() { 18371 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18372 mCurrentUserId, false /* enabledOnly */); 18373 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18374 for (int i = 0; i < currentProfileIds.length; i++) { 18375 currentProfileIds[i] = profiles.get(i).id; 18376 } 18377 mCurrentProfileIds = currentProfileIds; 18378 18379 synchronized (mUserProfileGroupIdsSelfLocked) { 18380 mUserProfileGroupIdsSelfLocked.clear(); 18381 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18382 for (int i = 0; i < users.size(); i++) { 18383 UserInfo user = users.get(i); 18384 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18385 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18386 } 18387 } 18388 } 18389 } 18390 18391 private Set getProfileIdsLocked(int userId) { 18392 Set userIds = new HashSet<Integer>(); 18393 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18394 userId, false /* enabledOnly */); 18395 for (UserInfo user : profiles) { 18396 userIds.add(Integer.valueOf(user.id)); 18397 } 18398 return userIds; 18399 } 18400 18401 @Override 18402 public boolean switchUser(final int userId) { 18403 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18404 String userName; 18405 synchronized (this) { 18406 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18407 if (userInfo == null) { 18408 Slog.w(TAG, "No user info for user #" + userId); 18409 return false; 18410 } 18411 if (userInfo.isManagedProfile()) { 18412 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18413 return false; 18414 } 18415 userName = userInfo.name; 18416 mTargetUserId = userId; 18417 } 18418 mHandler.removeMessages(START_USER_SWITCH_MSG); 18419 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18420 return true; 18421 } 18422 18423 private void showUserSwitchDialog(int userId, String userName) { 18424 // The dialog will show and then initiate the user switch by calling startUserInForeground 18425 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18426 true /* above system */); 18427 d.show(); 18428 } 18429 18430 private boolean startUser(final int userId, final boolean foreground) { 18431 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18432 != PackageManager.PERMISSION_GRANTED) { 18433 String msg = "Permission Denial: switchUser() from pid=" 18434 + Binder.getCallingPid() 18435 + ", uid=" + Binder.getCallingUid() 18436 + " requires " + INTERACT_ACROSS_USERS_FULL; 18437 Slog.w(TAG, msg); 18438 throw new SecurityException(msg); 18439 } 18440 18441 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18442 18443 final long ident = Binder.clearCallingIdentity(); 18444 try { 18445 synchronized (this) { 18446 final int oldUserId = mCurrentUserId; 18447 if (oldUserId == userId) { 18448 return true; 18449 } 18450 18451 mStackSupervisor.setLockTaskModeLocked(null, false); 18452 18453 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18454 if (userInfo == null) { 18455 Slog.w(TAG, "No user info for user #" + userId); 18456 return false; 18457 } 18458 if (foreground && userInfo.isManagedProfile()) { 18459 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18460 return false; 18461 } 18462 18463 if (foreground) { 18464 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18465 R.anim.screen_user_enter); 18466 } 18467 18468 boolean needStart = false; 18469 18470 // If the user we are switching to is not currently started, then 18471 // we need to start it now. 18472 if (mStartedUsers.get(userId) == null) { 18473 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18474 updateStartedUserArrayLocked(); 18475 needStart = true; 18476 } 18477 18478 final Integer userIdInt = Integer.valueOf(userId); 18479 mUserLru.remove(userIdInt); 18480 mUserLru.add(userIdInt); 18481 18482 if (foreground) { 18483 mCurrentUserId = userId; 18484 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18485 updateCurrentProfileIdsLocked(); 18486 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18487 // Once the internal notion of the active user has switched, we lock the device 18488 // with the option to show the user switcher on the keyguard. 18489 mWindowManager.lockNow(null); 18490 } else { 18491 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18492 updateCurrentProfileIdsLocked(); 18493 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18494 mUserLru.remove(currentUserIdInt); 18495 mUserLru.add(currentUserIdInt); 18496 } 18497 18498 final UserStartedState uss = mStartedUsers.get(userId); 18499 18500 // Make sure user is in the started state. If it is currently 18501 // stopping, we need to knock that off. 18502 if (uss.mState == UserStartedState.STATE_STOPPING) { 18503 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18504 // so we can just fairly silently bring the user back from 18505 // the almost-dead. 18506 uss.mState = UserStartedState.STATE_RUNNING; 18507 updateStartedUserArrayLocked(); 18508 needStart = true; 18509 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18510 // This means ACTION_SHUTDOWN has been sent, so we will 18511 // need to treat this as a new boot of the user. 18512 uss.mState = UserStartedState.STATE_BOOTING; 18513 updateStartedUserArrayLocked(); 18514 needStart = true; 18515 } 18516 18517 if (uss.mState == UserStartedState.STATE_BOOTING) { 18518 // Booting up a new user, need to tell system services about it. 18519 // Note that this is on the same handler as scheduling of broadcasts, 18520 // which is important because it needs to go first. 18521 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18522 } 18523 18524 if (foreground) { 18525 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18526 oldUserId)); 18527 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18528 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18529 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18530 oldUserId, userId, uss)); 18531 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18532 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18533 } 18534 18535 if (needStart) { 18536 // Send USER_STARTED broadcast 18537 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18538 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18539 | Intent.FLAG_RECEIVER_FOREGROUND); 18540 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18541 broadcastIntentLocked(null, null, intent, 18542 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18543 false, false, MY_PID, Process.SYSTEM_UID, userId); 18544 } 18545 18546 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18547 if (userId != UserHandle.USER_OWNER) { 18548 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18549 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18550 broadcastIntentLocked(null, null, intent, null, 18551 new IIntentReceiver.Stub() { 18552 public void performReceive(Intent intent, int resultCode, 18553 String data, Bundle extras, boolean ordered, 18554 boolean sticky, int sendingUser) { 18555 onUserInitialized(uss, foreground, oldUserId, userId); 18556 } 18557 }, 0, null, null, null, AppOpsManager.OP_NONE, 18558 true, false, MY_PID, Process.SYSTEM_UID, 18559 userId); 18560 uss.initializing = true; 18561 } else { 18562 getUserManagerLocked().makeInitialized(userInfo.id); 18563 } 18564 } 18565 18566 if (foreground) { 18567 if (!uss.initializing) { 18568 moveUserToForeground(uss, oldUserId, userId); 18569 } 18570 } else { 18571 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18572 } 18573 18574 if (needStart) { 18575 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18576 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18577 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18578 broadcastIntentLocked(null, null, intent, 18579 null, new IIntentReceiver.Stub() { 18580 @Override 18581 public void performReceive(Intent intent, int resultCode, String data, 18582 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18583 throws RemoteException { 18584 } 18585 }, 0, null, null, 18586 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18587 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18588 } 18589 } 18590 } finally { 18591 Binder.restoreCallingIdentity(ident); 18592 } 18593 18594 return true; 18595 } 18596 18597 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18598 long ident = Binder.clearCallingIdentity(); 18599 try { 18600 Intent intent; 18601 if (oldUserId >= 0) { 18602 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18603 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18604 int count = profiles.size(); 18605 for (int i = 0; i < count; i++) { 18606 int profileUserId = profiles.get(i).id; 18607 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18608 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18609 | Intent.FLAG_RECEIVER_FOREGROUND); 18610 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18611 broadcastIntentLocked(null, null, intent, 18612 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18613 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18614 } 18615 } 18616 if (newUserId >= 0) { 18617 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18618 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18619 int count = profiles.size(); 18620 for (int i = 0; i < count; i++) { 18621 int profileUserId = profiles.get(i).id; 18622 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18623 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18624 | Intent.FLAG_RECEIVER_FOREGROUND); 18625 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18626 broadcastIntentLocked(null, null, intent, 18627 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18628 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18629 } 18630 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18631 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18632 | Intent.FLAG_RECEIVER_FOREGROUND); 18633 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18634 broadcastIntentLocked(null, null, intent, 18635 null, null, 0, null, null, 18636 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18637 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18638 } 18639 } finally { 18640 Binder.restoreCallingIdentity(ident); 18641 } 18642 } 18643 18644 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18645 final int newUserId) { 18646 final int N = mUserSwitchObservers.beginBroadcast(); 18647 if (N > 0) { 18648 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18649 int mCount = 0; 18650 @Override 18651 public void sendResult(Bundle data) throws RemoteException { 18652 synchronized (ActivityManagerService.this) { 18653 if (mCurUserSwitchCallback == this) { 18654 mCount++; 18655 if (mCount == N) { 18656 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18657 } 18658 } 18659 } 18660 } 18661 }; 18662 synchronized (this) { 18663 uss.switching = true; 18664 mCurUserSwitchCallback = callback; 18665 } 18666 for (int i=0; i<N; i++) { 18667 try { 18668 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18669 newUserId, callback); 18670 } catch (RemoteException e) { 18671 } 18672 } 18673 } else { 18674 synchronized (this) { 18675 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18676 } 18677 } 18678 mUserSwitchObservers.finishBroadcast(); 18679 } 18680 18681 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18682 synchronized (this) { 18683 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18684 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18685 } 18686 } 18687 18688 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18689 mCurUserSwitchCallback = null; 18690 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18691 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18692 oldUserId, newUserId, uss)); 18693 } 18694 18695 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18696 synchronized (this) { 18697 if (foreground) { 18698 moveUserToForeground(uss, oldUserId, newUserId); 18699 } 18700 } 18701 18702 completeSwitchAndInitalize(uss, newUserId, true, false); 18703 } 18704 18705 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18706 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18707 if (homeInFront) { 18708 startHomeActivityLocked(newUserId); 18709 } else { 18710 mStackSupervisor.resumeTopActivitiesLocked(); 18711 } 18712 EventLogTags.writeAmSwitchUser(newUserId); 18713 getUserManagerLocked().userForeground(newUserId); 18714 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18715 } 18716 18717 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18718 completeSwitchAndInitalize(uss, newUserId, false, true); 18719 } 18720 18721 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18722 boolean clearInitializing, boolean clearSwitching) { 18723 boolean unfrozen = false; 18724 synchronized (this) { 18725 if (clearInitializing) { 18726 uss.initializing = false; 18727 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18728 } 18729 if (clearSwitching) { 18730 uss.switching = false; 18731 } 18732 if (!uss.switching && !uss.initializing) { 18733 mWindowManager.stopFreezingScreen(); 18734 unfrozen = true; 18735 } 18736 } 18737 if (unfrozen) { 18738 final int N = mUserSwitchObservers.beginBroadcast(); 18739 for (int i=0; i<N; i++) { 18740 try { 18741 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18742 } catch (RemoteException e) { 18743 } 18744 } 18745 mUserSwitchObservers.finishBroadcast(); 18746 } 18747 } 18748 18749 void scheduleStartProfilesLocked() { 18750 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18751 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18752 DateUtils.SECOND_IN_MILLIS); 18753 } 18754 } 18755 18756 void startProfilesLocked() { 18757 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18758 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18759 mCurrentUserId, false /* enabledOnly */); 18760 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18761 for (UserInfo user : profiles) { 18762 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18763 && user.id != mCurrentUserId) { 18764 toStart.add(user); 18765 } 18766 } 18767 final int n = toStart.size(); 18768 int i = 0; 18769 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18770 startUserInBackground(toStart.get(i).id); 18771 } 18772 if (i < n) { 18773 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18774 } 18775 } 18776 18777 void finishUserBoot(UserStartedState uss) { 18778 synchronized (this) { 18779 if (uss.mState == UserStartedState.STATE_BOOTING 18780 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18781 uss.mState = UserStartedState.STATE_RUNNING; 18782 final int userId = uss.mHandle.getIdentifier(); 18783 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18784 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18785 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18786 broadcastIntentLocked(null, null, intent, 18787 null, null, 0, null, null, 18788 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18789 true, false, MY_PID, Process.SYSTEM_UID, userId); 18790 } 18791 } 18792 } 18793 18794 void finishUserSwitch(UserStartedState uss) { 18795 synchronized (this) { 18796 finishUserBoot(uss); 18797 18798 startProfilesLocked(); 18799 18800 int num = mUserLru.size(); 18801 int i = 0; 18802 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18803 Integer oldUserId = mUserLru.get(i); 18804 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18805 if (oldUss == null) { 18806 // Shouldn't happen, but be sane if it does. 18807 mUserLru.remove(i); 18808 num--; 18809 continue; 18810 } 18811 if (oldUss.mState == UserStartedState.STATE_STOPPING 18812 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18813 // This user is already stopping, doesn't count. 18814 num--; 18815 i++; 18816 continue; 18817 } 18818 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18819 // Owner and current can't be stopped, but count as running. 18820 i++; 18821 continue; 18822 } 18823 // This is a user to be stopped. 18824 stopUserLocked(oldUserId, null); 18825 num--; 18826 i++; 18827 } 18828 } 18829 } 18830 18831 @Override 18832 public int stopUser(final int userId, final IStopUserCallback callback) { 18833 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18834 != PackageManager.PERMISSION_GRANTED) { 18835 String msg = "Permission Denial: switchUser() from pid=" 18836 + Binder.getCallingPid() 18837 + ", uid=" + Binder.getCallingUid() 18838 + " requires " + INTERACT_ACROSS_USERS_FULL; 18839 Slog.w(TAG, msg); 18840 throw new SecurityException(msg); 18841 } 18842 if (userId <= 0) { 18843 throw new IllegalArgumentException("Can't stop primary user " + userId); 18844 } 18845 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18846 synchronized (this) { 18847 return stopUserLocked(userId, callback); 18848 } 18849 } 18850 18851 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18852 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18853 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18854 return ActivityManager.USER_OP_IS_CURRENT; 18855 } 18856 18857 final UserStartedState uss = mStartedUsers.get(userId); 18858 if (uss == null) { 18859 // User is not started, nothing to do... but we do need to 18860 // callback if requested. 18861 if (callback != null) { 18862 mHandler.post(new Runnable() { 18863 @Override 18864 public void run() { 18865 try { 18866 callback.userStopped(userId); 18867 } catch (RemoteException e) { 18868 } 18869 } 18870 }); 18871 } 18872 return ActivityManager.USER_OP_SUCCESS; 18873 } 18874 18875 if (callback != null) { 18876 uss.mStopCallbacks.add(callback); 18877 } 18878 18879 if (uss.mState != UserStartedState.STATE_STOPPING 18880 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18881 uss.mState = UserStartedState.STATE_STOPPING; 18882 updateStartedUserArrayLocked(); 18883 18884 long ident = Binder.clearCallingIdentity(); 18885 try { 18886 // We are going to broadcast ACTION_USER_STOPPING and then 18887 // once that is done send a final ACTION_SHUTDOWN and then 18888 // stop the user. 18889 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18890 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18891 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18892 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18893 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18894 // This is the result receiver for the final shutdown broadcast. 18895 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18896 @Override 18897 public void performReceive(Intent intent, int resultCode, String data, 18898 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18899 finishUserStop(uss); 18900 } 18901 }; 18902 // This is the result receiver for the initial stopping broadcast. 18903 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18904 @Override 18905 public void performReceive(Intent intent, int resultCode, String data, 18906 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18907 // On to the next. 18908 synchronized (ActivityManagerService.this) { 18909 if (uss.mState != UserStartedState.STATE_STOPPING) { 18910 // Whoops, we are being started back up. Abort, abort! 18911 return; 18912 } 18913 uss.mState = UserStartedState.STATE_SHUTDOWN; 18914 } 18915 mBatteryStatsService.noteEvent( 18916 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18917 Integer.toString(userId), userId); 18918 mSystemServiceManager.stopUser(userId); 18919 broadcastIntentLocked(null, null, shutdownIntent, 18920 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18921 true, false, MY_PID, Process.SYSTEM_UID, userId); 18922 } 18923 }; 18924 // Kick things off. 18925 broadcastIntentLocked(null, null, stoppingIntent, 18926 null, stoppingReceiver, 0, null, null, 18927 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18928 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18929 } finally { 18930 Binder.restoreCallingIdentity(ident); 18931 } 18932 } 18933 18934 return ActivityManager.USER_OP_SUCCESS; 18935 } 18936 18937 void finishUserStop(UserStartedState uss) { 18938 final int userId = uss.mHandle.getIdentifier(); 18939 boolean stopped; 18940 ArrayList<IStopUserCallback> callbacks; 18941 synchronized (this) { 18942 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18943 if (mStartedUsers.get(userId) != uss) { 18944 stopped = false; 18945 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18946 stopped = false; 18947 } else { 18948 stopped = true; 18949 // User can no longer run. 18950 mStartedUsers.remove(userId); 18951 mUserLru.remove(Integer.valueOf(userId)); 18952 updateStartedUserArrayLocked(); 18953 18954 // Clean up all state and processes associated with the user. 18955 // Kill all the processes for the user. 18956 forceStopUserLocked(userId, "finish user"); 18957 } 18958 18959 // Explicitly remove the old information in mRecentTasks. 18960 removeRecentTasksForUserLocked(userId); 18961 } 18962 18963 for (int i=0; i<callbacks.size(); i++) { 18964 try { 18965 if (stopped) callbacks.get(i).userStopped(userId); 18966 else callbacks.get(i).userStopAborted(userId); 18967 } catch (RemoteException e) { 18968 } 18969 } 18970 18971 if (stopped) { 18972 mSystemServiceManager.cleanupUser(userId); 18973 synchronized (this) { 18974 mStackSupervisor.removeUserLocked(userId); 18975 } 18976 } 18977 } 18978 18979 @Override 18980 public UserInfo getCurrentUser() { 18981 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18982 != PackageManager.PERMISSION_GRANTED) && ( 18983 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18984 != PackageManager.PERMISSION_GRANTED)) { 18985 String msg = "Permission Denial: getCurrentUser() from pid=" 18986 + Binder.getCallingPid() 18987 + ", uid=" + Binder.getCallingUid() 18988 + " requires " + INTERACT_ACROSS_USERS; 18989 Slog.w(TAG, msg); 18990 throw new SecurityException(msg); 18991 } 18992 synchronized (this) { 18993 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18994 return getUserManagerLocked().getUserInfo(userId); 18995 } 18996 } 18997 18998 int getCurrentUserIdLocked() { 18999 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19000 } 19001 19002 @Override 19003 public boolean isUserRunning(int userId, boolean orStopped) { 19004 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19005 != PackageManager.PERMISSION_GRANTED) { 19006 String msg = "Permission Denial: isUserRunning() from pid=" 19007 + Binder.getCallingPid() 19008 + ", uid=" + Binder.getCallingUid() 19009 + " requires " + INTERACT_ACROSS_USERS; 19010 Slog.w(TAG, msg); 19011 throw new SecurityException(msg); 19012 } 19013 synchronized (this) { 19014 return isUserRunningLocked(userId, orStopped); 19015 } 19016 } 19017 19018 boolean isUserRunningLocked(int userId, boolean orStopped) { 19019 UserStartedState state = mStartedUsers.get(userId); 19020 if (state == null) { 19021 return false; 19022 } 19023 if (orStopped) { 19024 return true; 19025 } 19026 return state.mState != UserStartedState.STATE_STOPPING 19027 && state.mState != UserStartedState.STATE_SHUTDOWN; 19028 } 19029 19030 @Override 19031 public int[] getRunningUserIds() { 19032 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19033 != PackageManager.PERMISSION_GRANTED) { 19034 String msg = "Permission Denial: isUserRunning() from pid=" 19035 + Binder.getCallingPid() 19036 + ", uid=" + Binder.getCallingUid() 19037 + " requires " + INTERACT_ACROSS_USERS; 19038 Slog.w(TAG, msg); 19039 throw new SecurityException(msg); 19040 } 19041 synchronized (this) { 19042 return mStartedUserArray; 19043 } 19044 } 19045 19046 private void updateStartedUserArrayLocked() { 19047 int num = 0; 19048 for (int i=0; i<mStartedUsers.size(); i++) { 19049 UserStartedState uss = mStartedUsers.valueAt(i); 19050 // This list does not include stopping users. 19051 if (uss.mState != UserStartedState.STATE_STOPPING 19052 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19053 num++; 19054 } 19055 } 19056 mStartedUserArray = new int[num]; 19057 num = 0; 19058 for (int i=0; i<mStartedUsers.size(); i++) { 19059 UserStartedState uss = mStartedUsers.valueAt(i); 19060 if (uss.mState != UserStartedState.STATE_STOPPING 19061 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19062 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19063 num++; 19064 } 19065 } 19066 } 19067 19068 @Override 19069 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19070 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19071 != PackageManager.PERMISSION_GRANTED) { 19072 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19073 + Binder.getCallingPid() 19074 + ", uid=" + Binder.getCallingUid() 19075 + " requires " + INTERACT_ACROSS_USERS_FULL; 19076 Slog.w(TAG, msg); 19077 throw new SecurityException(msg); 19078 } 19079 19080 mUserSwitchObservers.register(observer); 19081 } 19082 19083 @Override 19084 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19085 mUserSwitchObservers.unregister(observer); 19086 } 19087 19088 private boolean userExists(int userId) { 19089 if (userId == 0) { 19090 return true; 19091 } 19092 UserManagerService ums = getUserManagerLocked(); 19093 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19094 } 19095 19096 int[] getUsersLocked() { 19097 UserManagerService ums = getUserManagerLocked(); 19098 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19099 } 19100 19101 UserManagerService getUserManagerLocked() { 19102 if (mUserManager == null) { 19103 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19104 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19105 } 19106 return mUserManager; 19107 } 19108 19109 private int applyUserId(int uid, int userId) { 19110 return UserHandle.getUid(userId, uid); 19111 } 19112 19113 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19114 if (info == null) return null; 19115 ApplicationInfo newInfo = new ApplicationInfo(info); 19116 newInfo.uid = applyUserId(info.uid, userId); 19117 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19118 + info.packageName; 19119 return newInfo; 19120 } 19121 19122 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19123 if (aInfo == null 19124 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19125 return aInfo; 19126 } 19127 19128 ActivityInfo info = new ActivityInfo(aInfo); 19129 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19130 return info; 19131 } 19132 19133 private final class LocalService extends ActivityManagerInternal { 19134 @Override 19135 public void goingToSleep() { 19136 ActivityManagerService.this.goingToSleep(); 19137 } 19138 19139 @Override 19140 public void wakingUp() { 19141 ActivityManagerService.this.wakingUp(); 19142 } 19143 19144 @Override 19145 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19146 String processName, String abiOverride, int uid, Runnable crashHandler) { 19147 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19148 processName, abiOverride, uid, crashHandler); 19149 } 19150 } 19151 19152 /** 19153 * An implementation of IAppTask, that allows an app to manage its own tasks via 19154 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19155 * only the process that calls getAppTasks() can call the AppTask methods. 19156 */ 19157 class AppTaskImpl extends IAppTask.Stub { 19158 private int mTaskId; 19159 private int mCallingUid; 19160 19161 public AppTaskImpl(int taskId, int callingUid) { 19162 mTaskId = taskId; 19163 mCallingUid = callingUid; 19164 } 19165 19166 private void checkCaller() { 19167 if (mCallingUid != Binder.getCallingUid()) { 19168 throw new SecurityException("Caller " + mCallingUid 19169 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19170 } 19171 } 19172 19173 @Override 19174 public void finishAndRemoveTask() { 19175 checkCaller(); 19176 19177 synchronized (ActivityManagerService.this) { 19178 long origId = Binder.clearCallingIdentity(); 19179 try { 19180 if (!removeTaskByIdLocked(mTaskId, false)) { 19181 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19182 } 19183 } finally { 19184 Binder.restoreCallingIdentity(origId); 19185 } 19186 } 19187 } 19188 19189 @Override 19190 public ActivityManager.RecentTaskInfo getTaskInfo() { 19191 checkCaller(); 19192 19193 synchronized (ActivityManagerService.this) { 19194 long origId = Binder.clearCallingIdentity(); 19195 try { 19196 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19197 if (tr == null) { 19198 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19199 } 19200 return createRecentTaskInfoFromTaskRecord(tr); 19201 } finally { 19202 Binder.restoreCallingIdentity(origId); 19203 } 19204 } 19205 } 19206 19207 @Override 19208 public void moveToFront() { 19209 checkCaller(); 19210 19211 final TaskRecord tr; 19212 synchronized (ActivityManagerService.this) { 19213 tr = recentTaskForIdLocked(mTaskId); 19214 if (tr == null) { 19215 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19216 } 19217 if (tr.getRootActivity() != null) { 19218 moveTaskToFrontLocked(tr.taskId, 0, null); 19219 return; 19220 } 19221 } 19222 19223 startActivityFromRecentsInner(tr.taskId, null); 19224 } 19225 19226 @Override 19227 public int startActivity(IBinder whoThread, String callingPackage, 19228 Intent intent, String resolvedType, Bundle options) { 19229 checkCaller(); 19230 19231 int callingUser = UserHandle.getCallingUserId(); 19232 TaskRecord tr; 19233 IApplicationThread appThread; 19234 synchronized (ActivityManagerService.this) { 19235 tr = recentTaskForIdLocked(mTaskId); 19236 if (tr == null) { 19237 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19238 } 19239 appThread = ApplicationThreadNative.asInterface(whoThread); 19240 if (appThread == null) { 19241 throw new IllegalArgumentException("Bad app thread " + appThread); 19242 } 19243 } 19244 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19245 resolvedType, null, null, null, null, 0, 0, null, null, 19246 null, options, callingUser, null, tr); 19247 } 19248 19249 @Override 19250 public void setExcludeFromRecents(boolean exclude) { 19251 checkCaller(); 19252 19253 synchronized (ActivityManagerService.this) { 19254 long origId = Binder.clearCallingIdentity(); 19255 try { 19256 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19257 if (tr == null) { 19258 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19259 } 19260 Intent intent = tr.getBaseIntent(); 19261 if (exclude) { 19262 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19263 } else { 19264 intent.setFlags(intent.getFlags() 19265 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19266 } 19267 } finally { 19268 Binder.restoreCallingIdentity(origId); 19269 } 19270 } 19271 } 19272 } 19273} 19274